Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@ -11,14 +11,14 @@ using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using SD = System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.ExceptionServices;
namespace Mono.Net.Security
{
delegate AsyncOperationStatus AsyncOperation (AsyncProtocolRequest asyncRequest, AsyncOperationStatus status);
class BufferOffsetSize
{
public byte[] Buffer;
@ -37,6 +37,13 @@ namespace Mono.Net.Security
public BufferOffsetSize (byte[] buffer, int offset, int size)
{
if (buffer == null)
throw new ArgumentNullException (nameof (buffer));
if (offset < 0)
throw new ArgumentOutOfRangeException (nameof (offset));
if (size < 0 || offset + size > buffer.Length)
throw new ArgumentOutOfRangeException (nameof (size));
Buffer = buffer;
Offset = offset;
Size = size;
@ -54,7 +61,7 @@ namespace Mono.Net.Security
public readonly int InitialSize;
public BufferOffsetSize2 (int size)
: base (new byte [size], 0, 0)
: base (new byte[size], 0, 0)
{
InitialSize = size;
}
@ -63,7 +70,7 @@ namespace Mono.Net.Security
{
Offset = Size = 0;
TotalBytes = 0;
Buffer = new byte [InitialSize];
Buffer = new byte[InitialSize];
Complete = false;
}
@ -74,11 +81,11 @@ namespace Mono.Net.Security
int missing = size - Remaining;
if (Offset == 0 && Size == 0) {
Buffer = new byte [size];
Buffer = new byte[size];
return;
}
var buffer = new byte [Buffer.Length + missing];
var buffer = new byte[Buffer.Length + missing];
Buffer.CopyTo (buffer, 0);
Buffer = buffer;
}
@ -91,201 +98,296 @@ namespace Mono.Net.Security
}
}
enum AsyncOperationStatus {
NotStarted,
enum AsyncOperationStatus
{
Initialize,
Continue,
Running,
Complete,
WantRead,
WantWrite,
ReadDone,
FinishWrite
Complete
}
class AsyncProtocolRequest
class AsyncProtocolResult
{
public readonly MobileAuthenticatedStream Parent;
public readonly BufferOffsetSize UserBuffer;
int RequestedSize;
public int CurrentSize;
public int UserResult;
AsyncOperation Operation;
int Status;
public readonly int ID = ++next_id;
static int next_id;
public readonly LazyAsyncResult UserAsyncResult;
public AsyncProtocolRequest (MobileAuthenticatedStream parent, LazyAsyncResult lazyResult, BufferOffsetSize userBuffer = null)
{
Parent = parent;
UserAsyncResult = lazyResult;
UserBuffer = userBuffer;
public int UserResult {
get;
}
public ExceptionDispatchInfo Error {
get;
}
public bool CompleteWithError (Exception ex)
public AsyncProtocolResult (int result)
{
Status = (int)AsyncOperationStatus.Complete;
if (UserAsyncResult == null)
return true;
if (!UserAsyncResult.InternalPeekCompleted)
UserAsyncResult.InvokeCallback (ex);
return false;
UserResult = result;
}
public AsyncProtocolResult (ExceptionDispatchInfo error)
{
Error = error;
}
}
abstract class AsyncProtocolRequest
{
public MobileAuthenticatedStream Parent {
get;
}
public bool RunSynchronously {
get;
}
public int ID => ++next_id;
public string Name => GetType ().Name;
public int UserResult {
get;
protected set;
}
int Started;
int RequestedSize;
int WriteRequested;
readonly object locker = new object ();
static int next_id;
public AsyncProtocolRequest (MobileAuthenticatedStream parent, bool sync)
{
Parent = parent;
RunSynchronously = sync;
}
[SD.Conditional ("MARTIN_DEBUG")]
protected void Debug (string message, params object[] args)
{
Parent.Debug ("AsyncProtocolRequest({0}:{1}): {2}", Parent.ID, ID, string.Format (message, args));
Parent.Debug ("{0}({1}:{2}): {3}", Name, Parent.ID, ID, string.Format (message, args));
}
internal void RequestRead (int size)
{
var oldStatus = (AsyncOperationStatus)Interlocked.CompareExchange (ref Status, (int)AsyncOperationStatus.WantRead, (int)AsyncOperationStatus.Running);
Debug ("RequestRead: {0} {1}", oldStatus, size);
if (oldStatus == AsyncOperationStatus.Running)
RequestedSize = size;
else if (oldStatus == AsyncOperationStatus.WantRead)
lock (locker) {
RequestedSize += size;
else if (oldStatus != AsyncOperationStatus.WantWrite)
throw new InvalidOperationException ();
}
internal void ResetRead ()
{
var oldStatus = (AsyncOperationStatus)Interlocked.CompareExchange (ref Status, (int)AsyncOperationStatus.Complete, (int)AsyncOperationStatus.WantRead);
Debug ("ResetRead: {0} {1}", oldStatus, Status);
}
internal void ResetWrite ()
{
var oldStatus = (AsyncOperationStatus)Interlocked.CompareExchange (ref Status, (int)AsyncOperationStatus.Complete, (int)AsyncOperationStatus.WantWrite);
Debug ("ResetWrite: {0} {1}", oldStatus, Status);
Debug ("RequestRead: {0}", size);
}
}
internal void RequestWrite ()
{
var oldStatus = (AsyncOperationStatus)Interlocked.CompareExchange (ref Status, (int)AsyncOperationStatus.WantWrite, (int)AsyncOperationStatus.Running);
Debug ("RequestWrite: {0} {1}", oldStatus, Status);
if (oldStatus == AsyncOperationStatus.Running)
return;
else if (oldStatus != AsyncOperationStatus.WantRead && oldStatus != AsyncOperationStatus.WantWrite)
throw new InvalidOperationException ();
WriteRequested = 1;
}
internal void StartOperation (AsyncOperation operation)
internal async Task<AsyncProtocolResult> StartOperation (CancellationToken cancellationToken)
{
Debug ("Start Operation: {0} {1}", Status, operation);
if (Interlocked.CompareExchange (ref Status, (int)AsyncOperationStatus.Initialize, (int)AsyncOperationStatus.NotStarted) != (int)AsyncOperationStatus.NotStarted)
Debug ("Start Operation: {0}", this);
if (Interlocked.CompareExchange (ref Started, 1, 0) != 0)
throw new InvalidOperationException ();
Operation = operation;
if (UserAsyncResult == null) {
StartOperation ();
return;
}
ThreadPool.QueueUserWorkItem (_ => StartOperation ());
}
void StartOperation ()
{
try {
ProcessOperation ();
if (UserAsyncResult != null && !UserAsyncResult.InternalPeekCompleted)
UserAsyncResult.InvokeCallback (UserResult);
await ProcessOperation (cancellationToken).ConfigureAwait (false);
return new AsyncProtocolResult (UserResult);
} catch (Exception ex) {
if (UserAsyncResult == null)
throw;
if (!UserAsyncResult.InternalPeekCompleted)
UserAsyncResult.InvokeCallback (ex);
var info = Parent.SetException (MobileAuthenticatedStream.GetSSPIException (ex));
return new AsyncProtocolResult (info);
}
}
void ProcessOperation ()
async Task ProcessOperation (CancellationToken cancellationToken)
{
AsyncOperationStatus status;
do {
status = (AsyncOperationStatus)Interlocked.Exchange (ref Status, (int)AsyncOperationStatus.Running);
var status = AsyncOperationStatus.Initialize;
while (status != AsyncOperationStatus.Complete) {
cancellationToken.ThrowIfCancellationRequested ();
Debug ("ProcessOperation: {0}", status);
status = ProcessOperation (status);
Debug ("ProcessOperation done: {0}", status);
AsyncOperationStatus oldStatus;
if (status == AsyncOperationStatus.Complete) {
oldStatus = (AsyncOperationStatus)Interlocked.CompareExchange (ref Status, (int)AsyncOperationStatus.FinishWrite, (int)AsyncOperationStatus.WantWrite);
if (oldStatus == AsyncOperationStatus.WantWrite) {
// We are done, but still need to flush the write queue.
status = AsyncOperationStatus.FinishWrite;
continue;
var ret = await InnerRead (cancellationToken).ConfigureAwait (false);
if (ret != null) {
if (ret == 0) {
// End-of-stream
Debug ("END OF STREAM!");
status = AsyncOperationStatus.ReadDone;
} else if (ret < 0) {
// remote prematurely closed connection.
throw new IOException ("Remote prematurely closed connection.");
}
}
oldStatus = (AsyncOperationStatus)Interlocked.CompareExchange (ref Status, (int)status, (int)AsyncOperationStatus.Running);
Debug ("ProcessOperation done: {0} -> {1}", oldStatus, status);
Debug ("ProcessOperation run: {0}", status);
if (oldStatus != AsyncOperationStatus.Running) {
if (status == oldStatus || status == AsyncOperationStatus.Continue || status == AsyncOperationStatus.Complete)
status = oldStatus;
else
throw new InvalidOperationException ();
AsyncOperationStatus newStatus;
switch (status) {
case AsyncOperationStatus.Initialize:
case AsyncOperationStatus.Continue:
case AsyncOperationStatus.ReadDone:
newStatus = Run (status);
break;
default:
throw new InvalidOperationException ();
}
} while (status != AsyncOperationStatus.Complete);
if (Interlocked.Exchange (ref WriteRequested, 0) != 0) {
// Flush the write queue.
await Parent.InnerWrite (RunSynchronously, cancellationToken);
}
Debug ("ProcessOperation done: {0} -> {1}", status, newStatus);
status = newStatus;
}
}
AsyncOperationStatus ProcessOperation (AsyncOperationStatus status)
async Task<int?> InnerRead (CancellationToken cancellationToken)
{
if (status == AsyncOperationStatus.WantRead) {
if (RequestedSize < 0)
int? totalRead = null;
var requestedSize = Interlocked.Exchange (ref RequestedSize, 0);
while (requestedSize > 0) {
Debug ("ProcessOperation - read inner: {0}", requestedSize);
var ret = await Parent.InnerRead (RunSynchronously, requestedSize, cancellationToken).ConfigureAwait (false);
Debug ("ProcessOperation - read inner done: {0} - {1}", requestedSize, ret);
if (ret <= 0)
return ret;
if (ret > requestedSize)
throw new InvalidOperationException ();
else if (RequestedSize == 0)
return AsyncOperationStatus.Continue;
Debug ("ProcessOperation - read inner: {0}", RequestedSize);
var ret = Parent.InnerRead (RequestedSize);
Debug ("ProcessOperation - read inner done: {0} - {1}", RequestedSize, ret);
totalRead += ret;
requestedSize -= ret;
var newRequestedSize = Interlocked.Exchange (ref RequestedSize, 0);
requestedSize += newRequestedSize;
}
if (ret < 0)
return AsyncOperationStatus.ReadDone;
return totalRead;
}
RequestedSize -= ret;
/*
* This will operate on the internal buffers and never block.
*/
protected abstract AsyncOperationStatus Run (AsyncOperationStatus status);
if (ret == 0 || RequestedSize == 0)
return AsyncOperationStatus.Continue;
else
return AsyncOperationStatus.WantRead;
} else if (status == AsyncOperationStatus.WantWrite) {
Debug ("ProcessOperation - want write");
Parent.InnerWrite ();
Debug ("ProcessOperation - want write done");
return AsyncOperationStatus.Continue;
} else if (status == AsyncOperationStatus.Initialize || status == AsyncOperationStatus.Continue) {
Debug ("ProcessOperation - continue");
status = Operation (this, status);
Debug ("ProcessOperation - continue done: {0}", status);
return status;
} else if (status == AsyncOperationStatus.ReadDone) {
Debug ("ProcessOperation - read done");
status = Operation (this, status);
Debug ("ProcessOperation - read done: {0}", status);
return status;
} else if (status == AsyncOperationStatus.FinishWrite) {
Debug ("ProcessOperation - finish write");
Parent.InnerWrite ();
Debug ("ProcessOperation - finish write done");
public override string ToString ()
{
return string.Format ("[{0}]", Name);
}
}
class AsyncHandshakeRequest : AsyncProtocolRequest
{
public AsyncHandshakeRequest (MobileAuthenticatedStream parent, bool sync)
: base (parent, sync)
{
}
protected override AsyncOperationStatus Run (AsyncOperationStatus status)
{
return Parent.ProcessHandshake (status);
}
}
abstract class AsyncReadOrWriteRequest : AsyncProtocolRequest
{
protected BufferOffsetSize UserBuffer {
get;
}
protected int CurrentSize {
get; set;
}
public AsyncReadOrWriteRequest (MobileAuthenticatedStream parent, bool sync, byte[] buffer, int offset, int size)
: base (parent, sync)
{
UserBuffer = new BufferOffsetSize (buffer, offset, size);
}
public override string ToString ()
{
return string.Format ("[{0}: {1}]", Name, UserBuffer);
}
}
class AsyncReadRequest : AsyncReadOrWriteRequest
{
public AsyncReadRequest (MobileAuthenticatedStream parent, bool sync, byte[] buffer, int offset, int size)
: base (parent, sync, buffer, offset, size)
{
}
protected override AsyncOperationStatus Run (AsyncOperationStatus status)
{
Debug ("ProcessRead - read user: {0} {1}", this, status);
var (ret, wantMore) = Parent.ProcessRead (UserBuffer);
Debug ("ProcessRead - read user done: {0} - {1} {2}", this, ret, wantMore);
if (ret < 0) {
UserResult = -1;
return AsyncOperationStatus.Complete;
}
throw new InvalidOperationException ();
CurrentSize += ret;
UserBuffer.Offset += ret;
UserBuffer.Size -= ret;
Debug ("Process Read - read user done #1: {0} - {1} {2}", this, CurrentSize, wantMore);
if (wantMore && CurrentSize == 0)
return AsyncOperationStatus.Continue;
UserResult = CurrentSize;
return AsyncOperationStatus.Complete;
}
}
class AsyncWriteRequest : AsyncReadOrWriteRequest
{
public AsyncWriteRequest (MobileAuthenticatedStream parent, bool sync, byte[] buffer, int offset, int size)
: base (parent, sync, buffer, offset, size)
{
}
protected override AsyncOperationStatus Run (AsyncOperationStatus status)
{
Debug ("ProcessWrite - write user: {0} {1}", this, status);
if (UserBuffer.Size == 0) {
UserResult = CurrentSize;
return AsyncOperationStatus.Complete;
}
var (ret, wantMore) = Parent.ProcessWrite (UserBuffer);
Debug ("ProcessWrite - write user done: {0} - {1} {2}", this, ret, wantMore);
if (ret < 0) {
UserResult = -1;
return AsyncOperationStatus.Complete;
}
CurrentSize += ret;
UserBuffer.Offset += ret;
UserBuffer.Size -= ret;
if (wantMore)
return AsyncOperationStatus.Continue;
UserResult = CurrentSize;
return AsyncOperationStatus.Complete;
}
}
class AsyncShutdownRequest : AsyncProtocolRequest
{
public AsyncShutdownRequest (MobileAuthenticatedStream parent)
: base (parent, false)
{
}
protected override AsyncOperationStatus Run (AsyncOperationStatus status)
{
return Parent.ProcessShutdown (status);
}
}
}
#endif

View File

@ -1,233 +0,0 @@
//
// IMonoSslStream.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Threading.Tasks;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
namespace Mono.Net.Security
{
interface IMonoSslStream : IDisposable
{
AuthenticatedStream AuthenticatedStream {
get;
}
void AuthenticateAsClient (string targetHost);
void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
AsyncCallback asyncCallback, object asyncState);
void EndAuthenticateAsClient (IAsyncResult asyncResult);
void AuthenticateAsServer (X509Certificate serverCertificate);
void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
AsyncCallback asyncCallback,
object asyncState);
void EndAuthenticateAsServer (IAsyncResult asyncResult);
TransportContext TransportContext {
get;
}
Task AuthenticateAsClientAsync (string targetHost);
Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
//
//
// Base class properties
//
bool IsAuthenticated {
get;
}
bool IsMutuallyAuthenticated {
get;
}
bool IsEncrypted {
get;
}
bool IsSigned {
get;
}
bool IsServer {
get;
}
//
//
//SSL specific properties
//
//
SslProtocols SslProtocol {
get;
}
bool CheckCertRevocationStatus {
get;
}
X509Certificate InternalLocalCertificate {
get;
}
X509Certificate LocalCertificate {
get;
}
X509Certificate RemoteCertificate {
get;
}
//
// More informational properties
//
CipherAlgorithmType CipherAlgorithm {
get;
}
int CipherStrength {
get;
}
HashAlgorithmType HashAlgorithm {
get;
}
int HashStrength {
get;
}
ExchangeAlgorithmType KeyExchangeAlgorithm {
get;
}
int KeyExchangeStrength {
get;
}
//
//
// Stream contract implementation
//
//
//
bool CanRead {
get;
}
bool CanTimeout {
get;
}
bool CanWrite {
get;
}
int ReadTimeout {
get;
set;
}
int WriteTimeout {
get;
set;
}
long Length {
get;
}
long Position {
get;
}
void SetLength (long value);
void Flush ();
int Read (byte[] buffer, int offset, int count);
void Write (byte[] buffer);
void Write (byte[] buffer, int offset, int count);
IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState);
int EndRead (IAsyncResult asyncResult);
IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState);
void EndWrite (IAsyncResult asyncResult);
#if SECURITY_DEP
MSI.MonoTlsProvider Provider {
get;
}
MSI.MonoTlsConnectionInfo GetConnectionInfo ();
#endif
}
}

View File

@ -1,74 +0,0 @@
//
// IMonoTlsProvider.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
#else
using Mono.Security.Interface;
#endif
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security
{
/*
* For consumption within System.dll only - do not access from friend assemblies.
*
* Unfortunately, there's some compiler madness involved when using Mono.Security.dll
* APIs from within System.dll because the compiler perceives those types which come
* from the prebuilt version of System.dll being different from those it's currently
* compiling. At runtime, there is only one single System.dll, so these all map to
* the same actual type.
*
* This internal interface helps to keep all this compilation stuff contained within
* the 'Mono.Net.Security.Private' namespace - this namespace should be considered
* strictly private and must not be accessed from files outside the Mono.Net.Security
* directory.
*
*/
interface IMonoTlsProvider
{
#if SECURITY_DEP
MonoTlsProvider Provider {
get;
}
IMonoSslStream CreateSslStream (
Stream innerStream, bool leaveInnerStreamOpen,
MonoTlsSettings settings);
#endif
}
}

View File

@ -81,16 +81,16 @@ namespace Mono.Net.Security.Private
SslStreamBase ssl_stream;
ICertificateValidator certificateValidator;
MonoTlsProvider provider;
#endregion // Fields
#region Constructors
public LegacySslStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings)
public LegacySslStream (Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, MonoTlsProvider provider, MonoTlsSettings settings)
: base (innerStream, leaveInnerStreamOpen)
{
this.provider = provider;
SslStream = owner;
Provider = provider;
certificateValidator = ChainValidationHelper.GetInternalValidator (provider, settings);
}
#endregion // Constructors
@ -575,6 +575,11 @@ namespace Mono.Net.Security.Private
#region IMonoSslStream
Task IMonoSslStream.ShutdownAsync ()
{
return Task.CompletedTask;
}
AuthenticatedStream IMonoSslStream.AuthenticatedStream {
get { return this; }
}
@ -583,11 +588,15 @@ namespace Mono.Net.Security.Private
get { throw new NotSupportedException (); }
}
MonoTlsProvider IMonoSslStream.Provider {
get { return provider; }
public SslStream SslStream {
get;
}
MonoTlsConnectionInfo IMonoSslStream.GetConnectionInfo ()
public MonoTlsProvider Provider {
get;
}
public MonoTlsConnectionInfo GetConnectionInfo ()
{
return null;
}

View File

@ -48,10 +48,8 @@ namespace Mono.Net.Security
*/
class LegacyTlsProvider : MSI.MonoTlsProvider
{
static readonly Guid id = new Guid ("809e77d5-56cc-4da8-b9f0-45e65ba9cceb");
public override Guid ID {
get { return id; }
get { return MonoTlsProviderFactory.LegacyId; }
}
public override string Name {
@ -78,8 +76,14 @@ namespace Mono.Net.Security
Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings = null)
{
var impl = new Private.LegacySslStream (innerStream, leaveInnerStreamOpen, this, settings);
return new Private.MonoSslStreamImpl (impl);
return SslStream.CreateMonoSslStream (innerStream, leaveInnerStreamOpen, this, settings);
}
internal override MSI.IMonoSslStream CreateSslStreamInternal (
SslStream sslStream, Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings)
{
return new Private.LegacySslStream (innerStream, leaveInnerStreamOpen, sslStream, this, settings);
}
internal override bool ValidateCertificate (

View File

@ -169,7 +169,7 @@ namespace Mono.Net.Security
public abstract int Write (byte[] buffer, int offset, int count, out bool wantMore);
public abstract void Close ();
public abstract void Shutdown ();
protected bool ValidateCertificate (X509Certificate leaf, X509Chain chain)
{

View File

@ -1,318 +0,0 @@
//
// MonoSslStream.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Threading.Tasks;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*/
class MonoSslStreamImpl : MSI.IMonoSslStream
{
IMonoSslStream impl;
internal IMonoSslStream Impl {
get {
CheckDisposed ();
return impl;
}
}
public MonoSslStreamImpl (IMonoSslStream impl)
{
this.impl = impl;
}
public void AuthenticateAsClient (string targetHost)
{
Impl.AuthenticateAsClient (targetHost);
}
public void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsClient (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsClient (asyncResult);
}
public void AuthenticateAsServer (X509Certificate serverCertificate)
{
Impl.AuthenticateAsServer (serverCertificate);
}
public void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsServer (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsServer (asyncResult);
}
public Task AuthenticateAsClientAsync (string targetHost)
{
return Impl.AuthenticateAsClientAsync (targetHost);
}
public Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
{
return Impl.AuthenticateAsServerAsync (serverCertificate);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
}
public void Flush ()
{
Impl.Flush ();
}
public int Read (byte[] buffer, int offset, int count)
{
return Impl.Read (buffer, offset, count);
}
public void Write (byte[] buffer)
{
Impl.Write (buffer);
}
public void Write (byte[] buffer, int offset, int count)
{
Impl.Write (buffer, offset, count);
}
public IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
}
public int EndRead (IAsyncResult asyncResult)
{
return Impl.EndRead (asyncResult);
}
public IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
}
public void EndWrite (IAsyncResult asyncResult)
{
Impl.EndWrite (asyncResult);
}
public TransportContext TransportContext {
get { return Impl.TransportContext; }
}
public bool IsAuthenticated {
get { return Impl.IsAuthenticated; }
}
public bool IsMutuallyAuthenticated {
get { return Impl.IsMutuallyAuthenticated; }
}
public bool IsEncrypted {
get { return Impl.IsEncrypted; }
}
public bool IsSigned {
get { return Impl.IsSigned; }
}
public bool IsServer {
get { return Impl.IsServer; }
}
public CipherAlgorithmType CipherAlgorithm {
get { return Impl.CipherAlgorithm; }
}
public int CipherStrength {
get { return Impl.CipherStrength; }
}
public HashAlgorithmType HashAlgorithm {
get { return Impl.HashAlgorithm; }
}
public int HashStrength {
get { return Impl.HashStrength; }
}
public ExchangeAlgorithmType KeyExchangeAlgorithm {
get { return Impl.KeyExchangeAlgorithm; }
}
public int KeyExchangeStrength {
get { return Impl.KeyExchangeStrength; }
}
public bool CanRead {
get { return Impl.CanRead; }
}
public bool CanTimeout {
get { return Impl.CanTimeout; }
}
public bool CanWrite {
get { return Impl.CanWrite; }
}
public long Length {
get { return Impl.Length; }
}
public long Position {
get { return Impl.Position; }
}
public void SetLength (long value)
{
Impl.SetLength (value);
}
public AuthenticatedStream AuthenticatedStream {
get { return Impl.AuthenticatedStream; }
}
public int ReadTimeout {
get { return Impl.ReadTimeout; }
set { Impl.ReadTimeout = value; }
}
public int WriteTimeout {
get { return Impl.WriteTimeout; }
set { Impl.WriteTimeout = value; }
}
public bool CheckCertRevocationStatus {
get { return Impl.CheckCertRevocationStatus; }
}
public X509Certificate InternalLocalCertificate {
get { return Impl.InternalLocalCertificate; }
}
public X509Certificate LocalCertificate {
get { return Impl.LocalCertificate; }
}
public X509Certificate RemoteCertificate {
get { return Impl.RemoteCertificate; }
}
public SslProtocols SslProtocol {
get { return Impl.SslProtocol; }
}
public MSI.MonoTlsProvider Provider {
get { return Impl.Provider; }
}
public MSI.MonoTlsConnectionInfo GetConnectionInfo ()
{
return Impl.GetConnectionInfo ();
}
void CheckDisposed ()
{
if (impl == null)
throw new ObjectDisposedException ("MonoSslStream");
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
if (impl != null && disposing) {
impl.Dispose ();
impl = null;
}
}
}
}
#endif

View File

@ -1,316 +0,0 @@
//
// MonoSslStreamImpl.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
using System.Threading.Tasks;
namespace Mono.Net.Security.Private
{
class MonoSslStreamWrapper : IMonoSslStream
{
MSI.IMonoSslStream impl;
internal MSI.IMonoSslStream Impl {
get {
CheckDisposed ();
return impl;
}
}
public MonoSslStreamWrapper (MSI.IMonoSslStream impl)
{
this.impl = impl;
}
public void AuthenticateAsClient (string targetHost)
{
Impl.AuthenticateAsClient (targetHost);
}
public void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsClient (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsClient (asyncResult);
}
public void AuthenticateAsServer (X509Certificate serverCertificate)
{
Impl.AuthenticateAsServer (serverCertificate);
}
public void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsServer (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsServer (asyncResult);
}
public Task AuthenticateAsClientAsync (string targetHost)
{
return Impl.AuthenticateAsClientAsync (targetHost);
}
public Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
{
return Impl.AuthenticateAsServerAsync (serverCertificate);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation);
}
public void Flush ()
{
Impl.Flush ();
}
public int Read (byte[] buffer, int offset, int count)
{
return Impl.Read (buffer, offset, count);
}
public void Write (byte[] buffer)
{
Impl.Write (buffer);
}
public void Write (byte[] buffer, int offset, int count)
{
Impl.Write (buffer, offset, count);
}
public IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
}
public int EndRead (IAsyncResult asyncResult)
{
return Impl.EndRead (asyncResult);
}
public IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
}
public void EndWrite (IAsyncResult asyncResult)
{
Impl.EndWrite (asyncResult);
}
public TransportContext TransportContext {
get { return Impl.TransportContext; }
}
public bool IsAuthenticated {
get { return Impl.IsAuthenticated; }
}
public bool IsMutuallyAuthenticated {
get { return Impl.IsMutuallyAuthenticated; }
}
public bool IsEncrypted {
get { return Impl.IsEncrypted; }
}
public bool IsSigned {
get { return Impl.IsSigned; }
}
public bool IsServer {
get { return Impl.IsServer; }
}
public CipherAlgorithmType CipherAlgorithm {
get { return (CipherAlgorithmType)Impl.CipherAlgorithm; }
}
public int CipherStrength {
get { return Impl.CipherStrength; }
}
public HashAlgorithmType HashAlgorithm {
get { return (HashAlgorithmType)Impl.HashAlgorithm; }
}
public int HashStrength {
get { return Impl.HashStrength; }
}
public ExchangeAlgorithmType KeyExchangeAlgorithm {
get { return (ExchangeAlgorithmType)Impl.KeyExchangeAlgorithm; }
}
public int KeyExchangeStrength {
get { return Impl.KeyExchangeStrength; }
}
public bool CanRead {
get { return Impl.CanRead; }
}
public bool CanTimeout {
get { return Impl.CanTimeout; }
}
public bool CanWrite {
get { return Impl.CanWrite; }
}
public long Length {
get { return Impl.Length; }
}
public long Position {
get { return Impl.Position; }
}
public void SetLength (long value)
{
Impl.SetLength (value);
}
public AuthenticatedStream AuthenticatedStream {
get { return Impl.AuthenticatedStream; }
}
public int ReadTimeout {
get { return Impl.ReadTimeout; }
set { Impl.ReadTimeout = value; }
}
public int WriteTimeout {
get { return Impl.WriteTimeout; }
set { Impl.WriteTimeout = value; }
}
public bool CheckCertRevocationStatus {
get { return Impl.CheckCertRevocationStatus; }
}
X509Certificate IMonoSslStream.InternalLocalCertificate {
get { return Impl.InternalLocalCertificate; }
}
public X509Certificate LocalCertificate {
get { return Impl.LocalCertificate; }
}
public X509Certificate RemoteCertificate {
get { return Impl.RemoteCertificate; }
}
public SslProtocols SslProtocol {
get { return (SslProtocols)Impl.SslProtocol; }
}
public MSI.MonoTlsProvider Provider {
get { return Impl.Provider; }
}
public MSI.MonoTlsConnectionInfo GetConnectionInfo ()
{
return Impl.GetConnectionInfo ();
}
void CheckDisposed ()
{
if (impl == null)
throw new ObjectDisposedException ("MonoSslStream");
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected void Dispose (bool disposing)
{
if (impl != null && disposing) {
impl.Dispose ();
impl = null;
}
}
}
}
#endif

