This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of X509Certificates, HttpClient, and SslStream…
… for macOS (#16445) Broken by this change: * A lot of TLS CipherSuites have no metadata defined. * macOS does not support version skipping in TLS. So `Tls | Tls12` is an invalid choice. In this change: General: * All OSStatus related exceptions now look up the error message. X509Certificates: * X509Certificate moves to using SecCertificateRef from OpenSSL's X509. * X509 metadata comes from a managed reader after being loaded by Security.framework, due to the significant amount of data that has no public export in Apple's libraries. * Significant code was factored out to be shared by OpenSSL and Apple implementations for X500DistinguishedName and X509Certficate2Collection.Find. * Loading a PFX (or, rather, the private keys from a PFX) via Apple's platform requires importing into a Keychain, and a Keychain requires a file on disk. A temporary keychain is created during cert loading and erased when safe. Like the perphemeral key load on Windows this can leak files due to abnormal program termination. * The X.509 My store for CurrentUser and LocalMachine are the default (user) and System keychains. * The X.509 Root store is an interpretation of the Apple SecTrustSettings data. * The X.509 Disallowed store hasn't been implemented yet, but should be a very small change. * Other X.509 stores cannot be created due to keychain complexity. HttpClient: * Initialization no longer wakes up OpenSSL SslStream: * New implementation based on Apple SecureTransport. * Currently has support for SNI (for AuthenticateAsClient)
- Loading branch information
Showing
105 changed files
with
9,391 additions
and
1,210 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
src/Common/src/Interop/OSX/Interop.CoreFoundation.CFArray.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
using Microsoft.Win32.SafeHandles; | ||
|
||
// Declared as signed long, which has sizeof(void*) on OSX. | ||
using CFIndex=System.IntPtr; | ||
|
||
internal static partial class Interop | ||
{ | ||
internal static partial class CoreFoundation | ||
{ | ||
[DllImport(Libraries.CoreFoundationLibrary, EntryPoint = "CFArrayGetCount")] | ||
private static extern CFIndex _CFArrayGetCount(SafeCFArrayHandle cfArray); | ||
|
||
// Follows the "Get" version of the "Create" rule, so needs to return an IntPtr to | ||
// prevent CFRelease from being called on the SafeHandle close. | ||
[DllImport(Libraries.CoreFoundationLibrary, EntryPoint = "CFArrayGetValueAtIndex")] | ||
private static extern IntPtr CFArrayGetValueAtIndex(SafeCFArrayHandle cfArray, CFIndex index); | ||
|
||
internal static long CFArrayGetCount(SafeCFArrayHandle cfArray) | ||
{ | ||
return _CFArrayGetCount(cfArray).ToInt64(); | ||
} | ||
|
||
internal static IntPtr CFArrayGetValueAtIndex(SafeCFArrayHandle cfArray, int index) | ||
{ | ||
return CFArrayGetValueAtIndex(cfArray, new CFIndex(index)); | ||
} | ||
} | ||
} | ||
|
||
namespace Microsoft.Win32.SafeHandles | ||
{ | ||
internal sealed class SafeCFArrayHandle : SafeHandle | ||
{ | ||
internal SafeCFArrayHandle() | ||
: base(IntPtr.Zero, ownsHandle: true) | ||
{ | ||
} | ||
|
||
protected override bool ReleaseHandle() | ||
{ | ||
Interop.CoreFoundation.CFRelease(handle); | ||
SetHandle(IntPtr.Zero); | ||
return true; | ||
} | ||
|
||
public override bool IsInvalid => handle == IntPtr.Zero; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
src/Common/src/Interop/OSX/Interop.CoreFoundation.CFDate.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
|
||
using Microsoft.Win32.SafeHandles; | ||
|
||
using CFAbsoluteTime=System.Double; | ||
|
||
internal static partial class Interop | ||
{ | ||
internal static partial class CoreFoundation | ||
{ | ||
// https://developer.apple.com/reference/corefoundation/cfabsolutetime | ||
private static readonly DateTime s_cfDateEpoch = new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Utc); | ||
|
||
[DllImport(Libraries.CoreFoundationLibrary)] | ||
private static extern SafeCFDateHandle CFDateCreate(IntPtr zero, CFAbsoluteTime at); | ||
|
||
internal static SafeCFDateHandle CFDateCreate(DateTime date) | ||
{ | ||
Debug.Assert( | ||
date.Kind != DateTimeKind.Unspecified, | ||
"DateTimeKind.Unspecified should be specified to Local or UTC by the caller"); | ||
|
||
// UTC stays unchanged, Local is changed. | ||
// Unspecified gets treated as Local (which may or may not be desired). | ||
DateTime utcDate = date.ToUniversalTime(); | ||
|
||
double epochDeltaSeconds = (utcDate - s_cfDateEpoch).TotalSeconds; | ||
|
||
SafeCFDateHandle cfDate = CFDateCreate(IntPtr.Zero, epochDeltaSeconds); | ||
|
||
if (cfDate.IsInvalid) | ||
{ | ||
cfDate.Dispose(); | ||
throw new OutOfMemoryException(); | ||
} | ||
|
||
return cfDate; | ||
} | ||
} | ||
} | ||
|
||
namespace Microsoft.Win32.SafeHandles | ||
{ | ||
internal sealed class SafeCFDateHandle : SafeHandle | ||
{ | ||
internal SafeCFDateHandle() | ||
: base(IntPtr.Zero, ownsHandle: true) | ||
{ | ||
} | ||
|
||
protected override bool ReleaseHandle() | ||
{ | ||
Interop.CoreFoundation.CFRelease(handle); | ||
SetHandle(IntPtr.Zero); | ||
return true; | ||
} | ||
|
||
public override bool IsInvalid => handle == IntPtr.Zero; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.