From cb885fe3e0aca53c464c118c636558c108bd2e0e Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Wed, 26 Apr 2017 17:15:37 -0400 Subject: [PATCH] [Mono.Security.Interface]: Improve synergy between `SslStream` and `IMonoSslStream` (#4756) * [Mono.Security.Interface]: Improve synergy between `MonoTlsProvider`, `SslStream` and `IMonoSslStream`. * Add `IMonoSslStream.SslStream` property; the `IMonoSslStream` is now only created my the `SslStream` constructor, so `SslStream` "owns" the `IMonoSslStream`. * Add internal `MonoTlsProvider.CreateSslStreamInternal()`. * `SslStream` does not need to implement any additional interfaces; we can do without after getting rid of the wrapper classes. * Add internal `SslStream.CreateMonoSslStream(Stream,bool,MonoTlsProvider,MonoTlsSettings)`. * `MonoTlsProvider.CreateSslStream()` implementations should use this new method. * Remove ancient obsolete MonoTlsProviderFactory APIs. * `HttpListener` and `HttpConnection` now use `SslStream` instead of `IMonoSslStream`. * [System]: Cleanup internal TLS Provider registration. * Make it build. --- .../Mono.Security.Interface/IMonoSslStream.cs | 4 + .../Mono.Security.Interface/MonoTlsProvider.cs | 4 + .../MonoTlsProviderFactory.cs | 16 -- mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs | 14 +- mcs/class/System/Mono.AppleTls/AppleTlsStream.cs | 6 +- mcs/class/System/Mono.Btls/MonoBtlsProvider.cs | 14 +- mcs/class/System/Mono.Btls/MonoBtlsStream.cs | 6 +- .../System/Mono.Net.Security/LegacySslStream.cs | 16 +- .../System/Mono.Net.Security/LegacyTlsProvider.cs | 13 +- .../Mono.Net.Security/MobileAuthenticatedStream.cs | 13 +- .../MonoTlsProviderFactory.Apple.cs | 120 -------------- .../MonoTlsProviderFactory.Droid.cs | 42 ----- .../Mono.Net.Security/MonoTlsProviderFactory.cs | 179 ++++++++++++++++----- .../System/Mono.Net.Security/NoReflectionHelper.cs | 2 +- mcs/class/System/System.Net.Security/SslStream.cs | 15 +- mcs/class/System/System.Net/HttpConnection.cs | 8 +- mcs/class/System/System.Net/HttpListener.cs | 11 +- mcs/class/System/monodroid_System.dll.sources | 1 - mcs/class/System/monotouch_System.dll.sources | 3 - .../monotouch_watch_System.dll.exclude.sources | 1 - mcs/class/System/xammac_System.dll.sources | 1 - mcs/class/System/xammac_net_4_5_System.dll.sources | 1 - 22 files changed, 220 insertions(+), 270 deletions(-) delete mode 100644 mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Apple.cs delete mode 100644 mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Droid.cs diff --git a/mcs/class/Mono.Security/Mono.Security.Interface/IMonoSslStream.cs b/mcs/class/Mono.Security/Mono.Security.Interface/IMonoSslStream.cs index 0098be9f45a..4982e804477 100644 --- a/mcs/class/Mono.Security/Mono.Security.Interface/IMonoSslStream.cs +++ b/mcs/class/Mono.Security/Mono.Security.Interface/IMonoSslStream.cs @@ -38,6 +38,10 @@ namespace Mono.Security.Interface { public interface IMonoSslStream : IDisposable { + SslStream SslStream { + get; + } + void AuthenticateAsClient (string targetHost); void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation); diff --git a/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs b/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs index 0d7a7512d6a..05f507a852e 100644 --- a/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs +++ b/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs @@ -122,6 +122,10 @@ namespace Mono.Security.Interface Stream innerStream, bool leaveInnerStreamOpen, MonoTlsSettings settings = null); + internal abstract IMonoSslStream CreateSslStreamInternal ( + SslStream sslStream, Stream innerStream, bool leaveInnerStreamOpen, + MonoTlsSettings settings); + #endregion #region Native Certificate Implementation diff --git a/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProviderFactory.cs b/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProviderFactory.cs index 918a273a78a..1ed77bbebdf 100644 --- a/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProviderFactory.cs +++ b/mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProviderFactory.cs @@ -167,22 +167,6 @@ namespace Mono.Security.Interface } #endregion - - #region Obsolete APIs - - [Obsolete ("Use GetProvider() instead.")] - public static MonoTlsProvider GetDefaultProvider () - { - return GetProvider (); - } - - [Obsolete ("Use Initialize(string provider) instead.")] - public static void SetDefaultProvider (string name) - { - Initialize (name); - } - - #endregion } } diff --git a/mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs b/mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs index 81f1b62a8ab..4fdabfd3ae3 100644 --- a/mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs +++ b/mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs @@ -16,6 +16,7 @@ using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -30,21 +31,26 @@ namespace Mono.AppleTls { class AppleTlsProvider : MonoTlsProvider { - static readonly Guid id = new Guid ("981af8af-a3a3-419a-9f01-a518e3a17c1c"); - public override string Name { get { return "apple-tls"; } } public override Guid ID { - get { return id; } + get { return MNS.MonoTlsProviderFactory.AppleTlsId; } } public override IMonoSslStream CreateSslStream ( Stream innerStream, bool leaveInnerStreamOpen, MonoTlsSettings settings = null) { - return new AppleTlsStream (innerStream, leaveInnerStreamOpen, settings, this); + return SslStream.CreateMonoSslStream (innerStream, leaveInnerStreamOpen, this, settings); + } + + internal override IMonoSslStream CreateSslStreamInternal ( + SslStream sslStream, Stream innerStream, bool leaveInnerStreamOpen, + MonoTlsSettings settings) + { + return new AppleTlsStream (innerStream, leaveInnerStreamOpen, sslStream, settings, this); } public override bool SupportsSslStream { diff --git a/mcs/class/System/Mono.AppleTls/AppleTlsStream.cs b/mcs/class/System/Mono.AppleTls/AppleTlsStream.cs index 749fec6d35d..e3b9fa85933 100644 --- a/mcs/class/System/Mono.AppleTls/AppleTlsStream.cs +++ b/mcs/class/System/Mono.AppleTls/AppleTlsStream.cs @@ -16,6 +16,7 @@ using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -30,8 +31,9 @@ namespace Mono.AppleTls { class AppleTlsStream : MNS.MobileAuthenticatedStream { - public AppleTlsStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsSettings settings, MonoTlsProvider provider) - : base (innerStream, leaveInnerStreamOpen, settings, provider) + public AppleTlsStream (Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, + MonoTlsSettings settings, MonoTlsProvider provider) + : base (innerStream, leaveInnerStreamOpen, owner, settings, provider) { } diff --git a/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs b/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs index 21aa003b4d8..bd979345e0d 100644 --- a/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs +++ b/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs @@ -32,6 +32,7 @@ using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Security.Authentication; @@ -49,10 +50,8 @@ namespace Mono.Btls { class MonoBtlsProvider : MonoTlsProvider { - static readonly Guid id = new Guid ("432d18c9-9348-4b90-bfbf-9f2a10e1f15b"); - public override Guid ID { - get { return id; } + get { return MNS.MonoTlsProviderFactory.BtlsId; } } public override string Name { get { return "btls"; } @@ -84,8 +83,15 @@ namespace Mono.Btls Stream innerStream, bool leaveInnerStreamOpen, MonoTlsSettings settings = null) { + return SslStream.CreateMonoSslStream (innerStream, leaveInnerStreamOpen, this, settings); + } + + internal override IMonoSslStream CreateSslStreamInternal ( + SslStream sslStream, Stream innerStream, bool leaveInnerStreamOpen, + MonoTlsSettings settings) + { return new MonoBtlsStream ( - innerStream, leaveInnerStreamOpen, settings, this); + innerStream, leaveInnerStreamOpen, sslStream, settings, this); } internal override bool HasNativeCertificates { diff --git a/mcs/class/System/Mono.Btls/MonoBtlsStream.cs b/mcs/class/System/Mono.Btls/MonoBtlsStream.cs index 38b6d83a4d6..e941fcd1c0c 100644 --- a/mcs/class/System/Mono.Btls/MonoBtlsStream.cs +++ b/mcs/class/System/Mono.Btls/MonoBtlsStream.cs @@ -30,6 +30,7 @@ extern alias MonoSecurity; using System; using System.IO; +using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -45,8 +46,9 @@ namespace Mono.Btls { class MonoBtlsStream : MNS.MobileAuthenticatedStream { - public MonoBtlsStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsSettings settings, MonoTlsProvider provider) - : base (innerStream, leaveInnerStreamOpen, settings, provider) + public MonoBtlsStream (Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, + MonoTlsSettings settings, MonoTlsProvider provider) + : base (innerStream, leaveInnerStreamOpen, owner, settings, provider) { } diff --git a/mcs/class/System/Mono.Net.Security/LegacySslStream.cs b/mcs/class/System/Mono.Net.Security/LegacySslStream.cs index 1ca30e6c96d..a5572addc13 100644 --- a/mcs/class/System/Mono.Net.Security/LegacySslStream.cs +++ b/mcs/class/System/Mono.Net.Security/LegacySslStream.cs @@ -81,16 +81,16 @@ namespace Mono.Net.Security.Private SslStreamBase ssl_stream; ICertificateValidator certificateValidator; - MonoTlsProvider provider; #endregion // Fields #region Constructors - public LegacySslStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings) + public LegacySslStream (Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, MonoTlsProvider provider, MonoTlsSettings settings) : base (innerStream, leaveInnerStreamOpen) { - this.provider = provider; + SslStream = owner; + Provider = provider; certificateValidator = ChainValidationHelper.GetInternalValidator (provider, settings); } #endregion // Constructors @@ -583,11 +583,15 @@ namespace Mono.Net.Security.Private get { throw new NotSupportedException (); } } - MonoTlsProvider IMonoSslStream.Provider { - get { return provider; } + public SslStream SslStream { + get; } - MonoTlsConnectionInfo IMonoSslStream.GetConnectionInfo () + public MonoTlsProvider Provider { + get; + } + + public MonoTlsConnectionInfo GetConnectionInfo () { return null; } diff --git a/mcs/class/System/Mono.Net.Security/LegacyTlsProvider.cs b/mcs/class/System/Mono.Net.Security/LegacyTlsProvider.cs index 666d4b0465d..a67b1ff069e 100644 --- a/mcs/class/System/Mono.Net.Security/LegacyTlsProvider.cs +++ b/mcs/class/System/Mono.Net.Security/LegacyTlsProvider.cs @@ -48,10 +48,8 @@ namespace Mono.Net.Security */ class LegacyTlsProvider : MSI.MonoTlsProvider { - static readonly Guid id = new Guid ("809e77d5-56cc-4da8-b9f0-45e65ba9cceb"); - public override Guid ID { - get { return id; } + get { return MonoTlsProviderFactory.LegacyId; } } public override string Name { @@ -78,7 +76,14 @@ namespace Mono.Net.Security Stream innerStream, bool leaveInnerStreamOpen, MSI.MonoTlsSettings settings = null) { - return new Private.LegacySslStream (innerStream, leaveInnerStreamOpen, this, settings); + return SslStream.CreateMonoSslStream (innerStream, leaveInnerStreamOpen, this, settings); + } + + internal override MSI.IMonoSslStream CreateSslStreamInternal ( + SslStream sslStream, Stream innerStream, bool leaveInnerStreamOpen, + MSI.MonoTlsSettings settings) + { + return new Private.LegacySslStream (innerStream, leaveInnerStreamOpen, sslStream, this, settings); } internal override bool ValidateCertificate ( diff --git a/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs b/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs index 8ca8fb65754..1e57c673415 100644 --- a/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs +++ b/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs @@ -50,10 +50,11 @@ namespace Mono.Net.Security static int uniqueNameInteger = 123; - public MobileAuthenticatedStream (Stream innerStream, bool leaveInnerStreamOpen, + public MobileAuthenticatedStream (Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, MSI.MonoTlsSettings settings, MSI.MonoTlsProvider provider) : base (innerStream, leaveInnerStreamOpen) { + SslStream = owner; Settings = settings; Provider = provider; @@ -61,18 +62,16 @@ namespace Mono.Net.Security writeBuffer = new BufferOffsetSize2 (16384); } - public MSI.MonoTlsSettings Settings { + public SslStream SslStream { get; - private set; } - public MSI.MonoTlsProvider Provider { + public MSI.MonoTlsSettings Settings { get; - private set; } - MSI.MonoTlsProvider MSI.IMonoSslStream.Provider { - get { return Provider; } + public MSI.MonoTlsProvider Provider { + get; } internal bool HasContext { diff --git a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Apple.cs b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Apple.cs deleted file mode 100644 index e5f2f0c2dd3..00000000000 --- a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Apple.cs +++ /dev/null @@ -1,120 +0,0 @@ -// -// MonoTlsProviderFactory.cs -// -// Author: -// Chris Hamons -// Martin Baulig -// -// Copyright (c) 2015 Xamarin, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#if !ONLY_APPLETLS -#error Use MonoTlsProviderFactory.cs instead -#endif - -#if SECURITY_DEP - -#if MONO_SECURITY_ALIAS -extern alias MonoSecurity; -using MSI = MonoSecurity::Mono.Security.Interface; -using MX = MonoSecurity::Mono.Security.X509; -#else -using MSI = Mono.Security.Interface; -using MX = Mono.Security.X509; -#endif -using System.Security.Cryptography.X509Certificates; -using Mono.AppleTls; - -using System; -using System.Net; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace Mono.Net.Security -{ - /* - * Keep in sync with Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs. - * Simple implementation that does hard codes only a single provider - */ - static partial class MonoTlsProviderFactory - { - #region Internal API - - /* - * APIs in this section are for consumption within System.dll only - do not access via - * reflection or from friend assemblies. - * - */ - internal static MSI.MonoTlsProvider GetProviderInternal () - { - return GetTlsProvider (); - } - - #endregion - - static object locker = new object (); - static MSI.MonoTlsProvider provider; - static MSI.MonoTlsProvider GetTlsProvider () - { - lock (locker) { - if (provider == null) - provider = new AppleTlsProvider (); - return provider; - } - } - - - #region Mono.Security visible API - - /* - * "Public" section, intended to be consumed via reflection. - * - * Mono.Security.dll provides a public wrapper around these. - */ - - internal static MSI.MonoTlsProvider GetProvider () - { - return GetTlsProvider (); - } - - internal static bool IsProviderSupported (string name) - { - return true; - } - - internal static MSI.MonoTlsProvider GetProvider (string name) - { - return GetTlsProvider (); - } - - internal static bool IsInitialized => true; - - internal static void Initialize () - { - } - - internal static void Initialize (string provider) - { - } - #endregion - } -} -#endif - diff --git a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Droid.cs b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Droid.cs deleted file mode 100644 index 49ac9fde664..00000000000 --- a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Droid.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 Xamarin Inc. All rights reserved. -#if SECURITY_DEP - -#if MONO_SECURITY_ALIAS -extern alias MonoSecurity; -using MSI = MonoSecurity::Mono.Security.Interface; -#else -using MSI = Mono.Security.Interface; -#endif - -#if MONO_FEATURE_BTLS -using Mono.Btls; -#endif - -using System; - -namespace Mono.Net.Security -{ - static partial class MonoTlsProviderFactory - { - static MSI.MonoTlsProvider CreateDefaultProviderImpl () - { - MSI.MonoTlsProvider provider = null; - var type = Environment.GetEnvironmentVariable ("XA_TLS_PROVIDER"); - switch (type) { - case null: - case "default": - case "legacy": - return new LegacyTlsProvider (); -#if MONO_FEATURE_BTLS - case "btls": - if (!IsBtlsSupported ()) - throw new NotSupportedException ("BTLS in not supported!"); - return new MonoBtlsProvider (); -#endif - default: - throw new NotSupportedException (string.Format ("Invalid TLS Provider: `{0}'.", provider)); - } - } - } -} -#endif diff --git a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.cs b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.cs index b9185964572..0fe5ef8294e 100644 --- a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.cs +++ b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if SECURITY_DEP && !ONLY_APPLETLS // ONLY_APPLETLS uses MonoTlsProviderFactory.Apple.cs instead +#if SECURITY_DEP #if MONO_SECURITY_ALIAS extern alias MonoSecurity; @@ -41,6 +41,10 @@ using System.Net; using System.Collections.Generic; using System.Runtime.CompilerServices; +#if MONO_FEATURE_BTLS +using Mono.Btls; +#endif + #if !MOBILE using System.Reflection; #endif @@ -53,7 +57,7 @@ namespace Mono.Net.Security */ static partial class MonoTlsProviderFactory { - #region Internal API +#region Internal API /* * APIs in this section are for consumption within System.dll only - do not access via @@ -85,6 +89,11 @@ namespace Mono.Net.Security if (provider == null) throw new NotSupportedException ("TLS Support not available."); + if (!providerCache.ContainsKey (provider.ID)) + providerCache.Add (provider.ID, provider); + + X509Helper2.Initialize (); + defaultProvider = provider; initialized = true; } @@ -97,76 +106,162 @@ namespace Mono.Net.Security throw new NotSupportedException ("TLS Subsystem already initialized."); defaultProvider = LookupProvider (provider, true); + + X509Helper2.Initialize (); initialized = true; } } - [MethodImpl (MethodImplOptions.InternalCall)] - internal extern static bool IsBtlsSupported (); - static object locker = new object (); static bool initialized; static MSI.MonoTlsProvider defaultProvider; - #endregion - - static Dictionary providerRegistration; + /* + * @providerRegistration maps provider names to a tuple containing its ID and full type name. + * On non-reflection enabled systems (such as XI and XM), we can use the Guid to uniquely + * identify the provider. + * + * @providerCache maps the provider's Guid to the MSI.MonoTlsProvider instance. + * + */ + static Dictionary> providerRegistration; + static Dictionary providerCache; +#if !ONLY_APPLETLS && !MONOTOUCH && !XAMMAC static Type LookupProviderType (string name, bool throwOnError) { lock (locker) { InitializeProviderRegistration (); - string typeName; - if (!providerRegistration.TryGetValue (name, out typeName)) { + Tuple entry; + if (!providerRegistration.TryGetValue (name, out entry)) { if (throwOnError) throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name)); return null; } - var type = Type.GetType (typeName, false); + var type = Type.GetType (entry.Item2, false); if (type == null && throwOnError) - throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", typeName)); + throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", entry.Item2)); return type; } } +#endif static MSI.MonoTlsProvider LookupProvider (string name, bool throwOnError) { - var type = LookupProviderType (name, throwOnError); - if (type == null) - return null; - - try { - return (MSI.MonoTlsProvider)Activator.CreateInstance (type, true); - } catch (Exception ex) { - throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex); + lock (locker) { + InitializeProviderRegistration (); + Tuple entry; + if (!providerRegistration.TryGetValue (name, out entry)) { + if (throwOnError) + throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name)); + return null; + } + + // Check cache before doing the reflection lookup. + MSI.MonoTlsProvider provider; + if (providerCache.TryGetValue (entry.Item1, out provider)) + return provider; + +#if !ONLY_APPLETLS && !MONOTOUCH && !XAMMAC + var type = Type.GetType (entry.Item2, false); + if (type == null && throwOnError) + throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", entry.Item2)); + + try { + provider = (MSI.MonoTlsProvider)Activator.CreateInstance (type, true); + } catch (Exception ex) { + throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex); + } +#endif + + if (provider == null) { + if (throwOnError) + throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name)); + return null; + } + + providerCache.Add (entry.Item1, provider); + return provider; } } +#endregion + + internal static readonly Guid AppleTlsId = new Guid ("981af8af-a3a3-419a-9f01-a518e3a17c1c"); + internal static readonly Guid BtlsId = new Guid ("432d18c9-9348-4b90-bfbf-9f2a10e1f15b"); + internal static readonly Guid LegacyId = new Guid ("809e77d5-56cc-4da8-b9f0-45e65ba9cceb"); + static void InitializeProviderRegistration () { lock (locker) { if (providerRegistration != null) return; - providerRegistration = new Dictionary (); - providerRegistration.Add ("legacy", "Mono.Net.Security.LegacyTlsProvider"); - + providerRegistration = new Dictionary> (); + providerCache = new Dictionary (); + + var appleTlsEntry = new Tuple (AppleTlsId, "Mono.AppleTls.AppleTlsProvider"); + +#if ONLY_APPLETLS || MONOTOUCH || XAMMAC + providerRegistration.Add ("default", appleTlsEntry); + providerRegistration.Add ("apple", appleTlsEntry); +#else + var legacyEntry = new Tuple (BtlsId, "Mono.Net.Security.LegacyTlsProvider"); +#if MONO_FEATURE_BTLS + var btlsEntry = new Tuple (LegacyId, "Mono.Btls.MonoBtlsProvider"); +#endif + + providerRegistration.Add ("legacy", legacyEntry); + if (Platform.IsMacOS) - providerRegistration.Add ("default", "Mono.AppleTls.AppleTlsProvider"); + providerRegistration.Add ("default", appleTlsEntry); else - providerRegistration.Add ("default", "Mono.Net.Security.LegacyTlsProvider"); + providerRegistration.Add ("default", legacyEntry); +#if MONO_FEATURE_BTLS if (IsBtlsSupported ()) - providerRegistration.Add ("btls", "Mono.Btls.MonoBtlsProvider"); - - providerRegistration.Add ("apple", "Mono.AppleTls.AppleTlsProvider"); - - X509Helper2.Initialize (); + providerRegistration.Add ("btls", btlsEntry); +#endif + + providerRegistration.Add ("apple", appleTlsEntry); +#endif } } -#if !MONODROID && !MONOTOUCH && !XAMMAC - static MSI.MonoTlsProvider TryDynamicLoad () +#region Platform-Specific code + +#if MONO_FEATURE_BTLS + [MethodImpl (MethodImplOptions.InternalCall)] + internal extern static bool IsBtlsSupported (); +#endif + +#if MONODROID + static MSI.MonoTlsProvider CreateDefaultProviderImpl () + { + MSI.MonoTlsProvider provider = null; + var type = Environment.GetEnvironmentVariable ("XA_TLS_PROVIDER"); + switch (type) { + case null: + case "default": + case "legacy": + return new LegacyTlsProvider (); +#if MONO_FEATURE_BTLS + case "btls": + if (!IsBtlsSupported ()) + throw new NotSupportedException ("BTLS in not supported!"); + return new MonoBtlsProvider (); +#endif + default: + throw new NotSupportedException (string.Format ("Invalid TLS Provider: `{0}'.", provider)); + } + } +#elif ONLY_APPLETLS || MONOTOUCH || XAMMAC + static MSI.MonoTlsProvider CreateDefaultProviderImpl () + { + return new AppleTlsProvider (); + } +#else + static MSI.MonoTlsProvider CreateDefaultProviderImpl () { var variable = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER"); if (string.IsNullOrEmpty (variable)) @@ -174,18 +269,11 @@ namespace Mono.Net.Security return LookupProvider (variable, true); } - - static MSI.MonoTlsProvider CreateDefaultProviderImpl () - { - var provider = TryDynamicLoad (); - if (provider != null) - return provider; - - return new LegacyTlsProvider (); - } #endif - #region Mono.Security visible API +#endregion + +#region Mono.Security visible API /* * "Public" section, intended to be consumed via reflection. @@ -204,7 +292,10 @@ namespace Mono.Net.Security internal static bool IsProviderSupported (string name) { - return LookupProvider (name, false) != null; + lock (locker) { + InitializeProviderRegistration (); + return providerRegistration.ContainsKey (name); + } } internal static MSI.MonoTlsProvider GetProvider (string name) @@ -229,7 +320,7 @@ namespace Mono.Net.Security { InitializeInternal (provider); } - #endregion +#endregion } } #endif diff --git a/mcs/class/System/Mono.Net.Security/NoReflectionHelper.cs b/mcs/class/System/Mono.Net.Security/NoReflectionHelper.cs index 8cd48453bfe..5aa87483142 100644 --- a/mcs/class/System/Mono.Net.Security/NoReflectionHelper.cs +++ b/mcs/class/System/Mono.Net.Security/NoReflectionHelper.cs @@ -132,7 +132,7 @@ namespace Mono.Net.Security internal static object GetMonoSslStream (HttpListenerContext context) { #if SECURITY_DEP - return context.Connection.SslStream; + return context.Connection.SslStream?.Impl; #else throw new NotSupportedException (); #endif diff --git a/mcs/class/System/System.Net.Security/SslStream.cs b/mcs/class/System/System.Net.Security/SslStream.cs index 603a18b0cf1..7f0c0d1b0a5 100644 --- a/mcs/class/System/System.Net.Security/SslStream.cs +++ b/mcs/class/System/System.Net.Security/SslStream.cs @@ -104,7 +104,7 @@ namespace System.Net.Security : base (innerStream, leaveInnerStreamOpen) { provider = GetProvider (); - impl = provider.CreateSslStream (innerStream, leaveInnerStreamOpen); + impl = provider.CreateSslStreamInternal (this, innerStream, leaveInnerStreamOpen, null); } public SslStream (Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback) @@ -128,6 +128,19 @@ namespace System.Net.Security { } + SslStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings) + : base (innerStream, leaveInnerStreamOpen) + { + this.provider = provider; + impl = provider.CreateSslStreamInternal (this, innerStream, leaveInnerStreamOpen, settings); + } + + internal static IMonoSslStream CreateMonoSslStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings) + { + var sslStream = new SslStream (innerStream, leaveInnerStreamOpen, provider, settings); + return sslStream.Impl; + } + public virtual void AuthenticateAsClient (string targetHost) { Impl.AuthenticateAsClient (targetHost); diff --git a/mcs/class/System/System.Net/HttpConnection.cs b/mcs/class/System/System.Net/HttpConnection.cs index 40a8e6c3e85..680ec8188ed 100644 --- a/mcs/class/System/System.Net/HttpConnection.cs +++ b/mcs/class/System/System.Net/HttpConnection.cs @@ -42,10 +42,10 @@ using System.IO; using System.Net.Sockets; using System.Text; using System.Threading; +using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; -using Mono.Net.Security; namespace System.Net { sealed class HttpConnection @@ -73,7 +73,7 @@ namespace System.Net { HttpListener last_listener; int [] client_cert_errors; X509Certificate2 client_cert; - MSI.IMonoSslStream ssl_stream; + SslStream ssl_stream; public HttpConnection (Socket sock, EndPointListener epl, bool secure, X509Certificate cert) { @@ -94,13 +94,13 @@ namespace System.Net { client_cert_errors = new int[] { (int)e }; return true; }); - stream = ssl_stream.AuthenticatedStream; + stream = ssl_stream; } timer = new Timer (OnTimeout, null, Timeout.Infinite, Timeout.Infinite); Init (); } - internal MSI.IMonoSslStream SslStream { + internal SslStream SslStream { get { return ssl_stream; } } diff --git a/mcs/class/System/System.Net/HttpListener.cs b/mcs/class/System/System.Net/HttpListener.cs index 5676357fb63..1748b5e2283 100644 --- a/mcs/class/System/System.Net/HttpListener.cs +++ b/mcs/class/System/System.Net/HttpListener.cs @@ -42,13 +42,11 @@ using System.IO; using System.Collections; using System.Threading; using System.Threading.Tasks; +using System.Net.Security; using System.Security.Authentication.ExtendedProtection; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; -using Mono.Net.Security; - - //TODO: logging namespace System.Net { public sealed class HttpListener : IDisposable { @@ -125,16 +123,17 @@ namespace System.Net { } } - internal MSI.IMonoSslStream CreateSslStream (Stream innerStream, bool ownsStream, MSI.MonoRemoteCertificateValidationCallback callback) + internal SslStream CreateSslStream (Stream innerStream, bool ownsStream, MSI.MonoRemoteCertificateValidationCallback callback) { lock (registry) { if (tlsProvider == null) - tlsProvider = MonoTlsProviderFactory.GetProviderInternal (); + tlsProvider = MSI.MonoTlsProviderFactory.GetProvider (); if (tlsSettings == null) tlsSettings = MSI.MonoTlsSettings.CopyDefaultSettings (); if (tlsSettings.RemoteCertificateValidationCallback == null) tlsSettings.RemoteCertificateValidationCallback = callback; - return tlsProvider.CreateSslStream (innerStream, ownsStream, tlsSettings); + var sslStream = tlsProvider.CreateSslStream (innerStream, ownsStream, tlsSettings); + return sslStream.SslStream; } } diff --git a/mcs/class/System/monodroid_System.dll.sources b/mcs/class/System/monodroid_System.dll.sources index c2950c536ca..c6769c373a7 100644 --- a/mcs/class/System/monodroid_System.dll.sources +++ b/mcs/class/System/monodroid_System.dll.sources @@ -1,4 +1,3 @@ #include mobile_System.dll.sources System/AndroidPlatform.cs -Mono.Net.Security/MonoTlsProviderFactory.Droid.cs Mono.Btls/MonoBtlsX509LookupAndroid.cs diff --git a/mcs/class/System/monotouch_System.dll.sources b/mcs/class/System/monotouch_System.dll.sources index 8d2f2fdbbc4..e478e8894eb 100644 --- a/mcs/class/System/monotouch_System.dll.sources +++ b/mcs/class/System/monotouch_System.dll.sources @@ -1,5 +1,2 @@ #include mobile_System.dll.sources -System.Net/MacProxy.cs - -Mono.Net.Security/MonoTlsProviderFactory.Apple.cs diff --git a/mcs/class/System/monotouch_watch_System.dll.exclude.sources b/mcs/class/System/monotouch_watch_System.dll.exclude.sources index c7317052010..650f8849d53 100644 --- a/mcs/class/System/monotouch_watch_System.dll.exclude.sources +++ b/mcs/class/System/monotouch_watch_System.dll.exclude.sources @@ -8,7 +8,6 @@ Mono.Net.Security/LegacyTlsProvider.cs Mono.Net.Security/LegacyTlsProvider.cs Mono.Net.Security/MobileAuthenticatedStream.cs Mono.Net.Security/MobileTlsContext.cs -Mono.Net.Security/MonoTlsProviderFactory.Apple.cs Mono.Net.Security/MonoTlsProviderFactory.cs Mono.Net.Security/MonoTlsProviderImpl.cs Mono.Net.Security/MonoTlsStream.cs diff --git a/mcs/class/System/xammac_System.dll.sources b/mcs/class/System/xammac_System.dll.sources index 73405e10266..70a77a6dbff 100644 --- a/mcs/class/System/xammac_System.dll.sources +++ b/mcs/class/System/xammac_System.dll.sources @@ -1,2 +1 @@ #include mobile_System.dll.sources -Mono.Net.Security/MonoTlsProviderFactory.Apple.cs diff --git a/mcs/class/System/xammac_net_4_5_System.dll.sources b/mcs/class/System/xammac_net_4_5_System.dll.sources index fe68fff758f..beb6f2415cf 100644 --- a/mcs/class/System/xammac_net_4_5_System.dll.sources +++ b/mcs/class/System/xammac_net_4_5_System.dll.sources @@ -1,2 +1 @@ #include net_4_x_System.dll.sources -Mono.Net.Security/MonoTlsProviderFactory.Apple.cs -- 2.11.4.GIT