Imported Upstream version 6.4.0.137

Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-07-26 19:53:28 +00:00
parent e9207cf623
commit ef583813eb
2712 changed files with 74169 additions and 40587 deletions

View File

@@ -71,11 +71,6 @@ namespace Mono.AppleTls
handle = GCHandle.Alloc (this, GCHandleType.Weak);
readFunc = NativeReadCallback;
writeFunc = NativeWriteCallback;
if (IsServer) {
if (LocalServerCertificate == null)
throw new ArgumentNullException (nameof (LocalServerCertificate));
}
}
public IntPtr Handle {
@@ -167,8 +162,20 @@ namespace Mono.AppleTls
SetSessionOption (SslSessionOption.BreakOnServerAuth, true);
if (IsServer) {
SafeSecCertificateHandle[] intermediateCerts;
serverIdentity = AppleCertificateHelper.GetIdentity (LocalServerCertificate, out intermediateCerts);
// If we have any of the server certificate selection callbacks, the we need to break on
// the ClientHello to pass the requested server name to the callback.
if (Options.ServerCertSelectionDelegate != null || Settings.ClientCertificateSelectionCallback != null)
SetSessionOption (SslSessionOption.BreakOnClientHello, true);
else if (LocalServerCertificate != null)
SetServerIdentity (LocalServerCertificate);
else
throw new SSA.AuthenticationException (SR.net_ssl_io_no_server_cert);
}
}
void SetServerIdentity (X509Certificate certificate)
{
using (var serverIdentity = AppleCertificateHelper.GetIdentity (certificate, out var intermediateCerts)) {
if (serverIdentity.IsInvalid)
throw new SSA.AuthenticationException ("Unable to get server certificate from keychain.");
@@ -199,15 +206,21 @@ namespace Mono.AppleTls
var status = SSLHandshake (Handle);
Debug ("Handshake: {0} - {0:x}", status);
CheckStatusAndThrow (status, SslStatus.WouldBlock, SslStatus.PeerAuthCompleted, SslStatus.PeerClientCertRequested);
CheckStatusAndThrow (status, SslStatus.WouldBlock, SslStatus.PeerAuthCompleted, SslStatus.PeerClientCertRequested, SslStatus.ClientHelloReceived);
if (status == SslStatus.PeerAuthCompleted) {
switch (status) {
case SslStatus.PeerAuthCompleted:
EvaluateTrust ();
} else if (status == SslStatus.PeerClientCertRequested) {
break;
case SslStatus.PeerClientCertRequested:
ClientCertificateRequested ();
} else if (status == SslStatus.WouldBlock) {
break;
case SslStatus.ClientHelloReceived:
ClientHelloReceived ();
break;
case SslStatus.WouldBlock:
return false;
} else if (status == SslStatus.Success) {
case SslStatus.Success:
Debug ("Handshake complete!");
handshakeFinished = true;
renegotiating = false;
@@ -229,6 +242,13 @@ namespace Mono.AppleTls
SetCertificate (clientIdentity, new SafeSecCertificateHandle [0]);
}
void ClientHelloReceived ()
{
var peerName = GetRequestedPeerName ();
Debug ($"Handshake - received ClientHello ({peerName})");
SetServerIdentity (SelectServerCertificate (peerName));
}
void EvaluateTrust ()
{
InitializeSession ();
@@ -658,6 +678,32 @@ namespace Mono.AppleTls
}
}
[DllImport (SecurityLibrary)]
extern static /* OSStatus */ SslStatus SSLCopyRequestedPeerNameLength (/* SSLContextRef */ IntPtr context, /* size_t * */ out IntPtr peerNameLen);
[DllImport (SecurityLibrary)]
extern static /* OSStatus */ SslStatus SSLCopyRequestedPeerName (/* SSLContextRef */ IntPtr context, /* char * */ byte[] peerName, /* size_t * */ ref IntPtr peerNameLen);
public string GetRequestedPeerName ()
{
IntPtr length;
var result = SSLCopyRequestedPeerNameLength (Handle, out length);
CheckStatusAndThrow (result);
if (result != SslStatus.Success || (int)length == 0)
return String.Empty;
var bytes = new byte [(int)length];
result = SSLCopyRequestedPeerName (Handle, bytes, ref length);
CheckStatusAndThrow (result);
int requestedPeerNameLength = (int)length;
if (result != SslStatus.Success)
return string.Empty;
if (requestedPeerNameLength > 0 && bytes [requestedPeerNameLength-1] == 0)
requestedPeerNameLength = requestedPeerNameLength - 1;
return Encoding.UTF8.GetString (bytes, 0, requestedPeerNameLength);
}
[DllImport (SecurityLibrary)]
extern unsafe static /* OSStatus */ SslStatus SSLSetCertificate (/* SSLContextRef */ IntPtr context, /* CFArrayRef */ IntPtr certRefs);

View File

@@ -73,7 +73,7 @@ namespace Mono.AppleTls {
BadConfiguration = -9848,
UnexpectedRecord = -9849,
SSLWeakPeerEphemeralDHKey = -9850,
SSLClientHelloReceived = -9851 // non falta
ClientHelloReceived = -9851 // non falta
}
// Security.framework/Headers/SecureTransport.h
@@ -91,7 +91,7 @@ namespace Mono.AppleTls {
// Fallback = 6,
// BreakOnClientHello = 7,
BreakOnClientHello = 7,
AllowRenegotiation = 8,
}