[BoringTls]: Merge the work branch.
authorMartin Baulig <martin.baulig@xamarin.com>
Thu, 7 Apr 2016 13:55:27 +0000 (15:55 +0200)
committerMartin Baulig <martin.baulig@xamarin.com>
Thu, 7 Apr 2016 14:42:10 +0000 (16:42 +0200)
* Mono.Security.Interface.ICertificateValidator2:
  new internal interface, deriving from ICertificateValidator.

* Mono.Security.Interface.CertificateValidationHelper:
  the internal GetValidator() now returns ICertificateValidator2.

* Mono.Security.Interface.MonoTlsProvider:
  make HasCustomSystemCertificateValidator and InvokeSystemCertificateValidator()
  internal and use ICertificateValidator2.

* Mono.Net.Security.ChainValidator:
  implement ICertificateValidator2; we may now be called with a
  fully-built X509Chain.

* corlib, System, Mono.Security:
  add [assembly: InternalsVisibleTo].

mcs/class/Mono.Security/Assembly/AssemblyInfo.cs
mcs/class/Mono.Security/Mono.Security.Interface/CertificateValidationHelper.cs
mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs
mcs/class/System/Assembly/AssemblyInfo.cs
mcs/class/System/Mono.Net.Security/ChainValidationHelper.cs
mcs/class/corlib/Assembly/AssemblyInfo.cs

