Imported Upstream version 4.3.2.467

Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
Xamarin Public Jenkins
2016-02-22 11:00:01 -05:00
parent f302175246
commit f3e3aab35a
4097 changed files with 122406 additions and 82300 deletions

View File

@@ -77,3 +77,9 @@ using System.Runtime.InteropServices;
[assembly: StringFreezing]
[assembly: DefaultDependency (LoadHint.Always)]
#endif
[assembly: InternalsVisibleTo ("Mono.Security.Providers.NewSystemSource, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
[assembly: InternalsVisibleTo ("Mono.Security.Providers.OldTls, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
[assembly: InternalsVisibleTo ("Mono.Security.Providers.NewTls, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
[assembly: InternalsVisibleTo ("Mono.Security.Providers.DotNet, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
[assembly: InternalsVisibleTo ("Mono.Security, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]

View File

@@ -1036,9 +1036,10 @@ public class CreateDefaultExample
<Parameters />
<Docs>
<remarks>
<attribution license="cc4" from="Microsoft" modified="false" />
<para>
<see cref="M:System.Net.WebRequest.GetSystemWebProxy" /> method reads the current user's Internet Explorer (IE) proxy settings. This process includes the IE options to automatically detect proxy settings, use an automatic configuration script, manual proxy server settings, and advanced manual proxy server settings.</para>
<attribution license="cc4" from="Microsoft" modified="true" />
<para><see cref="M:System.Net.WebRequest.GetSystemWebProxy" /> creates an appropriate proxy object for the current user.</para>
<para>On Windows, the method reads the current user's Internet Explorer (IE) proxy settings. The settings supported on Mono are proxy enabled, proxy URL, and proxy excluded domains.</para>
<para>On UNIX-like systems (but not including Mac OS, iOS, or Android), the method reads the environment variables "MONO_PROXY" (or "mono_proxy") and "NO_PROXY" (or "no_proxy"). See the mono man page for more information.</para>
<para>If your application is impersonating several users, you can use the <see cref="M:System.Net.WebRequest.GetSystemWebProxy" /> method to retrieve a proxy for each impersonated user.</para>
</remarks>
<summary>

View File

@@ -4,7 +4,7 @@
<remarks>To be added.</remarks>
<summary>
<attribution license="cc4" from="Microsoft" modified="false" />
<para>The <see cref="N:System.Security.Cryptography" /> namespace provides cryptographic services, including secure encoding and decoding of data, as well as many other operations, such as hashing, random number generation, and message authentication. For more information, see <format type="text/html"><a href="f96284bc-7b73-44b5-ac59-fac613ad09f8">Cryptographic Services</a></format>.</para>
<para>The <see cref="N:System.Security.Cryptography" /> namespace provides cryptographic services, including secure encoding and decoding of data, as well as many other operations, such as hashing, random number generation, and message authentication. For more information, see <format type="text/html"><a href="https://msdn.microsoft.com/en-us/library/92f9ye3s(v=vs.110).aspx">Cryptographic Services</a></format>.</para>
</summary>
</Docs>
</Namespace>

View File

@@ -23,25 +23,33 @@ TEST_MCS_FLAGS = -r:System.Drawing.dll -r:Mono.Security.dll -r:System.Data -r:Sy
$(foreach f, $(TEST_RESOURCES), -resource:$(f),$(notdir $(f)))
REFERENCE_SOURCES_FLAGS = -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX
ifndef NO_PROCESS_START
REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_PROCESS_START
TEST_MCS_FLAGS += -d:MONO_FEATURE_PROCESS_START
endif
LIB_MCS_FLAGS = -nowarn:618 -d:CONFIGURATION_2_0 $(REFERENCE_SOURCES_FLAGS) -unsafe $(RESOURCE_FILES:%=-resource:%)
TEST_MCS_FLAGS += -r:System.Configuration
PROFILE_ANY_MOBILE := $(filter monotouch monotouch_runtime monotouch_watch monodroid xammac mobile mobile_static, $(PROFILE))
ifndef NO_THREAD_ABORT
REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_ABORT
endif
ifndef NO_THREAD_SUSPEND_RESUME
REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
TEST_MCS_FLAGS += -d:MONO_FEATURE_THREAD_SUSPEND_RESUME
endif
RESOURCE_STRINGS = ../../../external/referencesource/System/System.txt
ifeq (2.1, $(FRAMEWORK_VERSION))
LIB_MCS_FLAGS += -d:INSIDE_SYSTEM
endif
ifeq (monotouch, $(subst _runtime,,$(PROFILE)))
LIB_MCS_FLAGS += -d:SECURITY_DEP
endif
ifeq (monotouch_watch, $(PROFILE))
LIB_MCS_FLAGS += -d:SECURITY_DEP
endif
ifeq (monodroid, $(PROFILE))
LIB_MCS_FLAGS += -d:SECURITY_DEP
endif
ifndef PROFILE_ANY_MOBILE
#
# MOBILE_PROFILE needs SECURITY_DEP
#
ifdef MOBILE_PROFILE
LIB_MCS_FLAGS += -d:INSIDE_SYSTEM -d:SECURITY_DEP
else
EXTERN_ALIAS_FLAGS = -d:MONO_SECURITY_ALIAS -d:MONO_X509_ALIAS
FINAL_MCS_FLAGS = -r:System.Configuration.dll -d:CONFIGURATION_DEP
endif
@@ -51,7 +59,7 @@ endif
ifeq (secxml/, $(intermediate))
LOCAL_MCS_FLAGS = -lib:$(bare_libdir)
LIB_REFS += System.Xml MonoSecurity=Mono.Security
LIB_MCS_FLAGS += -d:SECURITY_DEP -d:XML_DEP -r:PrebuiltSystem=$(bare_libdir)/System.dll
LIB_MCS_FLAGS += -d:SECURITY_DEP -d:XML_DEP -r:PrebuiltSystem=$(bare_libdir)/System.dll $(EXTERN_ALIAS_FLAGS)
endif
#
@@ -59,7 +67,7 @@ endif
#
ifndef intermediate
LIB_REFS += System.Xml MonoSecurity=Mono.Security
LIB_MCS_FLAGS += -d:SECURITY_DEP -d:XML_DEP -r:PrebuiltSystem=$(secxml_libdir)/System.dll $(FINAL_MCS_FLAGS)
LIB_MCS_FLAGS += -d:SECURITY_DEP -d:XML_DEP -r:PrebuiltSystem=$(secxml_libdir)/System.dll $(EXTERN_ALIAS_FLAGS) $(FINAL_MCS_FLAGS)
endif
EXTRA_DISTFILES = \
@@ -80,7 +88,7 @@ system_library_deps := \
$(the_libdir_base)Mono.Security.dll \
$(bare_libdir)/System.dll
ifndef PROFILE_ANY_MOBILE
ifndef MOBILE_PROFILE
system_library_deps += $(the_libdir_base)System.Configuration.dll
endif
@@ -91,7 +99,7 @@ artifacts = $(system_library_deps) \
.NOTPARALLEL: $(system_library_deps)
$(the_libdir_base)System.dll: $(system_library_deps)
$(the_libdir_base)System.dll: $(system_library_deps) ../Mono.Security/Makefile
ifeq (bare/,$(intermediate))
build-bare:
@@ -113,7 +121,7 @@ $(the_libdir_base)System.Xml.dll:
$(bare_libdir)/System.Xml.dll:
(cd ../System.XML; $(MAKE) $@)
$(the_libdir_base)Mono.Security.dll:
$(the_libdir_base)Mono.Security.dll: ../Mono.Security/Makefile
(cd ../Mono.Security; $(MAKE))
$(the_libdir_base)System.Configuration.dll:

View File

@@ -366,8 +366,6 @@ namespace Mono.CSharp
}
}
args.Append("/sdk:4.5");
args.Append (" -- ");
foreach (string source in fileNames)
args.AppendFormat("\"{0}\" ",source);
@@ -387,6 +385,12 @@ namespace Mono.CSharp
\s*
(?<message>.*)$";
static readonly Regex RelatedSymbolsRegex = new Regex(
@"
\(Location\ of\ the\ symbol\ related\ to\ previous\ (warning|error)\)
",
RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);
private static CompilerError CreateErrorFromString(string error_string)
{
if (error_string.StartsWith ("BETA"))
@@ -399,11 +403,17 @@ namespace Mono.CSharp
Regex reg = new Regex (ErrorRegexPattern, RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);
Match match=reg.Match(error_string);
if (!match.Success) {
// We had some sort of runtime crash
error.ErrorText = error_string;
error.IsWarning = false;
error.ErrorNumber = "";
return error;
match = RelatedSymbolsRegex.Match (error_string);
if (!match.Success) {
// We had some sort of runtime crash
error.ErrorText = error_string;
error.IsWarning = false;
error.ErrorNumber = "";
return error;
} else {
// This line is a continuation of previous warning of error
return null;
}
}
if (String.Empty != match.Result("${file}"))
error.FileName=match.Result("${file}");

View File

@@ -30,16 +30,17 @@
#if SECURITY_DEP
#if MONOTOUCH || MONODROID
using Mono.Security.Protocol.Ntlm;
#else
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
using MonoSecurity::Mono.Security.Protocol.Ntlm;
#else
using Mono.Security.Protocol.Ntlm;
#endif
using System;
using System.Collections;
using System.Net;
using System.Runtime.CompilerServices;
namespace Mono.Http
{
@@ -122,14 +123,8 @@ namespace Mono.Http
class NtlmClient : IAuthenticationModule
{
static Hashtable cache;
static NtlmClient ()
{
cache = new Hashtable ();
}
public NtlmClient () {}
static readonly ConditionalWeakTable<HttpWebRequest, NtlmSession> cache =
new ConditionalWeakTable<HttpWebRequest, NtlmSession> ();
public Authorization Authenticate (string challenge, WebRequest webRequest, ICredentials credentials)
{
@@ -153,12 +148,7 @@ namespace Mono.Http
return null;
lock (cache) {
NtlmSession ds = (NtlmSession) cache [request];
if (ds == null) {
ds = new NtlmSession ();
cache.Add (request, ds);
}
var ds = cache.GetValue (request, x => new NtlmSession ());
return ds.Authenticate (header, webRequest, credentials);
}
}

View File

@@ -0,0 +1,137 @@
//
// CallbackHelpers.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XX509Chain = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509Chain;
#else
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XX509Chain = System.Security.Cryptography.X509Certificates.X509Chain;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*/
static class CallbackHelpers
{
internal static MSI.MonoRemoteCertificateValidationCallback PublicToMono (RemoteCertificateValidationCallback callback)
{
if (callback == null)
return null;
return (h, c, ch, e) => callback (h, c, (X509Chain)(object)ch, (SslPolicyErrors)e);
}
internal static MSI.MonoLocalCertificateSelectionCallback PublicToMono (LocalCertificateSelectionCallback callback)
{
if (callback == null)
return null;
return (t, lc, rc, ai) => callback (null, t, (XX509CertificateCollection)(object)lc, rc, ai);
}
internal static MSI.MonoRemoteCertificateValidationCallback InternalToMono (RemoteCertValidationCallback callback)
{
if (callback == null)
return null;
return (h, c, ch, e) => callback (h, c, (X509Chain)(object)ch, (SslPolicyErrors)e);
}
internal static RemoteCertificateValidationCallback InternalToPublic (string hostname, RemoteCertValidationCallback callback)
{
if (callback == null)
return null;
return (s, c, ch, e) => callback (hostname, c, ch, e);
}
internal static MSI.MonoLocalCertificateSelectionCallback InternalToMono (LocalCertSelectionCallback callback)
{
if (callback == null)
return null;
return (t, lc, rc, ai) => callback (t, (XX509CertificateCollection)(object)lc, rc, ai);
}
internal static RemoteCertificateValidationCallback MonoToPublic (MSI.MonoRemoteCertificateValidationCallback callback)
{
if (callback == null)
return null;
return (t, c, ch, e) => callback (null, c, (XX509Chain)(object)ch, (MSI.MonoSslPolicyErrors)e);
}
internal static LocalCertificateSelectionCallback MonoToPublic (MSI.MonoLocalCertificateSelectionCallback callback)
{
if (callback == null)
return null;
return (s, t, lc, rc, ai) => callback (t, (XX509CertificateCollection)(object)lc, rc, ai);
}
internal static RemoteCertValidationCallback MonoToInternal (MSI.MonoRemoteCertificateValidationCallback callback)
{
if (callback == null)
return null;
return (h, c, ch, e) => callback (h, c, (XX509Chain)(object)ch, (MSI.MonoSslPolicyErrors)e);
}
internal static LocalCertSelectionCallback MonoToInternal (MSI.MonoLocalCertificateSelectionCallback callback)
{
if (callback == null)
return null;
return (t, lc, rc, ai) => callback (t, (XX509CertificateCollection)(object)lc, rc, ai);
}
}
}
#endif

View File

@@ -0,0 +1,344 @@
//
// System.Net.ServicePointManager
//
// Authors:
// Lawrence Pit (loz@cable.a2000.nl)
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2003-2010 Novell, Inc (http://www.novell.com)
//
//
// 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 SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
using MSX = MonoSecurity::Mono.Security.X509;
using MonoSecurity::Mono.Security.X509.Extensions;
#else
using Mono.Security.Interface;
using MSX = Mono.Security.X509;
using Mono.Security.X509.Extensions;
#endif
#if MONO_X509_ALIAS
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XX509Chain = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509Chain;
#else
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XX509Chain = System.Security.Cryptography.X509Certificates.X509Chain;
#endif
using System;
using System.Net;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Net.Configuration;
using System.Text.RegularExpressions;
using System.Security.Cryptography.X509Certificates;
using System.Globalization;
using System.Net.Security;
using System.Diagnostics;
namespace Mono.Net.Security
{
internal delegate bool ServerCertValidationCallbackWrapper (ServerCertValidationCallback callback, X509Certificate certificate, X509Chain chain, MonoSslPolicyErrors sslPolicyErrors);
internal class ChainValidationHelper : ICertificateValidator
{
readonly object sender;
readonly MonoTlsSettings settings;
readonly MonoTlsProvider provider;
readonly ServerCertValidationCallback certValidationCallback;
readonly LocalCertSelectionCallback certSelectionCallback;
readonly ServerCertValidationCallbackWrapper callbackWrapper;
readonly MonoTlsStream tlsStream;
readonly HttpWebRequest request;
internal static ICertificateValidator GetDefaultValidator (MonoTlsProvider provider, MonoTlsSettings settings)
{
if (settings == null)
return new ChainValidationHelper (provider, null, false, null, null);
if (settings.CertificateValidator != null)
return settings.CertificateValidator;
return new ChainValidationHelper (provider, settings, false, null, null);
}
#region SslStream support
/*
* This is a hack which is used in SslStream - see ReferenceSources/SslStream.cs for details.
*/
internal static ChainValidationHelper CloneWithCallbackWrapper (MonoTlsProvider provider, ref MonoTlsSettings settings, ServerCertValidationCallbackWrapper wrapper)
{
var helper = (ChainValidationHelper)settings.CertificateValidator;
if (helper == null)
helper = new ChainValidationHelper (provider, settings, true, null, wrapper);
else
helper = new ChainValidationHelper (helper, provider, settings, wrapper);
settings = helper.settings;
return helper;
}
internal static bool InvokeCallback (ServerCertValidationCallback callback, object sender, X509Certificate certificate, X509Chain chain, MonoSslPolicyErrors sslPolicyErrors)
{
return callback.Invoke (sender, certificate, chain, (SslPolicyErrors)sslPolicyErrors);
}
#endregion
ChainValidationHelper (ChainValidationHelper other, MonoTlsProvider provider, MonoTlsSettings settings, ServerCertValidationCallbackWrapper callbackWrapper = null)
{
sender = other.sender;
certValidationCallback = other.certValidationCallback;
certSelectionCallback = other.certSelectionCallback;
tlsStream = other.tlsStream;
request = other.request;
if (settings == null)
settings = MonoTlsSettings.DefaultSettings;
this.provider = provider;
this.settings = settings.CloneWithValidator (this);
this.callbackWrapper = callbackWrapper;
}
internal static ChainValidationHelper Create (MonoTlsProvider provider, ref MonoTlsSettings settings, MonoTlsStream stream)
{
var helper = new ChainValidationHelper (provider, settings, true, stream, null);
settings = helper.settings;
return helper;
}
ChainValidationHelper (MonoTlsProvider provider, MonoTlsSettings settings, bool cloneSettings, MonoTlsStream stream, ServerCertValidationCallbackWrapper callbackWrapper)
{
if (settings == null)
settings = MonoTlsSettings.CopyDefaultSettings ();
if (cloneSettings)
settings = settings.CloneWithValidator (this);
this.provider = provider;
this.settings = settings;
this.tlsStream = stream;
this.callbackWrapper = callbackWrapper;
var fallbackToSPM = false;
if (settings != null) {
if (settings.RemoteCertificateValidationCallback != null) {
var callback = Private.CallbackHelpers.MonoToPublic (settings.RemoteCertificateValidationCallback);
certValidationCallback = new ServerCertValidationCallback (callback);
}
certSelectionCallback = Private.CallbackHelpers.MonoToInternal (settings.ClientCertificateSelectionCallback);
fallbackToSPM = settings.UseServicePointManagerCallback;
}
if (stream != null) {
this.request = stream.Request;
this.sender = request;
if (certValidationCallback == null)
certValidationCallback = request.ServerCertValidationCallback;
if (certSelectionCallback == null)
certSelectionCallback = new LocalCertSelectionCallback (DefaultSelectionCallback);
if (settings == null)
fallbackToSPM = true;
}
if (fallbackToSPM && certValidationCallback == null)
certValidationCallback = ServicePointManager.ServerCertValidationCallback;
}
static X509Certificate DefaultSelectionCallback (string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
{
X509Certificate clientCertificate;
if (localCertificates == null || localCertificates.Count == 0)
clientCertificate = null;
else
clientCertificate = localCertificates [0];
return clientCertificate;
}
public MonoTlsProvider Provider {
get { return provider; }
}
public MonoTlsSettings Settings {
get { return settings; }
}
public bool HasCertificateSelectionCallback {
get { return certSelectionCallback != null; }
}
public bool SelectClientCertificate (
string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate,
string[] acceptableIssuers, out X509Certificate clientCertificate)
{
if (certSelectionCallback == null) {
clientCertificate = null;
return false;
}
clientCertificate = certSelectionCallback (targetHost, localCertificates, remoteCertificate, acceptableIssuers);
return true;
}
internal X509Certificate SelectClientCertificate (
string targetHost, XX509CertificateCollection localCertificates, X509Certificate remoteCertificate,
string[] acceptableIssuers)
{
if (certSelectionCallback == null)
return null;
return certSelectionCallback (targetHost, localCertificates, remoteCertificate, acceptableIssuers);
}
internal bool ValidateClientCertificate (X509Certificate certificate, MonoSslPolicyErrors errors)
{
var certs = new XX509CertificateCollection ();
certs.Add (new X509Certificate2 (certificate.GetRawCertData ()));
var result = ValidateChain (string.Empty, true, certs, (SslPolicyErrors)errors);
if (result == null)
return false;
return result.Trusted && !result.UserDenied;
}
public ValidationResult ValidateCertificate (string host, bool serverMode, XX509CertificateCollection certs)
{
try {
var result = ValidateChain (host, serverMode, certs, 0);
if (tlsStream != null)
tlsStream.CertificateValidationFailed = result == null || !result.Trusted || result.UserDenied;
return result;
} catch {
if (tlsStream != null)
tlsStream.CertificateValidationFailed = true;
throw;
}
}
ValidationResult ValidateChain (string host, bool server, XX509CertificateCollection certs, SslPolicyErrors errors)
{
// user_denied is true if the user callback is called and returns false
bool user_denied = false;
bool result = false;
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.SetServerCertificate (leaf);
if (leaf == null) {
errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
if (hasCallback) {
if (callbackWrapper != null)
result = callbackWrapper.Invoke (certValidationCallback, leaf, null, (MonoSslPolicyErrors)errors);
else
result = certValidationCallback.Invoke (sender, leaf, null, errors);
user_denied = !result;
}
return new ValidationResult (result, user_denied, 0, (MonoSslPolicyErrors)errors);
}
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) {
if (settings == null || settings.CallbackNeedsCertificateChain)
wantsChain = true;
}
if (wantsChain)
chain = SystemCertificateValidator.CreateX509Chain (certs);
if (wantsChain || SystemCertificateValidator.NeedsChain (settings))
SystemCertificateValidator.BuildX509Chain (certs, chain, ref errors, ref status11);
bool providerValidated = false;
if (provider != null && provider.HasCustomSystemCertificateValidator) {
var xerrors = (MonoSslPolicyErrors)errors;
var xchain = (XX509Chain)(object)chain;
providerValidated = provider.InvokeSystemCertificateValidator (this, host, server, certs, xchain, out result, ref xerrors, ref status11);
errors = (SslPolicyErrors)xerrors;
}
if (!providerValidated)
result = SystemCertificateValidator.Evaluate (settings, host, certs, chain, ref errors, ref status11);
if (policy != null && (!(policy is DefaultCertificatePolicy) || certValidationCallback == null)) {
ServicePoint sp = null;
if (request != null)
sp = request.ServicePointNoLock;
if (status11 == 0 && errors != 0) {
// TRUST_E_FAIL
status11 = unchecked ((int)0x800B010B);
}
// pre 2.0 callback
result = policy.CheckValidationResult (sp, leaf, request, status11);
user_denied = !result && !(policy is DefaultCertificatePolicy);
}
// If there's a 2.0 callback, it takes precedence
if (hasCallback) {
if (callbackWrapper != null)
result = callbackWrapper.Invoke (certValidationCallback, leaf, chain, (MonoSslPolicyErrors)errors);
else
result = certValidationCallback.Invoke (sender, leaf, chain, errors);
user_denied = !result;
}
return new ValidationResult (result, user_denied, status11, (MonoSslPolicyErrors)errors);
}
public bool InvokeSystemValidator (string targetHost, bool serverMode, XX509CertificateCollection certificates, XX509Chain xchain, ref MonoSslPolicyErrors xerrors, ref int status11)
{
X509Chain chain = (X509Chain)(object)xchain;
var errors = (SslPolicyErrors)xerrors;
var result = SystemCertificateValidator.Evaluate (settings, targetHost, certificates, chain, ref errors, ref status11);
xerrors = (MonoSslPolicyErrors)errors;
return result;
}
}
}
#endif

View File

@@ -0,0 +1,239 @@
//
// IMonoSslStream.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_X509_ALIAS
using X509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Threading.Tasks;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
namespace Mono.Net.Security
{
interface IMonoSslStream : IDisposable
{
AuthenticatedStream AuthenticatedStream {
get;
}
void AuthenticateAsClient (string targetHost);
void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
AsyncCallback asyncCallback, object asyncState);
void EndAuthenticateAsClient (IAsyncResult asyncResult);
void AuthenticateAsServer (X509Certificate serverCertificate);
void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
AsyncCallback asyncCallback,
object asyncState);
void EndAuthenticateAsServer (IAsyncResult asyncResult);
TransportContext TransportContext {
get;
}
Task AuthenticateAsClientAsync (string targetHost);
Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
//
//
// Base class properties
//
bool IsAuthenticated {
get;
}
bool IsMutuallyAuthenticated {
get;
}
bool IsEncrypted {
get;
}
bool IsSigned {
get;
}
bool IsServer {
get;
}
//
//
//SSL specific properties
//
//
SslProtocols SslProtocol {
get;
}
bool CheckCertRevocationStatus {
get;
}
X509Certificate InternalLocalCertificate {
get;
}
X509Certificate LocalCertificate {
get;
}
X509Certificate RemoteCertificate {
get;
}
//
// More informational properties
//
CipherAlgorithmType CipherAlgorithm {
get;
}
int CipherStrength {
get;
}
HashAlgorithmType HashAlgorithm {
get;
}
int HashStrength {
get;
}
ExchangeAlgorithmType KeyExchangeAlgorithm {
get;
}
int KeyExchangeStrength {
get;
}
//
//
// Stream contract implementation
//
//
//
bool CanRead {
get;
}
bool CanTimeout {
get;
}
bool CanWrite {
get;
}
int ReadTimeout {
get;
set;
}
int WriteTimeout {
get;
set;
}
long Length {
get;
}
long Position {
get;
}
void SetLength (long value);
void Flush ();
int Read (byte[] buffer, int offset, int count);
void Write (byte[] buffer);
void Write (byte[] buffer, int offset, int count);
IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState);
int EndRead (IAsyncResult asyncResult);
IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState);
void EndWrite (IAsyncResult asyncResult);
#if SECURITY_DEP
MSI.MonoTlsProvider Provider {
get;
}
MSI.MonoTlsConnectionInfo GetConnectionInfo ();
#endif
}
}

View File

@@ -0,0 +1,88 @@
//
// IMonoTlsProvider.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
#else
using Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#else
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security
{
/*
* For consumption within System.dll only - do not access from friend assemblies.
*
* Unfortunately, there's some compiler madness involved when using Mono.Security.dll
* APIs from within System.dll because the compiler perceives those types which come
* from the prebuilt version of System.dll being different from those it's currently
* compiling. At runtime, there is only one single System.dll, so these all map to
* the same actual type.
*
* This internal interface helps to keep all this compilation stuff contained within
* the 'Mono.Net.Security.Private' namespace - this namespace should be considered
* strictly private and must not be accessed from files outside the Mono.Net.Security
* directory.
*
*/
interface IMonoTlsProvider
{
#if SECURITY_DEP
MonoTlsProvider Provider {
get;
}
IMonoSslStream CreateSslStream (
Stream innerStream, bool leaveInnerStreamOpen,
MonoTlsSettings settings);
IMonoTlsContext CreateTlsContext (
string hostname, bool serverMode, TlsProtocols protocolFlags,
X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus,
MonoEncryptionPolicy encryptionPolicy, MonoTlsSettings settings);
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
//
// MonoDefaultTlsProvider.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_X509_ALIAS
using XHttpWebRequest = PrebuiltSystem::System.Net.HttpWebRequest;
using XSslProtocols = PrebuiltSystem::System.Security.Authentication.SslProtocols;
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#else
using XHttpWebRequest = System.Net.HttpWebRequest;
using XSslProtocols = System.Security.Authentication.SslProtocols;
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
#else
using Mono.Security.Interface;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*/
class MonoDefaultTlsProvider : MonoTlsProviderImpl
{
static readonly Guid id = new Guid ("809e77d5-56cc-4da8-b9f0-45e65ba9cceb");
public override Guid ID {
get { return id; }
}
public override string Name {
get { return "legacy"; }
}
public MonoTlsProvider Provider {
get { return this; }
}
public override bool SupportsSslStream {
get { return true; }
}
public override bool SupportsConnectionInfo {
get { return false; }
}
public override bool SupportsMonoExtensions {
get { return false; }
}
internal override bool SupportsTlsContext {
get { return false; }
}
public override XSslProtocols SupportedProtocols {
get { return XSslProtocols.Ssl3 | XSslProtocols.Tls; }
}
protected override IMonoSslStream CreateSslStreamImpl (
Stream innerStream, bool leaveInnerStreamOpen,
MonoTlsSettings settings)
{
return new LegacySslStream (innerStream, leaveInnerStreamOpen, this, settings);
}
protected override IMonoTlsContext CreateTlsContextImpl (
string hostname, bool serverMode, TlsProtocols protocolFlags,
X509Certificate serverCertificate, X509CertificateCollection clientCertificates,
bool remoteCertRequired, MonoEncryptionPolicy encryptionPolicy,
MonoTlsSettings settings)
{
throw new NotSupportedException ();
}
}
}
#endif

View File

@@ -0,0 +1,342 @@
//
// MonoSslStream.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XTransportContext = PrebuiltSystem::System.Net.TransportContext;
using XAuthenticatedStream = PrebuiltSystem::System.Net.Security.AuthenticatedStream;
using XCipherAlgorithmType = PrebuiltSystem::System.Security.Authentication.CipherAlgorithmType;
using XHashAlgorithmType = PrebuiltSystem::System.Security.Authentication.HashAlgorithmType;
using XExchangeAlgorithmType = PrebuiltSystem::System.Security.Authentication.ExchangeAlgorithmType;
using XSslProtocols = PrebuiltSystem::System.Security.Authentication.SslProtocols;
#else
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XTransportContext = System.Net.TransportContext;
using XAuthenticatedStream = System.Net.Security.AuthenticatedStream;
using XCipherAlgorithmType = System.Security.Authentication.CipherAlgorithmType;
using XHashAlgorithmType = System.Security.Authentication.HashAlgorithmType;
using XExchangeAlgorithmType = System.Security.Authentication.ExchangeAlgorithmType;
using XSslProtocols = System.Security.Authentication.SslProtocols;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Threading.Tasks;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*/
class MonoSslStreamImpl : MSI.IMonoSslStream
{
IMonoSslStream impl;
internal IMonoSslStream Impl {
get {
CheckDisposed ();
return impl;
}
}
public MonoSslStreamImpl (IMonoSslStream impl)
{
this.impl = impl;
}
public void AuthenticateAsClient (string targetHost)
{
Impl.AuthenticateAsClient (targetHost);
}
public void AuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsClient (targetHost, clientCertificates, (SslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, clientCertificates, (SslProtocols)enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsClient (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsClient (asyncResult);
}
public void AuthenticateAsServer (X509Certificate serverCertificate)
{
Impl.AuthenticateAsServer (serverCertificate);
}
public void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, (SslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, (SslProtocols)enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsServer (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsServer (asyncResult);
}
public Task AuthenticateAsClientAsync (string targetHost)
{
return Impl.AuthenticateAsClientAsync (targetHost);
}
public Task AuthenticateAsClientAsync (string targetHost, XX509CertificateCollection clientCertificates, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, (SslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
{
return Impl.AuthenticateAsServerAsync (serverCertificate);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, XSslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, (SslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public void Flush ()
{
Impl.Flush ();
}
public int Read (byte[] buffer, int offset, int count)
{
return Impl.Read (buffer, offset, count);
}
public void Write (byte[] buffer)
{
Impl.Write (buffer);
}
public void Write (byte[] buffer, int offset, int count)
{
Impl.Write (buffer, offset, count);
}
public IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
}
public int EndRead (IAsyncResult asyncResult)
{
return Impl.EndRead (asyncResult);
}
public IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
}
public void EndWrite (IAsyncResult asyncResult)
{
Impl.EndWrite (asyncResult);
}
public XTransportContext TransportContext {
get { return (XTransportContext)(object)Impl.TransportContext; }
}
public bool IsAuthenticated {
get { return Impl.IsAuthenticated; }
}
public bool IsMutuallyAuthenticated {
get { return Impl.IsMutuallyAuthenticated; }
}
public bool IsEncrypted {
get { return Impl.IsEncrypted; }
}
public bool IsSigned {
get { return Impl.IsSigned; }
}
public bool IsServer {
get { return Impl.IsServer; }
}
public XCipherAlgorithmType CipherAlgorithm {
get { return (XCipherAlgorithmType)Impl.CipherAlgorithm; }
}
public int CipherStrength {
get { return Impl.CipherStrength; }
}
public XHashAlgorithmType HashAlgorithm {
get { return (XHashAlgorithmType)Impl.HashAlgorithm; }
}
public int HashStrength {
get { return Impl.HashStrength; }
}
public XExchangeAlgorithmType KeyExchangeAlgorithm {
get { return (XExchangeAlgorithmType)Impl.KeyExchangeAlgorithm; }
}
public int KeyExchangeStrength {
get { return KeyExchangeStrength; }
}
public bool CanRead {
get { return Impl.CanRead; }
}
public bool CanTimeout {
get { return Impl.CanTimeout; }
}
public bool CanWrite {
get { return Impl.CanWrite; }
}
public long Length {
get { return Impl.Length; }
}
public long Position {
get { return Impl.Position; }
}
public void SetLength (long value)
{
Impl.SetLength (value);
}
public XAuthenticatedStream AuthenticatedStream {
get { return (XAuthenticatedStream)(Stream)Impl.AuthenticatedStream; }
}
public int ReadTimeout {
get { return Impl.ReadTimeout; }
set { Impl.ReadTimeout = value; }
}
public int WriteTimeout {
get { return Impl.WriteTimeout; }
set { Impl.WriteTimeout = value; }
}
public bool CheckCertRevocationStatus {
get { return Impl.CheckCertRevocationStatus; }
}
public X509Certificate InternalLocalCertificate {
get { return Impl.InternalLocalCertificate; }
}
public X509Certificate LocalCertificate {
get { return Impl.LocalCertificate; }
}
public X509Certificate RemoteCertificate {
get { return Impl.RemoteCertificate; }
}
public XSslProtocols SslProtocol {
get { return (XSslProtocols)Impl.SslProtocol; }
}
public MSI.MonoTlsProvider Provider {
get { return Impl.Provider; }
}
public MSI.MonoTlsConnectionInfo GetConnectionInfo ()
{
return Impl.GetConnectionInfo ();
}
void CheckDisposed ()
{
if (impl == null)
throw new ObjectDisposedException ("MonoSslStream");
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
if (impl != null && disposing) {
impl.Dispose ();
impl = null;
}
}
}
}
#endif

View File

@@ -0,0 +1,330 @@
//
// MonoSslStreamImpl.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XSslProtocols = PrebuiltSystem::System.Security.Authentication.SslProtocols;
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#else
using XSslProtocols = System.Security.Authentication.SslProtocols;
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
using CipherAlgorithmType = System.Security.Authentication.CipherAlgorithmType;
using HashAlgorithmType = System.Security.Authentication.HashAlgorithmType;
using ExchangeAlgorithmType = System.Security.Authentication.ExchangeAlgorithmType;
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
using System.Threading.Tasks;
namespace Mono.Net.Security.Private
{
class MonoSslStreamWrapper : IMonoSslStream
{
MSI.IMonoSslStream impl;
internal MSI.IMonoSslStream Impl {
get {
CheckDisposed ();
return impl;
}
}
public MonoSslStreamWrapper (MSI.IMonoSslStream impl)
{
this.impl = impl;
}
public void AuthenticateAsClient (string targetHost)
{
Impl.AuthenticateAsClient (targetHost);
}
public void AuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsClient (targetHost, (XX509CertificateCollection)(object)clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsClient (string targetHost, XX509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsClient (targetHost, (XX509CertificateCollection)(object)clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsClient (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsClient (asyncResult);
}
public void AuthenticateAsServer (X509Certificate serverCertificate)
{
Impl.AuthenticateAsServer (serverCertificate);
}
public void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
Impl.AuthenticateAsServer (serverCertificate, clientCertificateRequired, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, asyncCallback, asyncState);
}
public IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginAuthenticateAsServer (serverCertificate, clientCertificateRequired, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation, asyncCallback, asyncState);
}
public void EndAuthenticateAsServer (IAsyncResult asyncResult)
{
Impl.EndAuthenticateAsServer (asyncResult);
}
public Task AuthenticateAsClientAsync (string targetHost)
{
return Impl.AuthenticateAsClientAsync (targetHost);
}
public Task AuthenticateAsClientAsync (string targetHost, XX509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsClientAsync (targetHost, clientCertificates, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate)
{
return Impl.AuthenticateAsServerAsync (serverCertificate);
}
public Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
return Impl.AuthenticateAsServerAsync (serverCertificate, clientCertificateRequired, (XSslProtocols)enabledSslProtocols, checkCertificateRevocation);
}
public void Flush ()
{
Impl.Flush ();
}
public int Read (byte[] buffer, int offset, int count)
{
return Impl.Read (buffer, offset, count);
}
public void Write (byte[] buffer)
{
Impl.Write (buffer);
}
public void Write (byte[] buffer, int offset, int count)
{
Impl.Write (buffer, offset, count);
}
public IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginRead (buffer, offset, count, asyncCallback, asyncState);
}
public int EndRead (IAsyncResult asyncResult)
{
return Impl.EndRead (asyncResult);
}
public IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
{
return Impl.BeginWrite (buffer, offset, count, asyncCallback, asyncState);
}
public void EndWrite (IAsyncResult asyncResult)
{
Impl.EndWrite (asyncResult);
}
public TransportContext TransportContext {
get { return (TransportContext)(object)Impl.TransportContext; }
}
public bool IsAuthenticated {
get { return Impl.IsAuthenticated; }
}
public bool IsMutuallyAuthenticated {
get { return Impl.IsMutuallyAuthenticated; }
}
public bool IsEncrypted {
get { return Impl.IsEncrypted; }
}
public bool IsSigned {
get { return Impl.IsSigned; }
}
public bool IsServer {
get { return Impl.IsServer; }
}
public CipherAlgorithmType CipherAlgorithm {
get { return (CipherAlgorithmType)Impl.CipherAlgorithm; }
}
public int CipherStrength {
get { return Impl.CipherStrength; }
}
public HashAlgorithmType HashAlgorithm {
get { return (HashAlgorithmType)Impl.HashAlgorithm; }
}
public int HashStrength {
get { return Impl.HashStrength; }
}
public ExchangeAlgorithmType KeyExchangeAlgorithm {
get { return (ExchangeAlgorithmType)Impl.KeyExchangeAlgorithm; }
}
public int KeyExchangeStrength {
get { return Impl.KeyExchangeStrength; }
}
public bool CanRead {
get { return Impl.CanRead; }
}
public bool CanTimeout {
get { return Impl.CanTimeout; }
}
public bool CanWrite {
get { return Impl.CanWrite; }
}
public long Length {
get { return Impl.Length; }
}
public long Position {
get { return Impl.Position; }
}
public void SetLength (long value)
{
Impl.SetLength (value);
}
public AuthenticatedStream AuthenticatedStream {
get { return (AuthenticatedStream)(object)Impl.AuthenticatedStream; }
}
public int ReadTimeout {
get { return Impl.ReadTimeout; }
set { Impl.ReadTimeout = value; }
}
public int WriteTimeout {
get { return Impl.WriteTimeout; }
set { Impl.WriteTimeout = value; }
}
public bool CheckCertRevocationStatus {
get { return Impl.CheckCertRevocationStatus; }
}
X509Certificate IMonoSslStream.InternalLocalCertificate {
get { return Impl.InternalLocalCertificate; }
}
public X509Certificate LocalCertificate {
get { return Impl.LocalCertificate; }
}
public X509Certificate RemoteCertificate {
get { return Impl.RemoteCertificate; }
}
public SslProtocols SslProtocol {
get { return (SslProtocols)Impl.SslProtocol; }
}
public MSI.MonoTlsProvider Provider {
get { return Impl.Provider; }
}
public MSI.MonoTlsConnectionInfo GetConnectionInfo ()
{
return Impl.GetConnectionInfo ();
}
void CheckDisposed ()
{
if (impl == null)
throw new ObjectDisposedException ("MonoSslStream");
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected void Dispose (bool disposing)
{
if (impl != null && disposing) {
impl.Dispose ();
impl = null;
}
}
}
}
#endif

View File

@@ -0,0 +1,275 @@
//
// MonoTlsProviderFactory.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 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;
#endif
using System;
using System.Net;
using System.Collections.Generic;
#if !MOBILE
using System.Reflection;
#endif
namespace Mono.Net.Security
{
/*
* Keep in sync with Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs.
*
*/
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.
*
* @IMonoTlsProvider is defined as empty interface outside 'SECURITY_DEP', so we don't need
* this conditional here.
*/
internal static IMonoTlsProvider GetProviderInternal ()
{
lock (locker) {
if (currentProvider != null)
return currentProvider;
try {
defaultProvider = CreateDefaultProvider ();
} catch (Exception ex) {
throw new NotSupportedException ("TLS Support not available.", ex);
}
if (defaultProvider == null)
throw new NotSupportedException ("TLS Support not available.");
currentProvider = defaultProvider;
return currentProvider;
}
}
internal static IMonoTlsProvider GetDefaultProviderInternal ()
{
lock (locker) {
if (defaultProvider != null)
return defaultProvider;
try {
defaultProvider = CreateDefaultProvider ();
} catch (Exception ex) {
throw new NotSupportedException ("TLS Support not available.", ex);
}
if (defaultProvider == null)
throw new NotSupportedException ("TLS Support not available.");
return defaultProvider;
}
}
#if MONO_FEATURE_NEW_SYSTEM_SOURCE || (!MONOTOUCH && !XAMMAC)
static IMonoTlsProvider CreateDefaultProvider ()
{
#if SECURITY_DEP
#if MONO_FEATURE_NEW_SYSTEM_SOURCE
/*
* This is a hack, which is used in the Mono.Security.Providers.NewSystemSource
* assembly, which will provide a "fake" System.dll. Use the public Mono.Security
* API to get the "real" System.dll's provider via reflection, then wrap it with
* the "fake" version's perceived view.
*
* NewSystemSource needs to compile MonoTlsProviderFactory.cs, IMonoTlsProvider.cs,
* MonoTlsProviderWrapper.cs and CallbackHelpers.cs from this directory and only these.
*/
var userProvider = MSI.MonoTlsProviderFactory.GetProvider ();
return new Private.MonoTlsProviderWrapper (userProvider);
#else
return CreateDefaultProviderImpl ();
#endif
#else
return null;
#endif
}
#endif
static object locker = new object ();
static IMonoTlsProvider defaultProvider;
static IMonoTlsProvider currentProvider;
#endregion
#if SECURITY_DEP && !MONO_FEATURE_NEW_SYSTEM_SOURCE
static Dictionary<string,string> providerRegistration;
static Type LookupProviderType (string name, bool throwOnError)
{
lock (locker) {
InitializeProviderRegistration ();
string typeName;
if (!providerRegistration.TryGetValue (name, out typeName)) {
if (throwOnError)
throw new NotSupportedException (string.Format ("No such TLS Provider: `{0}'.", name));
return null;
}
var type = Type.GetType (typeName, false);
if (type == null && throwOnError)
throw new NotSupportedException (string.Format ("Could not find TLS Provider: `{0}'.", typeName));
return type;
}
}
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);
} catch (Exception ex) {
throw new NotSupportedException (string.Format ("Unable to instantiate TLS Provider `{0}'.", type), ex);
}
}
static void InitializeProviderRegistration ()
{
lock (locker) {
if (providerRegistration != null)
return;
providerRegistration = new Dictionary<string,string> ();
providerRegistration.Add ("newtls", "Mono.Security.Providers.NewTls.NewTlsProvider, Mono.Security.Providers.NewTls, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
providerRegistration.Add ("oldtls", "Mono.Security.Providers.OldTls.OldTlsProvider, Mono.Security.Providers.OldTls, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
}
}
#if !MOBILE
static IMonoTlsProvider TryDynamicLoad ()
{
var variable = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER");
if (variable == null)
return null;
if (string.Equals (variable, "default", StringComparison.OrdinalIgnoreCase))
return null;
var provider = LookupProvider (variable, true);
return new Private.MonoTlsProviderWrapper (provider);
}
#endif
static IMonoTlsProvider CreateDefaultProviderImpl ()
{
#if !MOBILE
var provider = TryDynamicLoad ();
if (provider != null)
return provider;
#endif
return new Private.MonoDefaultTlsProvider ();
}
#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 ()
{
var provider = GetProviderInternal ();
if (provider == null)
throw new NotSupportedException ("No TLS Provider available.");
return provider.Provider;
}
internal static MSI.MonoTlsProvider GetDefaultProvider ()
{
var provider = GetDefaultProviderInternal ();
if (provider == null)
throw new NotSupportedException ("No TLS Provider available.");
return provider.Provider;
}
internal static MSI.MonoTlsProvider GetProvider (string name)
{
return LookupProvider (name, false);
}
internal static bool HasProvider {
get {
lock (locker) {
return currentProvider != null;
}
}
}
internal static void SetDefaultProvider (string name)
{
lock (locker) {
var provider = LookupProvider (name, true);
currentProvider = new Private.MonoTlsProviderWrapper (provider);
}
}
internal static HttpWebRequest CreateHttpsRequest (Uri requestUri, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
{
lock (locker) {
var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
return new HttpWebRequest (requestUri, internalProvider, settings);
}
}
internal static HttpListener CreateHttpListener (X509Certificate certificate, MSI.MonoTlsProvider provider, MSI.MonoTlsSettings settings)
{
lock (locker) {
var internalProvider = provider != null ? new Private.MonoTlsProviderWrapper (provider) : null;
return new HttpListener (certificate, internalProvider, settings);
}
}
#endregion
#endif
}
}

View File

@@ -0,0 +1,118 @@
//
// MonoTlsProviderImpl.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XHttpWebRequest = PrebuiltSystem::System.Net.HttpWebRequest;
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#else
using XHttpWebRequest = System.Net.HttpWebRequest;
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*/
abstract class MonoTlsProviderImpl : MSI.MonoTlsProvider, IMonoTlsProvider
{
MSI.MonoTlsProvider IMonoTlsProvider.Provider {
get { return this; }
}
IMonoSslStream IMonoTlsProvider.CreateSslStream (
Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings)
{
return CreateSslStreamImpl (innerStream, leaveInnerStreamOpen, settings);
}
protected abstract IMonoSslStream CreateSslStreamImpl (
Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings);
public override MSI.IMonoSslStream CreateSslStream (
Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings = null)
{
var sslStream = CreateSslStreamImpl (innerStream, leaveInnerStreamOpen, settings);
return new MonoSslStreamImpl (sslStream);
}
MSI.IMonoTlsContext IMonoTlsProvider.CreateTlsContext (
string hostname, bool serverMode, MSI.TlsProtocols protocolFlags,
X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus,
MSI.MonoEncryptionPolicy encryptionPolicy, MSI.MonoTlsSettings settings)
{
return CreateTlsContextImpl (
hostname, serverMode, protocolFlags,
serverCertificate, (X509CertificateCollection)(object)clientCertificates,
remoteCertRequired, encryptionPolicy, settings);
}
protected abstract MSI.IMonoTlsContext CreateTlsContextImpl (
string hostname, bool serverMode, MSI.TlsProtocols protocolFlags,
X509Certificate serverCertificate, X509CertificateCollection clientCertificates,
bool remoteCertRequired, MSI.MonoEncryptionPolicy encryptionPolicy,
MSI.MonoTlsSettings settings);
internal override MSI.IMonoTlsContext CreateTlsContext (
string hostname, bool serverMode, MSI.TlsProtocols protocolFlags,
X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
bool remoteCertRequired, MSI.MonoEncryptionPolicy encryptionPolicy,
MSI.MonoTlsSettings settings)
{
return CreateTlsContextImpl (
hostname, serverMode, (MSI.TlsProtocols)protocolFlags,
serverCertificate, (X509CertificateCollection)(object)clientCertificates,
remoteCertRequired, (MSI.MonoEncryptionPolicy)encryptionPolicy,
settings);
}
}
}
#endif

View File

@@ -0,0 +1,102 @@
//
// MonoTlsProviderWrapper.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_SECURITY_ALIAS
using MSI = MonoSecurity::Mono.Security.Interface;
#else
using MSI = Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XHttpWebRequest = PrebuiltSystem::System.Net.HttpWebRequest;
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#else
using XHttpWebRequest = System.Net.HttpWebRequest;
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Mono.Net.Security.Private
{
/*
* Strictly private - do not use outside the Mono.Net.Security directory.
*
* This is used by MonoTlsProviderFactory.InstallProvider() to wrap and masquerade
* a user-supplied @MonoTlsProvider as @IMonoTlsProvider.
*/
class MonoTlsProviderWrapper : IMonoTlsProvider
{
MSI.MonoTlsProvider provider;
public MonoTlsProviderWrapper (MSI.MonoTlsProvider provider)
{
this.provider = provider;
}
public MSI.MonoTlsProvider Provider {
get { return provider; }
}
public IMonoSslStream CreateSslStream (
Stream innerStream, bool leaveInnerStreamOpen,
MSI.MonoTlsSettings settings)
{
var sslStream = provider.CreateSslStream (innerStream, leaveInnerStreamOpen, settings);
var monoSslStreamImpl = sslStream as MonoSslStreamImpl;
if (monoSslStreamImpl != null)
return monoSslStreamImpl.Impl;
return new MonoSslStreamWrapper (sslStream);
}
public MSI.IMonoTlsContext CreateTlsContext (
string hostname, bool serverMode, MSI.TlsProtocols protocolFlags,
X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus,
MSI.MonoEncryptionPolicy encryptionPolicy, MSI.MonoTlsSettings settings)
{
return provider.CreateTlsContext (
hostname, serverMode, protocolFlags,
serverCertificate, (XX509CertificateCollection)(object)clientCertificates,
remoteCertRequired, (MSI.MonoEncryptionPolicy)encryptionPolicy,
settings);
}
}
}
#endif

View File

@@ -0,0 +1,134 @@
//
// MonoTlsStream.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
#else
using Mono.Security.Interface;
#endif
#if MONO_X509_ALIAS
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#else
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
#endif
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Threading.Tasks;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Security.Cryptography;
namespace Mono.Net.Security
{
class MonoTlsStream
{
readonly IMonoTlsProvider provider;
readonly HttpWebRequest request;
readonly NetworkStream networkStream;
IMonoSslStream sslStream;
WebExceptionStatus status;
internal HttpWebRequest Request {
get { return request; }
}
internal IMonoSslStream SslStream {
get { return sslStream; }
}
internal WebExceptionStatus ExceptionStatus {
get { return status; }
}
internal bool CertificateValidationFailed {
get; set;
}
#if SECURITY_DEP
readonly ChainValidationHelper validationHelper;
readonly MonoTlsSettings settings;
public MonoTlsStream (HttpWebRequest request, NetworkStream networkStream)
{
this.request = request;
this.networkStream = networkStream;
settings = request.TlsSettings;
provider = request.TlsProvider ?? MonoTlsProviderFactory.GetProviderInternal ();
status = WebExceptionStatus.SecureChannelFailure;
validationHelper = ChainValidationHelper.Create (provider.Provider, ref settings, this);
}
internal Stream CreateStream (byte[] buffer)
{
sslStream = provider.CreateSslStream (networkStream, false, settings);
try {
sslStream.AuthenticateAsClient (
request.Address.Host, (XX509CertificateCollection)(object)request.ClientCertificates,
(SslProtocols)ServicePointManager.SecurityProtocol,
ServicePointManager.CheckCertificateRevocationList);
status = WebExceptionStatus.Success;
} finally {
if (CertificateValidationFailed)
status = WebExceptionStatus.TrustFailure;
request.ServicePoint.SetClientCertificate (sslStream.InternalLocalCertificate);
if (status != WebExceptionStatus.Success)
sslStream = null;
}
try {
if (buffer != null)
sslStream.Write (buffer, 0, buffer.Length);
} catch {
status = WebExceptionStatus.SendFailure;
sslStream = null;
throw;
}
return sslStream.AuthenticatedStream;
}
#endif
}
}

View File

@@ -0,0 +1,132 @@
//
// NoReflectionHelper.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// 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 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;
#endif
using System;
using System.Net;
using System.Net.Security;
namespace Mono.Net.Security
{
//
// Internal APIs which are used by Mono.Security.dll to avoid using reflection.
//
internal static class NoReflectionHelper
{
internal static object GetDefaultCertificateValidator (object provider, object settings)
{
#if SECURITY_DEP
return ChainValidationHelper.GetDefaultValidator ((MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
#else
throw new NotSupportedException ();
#endif
}
internal static object GetProvider ()
{
#if SECURITY_DEP
return MonoTlsProviderFactory.GetProvider ();
#else
throw new NotSupportedException ();
#endif
}
internal static object GetDefaultProvider ()
{
#if SECURITY_DEP
return MonoTlsProviderFactory.GetDefaultProvider ();
#else
throw new NotSupportedException ();
#endif
}
internal static bool HasProvider {
get {
#if SECURITY_DEP
return MonoTlsProviderFactory.HasProvider;
#else
throw new NotSupportedException ();
#endif
}
}
internal static void SetDefaultProvider (string name)
{
#if SECURITY_DEP
MonoTlsProviderFactory.SetDefaultProvider (name);
#else
throw new NotSupportedException ();
#endif
}
internal static HttpWebRequest CreateHttpsRequest (Uri requestUri, object provider, object settings)
{
#if SECURITY_DEP
return MonoTlsProviderFactory.CreateHttpsRequest (requestUri, (MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
#else
throw new NotSupportedException ();
#endif
}
internal static object CreateHttpListener (object certificate, object provider, object settings)
{
#if SECURITY_DEP
return MonoTlsProviderFactory.CreateHttpListener ((X509Certificate)certificate, (MSI.MonoTlsProvider)provider, (MSI.MonoTlsSettings)settings);
#else
throw new NotSupportedException ();
#endif
}
internal static object GetMonoSslStream (SslStream stream)
{
#if SECURITY_DEP
return stream.Impl;
#else
throw new NotSupportedException ();
#endif
}
internal static object GetProvider (string name)
{
#if SECURITY_DEP
return MonoTlsProviderFactory.GetProvider (name);
#else
throw new NotSupportedException ();
#endif
}
}
}

View File

@@ -0,0 +1,465 @@
#if SECURITY_DEP
#if MONO_SECURITY_ALIAS
extern alias MonoSecurity;
#endif
#if MONO_X509_ALIAS
extern alias PrebuiltSystem;
#endif
#if MONO_SECURITY_ALIAS
using MonoSecurity::Mono.Security.Interface;
using MSX = MonoSecurity::Mono.Security.X509;
using MonoSecurity::Mono.Security.X509.Extensions;
#else
using Mono.Security.Interface;
using MSX = Mono.Security.X509;
using Mono.Security.X509.Extensions;
#endif
#if MONO_X509_ALIAS
using XX509CertificateCollection = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XX509Chain = PrebuiltSystem::System.Security.Cryptography.X509Certificates.X509Chain;
#else
using XX509CertificateCollection = System.Security.Cryptography.X509Certificates.X509CertificateCollection;
using XX509Chain = System.Security.Cryptography.X509Certificates.X509Chain;
#endif
using System;
using System.Net;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Net.Configuration;
using System.Text.RegularExpressions;
using System.Security.Cryptography.X509Certificates;
using System.Globalization;
using System.Net.Security;
using System.Diagnostics;
namespace Mono.Net.Security
{
internal static class SystemCertificateValidator
{
static bool is_macosx;
#if !MOBILE
static X509RevocationMode revocation_mode;
#endif
static SystemCertificateValidator ()
{
#if MONOTOUCH
is_macosx = true;
#elif MONODROID
is_macosx = false;
#else
is_macosx = System.IO.File.Exists (OSX509Certificates.SecurityLibrary);
#endif
#if !MOBILE
revocation_mode = X509RevocationMode.NoCheck;
try {
string str = Environment.GetEnvironmentVariable ("MONO_X509_REVOCATION_MODE");
if (String.IsNullOrEmpty (str))
return;
revocation_mode = (X509RevocationMode)Enum.Parse (typeof(X509RevocationMode), str, true);
} catch {
}
#endif
}
public static X509Chain CreateX509Chain (XX509CertificateCollection certs)
{
var chain = new X509Chain ();
chain.ChainPolicy = new X509ChainPolicy ();
#if !MOBILE
chain.ChainPolicy.RevocationMode = revocation_mode;
#endif
for (int i = 1; i < certs.Count; i++) {
chain.ChainPolicy.ExtraStore.Add (certs [i]);
}
return chain;
}
public static bool BuildX509Chain (XX509CertificateCollection certs, X509Chain chain, ref SslPolicyErrors errors, ref int status11)
{
#if MOBILE
return true;
#else
if (is_macosx)
return true;
var leaf = (X509Certificate2)certs [0];
bool ok;
try {
ok = chain.Build (leaf);
if (!ok)
errors |= GetErrorsFromChain (chain);
} catch (Exception e) {
Console.Error.WriteLine ("ERROR building certificate chain: {0}", e);
Console.Error.WriteLine ("Please, report this problem to the Mono team");
errors |= SslPolicyErrors.RemoteCertificateChainErrors;
ok = false;
}
try {
status11 = GetStatusFromChain (chain);
} catch {
status11 = -2146762485; // TRUST_E_FAIL - generic
}
return ok;
#endif
}
static bool CheckUsage (XX509CertificateCollection certs, string host, ref SslPolicyErrors errors, ref int status11)
{
#if !MONOTOUCH
var leaf = (X509Certificate2)certs[0];
// for OSX and iOS we're using the native API to check for the SSL server policy and host names
if (!is_macosx) {
if (!CheckCertificateUsage (leaf)) {
errors |= SslPolicyErrors.RemoteCertificateChainErrors;
status11 = -2146762490; //CERT_E_PURPOSE 0x800B0106
return false;
}
if (host != null && !CheckServerIdentity (leaf, host)) {
errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
status11 = -2146762481; // CERT_E_CN_NO_MATCH 0x800B010F
return false;
}
}
#endif
return true;
}
static bool EvaluateSystem (XX509CertificateCollection certs, XX509CertificateCollection anchors, string host, X509Chain chain, ref SslPolicyErrors errors, ref int status11)
{
var leaf = certs [0];
var result = false;
#if MONODROID
result = AndroidPlatform.TrustEvaluateSsl (certs);
if (result) {
// chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
// Android (there are no mozroots or preinstalled root certificates),
// thus `errors` will ALWAYS have RemoteCertificateChainErrors.
// Android just verified the chain; clear RemoteCertificateChainErrors.
errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
}
#else
if (is_macosx) {
// Attempt to use OSX certificates
// Ideally we should return the SecTrustResult
OSX509Certificates.SecTrustResult trustResult = OSX509Certificates.SecTrustResult.Deny;
try {
trustResult = OSX509Certificates.TrustEvaluateSsl (certs, anchors, host);
// We could use the other values of trustResult to pass this extra information
// to the .NET 2 callback for values like SecTrustResult.Confirm
result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
trustResult == OSX509Certificates.SecTrustResult.Unspecified);
} catch {
// Ignore
}
if (result) {
// TrustEvaluateSsl was successful so there's no trust error
// IOW we discard our own chain (since we trust OSX one instead)
errors = 0;
} else {
// callback and DefaultCertificatePolicy needs this since 'result' is not specified
status11 = (int)trustResult;
errors |= SslPolicyErrors.RemoteCertificateChainErrors;
}
}
#endif
return result;
}
public static bool Evaluate (
MonoTlsSettings settings, string host, XX509CertificateCollection certs,
X509Chain chain, ref SslPolicyErrors errors, ref int status11)
{
if (!CheckUsage (certs, host, ref errors, ref status11))
return false;
if (settings != null && settings.SkipSystemValidators)
return false;
var anchors = settings != null ? settings.TrustAnchors : null;
return EvaluateSystem (certs, anchors, host, chain, ref errors, ref status11);
}
internal static bool NeedsChain (MonoTlsSettings settings)
{
#if MOBILE
return false;
#else
if (!CertificateValidationHelper.SupportsX509Chain)
return false;
if (settings != null)
return !settings.SkipSystemValidators || settings.CallbackNeedsCertificateChain;
else
return true;
#endif
}
#if !MOBILE
static int GetStatusFromChain (X509Chain chain)
{
long result = 0;
foreach (var status in chain.ChainStatus) {
X509ChainStatusFlags flags = status.Status;
if (flags == X509ChainStatusFlags.NoError)
continue;
// CERT_E_EXPIRED
if ((flags & X509ChainStatusFlags.NotTimeValid) != 0)
result = 0x800B0101;
// CERT_E_VALIDITYPERIODNESTING
else if ((flags & X509ChainStatusFlags.NotTimeNested) != 0)
result = 0x800B0102;
// CERT_E_REVOKED
else if ((flags & X509ChainStatusFlags.Revoked) != 0)
result = 0x800B010C;
// TRUST_E_CERT_SIGNATURE
else if ((flags & X509ChainStatusFlags.NotSignatureValid) != 0)
result = 0x80096004;
// CERT_E_WRONG_USAGE
else if ((flags & X509ChainStatusFlags.NotValidForUsage) != 0)
result = 0x800B0110;
// CERT_E_UNTRUSTEDROOT
else if ((flags & X509ChainStatusFlags.UntrustedRoot) != 0)
result = 0x800B0109;
// CRYPT_E_NO_REVOCATION_CHECK
else if ((flags & X509ChainStatusFlags.RevocationStatusUnknown) != 0)
result = 0x80092012;
// CERT_E_CHAINING
else if ((flags & X509ChainStatusFlags.Cyclic) != 0)
result = 0x800B010A;
// TRUST_E_FAIL - generic
else if ((flags & X509ChainStatusFlags.InvalidExtension) != 0)
result = 0x800B010B;
// CERT_E_UNTRUSTEDROOT
else if ((flags & X509ChainStatusFlags.InvalidPolicyConstraints) != 0)
result = 0x800B010D;
// TRUST_E_BASIC_CONSTRAINTS
else if ((flags & X509ChainStatusFlags.InvalidBasicConstraints) != 0)
result = 0x80096019;
// CERT_E_INVALID_NAME
else if ((flags & X509ChainStatusFlags.InvalidNameConstraints) != 0)
result = 0x800B0114;
// CERT_E_INVALID_NAME
else if ((flags & X509ChainStatusFlags.HasNotSupportedNameConstraint) != 0)
result = 0x800B0114;
// CERT_E_INVALID_NAME
else if ((flags & X509ChainStatusFlags.HasNotDefinedNameConstraint) != 0)
result = 0x800B0114;
// CERT_E_INVALID_NAME
else if ((flags & X509ChainStatusFlags.HasNotPermittedNameConstraint) != 0)
result = 0x800B0114;
// CERT_E_INVALID_NAME
else if ((flags & X509ChainStatusFlags.HasExcludedNameConstraint) != 0)
result = 0x800B0114;
// CERT_E_CHAINING
else if ((flags & X509ChainStatusFlags.PartialChain) != 0)
result = 0x800B010A;
// CERT_E_EXPIRED
else if ((flags & X509ChainStatusFlags.CtlNotTimeValid) != 0)
result = 0x800B0101;
// TRUST_E_CERT_SIGNATURE
else if ((flags & X509ChainStatusFlags.CtlNotSignatureValid) != 0)
result = 0x80096004;
// CERT_E_WRONG_USAGE
else if ((flags & X509ChainStatusFlags.CtlNotValidForUsage) != 0)
result = 0x800B0110;
// CRYPT_E_NO_REVOCATION_CHECK
else if ((flags & X509ChainStatusFlags.OfflineRevocation) != 0)
result = 0x80092012;
// CERT_E_ISSUERCHAINING
else if ((flags & X509ChainStatusFlags.NoIssuanceChainPolicy) != 0)
result = 0x800B0107;
else
result = 0x800B010B; // TRUST_E_FAIL - generic
break; // Exit the loop on the first error
}
return (int)result;
}
static SslPolicyErrors GetErrorsFromChain (X509Chain chain)
{
SslPolicyErrors errors = SslPolicyErrors.None;
foreach (var status in chain.ChainStatus) {
if (status.Status == X509ChainStatusFlags.NoError)
continue;
errors |= SslPolicyErrors.RemoteCertificateChainErrors;
break;
}
return errors;
}
#endif
#if !MONOTOUCH
static X509KeyUsageFlags s_flags = X509KeyUsageFlags.DigitalSignature |
X509KeyUsageFlags.KeyAgreement |
X509KeyUsageFlags.KeyEncipherment;
// Adapted to System 2.0+ from TlsServerCertificate.cs
//------------------------------
// Note: this method only works for RSA certificates
// DH certificates requires some changes - does anyone use one ?
static bool CheckCertificateUsage (X509Certificate2 cert)
{
try {
// certificate extensions are required for this
// we "must" accept older certificates without proofs
if (cert.Version < 3)
return true;
X509KeyUsageExtension kux = (cert.Extensions ["2.5.29.15"] as X509KeyUsageExtension);
X509EnhancedKeyUsageExtension eku = (cert.Extensions ["2.5.29.37"] as X509EnhancedKeyUsageExtension);
if (kux != null && eku != null) {
// RFC3280 states that when both KeyUsageExtension and
// ExtendedKeyUsageExtension are present then BOTH should
// be valid
if ((kux.KeyUsages & s_flags) == 0)
return false;
return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null ||
eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null;
} else if (kux != null) {
return ((kux.KeyUsages & s_flags) != 0);
} else if (eku != null) {
// Server Authentication (1.3.6.1.5.5.7.3.1) or
// Netscape Server Gated Crypto (2.16.840.1.113730.4)
return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null ||
eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null;
}
// last chance - try with older (deprecated) Netscape extensions
X509Extension ext = cert.Extensions ["2.16.840.1.113730.1.1"];
if (ext != null) {
string text = ext.NetscapeCertType (false);
return text.IndexOf ("SSL Server Authentication", StringComparison.Ordinal) != -1;
}
return true;
} catch (Exception e) {
Console.Error.WriteLine ("ERROR processing certificate: {0}", e);
Console.Error.WriteLine ("Please, report this problem to the Mono team");
return false;
}
}
// RFC2818 - HTTP Over TLS, Section 3.1
// http://www.ietf.org/rfc/rfc2818.txt
//
// 1. if present MUST use subjectAltName dNSName as identity
// 1.1. if multiples entries a match of any one is acceptable
// 1.2. wildcard * is acceptable
// 2. URI may be an IP address -> subjectAltName.iPAddress
// 2.1. exact match is required
// 3. Use of the most specific Common Name (CN=) in the Subject
// 3.1 Existing practice but DEPRECATED
static bool CheckServerIdentity (X509Certificate2 cert, string targetHost)
{
try {
var mcert = new MSX.X509Certificate (cert.RawData);
MSX.X509Extension ext = mcert.Extensions ["2.5.29.17"];
// 1. subjectAltName
if (ext != null) {
SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (ext);
// 1.1 - multiple dNSName
foreach (string dns in subjectAltName.DNSNames) {
// 1.2 TODO - wildcard support
if (Match (targetHost, dns))
return true;
}
// 2. ipAddress
foreach (string ip in subjectAltName.IPAddresses) {
// 2.1. Exact match required
if (ip == targetHost)
return true;
}
}
// 3. Common Name (CN=)
return CheckDomainName (mcert.SubjectName, targetHost);
} catch (Exception e) {
Console.Error.WriteLine ("ERROR processing certificate: {0}", e);
Console.Error.WriteLine ("Please, report this problem to the Mono team");
return false;
}
}
static bool CheckDomainName (string subjectName, string targetHost)
{
string domainName = String.Empty;
Regex search = new Regex (@"CN\s*=\s*([^,]*)");
MatchCollection elements = search.Matches (subjectName);
if (elements.Count == 1) {
if (elements [0].Success)
domainName = elements [0].Groups [1].Value.ToString ();
}
return Match (targetHost, domainName);
}
// ensure the pattern is valid wrt to RFC2595 and RFC2818
// http://www.ietf.org/rfc/rfc2595.txt
// http://www.ietf.org/rfc/rfc2818.txt
static bool Match (string hostname, string pattern)
{
// check if this is a pattern
int index = pattern.IndexOf ('*');
if (index == -1) {
// not a pattern, do a direct case-insensitive comparison
return (String.Compare (hostname, pattern, true, CultureInfo.InvariantCulture) == 0);
}
// check pattern validity
// A "*" wildcard character MAY be used as the left-most name component in the certificate.
// unless this is the last char (valid)
if (index != pattern.Length - 1) {
// then the next char must be a dot .'.
if (pattern [index + 1] != '.')
return false;
}
// only one (A) wildcard is supported
int i2 = pattern.IndexOf ('*', index + 1);
if (i2 != -1)
return false;
// match the end of the pattern
string end = pattern.Substring (index + 1);
int length = hostname.Length - end.Length;
// no point to check a pattern that is longer than the hostname
if (length <= 0)
return false;
if (String.Compare (hostname, length, end, 0, end.Length, true, CultureInfo.InvariantCulture) != 0)
return false;
// special case, we start with the wildcard
if (index == 0) {
// ensure we hostname non-matched part (start) doesn't contain a dot
int i3 = hostname.IndexOf ('.');
return ((i3 == -1) || (i3 >= (hostname.Length - end.Length)));
}
// match the start of the pattern
string start = pattern.Substring (0, index);
return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
}
#endif
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More