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
27 #if SECURITY_DEP && !ONLY_APPLETLS // ONLY_APPLETLS uses MonoTlsProviderFactory.Apple.cs instead
29 #if MONO_SECURITY_ALIAS
30 extern alias MonoSecurity;
31 using MSI = MonoSecurity::Mono.Security.Interface;
32 using MX = MonoSecurity::Mono.Security.X509;
34 using MSI = Mono.Security.Interface;
35 using MX = Mono.Security.X509;
37 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.
64 internal static MSI.MonoTlsProvider GetProviderInternal ()
67 InitializeInternal ();
68 return defaultProvider;
72 internal static void InitializeInternal ()
78 MSI.MonoTlsProvider provider;
80 provider = CreateDefaultProviderImpl ();
81 } catch (Exception ex) {
82 throw new NotSupportedException ("TLS Support not available.", ex);
86 throw new NotSupportedException ("TLS Support not available.");
88 defaultProvider = provider;
93 internal static void InitializeInternal (string provider)
97 throw new NotSupportedException ("TLS Subsystem already initialized.");
99 defaultProvider = LookupProvider (provider, true);
104 [MethodImpl (MethodImplOptions.InternalCall)]
105 internal extern static bool IsBtlsSupported ();
107 static object locker = new object ();
108 static bool initialized;
110 static MSI.MonoTlsProvider defaultProvider;
114 static Dictionary<string,string> providerRegistration;
116 static Type LookupProviderType (string name, bool throwOnError)
119 InitializeProviderRegistration ();
121 if (!providerRegistration.TryGetValue (name, out typeName)) {
123 throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name));
126 var type = Type.GetType (typeName, false);
127 if (type == null && throwOnError)
128 throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", typeName));
133 static MSI.MonoTlsProvider LookupProvider (string name, bool throwOnError)
135 var type = LookupProviderType (name, throwOnError);
140 return (MSI.MonoTlsProvider)Activator.CreateInstance (type, true);
141 } catch (Exception ex) {
142 throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex);
146 static void InitializeProviderRegistration ()
149 if (providerRegistration != null)
151 providerRegistration = new Dictionary<string,string> ();
152 providerRegistration.Add ("legacy", "Mono.Net.Security.LegacyTlsProvider");
154 if (Platform.IsMacOS)
155 providerRegistration.Add ("default", "Mono.AppleTls.AppleTlsProvider");
157 providerRegistration.Add ("default", "Mono.Net.Security.LegacyTlsProvider");
159 if (IsBtlsSupported ())
160 providerRegistration.Add ("btls", "Mono.Btls.MonoBtlsProvider");
162 providerRegistration.Add ("apple", "Mono.AppleTls.AppleTlsProvider");
164 X509Helper2.Initialize ();
168 #if !MONODROID && !MONOTOUCH && !XAMMAC
169 static MSI.MonoTlsProvider TryDynamicLoad ()
171 var variable = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER");
172 if (string.IsNullOrEmpty (variable))
173 variable = "default";
175 return LookupProvider (variable, true);
178 static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
180 var provider = TryDynamicLoad ();
181 if (provider != null)
184 return new LegacyTlsProvider ();
188 #region Mono.Security visible API
191 * "Public" section, intended to be consumed via reflection.
193 * Mono.Security.dll provides a public wrapper around these.
196 internal static MSI.MonoTlsProvider GetProvider ()
198 var provider = GetProviderInternal ();
199 if (provider == null)
200 throw new NotSupportedException ("No TLS Provider available.");
205 internal static bool IsProviderSupported (string name)
207 return LookupProvider (name, false) != null;
210 internal static MSI.MonoTlsProvider GetProvider (string name)
212 return LookupProvider (name, false);
215 internal static bool IsInitialized {
223 internal static void Initialize ()
225 InitializeInternal ();
228 internal static void Initialize (string provider)
230 InitializeInternal (provider);