You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
106
mcs/class/System/Mono.AppleTls/AppleCertificateHelper.cs
Normal file
106
mcs/class/System/Mono.AppleTls/AppleCertificateHelper.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// AppleCertificateHelper.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2015 Xamarin, Inc.
|
||||
//
|
||||
|
||||
#if MONO_SECURITY_ALIAS
|
||||
extern alias MonoSecurity;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
#if MONO_SECURITY_ALIAS
|
||||
using MonoSecurity::Mono.Security.Interface;
|
||||
#else
|
||||
using Mono.Security.Interface;
|
||||
#endif
|
||||
|
||||
namespace Mono.AppleTls
|
||||
{
|
||||
static class AppleCertificateHelper
|
||||
{
|
||||
public static SecIdentity GetIdentity (X509Certificate certificate)
|
||||
{
|
||||
/*
|
||||
* If we got an 'X509Certificate2', then we require it to have a private key
|
||||
* and import it.
|
||||
*/
|
||||
var certificate2 = certificate as X509Certificate2;
|
||||
if (certificate2 != null)
|
||||
return SecIdentity.Import (certificate2);
|
||||
|
||||
/*
|
||||
* Otherwise, we require the private key to be in the keychain.
|
||||
*/
|
||||
using (var secCert = new SecCertificate (certificate)) {
|
||||
return SecKeyChain.FindIdentity (secCert, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static SecIdentity GetIdentity (X509Certificate certificate, out SecCertificate[] intermediateCerts)
|
||||
{
|
||||
var identity = GetIdentity (certificate);
|
||||
|
||||
var impl2 = certificate.Impl as X509Certificate2Impl;
|
||||
if (impl2 == null || impl2.IntermediateCertificates == null) {
|
||||
intermediateCerts = new SecCertificate [0];
|
||||
return identity;
|
||||
}
|
||||
|
||||
try {
|
||||
intermediateCerts = new SecCertificate [impl2.IntermediateCertificates.Count];
|
||||
for (int i = 0; i < intermediateCerts.Length; i++)
|
||||
intermediateCerts [i] = new SecCertificate (impl2.IntermediateCertificates [i]);
|
||||
|
||||
return identity;
|
||||
} catch {
|
||||
identity.Dispose ();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool InvokeSystemCertificateValidator (
|
||||
ICertificateValidator2 validator, string targetHost, bool serverMode,
|
||||
X509CertificateCollection certificates,
|
||||
ref MonoSslPolicyErrors errors, ref int status11)
|
||||
{
|
||||
if (certificates == null) {
|
||||
errors |= MonoSslPolicyErrors.RemoteCertificateNotAvailable;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (targetHost)) {
|
||||
var pos = targetHost.IndexOf (':');
|
||||
if (pos > 0)
|
||||
targetHost = targetHost.Substring (0, pos);
|
||||
}
|
||||
|
||||
var policy = SecPolicy.CreateSslPolicy (!serverMode, targetHost);
|
||||
var trust = new SecTrust (certificates, policy);
|
||||
|
||||
if (validator.Settings.TrustAnchors != null) {
|
||||
var status = trust.SetAnchorCertificates (validator.Settings.TrustAnchors);
|
||||
if (status != SecStatusCode.Success)
|
||||
throw new InvalidOperationException (status.ToString ());
|
||||
trust.SetAnchorCertificatesOnly (false);
|
||||
}
|
||||
|
||||
var result = trust.Evaluate ();
|
||||
if (result == SecTrustResult.Unspecified)
|
||||
return true;
|
||||
|
||||
errors |= MonoSslPolicyErrors.RemoteCertificateChainErrors;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
907
mcs/class/System/Mono.AppleTls/AppleTlsContext.cs
Normal file
907
mcs/class/System/Mono.AppleTls/AppleTlsContext.cs
Normal file
File diff suppressed because it is too large
Load Diff
77
mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs
Normal file
77
mcs/class/System/Mono.AppleTls/AppleTlsProvider.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// AppleTlsProvider.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2015 Xamarin, Inc.
|
||||
//
|
||||
|
||||
#if MONO_SECURITY_ALIAS
|
||||
extern alias MonoSecurity;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using MNS = Mono.Net.Security;
|
||||
#if MONO_SECURITY_ALIAS
|
||||
using MonoSecurity::Mono.Security.Interface;
|
||||
#else
|
||||
using Mono.Security.Interface;
|
||||
#endif
|
||||
|
||||
namespace Mono.AppleTls
|
||||
{
|
||||
class AppleTlsProvider : MonoTlsProvider
|
||||
{
|
||||
static readonly Guid id = new Guid ("981af8af-a3a3-419a-9f01-a518e3a17c1c");
|
||||
|
||||
public override string Name {
|
||||
get { return "apple-tls"; }
|
||||
}
|
||||
|
||||
public override Guid ID {
|
||||
get { return id; }
|
||||
}
|
||||
|
||||
public override IMonoSslStream CreateSslStream (
|
||||
Stream innerStream, bool leaveInnerStreamOpen,
|
||||
MonoTlsSettings settings = null)
|
||||
{
|
||||
return new AppleTlsStream (innerStream, leaveInnerStreamOpen, settings, this);
|
||||
}
|
||||
|
||||
public override bool SupportsSslStream {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool SupportsMonoExtensions {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool SupportsConnectionInfo {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override SslProtocols SupportedProtocols {
|
||||
get { return SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; }
|
||||
}
|
||||
|
||||
internal override bool ValidateCertificate (
|
||||
ICertificateValidator2 validator, string targetHost, bool serverMode,
|
||||
X509CertificateCollection certificates, bool wantsChain, ref X509Chain chain,
|
||||
ref MonoSslPolicyErrors errors, ref int status11)
|
||||
{
|
||||
if (wantsChain)
|
||||
chain = MNS.SystemCertificateValidator.CreateX509Chain (certificates);
|
||||
return AppleCertificateHelper.InvokeSystemCertificateValidator (validator, targetHost, serverMode, certificates, ref errors, ref status11);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
50
mcs/class/System/Mono.AppleTls/AppleTlsStream.cs
Normal file
50
mcs/class/System/Mono.AppleTls/AppleTlsStream.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// AppleTlsStream.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2016 Xamarin, Inc.
|
||||
//
|
||||
|
||||
#if MONO_SECURITY_ALIAS
|
||||
extern alias MonoSecurity;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using MNS = Mono.Net.Security;
|
||||
#if MONO_SECURITY_ALIAS
|
||||
using MonoSecurity::Mono.Security.Interface;
|
||||
#else
|
||||
using Mono.Security.Interface;
|
||||
#endif
|
||||
|
||||
namespace Mono.AppleTls
|
||||
{
|
||||
class AppleTlsStream : MNS.MobileAuthenticatedStream
|
||||
{
|
||||
public AppleTlsStream (Stream innerStream, bool leaveInnerStreamOpen, MonoTlsSettings settings, MonoTlsProvider provider)
|
||||
: base (innerStream, leaveInnerStreamOpen, settings, provider)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MNS.MobileTlsContext CreateContext (
|
||||
MNS.MobileAuthenticatedStream parent, bool serverMode, string targetHost,
|
||||
SslProtocols enabledProtocols, X509Certificate serverCertificate,
|
||||
X509CertificateCollection clientCertificates, bool askForClientCert)
|
||||
{
|
||||
return new AppleTlsContext (
|
||||
parent, serverMode, targetHost,
|
||||
enabledProtocols, serverCertificate,
|
||||
clientCertificates, askForClientCert);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
341
mcs/class/System/Mono.AppleTls/Certificate.cs
Normal file
341
mcs/class/System/Mono.AppleTls/Certificate.cs
Normal file
@@ -0,0 +1,341 @@
|
||||
//
|
||||
// Certificate.cs: Implements the managed SecCertificate wrapper.
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza
|
||||
// Sebastien Pouliot <sebastien@xamarin.com>
|
||||
//
|
||||
// Copyright 2010 Novell, Inc
|
||||
// Copyright 2012-2013 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 && MONO_FEATURE_APPLETLS
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Mono.Net;
|
||||
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
|
||||
partial class SecCertificate : INativeObject, IDisposable {
|
||||
internal IntPtr handle;
|
||||
|
||||
internal SecCertificate (IntPtr handle, bool owns = false)
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new Exception ("Invalid handle");
|
||||
|
||||
this.handle = handle;
|
||||
if (!owns)
|
||||
CFObject.CFRetain (handle);
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary, EntryPoint="SecCertificateGetTypeID")]
|
||||
public extern static IntPtr GetTypeID ();
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static IntPtr SecCertificateCreateWithData (IntPtr allocator, IntPtr cfData);
|
||||
|
||||
public SecCertificate (X509Certificate certificate)
|
||||
{
|
||||
if (certificate == null)
|
||||
throw new ArgumentNullException ("certificate");
|
||||
|
||||
handle = certificate.Impl.GetNativeAppleCertificate ();
|
||||
if (handle != IntPtr.Zero) {
|
||||
CFObject.CFRetain (handle);
|
||||
return;
|
||||
}
|
||||
|
||||
using (CFData cert = CFData.FromData (certificate.GetRawCertData ())) {
|
||||
Initialize (cert);
|
||||
}
|
||||
}
|
||||
|
||||
internal SecCertificate (X509CertificateImpl impl)
|
||||
{
|
||||
handle = impl.GetNativeAppleCertificate ();
|
||||
if (handle != IntPtr.Zero) {
|
||||
CFObject.CFRetain (handle);
|
||||
return;
|
||||
}
|
||||
|
||||
using (CFData cert = CFData.FromData (impl.GetRawCertData ())) {
|
||||
Initialize (cert);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize (CFData data)
|
||||
{
|
||||
handle = SecCertificateCreateWithData (IntPtr.Zero, data.Handle);
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ArgumentException ("Not a valid DER-encoded X.509 certificate");
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static IntPtr SecCertificateCopySubjectSummary (IntPtr cert);
|
||||
|
||||
public string SubjectSummary {
|
||||
get {
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecCertificate");
|
||||
|
||||
IntPtr subjectSummaryHandle = IntPtr.Zero;
|
||||
try {
|
||||
subjectSummaryHandle = SecCertificateCopySubjectSummary (handle);
|
||||
CFString subjectSummary = CFString.AsString (subjectSummaryHandle);
|
||||
return subjectSummary;
|
||||
}
|
||||
finally {
|
||||
if (subjectSummaryHandle != IntPtr.Zero)
|
||||
CFObject.CFRelease (subjectSummaryHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static /* CFDataRef */ IntPtr SecCertificateCopyData (/* SecCertificateRef */ IntPtr cert);
|
||||
|
||||
public CFData DerData {
|
||||
get {
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecCertificate");
|
||||
|
||||
IntPtr data = SecCertificateCopyData (handle);
|
||||
if (data == IntPtr.Zero)
|
||||
throw new ArgumentException ("Not a valid certificate");
|
||||
return new CFData (data, true);
|
||||
}
|
||||
}
|
||||
|
||||
public X509Certificate ToX509Certificate ()
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecCertificate");
|
||||
|
||||
return new X509Certificate (handle);
|
||||
}
|
||||
|
||||
internal static bool Equals (SecCertificate first, SecCertificate second)
|
||||
{
|
||||
/*
|
||||
* This is a little bit expensive, but unfortunately there is no better API to compare two
|
||||
* SecCertificateRef's for equality.
|
||||
*/
|
||||
if (first == null)
|
||||
throw new ArgumentNullException ("first");
|
||||
if (second == null)
|
||||
throw new ArgumentNullException ("second");
|
||||
if (first.Handle == second.Handle)
|
||||
return true;
|
||||
|
||||
using (var firstData = first.DerData)
|
||||
using (var secondData = second.DerData) {
|
||||
if (firstData.Handle == secondData.Handle)
|
||||
return true;
|
||||
|
||||
if (firstData.Length != secondData.Length)
|
||||
return false;
|
||||
IntPtr length = (IntPtr)firstData.Length;
|
||||
for (long i = 0; i < (long)length; i++) {
|
||||
if (firstData [i] != secondData [i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
~SecCertificate ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero){
|
||||
CFObject.CFRelease (handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial class SecIdentity : INativeObject, IDisposable {
|
||||
|
||||
static readonly CFString ImportExportPassphase;
|
||||
static readonly CFString ImportItemIdentity;
|
||||
|
||||
static SecIdentity ()
|
||||
{
|
||||
var handle = CFObject.dlopen (AppleTlsContext.SecurityLibrary, 0);
|
||||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
try {
|
||||
ImportExportPassphase = CFObject.GetStringConstant (handle, "kSecImportExportPassphrase");
|
||||
ImportItemIdentity = CFObject.GetStringConstant (handle, "kSecImportItemIdentity");
|
||||
} finally {
|
||||
CFObject.dlclose (handle);
|
||||
}
|
||||
}
|
||||
|
||||
internal IntPtr handle;
|
||||
|
||||
internal SecIdentity (IntPtr handle, bool owns = false)
|
||||
{
|
||||
this.handle = handle;
|
||||
if (!owns)
|
||||
CFObject.CFRetain (handle);
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary, EntryPoint="SecIdentityGetTypeID")]
|
||||
public extern static IntPtr GetTypeID ();
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static /* OSStatus */ SecStatusCode SecIdentityCopyCertificate (/* SecIdentityRef */ IntPtr identityRef, /* SecCertificateRef* */ out IntPtr certificateRef);
|
||||
|
||||
public SecCertificate Certificate {
|
||||
get {
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecIdentity");
|
||||
IntPtr cert;
|
||||
SecStatusCode result = SecIdentityCopyCertificate (handle, out cert);
|
||||
if (result != SecStatusCode.Success)
|
||||
throw new InvalidOperationException (result.ToString ());
|
||||
return new SecCertificate (cert, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static SecIdentity Import (byte[] data, string password)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException ("data");
|
||||
if (string.IsNullOrEmpty (password)) // SecPKCS12Import() doesn't allow empty passwords.
|
||||
throw new ArgumentException ("password");
|
||||
using (var pwstring = CFString.Create (password))
|
||||
using (var options = CFDictionary.FromObjectAndKey (pwstring.Handle, ImportExportPassphase.Handle)) {
|
||||
CFDictionary [] array;
|
||||
SecStatusCode result = SecImportExport.ImportPkcs12 (data, options, out array);
|
||||
if (result != SecStatusCode.Success)
|
||||
throw new InvalidOperationException (result.ToString ());
|
||||
|
||||
return new SecIdentity (array [0].GetValue (ImportItemIdentity.Handle));
|
||||
}
|
||||
}
|
||||
|
||||
public static SecIdentity Import (X509Certificate2 certificate)
|
||||
{
|
||||
if (certificate == null)
|
||||
throw new ArgumentNullException ("certificate");
|
||||
if (!certificate.HasPrivateKey)
|
||||
throw new InvalidOperationException ("Need X509Certificate2 with a private key.");
|
||||
|
||||
/*
|
||||
* SecPSK12Import does not allow any empty passwords, so let's generate
|
||||
* a semi-random one here.
|
||||
*/
|
||||
var password = Guid.NewGuid ().ToString ();
|
||||
var pkcs12 = certificate.Export (X509ContentType.Pfx, password);
|
||||
return Import (pkcs12, password);
|
||||
}
|
||||
|
||||
~SecIdentity ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero){
|
||||
CFObject.CFRelease (handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial class SecKey : INativeObject, IDisposable {
|
||||
internal IntPtr handle;
|
||||
|
||||
public SecKey (IntPtr handle, bool owns = false)
|
||||
{
|
||||
this.handle = handle;
|
||||
if (!owns)
|
||||
CFObject.CFRetain (handle);
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary, EntryPoint="SecKeyGetTypeID")]
|
||||
public extern static IntPtr GetTypeID ();
|
||||
|
||||
~SecKey ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero){
|
||||
CFObject.CFRelease (handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
30
mcs/class/System/Mono.AppleTls/Enums.cs
Normal file
30
mcs/class/System/Mono.AppleTls/Enums.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
// Copyright 2011-2015 Xamarin Inc. All rights reserved.
|
||||
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
|
||||
// this is a subset of OSStatus -> SInt32 -> signed int - see CoreFoundation.framework/Headers/CFBase.h
|
||||
// values are defined in Security.framework/Headers/SecBase.h
|
||||
enum SecStatusCode {
|
||||
Success = 0,
|
||||
DuplicateItem = -25299,
|
||||
Param = -50,
|
||||
}
|
||||
|
||||
// typedef uint32_t SecTrustResultType;
|
||||
// values are defined in Security.framework/Headers/SecTrust.h
|
||||
enum SecTrustResult {
|
||||
Invalid,
|
||||
Proceed,
|
||||
|
||||
Confirm,
|
||||
Deny,
|
||||
Unspecified,
|
||||
RecoverableTrustFailure,
|
||||
FatalTrustFailure,
|
||||
ResultOtherError,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
21
mcs/class/System/Mono.AppleTls/INativeObject.cs
Normal file
21
mcs/class/System/Mono.AppleTls/INativeObject.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace ObjCRuntime {
|
||||
|
||||
internal interface INativeObject {
|
||||
IntPtr Handle {
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
static class NativeObjectHelper {
|
||||
|
||||
// help to avoid the (too common pattern)
|
||||
// var p = x == null ? IntPtr.Zero : x.Handle;
|
||||
static public IntPtr GetHandle (this INativeObject self)
|
||||
{
|
||||
return self == null ? IntPtr.Zero : self.Handle;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
62
mcs/class/System/Mono.AppleTls/ImportExport.cs
Normal file
62
mcs/class/System/Mono.AppleTls/ImportExport.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// ImportExport.cs
|
||||
//
|
||||
// Authors:
|
||||
// Sebastien Pouliot <sebastien@xamarin.com>
|
||||
//
|
||||
// Copyright 2011-2014 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.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using ObjCRuntime;
|
||||
using Mono.Net;
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
|
||||
internal partial class SecImportExport {
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static SecStatusCode SecPKCS12Import (IntPtr pkcs12_data, IntPtr options, out IntPtr items);
|
||||
|
||||
static public SecStatusCode ImportPkcs12 (byte[] buffer, CFDictionary options, out CFDictionary[] array)
|
||||
{
|
||||
using (CFData data = CFData.FromData (buffer)) {
|
||||
return ImportPkcs12 (data, options, out array);
|
||||
}
|
||||
}
|
||||
|
||||
static public SecStatusCode ImportPkcs12 (CFData data, CFDictionary options, out CFDictionary [] array)
|
||||
{
|
||||
if (options == null)
|
||||
throw new ArgumentNullException ("options");
|
||||
|
||||
IntPtr handle;
|
||||
SecStatusCode code = SecPKCS12Import (data.Handle, options.Handle, out handle);
|
||||
array = CFArray.ArrayFromHandle <CFDictionary> (handle, h => new CFDictionary (h, false));
|
||||
CFObject.CFRelease (handle);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
258
mcs/class/System/Mono.AppleTls/Items.cs
Normal file
258
mcs/class/System/Mono.AppleTls/Items.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// Items.cs: Implements the KeyChain query access APIs
|
||||
//
|
||||
// We use strong types and a helper SecQuery class to simplify the
|
||||
// creation of the dictionary used to query the Keychain
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza
|
||||
// Sebastien Pouliot
|
||||
//
|
||||
// Copyright 2010 Novell, Inc
|
||||
// Copyright 2011-2016 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.
|
||||
//
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using ObjCRuntime;
|
||||
using Mono.Net;
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
|
||||
enum SecKind {
|
||||
Identity
|
||||
}
|
||||
|
||||
static class SecKeyChain {
|
||||
static readonly IntPtr MatchLimitAll;
|
||||
static readonly IntPtr MatchLimitOne;
|
||||
static readonly IntPtr MatchLimit;
|
||||
|
||||
static SecKeyChain ()
|
||||
{
|
||||
var handle = CFObject.dlopen (AppleTlsContext.SecurityLibrary, 0);
|
||||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
try {
|
||||
MatchLimit = CFObject.GetIntPtr (handle, "kSecMatchLimit");
|
||||
MatchLimitAll = CFObject.GetIntPtr (handle, "kSecMatchLimitAll");
|
||||
MatchLimitOne = CFObject.GetIntPtr (handle, "kSecMatchLimitOne");
|
||||
} finally {
|
||||
CFObject.dlclose (handle);
|
||||
}
|
||||
}
|
||||
|
||||
public static SecIdentity FindIdentity (SecCertificate certificate, bool throwOnError = false)
|
||||
{
|
||||
if (certificate == null)
|
||||
throw new ArgumentNullException ("certificate");
|
||||
var identity = FindIdentity (cert => SecCertificate.Equals (certificate, cert));
|
||||
if (!throwOnError || identity != null)
|
||||
return identity;
|
||||
|
||||
throw new InvalidOperationException (string.Format ("Could not find SecIdentity for certificate '{0}' in keychain.", certificate.SubjectSummary));
|
||||
}
|
||||
|
||||
static SecIdentity FindIdentity (Predicate<SecCertificate> filter)
|
||||
{
|
||||
/*
|
||||
* Unfortunately, SecItemCopyMatching() does not allow any search
|
||||
* filters when looking up an identity.
|
||||
*
|
||||
* The following lookup will return all identities from the keychain -
|
||||
* we then need need to find the right one.
|
||||
*/
|
||||
using (var record = new SecRecord (SecKind.Identity)) {
|
||||
SecStatusCode status;
|
||||
var result = SecKeyChain.QueryAsReference (record, -1, out status);
|
||||
if (status != SecStatusCode.Success || result == null)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < result.Length; i++) {
|
||||
var identity = (SecIdentity)result [i];
|
||||
if (filter (identity.Certificate))
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static INativeObject[] QueryAsReference (SecRecord query, int max, out SecStatusCode result)
|
||||
{
|
||||
if (query == null){
|
||||
result = SecStatusCode.Param;
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var copy = query.queryDict.MutableCopy ()) {
|
||||
copy.SetValue (CFBoolean.True.Handle, SecItem.ReturnRef);
|
||||
SetLimit (copy, max);
|
||||
|
||||
IntPtr ptr;
|
||||
result = SecItem.SecItemCopyMatching (copy.Handle, out ptr);
|
||||
if ((result == SecStatusCode.Success) && (ptr != IntPtr.Zero)) {
|
||||
var array = CFArray.ArrayFromHandle<INativeObject> (ptr, p => {
|
||||
IntPtr cfType = CFType.GetTypeID (p);
|
||||
if (cfType == SecCertificate.GetTypeID ())
|
||||
return new SecCertificate (p, true);
|
||||
else if (cfType == SecKey.GetTypeID ())
|
||||
return new SecKey (p, true);
|
||||
else if (cfType == SecIdentity.GetTypeID ())
|
||||
return new SecIdentity (p, true);
|
||||
else
|
||||
throw new Exception (String.Format ("Unexpected type: 0x{0:x}", cfType));
|
||||
});
|
||||
return array;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static CFNumber SetLimit (CFMutableDictionary dict, int max)
|
||||
{
|
||||
CFNumber n = null;
|
||||
IntPtr val;
|
||||
if (max == -1)
|
||||
val = MatchLimitAll;
|
||||
else if (max == 1)
|
||||
val = MatchLimitOne;
|
||||
else {
|
||||
n = CFNumber.FromInt32 (max);
|
||||
val = n.Handle;
|
||||
}
|
||||
|
||||
dict.SetValue (val, SecKeyChain.MatchLimit);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
class SecRecord : IDisposable {
|
||||
|
||||
static readonly IntPtr SecClassKey;
|
||||
static SecRecord ()
|
||||
{
|
||||
var handle = CFObject.dlopen (AppleTlsContext.SecurityLibrary, 0);
|
||||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
try {
|
||||
SecClassKey = CFObject.GetIntPtr (handle, "kSecClassKey");
|
||||
} finally {
|
||||
CFObject.dlclose (handle);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix <= iOS 6 Behaviour - Desk #83099
|
||||
// NSCFDictionary: mutating method sent to immutable object
|
||||
// iOS 6 returns an inmutable NSDictionary handle and when we try to set its values it goes kaboom
|
||||
// By explicitly calling `MutableCopy` we ensure we always have a mutable reference we expect that.
|
||||
CFDictionary _queryDict;
|
||||
internal CFDictionary queryDict
|
||||
{
|
||||
get {
|
||||
return _queryDict;
|
||||
}
|
||||
set {
|
||||
_queryDict = value != null ? value.Copy () : null;
|
||||
}
|
||||
}
|
||||
|
||||
public SecRecord (SecKind secKind)
|
||||
{
|
||||
var kind = SecClass.FromSecKind (secKind);
|
||||
queryDict = CFDictionary.FromObjectAndKey (kind, SecClassKey);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (queryDict != null){
|
||||
if (disposing){
|
||||
queryDict.Dispose ();
|
||||
queryDict = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~SecRecord ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
}
|
||||
|
||||
partial class SecItem {
|
||||
public static readonly IntPtr ReturnRef;
|
||||
|
||||
static SecItem ()
|
||||
{
|
||||
var handle = CFObject.dlopen (AppleTlsContext.SecurityLibrary, 0);
|
||||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
try {
|
||||
ReturnRef = CFObject.GetIntPtr (handle, "kSecReturnRef");
|
||||
} finally {
|
||||
CFObject.dlclose (handle);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
internal extern static SecStatusCode SecItemCopyMatching (/* CFDictionaryRef */ IntPtr query, /* CFTypeRef* */ out IntPtr result);
|
||||
}
|
||||
|
||||
static partial class SecClass {
|
||||
|
||||
public static readonly IntPtr Identity;
|
||||
|
||||
static SecClass ()
|
||||
{
|
||||
var handle = CFObject.dlopen (AppleTlsContext.SecurityLibrary, 0);
|
||||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
try {
|
||||
Identity = CFObject.GetIntPtr (handle, "kSecClassIdentity");
|
||||
} finally {
|
||||
CFObject.dlclose (handle);
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr FromSecKind (SecKind secKind)
|
||||
{
|
||||
switch (secKind){
|
||||
case SecKind.Identity:
|
||||
return Identity;
|
||||
default:
|
||||
throw new ArgumentException ("secKind");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
87
mcs/class/System/Mono.AppleTls/Policy.cs
Normal file
87
mcs/class/System/Mono.AppleTls/Policy.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// Policy.cs: Implements the managed SecPolicy wrapper.
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza
|
||||
// Sebastien Pouliot <sebastien@xamarin.com>
|
||||
//
|
||||
// Copyright 2010 Novell, Inc
|
||||
// Copyright 2012-2014 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.
|
||||
//
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using ObjCRuntime;
|
||||
using Mono.Net;
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
partial class SecPolicy : INativeObject, IDisposable {
|
||||
IntPtr handle;
|
||||
|
||||
internal SecPolicy (IntPtr handle, bool owns = false)
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new Exception ("Invalid handle");
|
||||
|
||||
this.handle = handle;
|
||||
if (!owns)
|
||||
CFObject.CFRetain (handle);
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static IntPtr /* SecPolicyRef */ SecPolicyCreateSSL (bool server, IntPtr /* CFStringRef */ hostname);
|
||||
|
||||
static public SecPolicy CreateSslPolicy (bool server, string hostName)
|
||||
{
|
||||
CFString host = hostName == null ? null : CFString.Create (hostName);
|
||||
IntPtr handle = host == null ? IntPtr.Zero : host.Handle;
|
||||
SecPolicy policy = new SecPolicy (SecPolicyCreateSSL (server, handle), true);
|
||||
if (host != null)
|
||||
host.Dispose ();
|
||||
return policy;
|
||||
}
|
||||
|
||||
~SecPolicy ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get { return handle; }
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero){
|
||||
CFObject.CFRelease (handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
251
mcs/class/System/Mono.AppleTls/SecureTransport.cs
Normal file
251
mcs/class/System/Mono.AppleTls/SecureTransport.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
// Copyright 2014 Xamarin Inc. All rights reserved.
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslProtocol {
|
||||
Unknown = 0,
|
||||
// Ssl_3_0 = 2,
|
||||
Tls_1_0 = 4,
|
||||
Tls_1_1 = 7,
|
||||
Tls_1_2 = 8,
|
||||
// Dtls_1_0 = 9,
|
||||
|
||||
/* Obsolete on iOS */
|
||||
// Ssl_2_0 = 1,
|
||||
// Ssl_3_0_only = 3,
|
||||
// Tls_1_0_only = 5,
|
||||
// All = 6,
|
||||
}
|
||||
|
||||
// subset of OSStatus (int)
|
||||
enum SslStatus {
|
||||
Success = 0, // errSecSuccess in SecBase.h
|
||||
Protocol = -9800,
|
||||
Negotiation = -9801,
|
||||
FatalAlert = -9802,
|
||||
WouldBlock = -9803,
|
||||
SessionNotFound = -9804,
|
||||
ClosedGraceful = -9805,
|
||||
ClosedAbort = -9806,
|
||||
XCertChainInvalid = -9807,
|
||||
BadCert = -9808,
|
||||
Crypto = -9809,
|
||||
Internal = -9810,
|
||||
ModuleAttach = -9811,
|
||||
UnknownRootCert = -9812,
|
||||
NoRootCert = -9813,
|
||||
CertExpired = -9814,
|
||||
CertNotYetValid = -9815,
|
||||
ClosedNotNotified = -9816,
|
||||
BufferOverflow = -9817,
|
||||
BadCipherSuite = -9818,
|
||||
PeerUnexpectedMsg = -9819,
|
||||
PeerBadRecordMac = -9820,
|
||||
PeerDecryptionFail = -9821,
|
||||
PeerRecordOverflow = -9822,
|
||||
PeerDecompressFail = -9823,
|
||||
PeerHandshakeFail = -9824,
|
||||
PeerBadCert = -9825,
|
||||
PeerUnsupportedCert = -9826,
|
||||
PeerCertRevoked = -9827,
|
||||
PeerCertExpired = -9828,
|
||||
PeerCertUnknown = -9829,
|
||||
IllegalParam = -9830,
|
||||
PeerUnknownCA = -9831,
|
||||
PeerAccessDenied = -9832,
|
||||
PeerDecodeError = -9833,
|
||||
PeerDecryptError = -9834,
|
||||
PeerExportRestriction = -9835,
|
||||
PeerProtocolVersion = -9836,
|
||||
PeerInsufficientSecurity = -9837,
|
||||
PeerInternalError = -9838,
|
||||
PeerUserCancelled = -9839,
|
||||
PeerNoRenegotiation = -9840,
|
||||
PeerAuthCompleted = -9841, // non fatal
|
||||
PeerClientCertRequested = -9842, // non fatal
|
||||
HostNameMismatch = -9843,
|
||||
ConnectionRefused = -9844,
|
||||
DecryptionFail = -9845,
|
||||
BadRecordMac = -9846,
|
||||
RecordOverflow = -9847,
|
||||
BadConfiguration = -9848,
|
||||
UnexpectedRecord = -9849,
|
||||
SSLWeakPeerEphemeralDHKey = -9850,
|
||||
SSLClientHelloReceived = -9851 // non falta
|
||||
}
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslSessionOption {
|
||||
BreakOnServerAuth,
|
||||
BreakOnCertRequested,
|
||||
BreakOnClientAuth,
|
||||
|
||||
// FalseStart,
|
||||
|
||||
// SendOneByteRecord,
|
||||
|
||||
// AllowServerIdentityChange = 5,
|
||||
|
||||
// Fallback = 6,
|
||||
|
||||
// BreakOnClientHello = 7,
|
||||
|
||||
// AllowRenegotiation = 8,
|
||||
}
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslAuthenticate {
|
||||
// Never,
|
||||
// Always,
|
||||
Try = 2,
|
||||
}
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslProtocolSide {
|
||||
Server,
|
||||
Client,
|
||||
}
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslConnectionType {
|
||||
Stream,
|
||||
// Datagram
|
||||
}
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslSessionState {
|
||||
Invalid = -1,
|
||||
// Idle,
|
||||
// Handshake,
|
||||
// Connected,
|
||||
// Closed,
|
||||
// Aborted
|
||||
}
|
||||
|
||||
// Security.framework/Headers/SecureTransport.h
|
||||
// untyped enum
|
||||
enum SslClientCertificateState {
|
||||
None,
|
||||
Requested,
|
||||
Sent,
|
||||
Rejected
|
||||
}
|
||||
|
||||
// Security.framework/Headers/CipherSuite.h
|
||||
// 32 bits (uint32_t) on OSX, 16 bits (uint16_t) on iOS
|
||||
#if XAMMAC || XAMMAC_4_5
|
||||
enum SslCipherSuite : uint {
|
||||
#else
|
||||
enum SslCipherSuite : ushort {
|
||||
#endif
|
||||
// DO NOT RENAME VALUES - they don't look good but we need them to keep compatibility with our System.dll code
|
||||
// it's how it's defined across most SSL/TLS implementation (from RFC)
|
||||
|
||||
SSL_NULL_WITH_NULL_NULL = 0x0000, // value used before (not after) negotiation
|
||||
TLS_NULL_WITH_NULL_NULL = 0x0000,
|
||||
|
||||
// Not the whole list (too much unneeed metadata) but only what's supported
|
||||
// FIXME needs to be expended with OSX 10.9
|
||||
|
||||
SSL_RSA_WITH_NULL_MD5 = 0x0001,
|
||||
SSL_RSA_WITH_NULL_SHA = 0x0002,
|
||||
SSL_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003, // iOS 5.1 only
|
||||
SSL_RSA_WITH_RC4_128_MD5 = 0x0004,
|
||||
SSL_RSA_WITH_RC4_128_SHA = 0x0005,
|
||||
SSL_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A,
|
||||
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016,
|
||||
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017, // iOS 5.1 only
|
||||
SSL_DH_anon_WITH_RC4_128_MD5 = 0x0018,
|
||||
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B,
|
||||
|
||||
// TLS - identical values to SSL (above)
|
||||
|
||||
TLS_RSA_WITH_NULL_MD5 = 0x0001,
|
||||
TLS_RSA_WITH_NULL_SHA = 0x0002,
|
||||
TLS_RSA_WITH_RC4_128_MD5 = 0x0004,
|
||||
TLS_RSA_WITH_RC4_128_SHA = 0x0005,
|
||||
TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A,
|
||||
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016,
|
||||
TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018,
|
||||
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B,
|
||||
|
||||
// TLS specific
|
||||
|
||||
TLS_PSK_WITH_NULL_SHA = 0x002C,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F,
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033,
|
||||
TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035,
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039,
|
||||
TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A,
|
||||
TLS_RSA_WITH_NULL_SHA256 = 0x003B,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D,
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067,
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B,
|
||||
TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C,
|
||||
TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D,
|
||||
TLS_PSK_WITH_RC4_128_SHA = 0x008A,
|
||||
TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B,
|
||||
TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C,
|
||||
TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D,
|
||||
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C, // iOS 9+
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D, // iOS 9+
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E, // iOS 9+
|
||||
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F, // iOS 9+
|
||||
|
||||
TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6, // iOS 5.1 only
|
||||
TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7, // iOS 5.1 only
|
||||
TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE,
|
||||
TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF,
|
||||
TLS_PSK_WITH_NULL_SHA256 = 0x00B0,
|
||||
TLS_PSK_WITH_NULL_SHA384 = 0x00B1,
|
||||
TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001,
|
||||
TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002,
|
||||
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003,
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004,
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005,
|
||||
TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006,
|
||||
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007,
|
||||
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A,
|
||||
TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B,
|
||||
TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C,
|
||||
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D,
|
||||
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E,
|
||||
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F,
|
||||
TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010,
|
||||
TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011,
|
||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024,
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025,
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028,
|
||||
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029,
|
||||
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A,
|
||||
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B, // iOS 9+
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C, // iOS 9+
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D, // iOS 9+
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E, // iOS 9+
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F, // iOS 9+
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030, // iOS 9+
|
||||
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031, // iOS 9+
|
||||
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032, // iOS 9+
|
||||
}
|
||||
}
|
||||
#endif
|
||||
18
mcs/class/System/Mono.AppleTls/SslConnection.cs
Normal file
18
mcs/class/System/Mono.AppleTls/SslConnection.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// SslConnection
|
||||
//
|
||||
// Authors:
|
||||
// Sebastien Pouliot <sebastien@xamarin.com>
|
||||
//
|
||||
// Copyright 2014 Xamarin Inc.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace Mono.AppleTls
|
||||
{
|
||||
delegate SslStatus SslReadFunc (IntPtr connection, IntPtr data, /* size_t* */ ref IntPtr dataLength);
|
||||
delegate SslStatus SslWriteFunc (IntPtr connection, IntPtr data, /* size_t* */ ref IntPtr dataLength);
|
||||
}
|
||||
#endif
|
||||
186
mcs/class/System/Mono.AppleTls/Trust.cs
Normal file
186
mcs/class/System/Mono.AppleTls/Trust.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
#if SECURITY_DEP && MONO_FEATURE_APPLETLS
|
||||
//
|
||||
// Trust.cs: Implements the managed SecTrust wrapper.
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza
|
||||
// Sebastien Pouliot <sebastien@xamarin.com>
|
||||
//
|
||||
// Copyright 2010 Novell, Inc
|
||||
// Copyright 2012-2014 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.
|
||||
//
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using ObjCRuntime;
|
||||
using Mono.Net;
|
||||
|
||||
namespace Mono.AppleTls {
|
||||
partial class SecTrust : INativeObject, IDisposable {
|
||||
IntPtr handle;
|
||||
|
||||
internal SecTrust (IntPtr handle, bool owns = false)
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new Exception ("Invalid handle");
|
||||
|
||||
this.handle = handle;
|
||||
if (!owns)
|
||||
CFObject.CFRetain (handle);
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static SecStatusCode SecTrustCreateWithCertificates (
|
||||
/* CFTypeRef */ IntPtr certOrCertArray,
|
||||
/* CFTypeRef __nullable */ IntPtr policies,
|
||||
/* SecTrustRef *__nonull */ out IntPtr sectrustref);
|
||||
|
||||
|
||||
public SecTrust (X509CertificateCollection certificates, SecPolicy policy)
|
||||
{
|
||||
if (certificates == null)
|
||||
throw new ArgumentNullException ("certificates");
|
||||
|
||||
SecCertificate[] array = new SecCertificate [certificates.Count];
|
||||
int i = 0;
|
||||
foreach (var certificate in certificates)
|
||||
array [i++] = new SecCertificate (certificate);
|
||||
Initialize (array, policy);
|
||||
}
|
||||
|
||||
void Initialize (SecCertificate[] array, SecPolicy policy)
|
||||
{
|
||||
using (var certs = CFArray.CreateArray (array)) {
|
||||
Initialize (certs.Handle, policy);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize (IntPtr certHandle, SecPolicy policy)
|
||||
{
|
||||
SecStatusCode result = SecTrustCreateWithCertificates (certHandle, policy == null ? IntPtr.Zero : policy.Handle, out handle);
|
||||
if (result != SecStatusCode.Success)
|
||||
throw new ArgumentException (result.ToString ());
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static SecStatusCode /* OSStatus */ SecTrustEvaluate (IntPtr /* SecTrustRef */ trust, out /* SecTrustResultType */ SecTrustResult result);
|
||||
|
||||
public SecTrustResult Evaluate ()
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecTrust");
|
||||
|
||||
SecTrustResult trust;
|
||||
SecStatusCode result = SecTrustEvaluate (handle, out trust);
|
||||
if (result != SecStatusCode.Success)
|
||||
throw new InvalidOperationException (result.ToString ());
|
||||
return trust;
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static IntPtr /* CFIndex */ SecTrustGetCertificateCount (IntPtr /* SecTrustRef */ trust);
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
if (handle == IntPtr.Zero)
|
||||
return 0;
|
||||
return (int) SecTrustGetCertificateCount (handle);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static IntPtr /* SecCertificateRef */ SecTrustGetCertificateAtIndex (IntPtr /* SecTrustRef */ trust, IntPtr /* CFIndex */ ix);
|
||||
|
||||
public SecCertificate this [IntPtr index] {
|
||||
get {
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecTrust");
|
||||
if (((long)index < 0) || ((long)index >= Count))
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
return new SecCertificate (SecTrustGetCertificateAtIndex (handle, index));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static SecStatusCode /* OSStatus */ SecTrustSetAnchorCertificates (IntPtr /* SecTrustRef */ trust, IntPtr /* CFArrayRef */ anchorCertificates);
|
||||
|
||||
public SecStatusCode SetAnchorCertificates (X509CertificateCollection certificates)
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecTrust");
|
||||
if (certificates == null)
|
||||
return SecTrustSetAnchorCertificates (handle, IntPtr.Zero);
|
||||
|
||||
SecCertificate[] array = new SecCertificate [certificates.Count];
|
||||
int i = 0;
|
||||
foreach (var certificate in certificates)
|
||||
array [i++] = new SecCertificate (certificate);
|
||||
return SetAnchorCertificates (array);
|
||||
}
|
||||
|
||||
public SecStatusCode SetAnchorCertificates (SecCertificate[] array)
|
||||
{
|
||||
if (array == null)
|
||||
return SecTrustSetAnchorCertificates (handle, IntPtr.Zero);
|
||||
using (var certs = CFArray.FromNativeObjects (array)) {
|
||||
return SecTrustSetAnchorCertificates (handle, certs.Handle);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport (AppleTlsContext.SecurityLibrary)]
|
||||
extern static SecStatusCode /* OSStatus */ SecTrustSetAnchorCertificatesOnly (IntPtr /* SecTrustRef */ trust, bool anchorCertificatesOnly);
|
||||
|
||||
public SecStatusCode SetAnchorCertificatesOnly (bool anchorCertificatesOnly)
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
throw new ObjectDisposedException ("SecTrust");
|
||||
|
||||
return SecTrustSetAnchorCertificatesOnly (handle, anchorCertificatesOnly);
|
||||
}
|
||||
|
||||
~SecTrust ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero) {
|
||||
CFObject.CFRelease (handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get { return handle; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user