205 lines
4.9 KiB
C#
205 lines
4.9 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;
|
|||
|
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;
|
|||
|
|
|||
|
certificateValidator = CertificateValidationHelper.GetDefaultValidator (
|
|||
|
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 ("MARTIN_DEBUG")]
|
|||
|
protected void Debug (string message, params object[] args)
|
|||
|
{
|
|||
|
Console.Error.WriteLine ("{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 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 Read (byte[] buffer, int offset, int count, out bool wantMore);
|
|||
|
|
|||
|
public abstract int Write (byte[] buffer, int offset, int count, out bool wantMore);
|
|||
|
|
|||
|
public abstract void Close ();
|
|||
|
|
|||
|
protected ValidationResult ValidateCertificate (X509Certificate leaf, X509Chain chain)
|
|||
|
{
|
|||
|
return certificateValidator.ValidateCertificate (
|
|||
|
targetHost, serverMode, leaf, chain);
|
|||
|
}
|
|||
|
|
|||
|
protected X509Certificate SelectClientCertificate (string[] acceptableIssuers)
|
|||
|
{
|
|||
|
X509Certificate certificate;
|
|||
|
var selected = certificateValidator.SelectClientCertificate (
|
|||
|
targetHost, clientCertificates, serverCertificate,
|
|||
|
null, out certificate);
|
|||
|
if (selected)
|
|||
|
return certificate;
|
|||
|
|
|||
|
if (clientCertificates == null || clientCertificates.Count == 0)
|
|||
|
return null;
|
|||
|
|
|||
|
if (clientCertificates.Count == 1)
|
|||
|
return clientCertificates [0];
|
|||
|
|
|||
|
// FIXME: select one.
|
|||
|
throw new NotImplementedException ();
|
|||
|
}
|
|||
|
|
|||
|
public void Dispose ()
|
|||
|
{
|
|||
|
Dispose (true);
|
|||
|
GC.SuppressFinalize (this);
|
|||
|
}
|
|||
|
|
|||
|
protected virtual void Dispose (bool disposing)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
~MobileTlsContext ()
|
|||
|
{
|
|||
|
Dispose (false);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|