You've already forked linux-packaging-mono
Imported Upstream version 5.16.0.100
Former-commit-id: 38faa55fb9669e35e7d8448b15c25dc447f25767
This commit is contained in:
parent
0a9828183b
commit
7d7f676260
@ -32,56 +32,49 @@ namespace Mono.Net.Security
|
||||
{
|
||||
abstract class MobileTlsContext : IDisposable
|
||||
{
|
||||
MobileAuthenticatedStream parent;
|
||||
bool serverMode;
|
||||
string targetHost;
|
||||
string serverName;
|
||||
SslProtocols enabledProtocols;
|
||||
X509Certificate serverCertificate;
|
||||
X509CertificateCollection clientCertificates;
|
||||
bool askForClientCert;
|
||||
ICertificateValidator2 certificateValidator;
|
||||
|
||||
public MobileTlsContext (
|
||||
MobileAuthenticatedStream parent, bool serverMode, string targetHost,
|
||||
SslProtocols enabledProtocols, X509Certificate serverCertificate,
|
||||
X509CertificateCollection clientCertificates, bool askForClientCert)
|
||||
protected MobileTlsContext (MobileAuthenticatedStream parent, MonoSslAuthenticationOptions options)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.serverMode = serverMode;
|
||||
this.targetHost = targetHost;
|
||||
this.enabledProtocols = enabledProtocols;
|
||||
this.serverCertificate = serverCertificate;
|
||||
this.clientCertificates = clientCertificates;
|
||||
this.askForClientCert = askForClientCert;
|
||||
Parent = parent;
|
||||
Options = options;
|
||||
IsServer = options.ServerMode;
|
||||
EnabledProtocols = options.EnabledSslProtocols;
|
||||
|
||||
serverName = targetHost;
|
||||
if (!string.IsNullOrEmpty (serverName)) {
|
||||
var pos = serverName.IndexOf (':');
|
||||
if (pos > 0)
|
||||
serverName = serverName.Substring (0, pos);
|
||||
if (options.ServerMode) {
|
||||
LocalServerCertificate = options.ServerCertificate;
|
||||
AskForClientCertificate = options.ClientCertificateRequired;
|
||||
} else {
|
||||
ClientCertificates = options.ClientCertificates;
|
||||
TargetHost = options.TargetHost;
|
||||
ServerName = options.TargetHost;
|
||||
if (!string.IsNullOrEmpty (ServerName)) {
|
||||
var pos = ServerName.IndexOf (':');
|
||||
if (pos > 0)
|
||||
ServerName = ServerName.Substring (0, pos);
|
||||
}
|
||||
}
|
||||
|
||||
certificateValidator = CertificateValidationHelper.GetInternalValidator (
|
||||
parent.Settings, parent.Provider);
|
||||
certificateValidator = (ICertificateValidator2)ChainValidationHelper.GetInternalValidator (
|
||||
parent.SslStream, parent.Provider, parent.Settings);
|
||||
}
|
||||
|
||||
internal MonoSslAuthenticationOptions Options {
|
||||
get;
|
||||
}
|
||||
|
||||
internal MobileAuthenticatedStream Parent {
|
||||
get { return parent; }
|
||||
get;
|
||||
}
|
||||
|
||||
public MonoTlsSettings Settings {
|
||||
get { return parent.Settings; }
|
||||
}
|
||||
public MonoTlsSettings Settings => Parent.Settings;
|
||||
|
||||
public MonoTlsProvider Provider {
|
||||
get { return parent.Provider; }
|
||||
}
|
||||
public MonoTlsProvider Provider => Parent.Provider;
|
||||
|
||||
[SD.Conditional ("MONO_TLS_DEBUG")]
|
||||
protected void Debug (string message, params object[] args)
|
||||
{
|
||||
parent.Debug ("{0}: {1}", GetType ().Name, string.Format (message, args));
|
||||
Parent.Debug ("{0}: {1}", GetType ().Name, string.Format (message, args));
|
||||
}
|
||||
|
||||
public abstract bool HasContext {
|
||||
@ -93,44 +86,52 @@ namespace Mono.Net.Security
|
||||
}
|
||||
|
||||
public bool IsServer {
|
||||
get { return serverMode; }
|
||||
get;
|
||||
}
|
||||
|
||||
protected string TargetHost {
|
||||
get { return targetHost; }
|
||||
internal string TargetHost {
|
||||
get;
|
||||
}
|
||||
|
||||
protected string ServerName {
|
||||
get { return serverName; }
|
||||
get;
|
||||
}
|
||||
|
||||
protected bool AskForClientCertificate {
|
||||
get { return askForClientCert; }
|
||||
get;
|
||||
}
|
||||
|
||||
protected SslProtocols EnabledProtocols {
|
||||
get { return enabledProtocols; }
|
||||
get;
|
||||
}
|
||||
|
||||
protected X509CertificateCollection ClientCertificates {
|
||||
get { return clientCertificates; }
|
||||
get;
|
||||
}
|
||||
|
||||
protected void GetProtocolVersions (out TlsProtocolCode min, out TlsProtocolCode max)
|
||||
{
|
||||
if ((enabledProtocols & SslProtocols.Tls) != 0)
|
||||
min = TlsProtocolCode.Tls10;
|
||||
else if ((enabledProtocols & SslProtocols.Tls11) != 0)
|
||||
min = TlsProtocolCode.Tls11;
|
||||
else
|
||||
min = TlsProtocolCode.Tls12;
|
||||
internal bool AllowRenegotiation {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
if ((enabledProtocols & SslProtocols.Tls12) != 0)
|
||||
max = TlsProtocolCode.Tls12;
|
||||
else if ((enabledProtocols & SslProtocols.Tls11) != 0)
|
||||
max = TlsProtocolCode.Tls11;
|
||||
protected void GetProtocolVersions (out TlsProtocolCode? min, out TlsProtocolCode? max)
|
||||
{
|
||||
if ((EnabledProtocols & SslProtocols.Tls) != 0)
|
||||
min = TlsProtocolCode.Tls10;
|
||||
else if ((EnabledProtocols & SslProtocols.Tls11) != 0)
|
||||
min = TlsProtocolCode.Tls11;
|
||||
else if ((EnabledProtocols & SslProtocols.Tls12) != 0)
|
||||
min = TlsProtocolCode.Tls12;
|
||||
else
|
||||
min = null;
|
||||
|
||||
if ((EnabledProtocols & SslProtocols.Tls12) != 0)
|
||||
max = TlsProtocolCode.Tls12;
|
||||
else if ((EnabledProtocols & SslProtocols.Tls11) != 0)
|
||||
max = TlsProtocolCode.Tls11;
|
||||
else if ((EnabledProtocols & SslProtocols.Tls) != 0)
|
||||
max = TlsProtocolCode.Tls10;
|
||||
else
|
||||
max = null;
|
||||
}
|
||||
|
||||
public abstract void StartHandshake ();
|
||||
@ -144,7 +145,7 @@ namespace Mono.Net.Security
|
||||
}
|
||||
|
||||
internal X509Certificate LocalServerCertificate {
|
||||
get { return serverCertificate; }
|
||||
get;
|
||||
}
|
||||
|
||||
internal abstract bool IsRemoteCertificateAvailable {
|
||||
@ -171,6 +172,8 @@ namespace Mono.Net.Security
|
||||
|
||||
public abstract void Shutdown ();
|
||||
|
||||
public abstract bool PendingRenegotiation ();
|
||||
|
||||
protected bool ValidateCertificate (X509Certificate leaf, X509Chain chain)
|
||||
{
|
||||
var result = certificateValidator.ValidateCertificate (TargetHost, IsServer, leaf, chain);
|
||||
@ -183,24 +186,78 @@ namespace Mono.Net.Security
|
||||
return result != null && result.Trusted && !result.UserDenied;
|
||||
}
|
||||
|
||||
protected X509Certificate SelectClientCertificate (X509Certificate serverCertificate, string[] acceptableIssuers)
|
||||
protected X509Certificate SelectClientCertificate (string[] acceptableIssuers)
|
||||
{
|
||||
if (Settings.DisallowUnauthenticatedCertificateRequest && !IsAuthenticated)
|
||||
return null;
|
||||
|
||||
if (RemoteCertificate == null)
|
||||
throw new TlsException (AlertDescription.InternalError, "Cannot request client certificate before receiving one from the server.");
|
||||
|
||||
/*
|
||||
* We need to pass null to the user selection callback during the initial handshake, to allow the callback to distinguish
|
||||
* between an authenticated and unauthenticated session.
|
||||
*/
|
||||
X509Certificate certificate;
|
||||
var selected = certificateValidator.SelectClientCertificate (
|
||||
TargetHost, ClientCertificates, serverCertificate, acceptableIssuers, out certificate);
|
||||
TargetHost, ClientCertificates, IsAuthenticated ? RemoteCertificate : null, acceptableIssuers, out certificate);
|
||||
if (selected)
|
||||
return certificate;
|
||||
|
||||
if (clientCertificates == null || clientCertificates.Count == 0)
|
||||
if (ClientCertificates == null || ClientCertificates.Count == 0)
|
||||
return null;
|
||||
|
||||
if (clientCertificates.Count == 1)
|
||||
return clientCertificates [0];
|
||||
/*
|
||||
* .NET actually scans the entire collection to ensure the selected certificate has a private key in it.
|
||||
*
|
||||
* However, since we do not support private key retrieval from the key store, we require all certificates
|
||||
* to have a private key in them (explicitly or implicitly via OS X keychain lookup).
|
||||
*/
|
||||
if (acceptableIssuers == null || acceptableIssuers.Length == 0)
|
||||
return ClientCertificates [0];
|
||||
|
||||
// FIXME: select onne.
|
||||
throw new NotImplementedException ();
|
||||
// Copied from the referencesource implementation in referencesource/System/net/System/Net/_SecureChannel.cs.
|
||||
for (int i = 0; i < ClientCertificates.Count; i++) {
|
||||
var certificate2 = ClientCertificates[i] as X509Certificate2;
|
||||
if (certificate2 == null)
|
||||
continue;
|
||||
|
||||
X509Chain chain = null;
|
||||
try {
|
||||
chain = new X509Chain ();
|
||||
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
|
||||
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreInvalidName;
|
||||
chain.Build (certificate2);
|
||||
|
||||
//
|
||||
// We ignore any errors happened with chain.
|
||||
// Consider: try to locate the "best" client cert that has no errors and the lognest validity internal
|
||||
//
|
||||
if (chain.ChainElements.Count == 0)
|
||||
continue;
|
||||
for (int ii=0; ii< chain.ChainElements.Count; ++ii) {
|
||||
var issuer = chain.ChainElements[ii].Certificate.Issuer;
|
||||
if (Array.IndexOf (acceptableIssuers, issuer) != -1)
|
||||
return certificate2;
|
||||
}
|
||||
} catch {
|
||||
; // ignore errors
|
||||
} finally {
|
||||
if (chain != null)
|
||||
chain.Reset ();
|
||||
}
|
||||
}
|
||||
|
||||
// No certificate matches.
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract bool CanRenegotiate {
|
||||
get;
|
||||
}
|
||||
|
||||
public abstract void Renegotiate ();
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
|
Reference in New Issue
Block a user