2 // MonoTlsProviderFactory.cs
5 // Martin Baulig <martin.baulig@xamarin.com>
7 // Copyright (c) 2015 Xamarin, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 #if MONO_SECURITY_ALIAS
29 extern alias MonoSecurity;
30 using MSI = MonoSecurity::Mono.Security.Interface;
31 using MX = MonoSecurity::Mono.Security.X509;
33 using MSI = Mono.Security.Interface;
34 using MX = Mono.Security.X509;
36 using System.Security.Cryptography.X509Certificates;
41 using System.Collections.Generic;
42 using System.Runtime.CompilerServices;
45 using System.Reflection;
48 namespace Mono.Net.Security
51 * Keep in sync with Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs.
54 static partial class MonoTlsProviderFactory
59 * APIs in this section are for consumption within System.dll only - do not access via
60 * reflection or from friend assemblies.
62 * @IMonoTlsProvider is defined as empty interface outside 'SECURITY_DEP', so we don't need
63 * this conditional here.
66 internal static IMonoTlsProvider GetProviderInternal ()
70 InitializeInternal ();
71 return defaultProvider;
74 throw new NotSupportedException ("TLS Support not available.");
79 internal static void InitializeInternal ()
85 MSI.MonoTlsProvider provider;
87 provider = CreateDefaultProviderImpl ();
88 } catch (Exception ex) {
89 throw new NotSupportedException ("TLS Support not available.", ex);
93 throw new NotSupportedException ("TLS Support not available.");
95 defaultProvider = new Private.MonoTlsProviderWrapper (provider);
100 internal static void InitializeInternal (string provider)
104 throw new NotSupportedException ("TLS Subsystem already initialized.");
106 var msiProvider = LookupProvider (provider, true);
107 defaultProvider = new Private.MonoTlsProviderWrapper (msiProvider);
112 [MethodImpl (MethodImplOptions.InternalCall)]
113 internal extern static bool IsBtlsSupported ();
115 static object locker = new object ();
116 static bool initialized;
118 static IMonoTlsProvider defaultProvider;
124 static Dictionary<string,string> providerRegistration;
126 static Type LookupProviderType (string name, bool throwOnError)
129 InitializeProviderRegistration ();
131 if (!providerRegistration.TryGetValue (name, out typeName)) {
133 throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name));
136 var type = Type.GetType (typeName, false);
137 if (type == null && throwOnError)
138 throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", typeName));
143 static MSI.MonoTlsProvider LookupProvider (string name, bool throwOnError)
145 var type = LookupProviderType (name, throwOnError);
150 return (MSI.MonoTlsProvider)Activator.CreateInstance (type, true);
151 } catch (Exception ex) {
152 throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex);
156 static void InitializeProviderRegistration ()
159 if (providerRegistration != null)
161 providerRegistration = new Dictionary<string,string> ();
162 providerRegistration.Add ("legacy", "Mono.Net.Security.LegacyTlsProvider");
163 providerRegistration.Add ("default", "Mono.Net.Security.LegacyTlsProvider");
164 if (IsBtlsSupported ())
165 providerRegistration.Add ("btls", "Mono.Btls.MonoBtlsProvider");
166 X509Helper2.Initialize ();
170 #if !MONODROID && !MONOTOUCH && !XAMMAC
171 static MSI.MonoTlsProvider TryDynamicLoad ()
173 var variable = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER");
174 if (string.IsNullOrEmpty (variable))
175 variable = "default";
177 return LookupProvider (variable, true);
180 static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
182 var provider = TryDynamicLoad ();
183 if (provider != null)
186 return new LegacyTlsProvider ();
190 #region Mono.Security visible API
193 * "Public" section, intended to be consumed via reflection.
195 * Mono.Security.dll provides a public wrapper around these.
198 internal static MSI.MonoTlsProvider GetProvider ()
200 var provider = GetProviderInternal ();
201 if (provider == null)
202 throw new NotSupportedException ("No TLS Provider available.");
204 return provider.Provider;
207 internal static bool IsProviderSupported (string name)
209 return LookupProvider (name, false) != null;
212 internal static MSI.MonoTlsProvider GetProvider (string name)
214 return LookupProvider (name, false);
217 internal static bool IsInitialized {
225 internal static void Initialize ()
228 InitializeInternal ();
230 throw new NotSupportedException ("TLS Support not available.");
234 internal static void Initialize (string provider)
237 InitializeInternal (provider);
239 throw new NotSupportedException ("TLS Support not available.");
243 internal static HttpWebRequest CreateHttpsRequest (Uri requestUri, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
246 var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
247 return new HttpWebRequest (requestUri, internalProvider, settings);
251 internal static HttpListener CreateHttpListener (X509Certificate certificate, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
254 var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
255 return new HttpListener (certificate, internalProvider, settings);