205 lines
4.9 KiB
C#
Raw Normal View History

//
// 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