index 55e17aad73d7012b058a7295e29c9a4e050974f4..b5bf191148e12eb7995fa6f6b1ebbddc328ce77e 100644 (file)
@@ -70,3 +70,4 @@ using System.Runtime.InteropServices;
 [assembly: InternalsVisibleTo ("Mono.Security.Providers.OldTls, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
 [assembly: InternalsVisibleTo ("Mono.Security.Providers.DotNet, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
 [assembly: InternalsVisibleTo ("Mono.Security.Providers.NewSystemSource, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
+[assembly: InternalsVisibleTo ("Xamarin.BoringTls, PublicKey=002400000480000094000000060200000024000052534131000400001100000099dd12eda85767ae6f06023ee28e711c7e5a212462095c83868c29db75eddf6d8e296e03824c14fedd5f55553fed0b6173be3cc985a4b7f9fb7c83ccff8ba3938563b3d1f45a81122f12a1bcb73edcaad61a8456c7595a6da5184b4dd9d10f011b949ef1391fccfeab1ba62aa51c267ef8bd57ef1b6ba5a4c515d0badb81a78f")]
index fc901084a7033bd84d08cd41e36590e0e52179b8..561e7888db7d1dc1162964c83b88a22c485fe056 100644 (file)
@@ -95,6 +95,14 @@ namespace Mono.Security.Interface
                 * 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);
+       }
+
+       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.
@@ -137,15 +145,15 @@ namespace Mono.Security.Interface
                        get { return supportsTrustAnchors; }
                }
 
-               static ICertificateValidator GetDefaultValidator (MonoTlsProvider provider, MonoTlsSettings settings)
+               static ICertificateValidator2 GetDefaultValidator (MonoTlsProvider provider, MonoTlsSettings settings)
                {
-                       return (ICertificateValidator)NoReflectionHelper.GetDefaultCertificateValidator (provider, settings);
+                       return (ICertificateValidator2)NoReflectionHelper.GetDefaultCertificateValidator (provider, settings);
                }
 
                /*
                 * Internal API, intended to be used by MonoTlsProvider implementations.
                 */
-               public static ICertificateValidator GetValidator (MonoTlsProvider provider, MonoTlsSettings settings)
+               internal static ICertificateValidator2 GetValidator (MonoTlsProvider provider, MonoTlsSettings settings)
                {
                        return GetDefaultValidator (provider, settings);
                }
index 8b7c6ddecfc28a375c64139d08d003fb67f6a2ce..59b148c48c633a14c1dae94a1608242405aafd39 100644 (file)
@@ -129,7 +129,7 @@ namespace Mono.Security.Interface
                /*
                 * Allows a TLS provider to provide a custom system certificiate validator.
                 */
-               public virtual bool HasCustomSystemCertificateValidator {
+               internal virtual bool HasCustomSystemCertificateValidator {
                        get { return false; }
                }
 
@@ -142,13 +142,12 @@ namespace Mono.Security.Interface
                 * Returns `true` if certificate validation has been performed and `false` to invoke the
                 * default system validator.
                 */
-               public virtual bool InvokeSystemCertificateValidator (
-                       ICertificateValidator validator, string targetHost, bool serverMode,
-                       X509CertificateCollection certificates, ref X509Chain chain, out bool success,
-                       ref MonoSslPolicyErrors errors, ref int status11)
+               internal virtual bool InvokeSystemCertificateValidator (
+                       ICertificateValidator2 validator, string targetHost, bool serverMode,
+                       X509CertificateCollection certificates, bool wantsChain, ref X509Chain chain,
+                       out bool success, ref MonoSslPolicyErrors errors, ref int status11)
                {
-                       success = false;
-                       return false;
+                       throw new InvalidOperationException ();
                }
 
 #endregion
index a7651da891f7900adbb0b0cead4fa0ad03b94ce3..69456085a2bda90e18facc43bc4dcfcdffedf776 100644 (file)
@@ -83,3 +83,5 @@ using System.Runtime.InteropServices;
        [assembly: InternalsVisibleTo ("Mono.Security.Providers.NewTls, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
        [assembly: InternalsVisibleTo ("Mono.Security.Providers.DotNet, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
        [assembly: InternalsVisibleTo ("Mono.Security, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
+
+       [assembly: InternalsVisibleTo ("Xamarin.BoringTls, PublicKey=002400000480000094000000060200000024000052534131000400001100000099dd12eda85767ae6f06023ee28e711c7e5a212462095c83868c29db75eddf6d8e296e03824c14fedd5f55553fed0b6173be3cc985a4b7f9fb7c83ccff8ba3938563b3d1f45a81122f12a1bcb73edcaad61a8456c7595a6da5184b4dd9d10f011b949ef1391fccfeab1ba62aa51c267ef8bd57ef1b6ba5a4c515d0badb81a78f")]
index 617fbdefd531e5d2e6686ce7cc15f85348498a34..9a5eab25ce6f4aee6f104fb0eb41ef4479c53c2c 100644 (file)
@@ -74,7 +74,7 @@ namespace Mono.Net.Security
 {
        internal delegate bool ServerCertValidationCallbackWrapper (ServerCertValidationCallback callback, X509Certificate certificate, X509Chain chain, MonoSslPolicyErrors sslPolicyErrors);
 
-       internal class ChainValidationHelper : ICertificateValidator
+       internal class ChainValidationHelper : ICertificateValidator2
        {
                readonly object sender;
                readonly MonoTlsSettings settings;
@@ -228,7 +228,7 @@ namespace Mono.Net.Security
                        var certs = new XX509CertificateCollection ();
                        certs.Add (new X509Certificate2 (certificate.GetRawCertData ()));
 
-                       var result = ValidateChain (string.Empty, true, certs, (SslPolicyErrors)errors);
+                       var result = ValidateChain (string.Empty, true, certificate, null, certs, (SslPolicyErrors)errors);
                        if (result == null)
                                return false;
 
@@ -238,7 +238,27 @@ namespace Mono.Net.Security
                public ValidationResult ValidateCertificate (string host, bool serverMode, XX509CertificateCollection certs)
                {
                        try {
-                               var result = ValidateChain (host, serverMode, certs, 0);
+                               X509Certificate leaf;
+                               if (certs != null && certs.Count != 0)
+                                       leaf = certs [0];
+                               else
+                                       leaf = null;
+                               var result = ValidateChain (host, serverMode, leaf, null, certs, 0);
+                               if (tlsStream != null)
+                                       tlsStream.CertificateValidationFailed = result == null || !result.Trusted || result.UserDenied;
+                               return result;
+                       } catch {
+                               if (tlsStream != null)
+                                       tlsStream.CertificateValidationFailed = true;
+                               throw;
+                       }
+               }
+
+               public ValidationResult ValidateCertificate (string host, bool serverMode, X509Certificate leaf, XX509Chain xchain)
+               {
+                       try {
+                               var chain = (X509Chain)(object)xchain;
+                               var result = ValidateChain (host, serverMode, leaf, chain, null, 0);
                                if (tlsStream != null)
                                        tlsStream.CertificateValidationFailed = result == null || !result.Trusted || result.UserDenied;
                                return result;
@@ -249,7 +269,28 @@ namespace Mono.Net.Security
                        }
                }
 
-               ValidationResult ValidateChain (string host, bool server, XX509CertificateCollection certs, SslPolicyErrors errors)
+               ValidationResult ValidateChain (string host, bool server, X509Certificate leaf,
+                                               X509Chain chain, XX509CertificateCollection certs,
+                                               SslPolicyErrors errors)
+               {
+                       var oldChain = chain;
+                       var ownsChain = chain == null;
+                       try {
+                               var result = ValidateChain (host, server, leaf, ref chain, certs, errors);
+                               if (chain != oldChain)
+                                       ownsChain = true;
+
+                               return result;
+                       } finally {
+                               // If ValidateChain() changed the chain, then we need to free it.
+                               if (ownsChain && chain != null)
+                                       chain.Dispose ();
+                       }
+               }
+
+               ValidationResult ValidateChain (string host, bool server, X509Certificate leaf,
+                                               ref X509Chain chain, XX509CertificateCollection certs,
+                                               SslPolicyErrors errors)
                {
                        // user_denied is true if the user callback is called and returns false
                        bool user_denied = false;
@@ -257,12 +298,6 @@ namespace Mono.Net.Security
 
                        var hasCallback = certValidationCallback != null || callbackWrapper != null;
 
-                       X509Certificate leaf;
-                       if (certs == null || certs.Count == 0)
-                               leaf = null;
-                       else
-                               leaf = certs [0];
-
                        if (tlsStream != null)
                                request.ServicePoint.UpdateServerCertificate (leaf);
 
@@ -281,7 +316,6 @@ namespace Mono.Net.Security
                        ICertificatePolicy policy = ServicePointManager.GetLegacyCertificatePolicy ();
 
                        int status11 = 0; // Error code passed to the obsolete ICertificatePolicy callback
-                       X509Chain chain = null;
 
                        bool wantsChain = SystemCertificateValidator.NeedsChain (settings);
                        if (!wantsChain && hasCallback) {
@@ -289,16 +323,15 @@ namespace Mono.Net.Security
                                        wantsChain = true;
                        }
 
-                       if (wantsChain)
-                               chain = SystemCertificateValidator.CreateX509Chain (certs);
-
                        bool providerValidated = false;
                        if (provider != null && provider.HasCustomSystemCertificateValidator) {
                                var xerrors = (MonoSslPolicyErrors)errors;
                                var xchain = (XX509Chain)(object)chain;
-                               providerValidated = provider.InvokeSystemCertificateValidator (this, host, server, certs, ref xchain, out result, ref xerrors, ref status11);
+                               providerValidated = provider.InvokeSystemCertificateValidator (this, host, server, certs, wantsChain, ref xchain, out result, ref xerrors, ref status11);
                                chain = (X509Chain)(object)xchain;
                                errors = (SslPolicyErrors)xerrors;
+                       } else if (wantsChain) {
+                               chain = SystemCertificateValidator.CreateX509Chain (certs);
                        }
 
                        if (!providerValidated)
index cf95aee80ea0e92aa4eec92c3b2ce8c4a6bf8ccd..3c68cceb82bd865d74cc309f0221d75921bfc667 100644 (file)
@@ -94,4 +94,5 @@ using System.Runtime.InteropServices;
 [assembly: InternalsVisibleTo ("Xamarin.Mac, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
 #endif
 
+[assembly: InternalsVisibleTo ("Xamarin.BoringTls, PublicKey=002400000480000094000000060200000024000052534131000400001100000099dd12eda85767ae6f06023ee28e711c7e5a212462095c83868c29db75eddf6d8e296e03824c14fedd5f55553fed0b6173be3cc985a4b7f9fb7c83ccff8ba3938563b3d1f45a81122f12a1bcb73edcaad61a8456c7595a6da5184b4dd9d10f011b949ef1391fccfeab1ba62aa51c267ef8bd57ef1b6ba5a4c515d0badb81a78f")]
 [assembly: Guid ("BED7F4EA-1A96-11D2-8F08-00A0C9A6186D")]