View File

@ -1,146 +0,0 @@
//
// MonoTlsProviderFactory.cs
//
// Author:
// Chris Hamons <chris.hamons@xamarin.com>
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if !ONLY_APPLETLS
#error Use MonoTlsProviderFactory.cs instead
#endif
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
using MSI = MonoSecurity::Mono.Security.Interface;
using MX = MonoSecurity::Mono.Security.X509;
#else
using MSI = Mono.Security.Interface;
using MX = Mono.Security.X509;
#endif
using System.Security.Cryptography.X509Certificates;
using Mono.AppleTls;
#endif
using System;
using System.Net;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Mono.Net.Security
{
/*
* Keep in sync with Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs.
* Simple implementation that does hard codes only a single provider
*/
static partial class MonoTlsProviderFactory
{
#region Internal API
/*
* APIs in this section are for consumption within System.dll only - do not access via
* reflection or from friend assemblies.
*
* @IMonoTlsProvider is defined as empty interface outside 'SECURITY_DEP', so we don't need
* this conditional here.
*/
internal static IMonoTlsProvider GetProviderInternal ()
{
#if SECURITY_DEP
return GetTlsProvider ();
#else
throw new NotSupportedException ("TLS Support not available.");
#endif
}
#endregion
#if SECURITY_DEP
static object locker = new object ();
static IMonoTlsProvider provider;
static IMonoTlsProvider GetTlsProvider ()
{
lock (locker) {
if (provider == null)
provider = new Private.MonoTlsProviderWrapper (new AppleTlsProvider ());
return provider;
}
}
#region Mono.Security visible API
/*
* "Public" section, intended to be consumed via reflection.
*
* Mono.Security.dll provides a public wrapper around these.
*/
internal static MSI.MonoTlsProvider GetProvider ()
{
return GetTlsProvider ().Provider;
}
internal static bool IsProviderSupported (string name)
{
return true;
}
internal static MSI.MonoTlsProvider GetProvider (string name)
{
return GetTlsProvider ().Provider;
}
internal static bool IsInitialized => true;
internal static void Initialize ()
{
}
internal static void Initialize (string provider)
{
}
internal static HttpWebRequest CreateHttpsRequest (Uri requestUri, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
{
lock (locker) {
var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
return new HttpWebRequest (requestUri, internalProvider, settings);
}
}
internal static HttpListener CreateHttpListener (X509Certificate certificate, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
{
lock (locker) {
var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
return new HttpListener (certificate, internalProvider, settings);
}
}
#endregion
#endif
}
}

View File

@ -1,42 +0,0 @@
// Copyright 2015 Xamarin Inc. All rights reserved.
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#if MONO_FEATURE_BTLS
using Mono.Btls;
#endif
using System;
namespace Mono.Net.Security
{
static partial class MonoTlsProviderFactory
{
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
{
MSI.MonoTlsProvider provider = null;
var type = Environment.GetEnvironmentVariable ("XA_TLS_PROVIDER");
switch (type) {
case null:
case "default":
case "legacy":
return new LegacyTlsProvider ();
#if MONO_FEATURE_BTLS
case "btls":
if (!IsBtlsSupported ())
throw new NotSupportedException ("BTLS in not supported!");
return new MonoBtlsProvider ();
#endif
default:
throw new NotSupportedException (string.Format ("Invalid TLS Provider: `{0}'.", provider));
}
}
}
}
#endif

View File

@ -24,9 +24,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if !ONLY_APPLETLS // ONLY_APPLETLS uses MonoTlsProviderFactory.Apple.cs instead
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
using MSI = MonoSecurity::Mono.Security.Interface;
@ -36,13 +35,20 @@ using MSI = Mono.Security.Interface;
using MX = Mono.Security.X509;
#endif
using System.Security.Cryptography.X509Certificates;
#endif
using System;
using System.Net;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
#if MONO_FEATURE_BTLS
using Mono.Btls;
#endif
#if MONO_FEATURE_APPLETLS
using Mono.AppleTls;
#endif
#if !MOBILE
using System.Reflection;
#endif
@ -55,35 +61,30 @@ namespace Mono.Net.Security
*/
static partial class MonoTlsProviderFactory
{
#region Internal API
#region Internal API
/*
* APIs in this section are for consumption within System.dll only - do not access via
* reflection or from friend assemblies.
*
* @IMonoTlsProvider is defined as empty interface outside 'SECURITY_DEP', so we don't need
* this conditional here.
*/
internal static IMonoTlsProvider GetProviderInternal ()
internal static MSI.MonoTlsProvider GetProviderInternal ()
{
#if SECURITY_DEP
lock (locker) {
InitializeInternal ();
return defaultProvider;
}
#else
throw new NotSupportedException ("TLS Support not available.");
#endif
}
#if SECURITY_DEP
internal static void InitializeInternal ()
{
lock (locker) {
if (initialized)
return;
InitializeProviderRegistration ();
MSI.MonoTlsProvider provider;
try {
provider = CreateDefaultProviderImpl ();
@ -94,7 +95,12 @@ namespace Mono.Net.Security
if (provider == null)
throw new NotSupportedException ("TLS Support not available.");
defaultProvider = new Private.MonoTlsProviderWrapper (provider);
if (!providerCache.ContainsKey (provider.ID))
providerCache.Add (provider.ID, provider);
X509Helper2.Initialize ();
defaultProvider = provider;
initialized = true;
}
}
@ -105,90 +111,164 @@ namespace Mono.Net.Security
if (initialized)
throw new NotSupportedException ("TLS Subsystem already initialized.");
var msiProvider = LookupProvider (provider, true);
defaultProvider = new Private.MonoTlsProviderWrapper (msiProvider);
defaultProvider = LookupProvider (provider, true);
X509Helper2.Initialize ();
initialized = true;
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
internal extern static bool IsBtlsSupported ();
static object locker = new object ();
static bool initialized;
static IMonoTlsProvider defaultProvider;
#endif
#endregion
static MSI.MonoTlsProvider defaultProvider;
#if SECURITY_DEP
static Dictionary<string,string> providerRegistration;
/*
* @providerRegistration maps provider names to a tuple containing its ID and full type name.
* On non-reflection enabled systems (such as XI and XM), we can use the Guid to uniquely
* identify the provider.
*
* @providerCache maps the provider's Guid to the MSI.MonoTlsProvider instance.
*
*/
static Dictionary<string,Tuple<Guid,string>> providerRegistration;
static Dictionary<Guid,MSI.MonoTlsProvider> providerCache;
#if !ONLY_APPLETLS && !MONOTOUCH && !XAMMAC
static Type LookupProviderType (string name, bool throwOnError)
{
lock (locker) {
InitializeProviderRegistration ();
string typeName;
if (!providerRegistration.TryGetValue (name, out typeName)) {
Tuple<Guid,string> entry;
if (!providerRegistration.TryGetValue (name, out entry)) {
if (throwOnError)
throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name));
return null;
}
var type = Type.GetType (typeName, false);
var type = Type.GetType (entry.Item2, false);
if (type == null && throwOnError)
throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", typeName));
throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", entry.Item2));
return type;
}
}
#endif
static MSI.MonoTlsProvider LookupProvider (string name, bool throwOnError)
{
var type = LookupProviderType (name, throwOnError);
if (type == null)
return null;
lock (locker) {
InitializeProviderRegistration ();
Tuple<Guid,string> entry;
if (!providerRegistration.TryGetValue (name, out entry)) {
if (throwOnError)
throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name));
return null;
}
try {
return (MSI.MonoTlsProvider)Activator.CreateInstance (type, true);
} catch (Exception ex) {
throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex);
// Check cache before doing the reflection lookup.
MSI.MonoTlsProvider provider;
if (providerCache.TryGetValue (entry.Item1, out provider))
return provider;
#if !ONLY_APPLETLS && !MONOTOUCH && !XAMMAC
var type = Type.GetType (entry.Item2, false);
if (type == null && throwOnError)
throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", entry.Item2));
try {
provider = (MSI.MonoTlsProvider)Activator.CreateInstance (type, true);
} catch (Exception ex) {
throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex);
}
#endif
if (provider == null) {
if (throwOnError)
throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name));
return null;
}
providerCache.Add (entry.Item1, provider);
return provider;
}
}
#endregion
internal static readonly Guid AppleTlsId = new Guid ("981af8af-a3a3-419a-9f01-a518e3a17c1c");
internal static readonly Guid BtlsId = new Guid ("432d18c9-9348-4b90-bfbf-9f2a10e1f15b");
internal static readonly Guid LegacyId = new Guid ("809e77d5-56cc-4da8-b9f0-45e65ba9cceb");
static void InitializeProviderRegistration ()
{
lock (locker) {
if (providerRegistration != null)
return;
providerRegistration = new Dictionary<string,string> ();
providerRegistration = new Dictionary<string,Tuple<Guid,string>> ();
providerCache = new Dictionary<Guid,MSI.MonoTlsProvider> ();
string legacyProvider = "Mono.Net.Security.LegacyTlsProvider";
providerRegistration.Add ("legacy", legacyProvider);
var appleTlsEntry = new Tuple<Guid,String> (AppleTlsId, "Mono.AppleTls.AppleTlsProvider");
string defaultProvider = null;
#if ONLY_APPLETLS || MONOTOUCH || XAMMAC
providerRegistration.Add ("default", appleTlsEntry);
providerRegistration.Add ("apple", appleTlsEntry);
#else
var legacyEntry = new Tuple<Guid,String> (LegacyId, "Mono.Net.Security.LegacyTlsProvider");
providerRegistration.Add ("legacy", legacyEntry);
Tuple<Guid,String> btlsEntry = null;
#if MONO_FEATURE_BTLS
if (IsBtlsSupported ()) {
var btlsProvider = "Mono.Btls.MonoBtlsProvider";
providerRegistration.Add ("btls", btlsProvider);
defaultProvider = btlsProvider;
}
if (Platform.IsMacOS) {
var appleProvider = "Mono.AppleTls.AppleTlsProvider";
providerRegistration.Add ("apple", appleProvider);
defaultProvider = appleProvider;
btlsEntry = new Tuple<Guid,String> (BtlsId, "Mono.Btls.MonoBtlsProvider");
providerRegistration.Add ("btls", btlsEntry);
}
#endif
if (defaultProvider == null)
defaultProvider = legacyProvider;
if (Platform.IsMacOS)
providerRegistration.Add ("default", appleTlsEntry);
else if (btlsEntry != null)
providerRegistration.Add ("default", btlsEntry);
else
providerRegistration.Add ("default", legacyEntry);
providerRegistration.Add ("default", defaultProvider);
X509Helper2.Initialize ();
providerRegistration.Add ("apple", appleTlsEntry);
#endif
}
}
#if !MONODROID && !MONOTOUCH && !XAMMAC
static MSI.MonoTlsProvider TryDynamicLoad ()
#region Platform-Specific code
#if MONO_FEATURE_BTLS
[MethodImpl (MethodImplOptions.InternalCall)]
internal extern static bool IsBtlsSupported ();
#endif
#if MONODROID
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
{
MSI.MonoTlsProvider provider = null;
var type = Environment.GetEnvironmentVariable ("XA_TLS_PROVIDER");
switch (type) {
case null:
case "default":
case "legacy":
return new LegacyTlsProvider ();
#if MONO_FEATURE_BTLS
case "btls":
if (!IsBtlsSupported ())
throw new NotSupportedException ("BTLS in not supported!");
return new MonoBtlsProvider ();
#endif
default:
throw new NotSupportedException (string.Format ("Invalid TLS Provider: `{0}'.", provider));
}
}
#elif ONLY_APPLETLS || MONOTOUCH || XAMMAC
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
{
return new AppleTlsProvider ();
}
#else
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
{
var variable = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER");
if (string.IsNullOrEmpty (variable))
@ -196,18 +276,11 @@ namespace Mono.Net.Security
return LookupProvider (variable, true);
}
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
{
var provider = TryDynamicLoad ();
if (provider != null)
return provider;
return new LegacyTlsProvider ();
}
#endif
#region Mono.Security visible API
#endregion
#region Mono.Security visible API
/*
* "Public" section, intended to be consumed via reflection.
@ -221,12 +294,15 @@ namespace Mono.Net.Security
if (provider == null)
throw new NotSupportedException ("No TLS Provider available.");
return provider.Provider;
return provider;
}
internal static bool IsProviderSupported (string name)
{
return LookupProvider (name, false) != null;
lock (locker) {
InitializeProviderRegistration ();
return providerRegistration.ContainsKey (name);
}
}
internal static MSI.MonoTlsProvider GetProvider (string name)
@ -244,41 +320,14 @@ namespace Mono.Net.Security
internal static void Initialize ()
{
#if SECURITY_DEP
InitializeInternal ();
#else
throw new NotSupportedException ("TLS Support not available.");
#endif
}
internal static void Initialize (string provider)
{
#if SECURITY_DEP
InitializeInternal (provider);
#else
throw new NotSupportedException ("TLS Support not available.");
#endif
}
internal static HttpWebRequest CreateHttpsRequest (Uri requestUri, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
{
lock (locker) {
var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
return new HttpWebRequest (requestUri, internalProvider, settings);
}
}
internal static HttpListener CreateHttpListener (X509Certificate certificate, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
{
lock (locker) {
var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
return new HttpListener (certificate, internalProvider, settings);
}
}
#endregion
#endif
#endregion
}
}
#endif

View File

@ -1,79 +0,0 @@
//
// MonoTlsProviderWrapper.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2015 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*
* This is used by MonoTlsProviderFactory.InstallProvider() to wrap and masquerade
* a user-supplied @MonoTlsProvider as @IMonoTlsProvider.
*/
class MonoTlsProviderWrapper : IMonoTlsProvider
{
MSI.MonoTlsProvider provider;
public MonoTlsProviderWrapper (MSI.MonoTlsProvider provider)
{
this.provider = provider;
}
public MSI.MonoTlsProvider Provider {
get { return provider; }
}
public IMonoSslStream CreateSslStream (
Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings)
{
var sslStream = provider.CreateSslStream (innerStream, leaveInnerStreamOpen, settings);
var monoSslStreamImpl = sslStream as MonoSslStreamImpl;
if (monoSslStreamImpl != null)
return monoSslStreamImpl.Impl;
return new MonoSslStreamWrapper (sslStream);
}
}
}
#endif

