Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ internal static void SSLStreamSetTargetHost(
throw new SslException();
}

[LibraryImport(Interop.Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_SSLStreamIsLocalCertificateUsed")]
[return: MarshalAs(UnmanagedType.U1)]
internal static partial bool SSLStreamIsLocalCertificateUsed(SafeSslHandle sslHandle);

[LibraryImport(Interop.Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_SSLStreamRequestClientAuthentication")]
internal static partial void SSLStreamRequestClientAuthentication(SafeSslHandle sslHandle);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,15 @@ internal static SslPolicyErrors VerifyCertificateProperties(
return cert;
}

// This is only called when we selected local client certificate.
// Currently this is only when Java crypto asked for it.
internal static bool IsLocalCertificateUsed(SafeDeleteContext? _) => true;
// Check if the local certificate has been sent to the peer during the handshake.
internal static bool IsLocalCertificateUsed(SafeDeleteContext? securityContext)
{
SafeSslHandle? sslContext = ((SafeDeleteSslContext?)securityContext)?.SslContext;
if (sslContext == null)
return false;

return Interop.AndroidCrypto.SSLStreamIsLocalCertificateUsed(sslContext);
}

//
// Used only by client SSL code, never returns null.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public async Task SslStream_RequireClientCert_IsMutuallyAuthenticated_ReturnsTru

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[ClassData(typeof(SslProtocolSupport.SupportedSslProtocolsTestData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/65563", TestPlatforms.Android)]
public async Task SslStream_CachedCredentials_IsMutuallyAuthenticatedCorrect(
SslProtocols protocol)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ jmethodID g_SSLContextCreateSSLEngineMethodWithHostAndPort;
jclass g_SSLSession;
jmethodID g_SSLSessionGetApplicationBufferSize;
jmethodID g_SSLSessionGetCipherSuite;
jmethodID g_SSLSessionGetLocalCertificates;
jmethodID g_SSLSessionGetPacketBufferSize;
jmethodID g_SSLSessionGetPeerCertificates;
jmethodID g_SSLSessionGetProtocol;
Expand Down Expand Up @@ -1054,6 +1055,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved)
g_SSLSession = GetClassGRef(env, "javax/net/ssl/SSLSession");
g_SSLSessionGetApplicationBufferSize = GetMethod(env, false, g_SSLSession, "getApplicationBufferSize", "()I");
g_SSLSessionGetCipherSuite = GetMethod(env, false, g_SSLSession, "getCipherSuite", "()Ljava/lang/String;");
g_SSLSessionGetLocalCertificates = GetMethod(env, false, g_SSLSession, "getLocalCertificates", "()[Ljava/security/cert/Certificate;");
g_SSLSessionGetPacketBufferSize = GetMethod(env, false, g_SSLSession, "getPacketBufferSize", "()I");
g_SSLSessionGetPeerCertificates = GetMethod(env, false, g_SSLSession, "getPeerCertificates", "()[Ljava/security/cert/Certificate;");
g_SSLSessionGetProtocol = GetMethod(env, false, g_SSLSession, "getProtocol", "()Ljava/lang/String;");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ extern jmethodID g_SSLContextCreateSSLEngineMethodWithHostAndPort;
extern jclass g_SSLSession;
extern jmethodID g_SSLSessionGetApplicationBufferSize;
extern jmethodID g_SSLSessionGetCipherSuite;
extern jmethodID g_SSLSessionGetLocalCertificates;
extern jmethodID g_SSLSessionGetPacketBufferSize;
extern jmethodID g_SSLSessionGetPeerCertificates;
extern jmethodID g_SSLSessionGetProtocol;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,25 @@ bool AndroidCryptoNative_SSLStreamVerifyHostname(SSLStream* sslStream, char* hos
return ret;
}

bool AndroidCryptoNative_SSLStreamIsLocalCertificateUsed(SSLStream* sslStream)
{
abort_if_invalid_pointer_argument(sslStream);
JNIEnv* env = GetJNIEnv();

bool ret = false;
INIT_LOCALS(loc, localCertificates);

// X509Certificate[] localCertificates = sslSession.getLocalCertificates();
loc[localCertificates] = (*env)->CallObjectMethod(env, sslStream->sslSession, g_SSLSessionGetLocalCertificates);
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);

ret = loc[localCertificates] != NULL;

cleanup:
RELEASE_LOCALS(loc, env);
return ret;
}

bool AndroidCryptoNative_SSLStreamShutdown(SSLStream* sslStream)
{
abort_if_invalid_pointer_argument (sslStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ Returns 1 on success, 0 otherwise
*/
PALEXPORT int32_t AndroidCryptoNative_SSLStreamSetTargetHost(SSLStream* sslStream, char* targetHost);

/*
Check if the local certificate has been sent to the peer during the TLS handshake.

Returns true if the local certificate has been sent to the peer, false otherwise.
*/
PALEXPORT bool AndroidCryptoNative_SSLStreamIsLocalCertificateUsed(SSLStream* sslStream);

/*
Start or continue the TLS handshake
*/
Expand Down