Merge pull request #3769 from evincarofautumn/fix-verify-before-allocs
[mono.git] / mcs / class / System / System.Security.Cryptography.X509Certificates / X509Helper2.cs
index 1dd6b2fdac1eb597268b956eab7e90a719bf3cd1..7d0b3d1487cda4b4b5a74edbc957997fa56556f1 100644 (file)
@@ -33,12 +33,18 @@ extern alias MonoSecurity;
 
 #if MONO_SECURITY_ALIAS
 using MonoSecurity::Mono.Security.Interface;
+using MX = MonoSecurity::Mono.Security.X509;
 #else
+#if MONO_FEATURE_BTLS
 using Mono.Security.Interface;
 #endif
+using MX = Mono.Security.X509;
+#endif
 
+#if MONO_FEATURE_BTLS
 using Mono.Btls;
 #endif
+#endif
 
 using System.IO;
 using System.Text;
@@ -88,6 +94,12 @@ namespace System.Security.Cryptography.X509Certificates
                        X509Helper.ThrowIfContextInvalid (impl);
                }
 
+#if !MONO_FEATURE_BTLS
+               static X509Certificate GetNativeInstance (X509CertificateImpl impl)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+#else
                static MonoBtlsX509 GetNativeInstance (X509CertificateImpl impl)
                {
                        ThrowIfContextInvalid (impl);
@@ -110,33 +122,62 @@ namespace System.Security.Cryptography.X509Certificates
                                x509.ExportAsPEM (bio, includeHumanReadableForm);
                        }
                }
+#endif // !MONO_FEATURE_BTLS
 
-               internal static X509Certificate2Impl Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
+               internal static X509Certificate2Impl Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags, bool disableProvider = false)
                {
-                       var provider = MonoTlsProviderFactory.GetProvider ();
-                       if (provider.HasNativeCertificates) {
-                               var impl = provider.GetNativeCertificate (rawData, password, keyStorageFlags);
-                               return impl;
-                       } else {
-                               var impl = new X509Certificate2ImplMono ();
-                               impl.Import (rawData, password, keyStorageFlags);
-                               return impl;
+#if MONO_FEATURE_BTLS
+                       if (!disableProvider) {
+                               var provider = MonoTlsProviderFactory.GetProvider ();
+                               if (provider.HasNativeCertificates) {
+                                       var impl = provider.GetNativeCertificate (rawData, password, keyStorageFlags);
+                                       return impl;
+                               }
                        }
+#endif // MONO_FEATURE_BTLS
+                       var impl2 = new X509Certificate2ImplMono ();
+                       impl2.Import (rawData, password, keyStorageFlags);
+                       return impl2;
                }
 
-               internal static X509Certificate2Impl Import (X509Certificate cert)
+               internal static X509Certificate2Impl Import (X509Certificate cert, bool disableProvider = false)
                {
-                       var provider = MonoTlsProviderFactory.GetProvider ();
-                       if (provider.HasNativeCertificates) {
-                               var impl = provider.GetNativeCertificate (cert);
-                               return impl;
+#if MONO_FEATURE_BTLS
+                       if (!disableProvider) {
+                               var provider = MonoTlsProviderFactory.GetProvider ();
+                               if (provider.HasNativeCertificates) {
+                                       var impl = provider.GetNativeCertificate (cert);
+                                       return impl;
+                               }
                        }
+#endif // MONO_FEATURE_BTLS
                        var impl2 = cert.Impl as X509Certificate2Impl;
                        if (impl2 != null)
                                return (X509Certificate2Impl)impl2.Clone ();
                        return Import (cert.GetRawCertData (), null, X509KeyStorageFlags.DefaultKeySet);
                }
 
+               /*
+                * This is used by X509ChainImplMono
+                * 
+                * Some of the missing APIs such as X509v3 extensions can be added to the native
+                * BTLS implementation.
+                * 
+                * We should also consider replacing X509ChainImplMono with a new X509ChainImplBtls
+                * at some point.
+                */
+               [MonoTODO ("Investigate replacement; see comments in source.")]
+               internal static MX.X509Certificate GetMonoCertificate (X509Certificate2 certificate)
+               {
+                       var impl2 = certificate.Impl as X509Certificate2Impl;
+                       if (impl2 == null)
+                               impl2 = Import (certificate, true);
+                       var fallbackImpl = impl2.FallbackImpl as X509Certificate2ImplMono;
+                       if (fallbackImpl == null)
+                               throw new NotSupportedException ();
+                       return fallbackImpl.MonoCertificate;
+               }
+
                internal static X509ChainImpl CreateChainImpl (bool useMachineContext)
                {
                        return new X509ChainImplMono (useMachineContext);