View File

@ -52,7 +52,7 @@ namespace Mono.Net.Security
class MonoTlsStream
{
#if SECURITY_DEP
readonly IMonoTlsProvider provider;
readonly MonoTlsProvider provider;
readonly NetworkStream networkStream;
readonly HttpWebRequest request;
@ -90,7 +90,7 @@ namespace Mono.Net.Security
provider = request.TlsProvider ?? MonoTlsProviderFactory.GetProviderInternal ();
status = WebExceptionStatus.SecureChannelFailure;
/*validationHelper =*/ ChainValidationHelper.Create (provider.Provider, ref settings, this);
/*validationHelper =*/ ChainValidationHelper.Create (provider, ref settings, this);
}
internal Stream CreateStream (byte[] buffer)

View File

@ -105,7 +105,7 @@ namespace Mono.Net.Security
internal static HttpWebRequest CreateHttpsRequest (Uri requestUri, object provider, object settings)
{
#if SECURITY_DEP
return MonoTlsProviderFactory.CreateHttpsRequest (requestUri, (MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
return new HttpWebRequest (requestUri, (MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
#else
throw new NotSupportedException ();
#endif
@ -114,7 +114,7 @@ namespace Mono.Net.Security
internal static object CreateHttpListener (object certificate, object provider, object settings)
{
#if SECURITY_DEP
return MonoTlsProviderFactory.CreateHttpListener ((X509Certificate)certificate, (MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
return new HttpListener ((X509Certificate)certificate, (MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
#else
throw new NotSupportedException ();
#endif
@ -129,6 +129,15 @@ namespace Mono.Net.Security
#endif
}
internal static object GetMonoSslStream (HttpListenerContext context)
{
#if SECURITY_DEP
return context.Connection.SslStream?.Impl;
#else
throw new NotSupportedException ();
#endif
}
internal static bool IsProviderSupported (string name)
{
#if SECURITY_DEP