Skip to content
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

[Android] Improvements to remote certificate verification in SslStream #77386

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
4fdd70a
Extract existing validation code into a separate class
simonrozsival Oct 24, 2022
a4726a6
Implement AndroidDexBuilderTask
simonrozsival Oct 24, 2022
18214ea
Implement TrustManager proxy
simonrozsival Oct 24, 2022
193f3c6
Integrate the trust manager proxy with SslStream on Android
simonrozsival Oct 24, 2022
6e8659f
Update tests
simonrozsival Oct 24, 2022
c84e355
Update System.Net.Http tests
simonrozsival Oct 24, 2022
f1d429f
Update System.Net.Security tests
simonrozsival Oct 24, 2022
3e72ff3
Fix packaging
simonrozsival Oct 24, 2022
2d9a2ec
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Oct 26, 2022
04da7c9
Propagate caught exceptions
simonrozsival Oct 26, 2022
28c360b
Build and pack .jar
simonrozsival Oct 26, 2022
220a83e
Optimize allocation and deallocation of memory for certificate data
simonrozsival Oct 27, 2022
c483e31
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Oct 27, 2022
e42a67d
Fix building .jar
simonrozsival Nov 3, 2022
476bd84
Cleanup
simonrozsival Nov 9, 2022
f3fb8c5
Remove complicated certificate copying
simonrozsival Nov 9, 2022
f579d38
Remove unnecessary JNI classes and methods
simonrozsival Nov 9, 2022
663c40d
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Nov 9, 2022
e68908b
Simplify and fix the core implementation
simonrozsival Nov 9, 2022
9cfd08b
Update enabled and disabled tests
simonrozsival Nov 9, 2022
1bc237e
Cleanup
simonrozsival Nov 9, 2022
7b04be0
Renaming
simonrozsival Nov 9, 2022
2f70a5d
Remove unnecessary changes
simonrozsival Nov 9, 2022
af18da7
Fix invoking validation even when the Java callbacks aren't called (n…
simonrozsival Nov 9, 2022
4a7c785
Minor refactoring
simonrozsival Nov 10, 2022
21a69ed
Enable more unnecessarily disabled tests
simonrozsival Nov 10, 2022
6cb7122
Refactor exception handling
simonrozsival Nov 11, 2022
7aa11a9
Update disabled tests
simonrozsival Nov 11, 2022
405dd0c
Renaming
simonrozsival Nov 14, 2022
0e86a01
Remove network security config workarounds
simonrozsival Nov 14, 2022
b4f0e81
Keep existing active issue
simonrozsival Nov 14, 2022
c74d272
Remove unnecessary changes
simonrozsival Nov 14, 2022
90ea148
Remove unnecessary code
simonrozsival Nov 14, 2022
343cc65
Enable more disabled tests
simonrozsival Nov 14, 2022
2dd1ab7
Fix throwing exception
simonrozsival Nov 14, 2022
d7d95e0
Fix intptr_t cast to Java
simonrozsival Nov 15, 2022
aeb5714
Remove initialization lock
simonrozsival Nov 15, 2022
b4b5589
Update naming
simonrozsival Nov 15, 2022
3118376
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Nov 18, 2022
c16ad79
Fix type casting
simonrozsival Nov 21, 2022
446d4a3
Improve throwing validation exception
simonrozsival Nov 22, 2022
4b4af02
Experiment with code structure
simonrozsival Nov 23, 2022
ae2fb90
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Nov 24, 2022
eb41d22
Fix repeated calls to beginHandshake
simonrozsival Nov 24, 2022
e9c018f
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Nov 29, 2022
c2038ac
Make SslStream proxy mandatory
simonrozsival Nov 29, 2022
ac72811
Add missing attributes
simonrozsival Nov 29, 2022
3c7378a
Free temporary buffer
simonrozsival Nov 30, 2022
010516c
Update src/native/libs/System.Security.Cryptography.Native.Android/pa…
simonrozsival Dec 1, 2022
9681df0
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Dec 1, 2022
ccae3e2
Refactor creating array of trust managers
simonrozsival Dec 1, 2022
019a83d
Add comments and clean up pal_sslstream.c
simonrozsival Dec 1, 2022
fb793fa
Merge branch 'android-remote-certificate-verification-improvements' o…
simonrozsival Dec 1, 2022
5d26948
Revert experimental change
simonrozsival Dec 1, 2022
2dec0d5
Remove special case for IPv6 addresses as hostnames and disable affec…
simonrozsival Dec 1, 2022
6d55d21
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Dec 6, 2022
0d42b22
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Dec 7, 2022
694589b
Fix duplicate variable after merge
simonrozsival Dec 7, 2022
315ca06
Improve code formatting
simonrozsival Dec 7, 2022
9c1e0a3
Merge branch 'main' into android-remote-certificate-verification-impr…
simonrozsival Jan 5, 2023
b94a12c
Remove the hack with SafeDeleteContextStub
simonrozsival Jan 6, 2023
061285a
Enable passing test
simonrozsival Jan 6, 2023
52e65b1
Merge branch 'android-remote-certificate-verification-improvements' o…
simonrozsival Jan 6, 2023
d2d695a
Remove unnecessary factory
simonrozsival Jan 6, 2023
b6f5385
Move clearing selected client certificate out of the remote certifica…
simonrozsival Jan 6, 2023
6a0b8ef
Fix typo in comment
simonrozsival Jan 9, 2023
e5d1e8d
Add comment with java equivalent
simonrozsival Jan 9, 2023
292b893
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Jan 9, 2023
50befcf
Move Android specific runtime files into a separate item group
simonrozsival Jan 9, 2023
34e7fac
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Jan 10, 2023
5dcf43a
Merge branch 'main' of https://github.com/dotnet/runtime into android…
simonrozsival Jan 12, 2023
f3d9ac4
Apply suggestions from code review
simonrozsival Jan 13, 2023
1338689
Update src/native/libs/build-native.proj
simonrozsival Jan 13, 2023
f4ff98a
Disable test that fails on Android emualtors
simonrozsival Jan 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions eng/liveBuilds.targets
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@
$(LibrariesNativeArtifactsPath)*.pdb"
IsNative="true"
Exclude="@(ExcludeNativeLibrariesRuntimeFiles)" />
<LibrariesRuntimeFiles Condition="'$(TargetOS)' == 'android'"
Include="
$(LibrariesNativeArtifactsPath)*.dex;
$(LibrariesNativeArtifactsPath)*.jar;"
IsNative="true" />
<LibrariesRuntimeFiles Condition="'$(TargetOS)' == 'browser'"
Include="
$(LibrariesNativeArtifactsPath)dotnet.js;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.Apple.dylib" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.Android.a" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.Android.so" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.Android.dex" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.Android.jar" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.OpenSsl.a" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.OpenSsl.dylib" IsNative="true" />
<PlatformManifestFileEntry Include="libSystem.Security.Cryptography.Native.OpenSsl.so" IsNative="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,37 @@ internal enum PAL_SSLStreamStatus
};

