You've already forked linux-packaging-mono
Imported Upstream version 5.4.0.167
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
parent
e49d6f06c0
commit
536cd135cc
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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 (
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user