using System.Net;
using System.Net.Security;
using System.Threading;
-using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Mono.Security.Protocol.Tls;
using MX = Mono.Security.X509;
-#if MOBILE
using Mono.Net.Security;
-#endif
namespace Mono.Security.Interface
{
- #if (!MONOTOUCH && !MONODROID) || INSIDE_SYSTEM
public class ValidationResult
{
bool trusted;
bool user_denied;
int error_code;
- MonoSslPolicyErrors policy_errors;
+ MonoSslPolicyErrors? policy_errors;
- public ValidationResult (bool trusted, bool user_denied, int error_code, MonoSslPolicyErrors policy_errors)
+ public ValidationResult (bool trusted, bool user_denied, int error_code, MonoSslPolicyErrors? policy_errors)
{
this.trusted = trusted;
this.user_denied = user_denied;
this.policy_errors = policy_errors;
}
+ internal ValidationResult (bool trusted, bool user_denied, int error_code)
+ {
+ this.trusted = trusted;
+ this.user_denied = user_denied;
+ this.error_code = error_code;
+ }
+
public bool Trusted {
get { return trusted; }
}
get { return error_code; }
}
- public MonoSslPolicyErrors PolicyErrors {
+ public MonoSslPolicyErrors? PolicyErrors {
get { return policy_errors; }
}
}
get;
}
- X509Certificate SelectClientCertificate (
+ /*
+ * Returns `true` if a client certificate has been selected (which could be `null`).
+ */
+ bool SelectClientCertificate (
string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate,
- string[] acceptableIssuers);
+ string[] acceptableIssuers, out X509Certificate clientCertificate);
- ValidationResult ValidateChain (string targetHost, X509CertificateCollection certificates);
+ /*
+ * If @serverMode is true, then we're a server and want to validate a certificate that we received from a client.
+ */
+ ValidationResult ValidateCertificate (string targetHost, bool serverMode, X509CertificateCollection certificates);
+ }
- ValidationResult ValidateClientCertificate (X509CertificateCollection certificates);
+ internal interface ICertificateValidator2 : ICertificateValidator
+ {
+ /*
+ * Internal use only.
+ */
+ ValidationResult ValidateCertificate (string targetHost, bool serverMode, X509Certificate leaf, X509Chain chain);
+
+ /*
+ * On OS X and Mobile, the @chain will be initialized with the @certificates, but not actually built.
+ */
+ bool InvokeSystemValidator (
+ string targetHost, bool serverMode, X509CertificateCollection certificates,
+ X509Chain chain, ref MonoSslPolicyErrors errors, ref int status11);
}
- #endif
- #if !INSIDE_SYSTEM
- public
- #endif
- static class CertificateValidationHelper
+ public static class CertificateValidationHelper
{
const string SecurityLibrary = "/System/Library/Frameworks/Security.framework/Security";
static readonly bool noX509Chain;
-
- #if !INSIDE_SYSTEM
- const string InternalHelperTypeName = "Mono.Net.Security.ChainValidationHelper";
- static readonly Type internalHelperType;
- static readonly MethodInfo createMethod;
- static readonly MethodInfo validateClientCertificateMethod;
- static readonly MethodInfo validateChainMethod;
- #endif
+ static readonly bool supportsTrustAnchors;
static CertificateValidationHelper ()
{
- #if !INSIDE_SYSTEM
- internalHelperType = Type.GetType (InternalHelperTypeName + ", " + Consts.AssemblySystem, true);
- if (internalHelperType == null)
- throw new NotSupportedException ();
- createMethod = internalHelperType.GetMethod ("GetDefaultValidator", BindingFlags.Static | BindingFlags.NonPublic);
- if (createMethod == null)
- throw new NotSupportedException ();
- validateClientCertificateMethod = internalHelperType.GetMethod ("ValidateClientCertificate", BindingFlags.Instance | BindingFlags.Public);
- if (validateClientCertificateMethod == null)
- throw new NotSupportedException ();
- validateChainMethod = internalHelperType.GetMethod ("ValidateChain", BindingFlags.Instance | BindingFlags.Public);
- if (validateChainMethod == null)
- throw new NotSupportedException ();
- #endif
-
#if MONOTOUCH || XAMMAC
noX509Chain = true;
+ supportsTrustAnchors = true;
+ #elif MONODROID
+ noX509Chain = true;
+ supportsTrustAnchors = false;
#else
- noX509Chain = File.Exists (SecurityLibrary);
+ if (File.Exists (SecurityLibrary)) {
+ noX509Chain = true;
+ supportsTrustAnchors = true;
+ } else {
+ noX509Chain = false;
+ supportsTrustAnchors = false;
+ }
#endif
}
get { return !noX509Chain; }
}
- internal static ICertificateValidator GetDefaultValidator (MonoTlsSettings settings)
+ public static bool SupportsTrustAnchors {
+ get { return supportsTrustAnchors; }
+ }
+
+ /*
+ * Internal API, intended to be used by MonoTlsProvider implementations.
+ */
+ internal static ICertificateValidator2 GetInternalValidator (MonoTlsSettings settings, MonoTlsProvider provider)
{
- #if INSIDE_SYSTEM
- return ChainValidationHelper.GetDefaultValidator (settings);
- #else
- return (ICertificateValidator)createMethod.Invoke (null, new object[] { settings });
- #endif
+ return (ICertificateValidator2)NoReflectionHelper.GetInternalValidator (provider, settings);
+ }
+
+ [Obsolete ("Use GetInternalValidator")]
+ internal static ICertificateValidator2 GetDefaultValidator (MonoTlsSettings settings, MonoTlsProvider provider)
+ {
+ return GetInternalValidator (settings, provider);
}
- #if !INSIDE_SYSTEM
+ /*
+ * Use this overloaded version in user code.
+ */
public static ICertificateValidator GetValidator (MonoTlsSettings settings)
{
- return GetDefaultValidator (settings);
+ return (ICertificateValidator)NoReflectionHelper.GetDefaultValidator (settings);
}
- #endif
}
}