[LibraryImport(Interop.Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_SSLStreamCreate")]
internal static partial SafeSslHandle SSLStreamCreate();
private static partial SafeSslHandle SSLStreamCreate(IntPtr sslStreamProxyHandle);
internal static SafeSslHandle SSLStreamCreate(SslStream.JavaProxy sslStreamProxy)
=> SSLStreamCreate(sslStreamProxy.Handle);

[LibraryImport(Interop.Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_SSLStreamCreateWithCertificates")]
private static partial SafeSslHandle SSLStreamCreateWithCertificates(
IntPtr sslStreamProxyHandle,
ref byte pkcs8PrivateKey,
int pkcs8PrivateKeyLen,
PAL_KeyAlgorithm algorithm,
IntPtr[] certs,
int certsLen);
internal static SafeSslHandle SSLStreamCreateWithCertificates(ReadOnlySpan<byte> pkcs8PrivateKey, PAL_KeyAlgorithm algorithm, IntPtr[] certificates)
internal static SafeSslHandle SSLStreamCreateWithCertificates(
SslStream.JavaProxy sslStreamProxy,
ReadOnlySpan<byte> pkcs8PrivateKey,
PAL_KeyAlgorithm algorithm,
IntPtr[] certificates)
{
return SSLStreamCreateWithCertificates(
sslStreamProxy.Handle,
ref MemoryMarshal.GetReference(pkcs8PrivateKey),
pkcs8PrivateKey.Length,
algorithm,
certificates,
certificates.Length);
}

[LibraryImport(Interop.Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_RegisterRemoteCertificateValidationCallback")]
internal static unsafe partial void RegisterRemoteCertificateValidationCallback(
delegate* unmanaged<IntPtr, bool> verifyRemoteCertificate);

[LibraryImport(Interop.Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_SSLStreamInitialize")]
private static unsafe partial int SSLStreamInitializeImpl(
SafeSslHandle sslHandle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ await TestHelper.WhenAllCompletedOrAnyFailed(
[OuterLoop]
[ConditionalTheory(nameof(ClientSupportsDHECipherSuites))]
[MemberData(nameof(InvalidCertificateServers))]
[SkipOnPlatform(TestPlatforms.Android, "Android rejects the certificate, the custom validation callback in .NET cannot override OS behavior in the current implementation")]
public async Task InvalidCertificateServers_CertificateValidationDisabled_Succeeds(string url)
{
using (HttpClientHandler handler = CreateHttpClientHandler(allowAllCertificates: true))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ private async Task UseCallback_BadCertificate_ExpectedPolicyErrors_Helper(string
[OuterLoop("Uses external servers")]
[Theory]
[MemberData(nameof(CertificateValidationServersAndExpectedPolicies))]
[SkipOnPlatform(TestPlatforms.Android, "Android rejects the certificate, the custom validation callback in .NET cannot override OS behavior in the current implementation")]
public async Task UseCallback_BadCertificate_ExpectedPolicyErrors(string url, SslPolicyErrors expectedErrors)
{
const int SEC_E_BUFFER_TOO_SMALL = unchecked((int)0x80090321);
Expand All @@ -310,7 +309,6 @@ public async Task UseCallback_BadCertificate_ExpectedPolicyErrors(string url, Ss
}

[Fact]
[SkipOnPlatform(TestPlatforms.Android, "Android rejects the certificate, the custom validation callback in .NET cannot override OS behavior in the current implementation")]
public async Task UseCallback_SelfSignedCertificate_ExpectedPolicyErrors()
{
using (HttpClientHandler handler = CreateHttpClientHandler())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public void Properties_AddItemToDictionary_ItemPresent()

[ConditionalFact]
[SkipOnPlatform(TestPlatforms.Browser, "ServerCertificateCustomValidationCallback not supported on Browser")]
[SkipOnPlatform(TestPlatforms.Android, "IPv6 loopback with SSL doesn't work on Android")]
[SkipOnPlatform(TestPlatforms.Android, "TargetHost cannot be set to an IPv6 address on Android because the string doesn't conform to the STD 3 ASCII rules")]
public async Task GetAsync_IPv6LinkLocalAddressUri_Success()
{
if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
Expand Down Expand Up @@ -205,7 +205,7 @@ public async Task GetAsync_IPBasedUri_Success(IPAddress address)

if (PlatformDetection.IsAndroid && options.UseSsl && address == IPAddress.IPv6Loopback)
{
throw new SkipTestException("IPv6 loopback with SSL doesn't work on Android");
throw new SkipTestException("TargetHost cannot be set to an IPv6 address on Android because the string doesn't conform to the STD 3 ASCII rules");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like that can be turned off..????
https://developer.android.com/reference/java/net/IDN
Is this because it does not like "::1" format?
Would it work in the long form? e.g. "0:0:0:0:0:0:0:1" or "[0:0:0:0:0:0:0:1]"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has an allow list of characters that doesn't include :, it's not just about the loopback address specifically so the long forms don't work either. We can't turn it off AFAIK. I'm by no means an expert in this area but from what I read it's a bad practice to put IP addresses into SNI host name (see #79143).

}

await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
Expand Down Expand Up @@ -287,7 +287,7 @@ public async Task GetAsync_SecureAndNonSecureIPBasedUri_CorrectlyFormatted(IPAdd

if (PlatformDetection.IsAndroid && useSsl && address == IPAddress.IPv6Loopback)
{
throw new SkipTestException("IPv6 loopback with SSL doesn't work on Android");
throw new SkipTestException("TargetHost cannot be set to an IPv6 address on Android because the string doesn't conform to the STD 3 ASCII rules");
}

var options = new LoopbackServer.Options { Address = address, UseSsl = useSsl };
Expand Down
3 changes: 0 additions & 3 deletions src/libraries/Common/tests/System/Net/Http/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,6 @@ public static SocketsHttpHandler CreateSocketsHttpHandler(bool allowAllCertifica
// Browser doesn't support ServerCertificateCustomValidationCallback
if (allowAllCertificates && PlatformDetection.IsNotBrowser)
{
// On Android, it is not enough to set the custom validation callback, the certificates also need to be trusted by the OS.
// See HttpClientHandlerTestBase.SocketsHttpHandler.cs:CreateHttpClientHandler for more details.

handler.SslOptions.RemoteCertificateValidationCallback = delegate { return true; };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ protected static HttpClientHandler CreateHttpClientHandler(Version useVersion =
// Browser doesn't support ServerCertificateCustomValidationCallback
if (allowAllCertificates && PlatformDetection.IsNotBrowser)
{
// On Android, it is not enough to set the custom validation callback, the certificates also need to be trusted by the OS.
// The public keys of our self-signed certificates that are used by the loopback server are part of the System.Net.TestData
// package and they can be included in a the Android test apk by adding the following property to the test's .csproj:
//
// <IncludeNetworkSecurityConfig Condition="'$(TargetOS)' == 'android'">true</IncludeNetworkSecurityConfig>
//

handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4076,7 +4076,6 @@ public abstract class SocketsHttpHandler_SecurityTest : HttpClientHandlerTestBas
public SocketsHttpHandler_SecurityTest(ITestOutputHelper output) : base(output) { }

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[SkipOnPlatform(TestPlatforms.Android, "Self-signed certificates are rejected by Android before the .NET validation is reached")]
public async Task SslOptions_CustomTrust_Ok()
{
X509Certificate2Collection caCerts = new X509Certificate2Collection();
Expand Down Expand Up @@ -4113,7 +4112,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(
}

[Fact]
[SkipOnPlatform(TestPlatforms.Android, "Self-signed certificates are rejected by Android before the .NET validation is reached")]
public async Task SslOptions_InvalidName_Throws()
{
X509Certificate2Collection caCerts = new X509Certificate2Collection();
Expand Down Expand Up @@ -4144,7 +4142,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(
}

[Fact]
[SkipOnPlatform(TestPlatforms.Android, "Self-signed certificates are rejected by Android before the .NET validation is reached")]
public async Task SslOptions_CustomPolicy_IgnoresNameMismatch()
{
X509Certificate2Collection caCerts = new X509Certificate2Collection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task TestLoopbackAsync(string scheme, bool useSsl, bool useAuth, st

if (PlatformDetection.IsAndroid && useSsl && host == "::1")
{
throw new SkipTestException("IPv6 loopback with SSL doesn't work on Android");
throw new SkipTestException("TargetHost cannot be set to an IPv6 address on Android because the string doesn't conform to the STD 3 ASCII rules");
}

await LoopbackServerFactory.CreateClientAndServerAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent)-osx</TargetFrameworks>
<EnableLibraryImportGenerator>true</EnableLibraryImportGenerator>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<!-- the res/xml/network_security_config.xml file comes from the System.Net.TestData package -->
<IncludeNetworkSecurityConfig Condition="'$(TargetOS)' == 'android'">true</IncludeNetworkSecurityConfig>
<EventSourceSupport Condition="'$(TestNativeAot)' == 'true'">true</EventSourceSupport>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
<IgnoreForCI Condition="'$(TargetOS)' == 'browser'">true</IgnoreForCI>
<!-- SYSLIB0014: WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead. -->
<NoWarn>$(NoWarn);SYSLIB0014</NoWarn>
<!-- the res/xml/network_security_config.xml file comes from the System.Net.TestData package -->
<IncludeNetworkSecurityConfig Condition="'$(TargetOS)' == 'android'">true</IncludeNetworkSecurityConfig>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<EventSourceSupport Condition="'$(TestNativeAot)' == 'true'">true</EventSourceSupport>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<GeneratePlatformNotSupportedAssemblyMessage Condition="'$(TargetPlatformIdentifier)' == ''">SR.SystemNetSecurity_PlatformNotSupported</GeneratePlatformNotSupportedAssemblyMessage>
<DefineConstants Condition="'$(TargetPlatformIdentifier)' == 'windows'">$(DefineConstants);TARGET_WINDOWS</DefineConstants>
<DefineConstants Condition="'$(TargetPlatformIdentifier)' == 'android'">$(DefineConstants);TARGET_ANDROID</DefineConstants>
<UseAndroidCrypto Condition="'$(TargetPlatformIdentifier)' == 'android'">true</UseAndroidCrypto>
<UseAppleCrypto Condition="'$(TargetPlatformIdentifier)' == 'osx' or '$(TargetPlatformIdentifier)' == 'ios' or '$(TargetPlatformIdentifier)' == 'tvos'">true</UseAppleCrypto>
<UseManagedNtlm Condition="'$(TargetPlatformIdentifier)' == 'android' or '$(TargetPlatformIdentifier)' == 'tvos'">true</UseManagedNtlm>
Expand Down Expand Up @@ -102,7 +103,7 @@
Link="Common\System\Net\SecurityStatusPal.cs" />
<Compile Include="$(CommonPath)System\HexConverter.cs"
Link="Common\System\HexConverter.cs" />
<Compile Include="$(CommonPath)System\Obsoletions.cs"
<Compile Include="$(CommonPath)System\Obsoletions.cs"
Link="Common\System\Obsoletions.cs" />
</ItemGroup>
<!-- This file depends on IANA registry. We do not want anyone's build to break after the update -->
Expand Down Expand Up @@ -382,6 +383,7 @@
<Compile Include="System\Net\Security\Pal.Android\SafeDeleteSslContext.cs" />
<Compile Include="System\Net\Security\Pal.Managed\SslProtocolsValidation.cs" />
<Compile Include="System\Net\Security\SslConnectionInfo.Android.cs" />
<Compile Include="System\Net\Security\SslStream.Android.cs" />
<Compile Include="System\Net\Security\SslStreamCertificateContext.Android.cs" />
<Compile Include="System\Net\Security\SslStreamPal.Android.cs" />
<Compile Include="System\Net\Security\StreamSizes.Unix.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@ internal sealed class SafeDeleteSslContext : SafeDeleteContext
private ArrayBuffer _inputBuffer = new ArrayBuffer(InitialBufferSize);
private ArrayBuffer _outputBuffer = new ArrayBuffer(InitialBufferSize);

public SslStream.JavaProxy SslStreamProxy { get; }

public SafeSslHandle SslContext => _sslContext;

public SafeDeleteSslContext(SslAuthenticationOptions authOptions)
: base(IntPtr.Zero)
{
SslStreamProxy = authOptions.SslStreamProxy
?? throw new ArgumentNullException(nameof(authOptions.SslStreamProxy));

try
{
_sslContext = CreateSslContext(authOptions);
_sslContext = CreateSslContext(SslStreamProxy, authOptions);
InitializeSslContext(_sslContext, authOptions);
}
catch (Exception ex)
Expand All @@ -58,8 +63,7 @@ protected override void Dispose(bool disposing)
{
if (disposing)
{
SafeSslHandle sslContext = _sslContext;
if (sslContext != null)
if (_sslContext is SafeSslHandle sslContext)
{
_inputBuffer.Dispose();
_outputBuffer.Dispose();
Expand Down Expand Up @@ -145,11 +149,11 @@ internal int ReadPendingWrites(byte[] buf, int offset, int count)
return limit;
}

private static SafeSslHandle CreateSslContext(SslAuthenticationOptions authOptions)
private static SafeSslHandle CreateSslContext(SslStream.JavaProxy sslStreamProxy, SslAuthenticationOptions authOptions)
{
if (authOptions.CertificateContext == null)
{
return Interop.AndroidCrypto.SSLStreamCreate();
return Interop.AndroidCrypto.SSLStreamCreate(sslStreamProxy);
}

SslStreamCertificateContext context = authOptions.CertificateContext;
Expand All @@ -169,7 +173,7 @@ private static SafeSslHandle CreateSslContext(SslAuthenticationOptions authOptio
ptrs[i + 1] = context.IntermediateCertificates[i].Handle;
}

return Interop.AndroidCrypto.SSLStreamCreateWithCertificates(keyBytes, algorithm, ptrs);
return Interop.AndroidCrypto.SSLStreamCreateWithCertificates(sslStreamProxy, keyBytes, algorithm, ptrs);
}

private static AsymmetricAlgorithm GetPrivateKeyAlgorithm(X509Certificate2 cert, out PAL_KeyAlgorithm algorithm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,9 @@ private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols proto
internal object? UserState { get; set; }
internal ServerOptionsSelectionCallback? ServerOptionDelegate { get; set; }
internal X509ChainPolicy? CertificateChainPolicy { get; set; }

#if TARGET_ANDROID
internal SslStream.JavaProxy? SslStreamProxy { get; set; }
#endif
}
}
Loading