-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[OSX][TLS 1.3] Network Framework Native Layer + Interop Classes Implementations #117016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
liveans
wants to merge
25
commits into
dotnet:main
from
liveans:network_framework_integration_native_interop
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
c062e18
Native Interop Layer
liveans ecba3f7
Native Layer Compilation fix for Mono + NativeAOT + templates
liveans bf130f3
First shape of new native + interop
liveans 0dcc599
Newlines at the end of files
liveans 44b3597
Default constructor ownsHandle to true
liveans 3cbcea7
Delete couple of unsafe keyword in Interop
liveans 3defe85
Update src/native/libs/System.Net.Security.Native.Apple/pal_networkfr…
liveans 57a7069
Merge branch 'main' into network_framework_integration_native_interop
liveans c1a2b6b
Fix PlatformManifestFileEntry
liveans 0977679
Review feedback
liveans fe343b0
Apply suggestions from code review
liveans 0fff060
Update src/libraries/Common/src/Interop/OSX/Interop.Network.Tls.cs
liveans 3441093
Review feedbacks
liveans 3e547c5
Merge branch 'main' into network_framework_integration_native_interop
liveans 25b8950
Further review feedback
liveans 91238c5
Add new library name to nativeaot build target file
liveans a250b67
Merge branch 'main' into network_framework_integration_native_interop
liveans beb5f93
Merge System.Net.Security.Native.Apple with System.Security.Cryptogra…
rzikm 0ab06b2
fixup! Merge System.Net.Security.Native.Apple with System.Security.Cr…
rzikm 39bef6d
Shared OSStatus
rzikm 8267454
Correctly release some handles
rzikm 4bf6eb9
Remove printf
rzikm f771ea9
Add comments
rzikm 6ab3942
Fix build
rzikm cc950a1
Merge branch 'main' into network_framework_integration_native_interop
liveans File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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
142 changes: 142 additions & 0 deletions
142
src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.Tls.cs
This file contains hidden or 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,142 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics; | ||
| using System.Net.Security; | ||
| using System.Runtime.InteropServices; | ||
| using System.Security.Authentication; | ||
| using Microsoft.Win32.SafeHandles; | ||
|
|
||
| internal static partial class Interop | ||
| { | ||
| // TLS 1.3 specific Network Framework implementation for macOS | ||
| internal static partial class NetworkFramework | ||
| { | ||
| internal static partial class Tls | ||
| { | ||
| // Initialize internal shim for NetworkFramework integration | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwInit")] | ||
| [return: MarshalAs(UnmanagedType.I4)] | ||
| internal static unsafe partial bool Init( | ||
| delegate* unmanaged<IntPtr, StatusUpdates, IntPtr, IntPtr, void> statusCallback, | ||
| delegate* unmanaged<IntPtr, byte*, void**, int> readCallback, | ||
| delegate* unmanaged<IntPtr, byte*, void**, int> writeCallback); | ||
|
|
||
| // Create a new connection context | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwCreateContext")] | ||
| internal static partial SafeNwHandle CreateContext([MarshalAs(UnmanagedType.I4)] bool isServer); | ||
|
|
||
| // Set TLS options for a connection | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwSetTlsOptions", StringMarshalling = StringMarshalling.Utf8)] | ||
| private static partial void SetTlsOptions(SafeNwHandle connection, IntPtr state, | ||
| string targetName, Span<byte> alpnBuffer, int alpnLength, SslProtocols minTlsProtocol, SslProtocols maxTlsProtocol); | ||
|
|
||
| internal static void SetTlsOptions(SafeNwHandle nwHandle, IntPtr state, string targetName, List<SslApplicationProtocol>? applicationProtocols, SslProtocols minTlsVersion, SslProtocols maxTlsVersion) | ||
| { | ||
| int alpnLength = GetAlpnProtocolListSerializedLength(applicationProtocols); | ||
| Span<byte> alpn = stackalloc byte[256]; | ||
| SerializeAlpnProtocolList(applicationProtocols, alpn); | ||
|
|
||
| SetTlsOptions(nwHandle, state, targetName, alpn, alpnLength, minTlsVersion, maxTlsVersion); | ||
| } | ||
|
|
||
| // Start the TLS handshake, notifications are received via the status callback (potentially from a different thread). | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwStartTlsHandshake")] | ||
| internal static partial int StartTlsHandshake(SafeNwHandle connection, IntPtr state); | ||
|
|
||
| // takes encrypted input from underlying stream and feed it to the connection. | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwProcessInputData")] | ||
| internal static unsafe partial int ProcessInputData(SafeNwHandle connection, SafeNwHandle framer, byte* buffer, int bufferLength); | ||
|
|
||
| // sends plaintext data to the connection. | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwSendToConnection")] | ||
| internal static unsafe partial void SendToConnection(SafeNwHandle connection, IntPtr state, void* buffer, int bufferLength); | ||
|
|
||
| // read plaintext data from the connection. | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwReadFromConnection")] | ||
| internal static partial void ReadFromConnection(SafeNwHandle connection, IntPtr state); | ||
|
|
||
| // starts connection cleanup | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwCancelConnection")] | ||
| internal static partial void CancelConnection(SafeNwHandle connection); | ||
|
|
||
| // gets TLS connection information | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwGetConnectionInfo")] | ||
| internal static unsafe partial int GetConnectionInfo(SafeNwHandle connection, out SslProtocols pProtocol, out TlsCipherSuite pCipherSuiteOut, ref byte* negotiatedAlpn, out int negotiatedAlpnLength); | ||
|
|
||
| // copies the certificate chain from the connection | ||
| [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwCopyCertChain")] | ||
| internal static partial void CopyCertChain(SafeNwHandle connection, out SafeCFArrayHandle certificates, out int count); | ||
|
|
||
| internal static int GetAlpnProtocolListSerializedLength(List<SslApplicationProtocol>? applicationProtocols) | ||
| { | ||
| if (applicationProtocols is null) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| int protocolSize = 0; | ||
|
|
||
| foreach (SslApplicationProtocol protocol in applicationProtocols) | ||
| { | ||
| protocolSize += protocol.Protocol.Length + 2; | ||
| } | ||
|
|
||
| return protocolSize; | ||
| } | ||
|
|
||
| private static void SerializeAlpnProtocolList(List<SslApplicationProtocol>? applicationProtocols, Span<byte> buffer) | ||
| { | ||
| if (applicationProtocols is null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| Debug.Assert(GetAlpnProtocolListSerializedLength(applicationProtocols) == buffer.Length); | ||
|
|
||
| int offset = 0; | ||
| foreach (SslApplicationProtocol protocol in applicationProtocols) | ||
| { | ||
| buffer[offset++] = (byte)protocol.Protocol.Length; | ||
| protocol.Protocol.Span.CopyTo(buffer.Slice(offset)); | ||
| offset += protocol.Protocol.Length; | ||
| buffer[offset++] = 0; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Status enumeration for Network Framework TLS operations | ||
| internal enum StatusUpdates | ||
| { | ||
| UnknownError = 0, | ||
| FramerStart = 1, | ||
| FramerStop = 2, | ||
| HandshakeFinished = 3, | ||
| HandshakeFailed = 4, | ||
| ConnectionReadFinished = 100, | ||
| ConnectionWriteFinished = 101, | ||
| ConnectionWriteFailed = 102, | ||
| ConnectionCancelled = 103, | ||
| } | ||
| } | ||
|
|
||
| // Safe handle classes for Network Framework TLS resources | ||
| internal sealed class SafeNwHandle : SafeHandleZeroOrMinusOneIsInvalid | ||
| { | ||
| public SafeNwHandle() : base(ownsHandle: true) { } | ||
|
|
||
| public SafeNwHandle(IntPtr handle, bool ownsHandle) : base(ownsHandle) | ||
| { | ||
| SetHandle(handle); | ||
| } | ||
|
|
||
| protected override bool ReleaseHandle() | ||
| { | ||
| NetworkFramework.Release(handle); | ||
| SetHandle(IntPtr.Zero); | ||
| return true; | ||
| } | ||
| } | ||
| } |
18 changes: 18 additions & 0 deletions
18
src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.cs
This file contains hidden or 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,18 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| internal static partial class Interop | ||
| { | ||
| internal static partial class NetworkFramework | ||
| { | ||
| // Network Framework reference counting functions | ||
| [LibraryImport(Libraries.NetworkFramework, EntryPoint = "nw_retain")] | ||
| internal static partial IntPtr Retain(IntPtr obj); | ||
|
|
||
| [LibraryImport(Libraries.NetworkFramework, EntryPoint = "nw_release")] | ||
| internal static partial void Release(IntPtr obj); | ||
| } | ||
| } |
16 changes: 16 additions & 0 deletions
16
...ries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.OSStatus.cs
This file contains hidden or 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,16 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| internal static partial class Interop | ||
| { | ||
| internal static partial class AppleCrypto | ||
| { | ||
| internal static class OSStatus | ||
| { | ||
| public const int NoErr = 0; | ||
| public const int ReadErr = -19; | ||
| public const int WritErr = -20; | ||
| public const int ErrSSLWouldBlock = -9803; | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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
56 changes: 56 additions & 0 deletions
56
src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.h
This file contains hidden or 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,56 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "pal_compiler.h" | ||
| #include <pal_ssl_types.h> | ||
| #include <stdint.h> | ||
| #include <stddef.h> | ||
| #include <sys/types.h> // for intptr_t | ||
|
|
||
| #ifdef __OBJC__ | ||
| #import <Network/Network.h> | ||
| #else | ||
| #include <Network/Network.h> | ||
| #endif | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| // Status update enumeration for TLS operations | ||
| typedef enum | ||
| { | ||
| PAL_NwStatusUpdates_UnknownError = 0, | ||
| PAL_NwStatusUpdates_FramerStart = 1, | ||
| PAL_NwStatusUpdates_FramerStop = 2, | ||
| PAL_NwStatusUpdates_HandshakeFinished = 3, | ||
| PAL_NwStatusUpdates_HandshakeFailed = 4, | ||
|
|
||
| PAL_NwStatusUpdates_ConnectionReadFinished = 100, | ||
| PAL_NwStatusUpdates_ConnectionWriteFinished = 101, | ||
| PAL_NwStatusUpdates_ConnectionWriteFailed = 102, | ||
| PAL_NwStatusUpdates_ConnectionCancelled = 103, | ||
| } PAL_NwStatusUpdates; | ||
|
|
||
| // Callback type definitions that match the implementation usage | ||
| typedef void (*StatusUpdateCallback)(size_t context, PAL_NwStatusUpdates status, size_t data1, size_t data2); | ||
| typedef int32_t (*ReadCallback)(void* context, uint8_t* buffer, size_t* length); | ||
| typedef int32_t (*WriteCallback)(void* context, uint8_t* buffer, size_t length); | ||
|
|
||
| // Only TLS-specific Network Framework functions are exported | ||
| PALEXPORT nw_connection_t AppleCryptoNative_NwCreateContext(int32_t isServer); | ||
| PALEXPORT int32_t AppleCryptoNative_NwStartTlsHandshake(nw_connection_t connection, size_t gcHandle); | ||
| PALEXPORT int32_t AppleCryptoNative_NwInit(StatusUpdateCallback statusFunc, ReadCallback readFunc, WriteCallback writeFunc); | ||
| PALEXPORT void AppleCryptoNative_NwSendToConnection(nw_connection_t connection, size_t gcHandle, uint8_t* buffer, int length); | ||
| PALEXPORT void AppleCryptoNative_NwReadFromConnection(nw_connection_t connection, size_t gcHandle); | ||
| PALEXPORT int32_t AppleCryptoNative_NwProcessInputData(nw_connection_t connection, nw_framer_t framer, const uint8_t * data, int dataLength); | ||
| PALEXPORT void AppleCryptoNative_NwSetTlsOptions(nw_connection_t connection, size_t gcHandle, char* targetName, const uint8_t* alpnBuffer, int alpnLength, PAL_SslProtocol minTlsProtocol, PAL_SslProtocol maxTlsProtocol); | ||
| PALEXPORT int32_t AppleCryptoNative_NwGetConnectionInfo(nw_connection_t connection, PAL_SslProtocol* pProtocol, uint16_t* pCipherSuiteOut, const char** negotiatedAlpn, int32_t* negotiatedAlpnLength); | ||
| PALEXPORT void AppleCryptoNative_NwCopyCertChain(nw_connection_t connection, CFArrayRef* certificates, int* count); | ||
| PALEXPORT void AppleCryptoNative_NwCancelConnection(nw_connection_t connection); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.