[Android] Enable two networking tests (#81895)
authorŠimon Rozsíval <simon@rozsival.com>
Fri, 10 Feb 2023 09:24:50 +0000 (10:24 +0100)
committerGitHub <noreply@github.com>
Fri, 10 Feb 2023 09:24:50 +0000 (10:24 +0100)
* Avoid crashing when AndroidCryptoNative_RegisterRemoteCertificateValidationCallback is called more than once

* Enable GetAsync_IPv6LinkLocalAddressUri_Success test on Android

* Enable supported cases of SslStream_ServerCallbackNotSet_UsesLocalCertificateSelection on Android

src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs
src/native/libs/System.Security.Cryptography.Native.Android/pal_trust_manager.c

index d5116fc..1139919 100644 (file)
@@ -153,7 +153,6 @@ namespace System.Net.Http.Functional.Tests
 
         [ConditionalFact]
         [SkipOnPlatform(TestPlatforms.Browser, "ServerCertificateCustomValidationCallback not supported on Browser")]
-        [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)
index ced88b1..1a741bf 100644 (file)
@@ -3,12 +3,14 @@
 
 using System.Collections.Generic;
 using System.IO;
+using System.Linq;
 using System.Net.Test.Common;
 using System.Security.Authentication;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Threading.Tasks;
 using Xunit;
+using Microsoft.DotNet.XUnitExtensions;
 
 namespace System.Net.Security.Tests
 {
@@ -94,11 +96,13 @@ namespace System.Net.Security.Tests
             }
         }
 
-        [Theory]
+        [ConditionalTheory]
         [MemberData(nameof(HostNameData))]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/68206", TestPlatforms.Android)]
         public async Task SslStream_ServerCallbackNotSet_UsesLocalCertificateSelection(string hostName)
         {
+            if (PlatformDetection.IsAndroid && hostName.ToCharArray().Any(c => !char.IsAscii(c)))
+                throw new SkipTestException("Android does not support non-ASCII host names");
+
             using X509Certificate serverCert = Configuration.Certificates.GetSelfSignedServerCertificate();
 
             int timesCallbackCalled = 0;
index c0097c9..af87c04 100644 (file)
@@ -1,11 +1,11 @@
 #include "pal_trust_manager.h"
+#include <stdatomic.h>
 
-static RemoteCertificateValidationCallback verifyRemoteCertificate;
+static _Atomic RemoteCertificateValidationCallback verifyRemoteCertificate;
 
 ARGS_NON_NULL_ALL void AndroidCryptoNative_RegisterRemoteCertificateValidationCallback(RemoteCertificateValidationCallback callback)
 {
-    abort_unless(verifyRemoteCertificate == NULL, "AndroidCryptoNative_RegisterRemoteCertificateValidationCallback can only be used once");
-    verifyRemoteCertificate = callback;
+    atomic_store(&verifyRemoteCertificate, callback);
 }
 
 ARGS_NON_NULL_ALL jobjectArray GetTrustManagers(JNIEnv* env, intptr_t sslStreamProxyHandle)
@@ -31,6 +31,7 @@ cleanup:
 ARGS_NON_NULL_ALL jboolean Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate(
     JNIEnv* env, jobject thisHandle, jlong sslStreamProxyHandle)
 {
-    abort_unless(verifyRemoteCertificate, "verifyRemoteCertificate callback has not been registered");
-    return verifyRemoteCertificate((intptr_t)sslStreamProxyHandle);
+    RemoteCertificateValidationCallback verify = atomic_load(&verifyRemoteCertificate);
+    abort_unless(verify, "verifyRemoteCertificate callback has not been registered");
+    return verify((intptr_t)sslStreamProxyHandle);
 }