7d05485754
Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
222 lines
5.3 KiB
C#
222 lines
5.3 KiB
C#
//
|
|
// MobileTlsContext.cs
|
|
//
|
|
// Author:
|
|
// Martin Baulig <martin.baulig@xamarin.com>
|
|
//
|
|
// Copyright (c) 2015 Xamarin, Inc.
|
|
//
|
|
|
|
#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
|
|
|
|
using System;
|
|
using System.IO;
|
|
using SD = System.Diagnostics;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Security.Authentication;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
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)
|
|
{
|
|
this.parent = parent;
|
|
this.serverMode = serverMode;
|
|
this.targetHost = targetHost;
|
|
this.enabledProtocols = enabledProtocols;
|
|
this.serverCertificate = serverCertificate;
|
|
this.clientCertificates = clientCertificates;
|
|
this.askForClientCert = askForClientCert;
|
|
|
|
serverName = targetHost;
|
|
if (!string.IsNullOrEmpty (serverName)) {
|
|
var pos = serverName.IndexOf (':');
|
|
if (pos > 0)
|
|
serverName = serverName.Substring (0, pos);
|
|
}
|
|
|
|
certificateValidator = CertificateValidationHelper.GetInternalValidator (
|
|
parent.Settings, parent.Provider);
|
|
}
|
|
|
|
internal MobileAuthenticatedStream Parent {
|
|
get { return parent; }
|
|
}
|
|
|
|
public MonoTlsSettings Settings {
|
|
get { return parent.Settings; }
|
|
}
|
|
|
|
public MonoTlsProvider Provider {
|
|
get { return 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));
|
|
}
|
|
|
|
public abstract bool HasContext {
|
|
get;
|
|
}
|
|
|
|
public abstract bool IsAuthenticated {
|
|
get;
|
|
}
|
|
|
|
public bool IsServer {
|
|
get { return serverMode; }
|
|
}
|
|
|
|
protected string TargetHost {
|
|
get { return targetHost; }
|
|
}
|
|
|
|
protected string ServerName {
|
|
get { return serverName; }
|
|
}
|
|
|
|
protected bool AskForClientCertificate {
|
|
get { return askForClientCert; }
|
|
}
|
|
|
|
protected SslProtocols EnabledProtocols {
|
|
get { return enabledProtocols; }
|
|
}
|
|
|
|
protected X509CertificateCollection ClientCertificates {
|
|
get { return clientCertificates; }
|
|
}
|
|
|
|
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;
|
|
|
|
if ((enabledProtocols & SslProtocols.Tls12) != 0)
|
|
max = TlsProtocolCode.Tls12;
|
|
else if ((enabledProtocols & SslProtocols.Tls11) != 0)
|
|
max = TlsProtocolCode.Tls11;
|
|
else
|
|
max = TlsProtocolCode.Tls10;
|
|
}
|
|
|
|
public abstract void StartHandshake ();
|
|
|
|
public abstract bool ProcessHandshake ();
|
|
|
|
public abstract void FinishHandshake ();
|
|
|
|
public abstract MonoTlsConnectionInfo ConnectionInfo {
|
|
get;
|
|
}
|
|
|
|
internal X509Certificate LocalServerCertificate {
|
|
get { return serverCertificate; }
|
|
}
|
|
|
|
internal abstract bool IsRemoteCertificateAvailable {
|
|
get;
|
|
}
|
|
|
|
internal abstract X509Certificate LocalClientCertificate {
|
|
get;
|
|
}
|
|
|
|
public abstract X509Certificate RemoteCertificate {
|
|
get;
|
|
}
|
|
|
|
public abstract TlsProtocols NegotiatedProtocol {
|
|
get;
|
|
}
|
|
|
|
public abstract void Flush ();
|
|
|
|
public abstract (int ret, bool wantMore) Read (byte[] buffer, int offset, int count);
|
|
|
|
public abstract (int ret, bool wantMore) Write (byte[] buffer, int offset, int count);
|
|
|
|
public abstract void Shutdown ();
|
|
|
|
protected bool ValidateCertificate (X509Certificate leaf, X509Chain chain)
|
|
{
|
|
var result = certificateValidator.ValidateCertificate (TargetHost, IsServer, leaf, chain);
|
|
return result != null && result.Trusted && !result.UserDenied;
|
|
}
|
|
|
|
protected bool ValidateCertificate (X509CertificateCollection certificates)
|
|
{
|
|
var result = certificateValidator.ValidateCertificate (TargetHost, IsServer, certificates);
|
|
return result != null && result.Trusted && !result.UserDenied;
|
|
}
|
|
|
|
protected X509Certificate SelectClientCertificate (X509Certificate serverCertificate, string[] acceptableIssuers)
|
|
{
|
|
X509Certificate certificate;
|
|
var selected = certificateValidator.SelectClientCertificate (
|
|
TargetHost, ClientCertificates, serverCertificate, acceptableIssuers, out certificate);
|
|
if (selected)
|
|
return certificate;
|
|
|
|
if (clientCertificates == null || clientCertificates.Count == 0)
|
|
return null;
|
|
|
|
if (clientCertificates.Count == 1)
|
|
return clientCertificates [0];
|
|
|
|
// FIXME: select onne.
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
public void Dispose ()
|
|
{
|
|
Dispose (true);
|
|
GC.SuppressFinalize (this);
|
|
}
|
|
|
|
protected virtual void Dispose (bool disposing)
|
|
{
|
|
}
|
|
|
|
~MobileTlsContext ()
|
|
{
|
|
Dispose (false);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|