Skip to content

Commit c7460d0

Browse files
[Android] Remove repeated calls to beginHandshake (#78849)
Cleanup Revert some changes
1 parent 019a362 commit c7460d0

File tree

3 files changed

+50
-14
lines changed

3 files changed

+50
-14
lines changed

src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ jmethodID g_SSLEngineBeginHandshake;
419419
jmethodID g_SSLEngineCloseOutbound;
420420
jmethodID g_SSLEngineGetApplicationProtocol;
421421
jmethodID g_SSLEngineGetHandshakeStatus;
422+
jmethodID g_SSLEngineGetHandshakeSession;
422423
jmethodID g_SSLEngineGetSession;
423424
jmethodID g_SSLEngineGetSSLParameters;
424425
jmethodID g_SSLEngineGetSupportedProtocols;
@@ -1002,6 +1003,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved)
10021003
g_SSLEngineGetApplicationProtocol = GetOptionalMethod(env, false, g_SSLEngine, "getApplicationProtocol", "()Ljava/lang/String;");
10031004
g_SSLEngineGetHandshakeStatus = GetMethod(env, false, g_SSLEngine, "getHandshakeStatus", "()Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
10041005
g_SSLEngineGetSession = GetMethod(env, false, g_SSLEngine, "getSession", "()Ljavax/net/ssl/SSLSession;");
1006+
g_SSLEngineGetHandshakeSession = GetOptionalMethod(env, false, g_SSLEngine, "getHandshakeSession", "()Ljavax/net/ssl/SSLSession;");
10051007
g_SSLEngineGetSSLParameters = GetMethod(env, false, g_SSLEngine, "getSSLParameters", "()Ljavax/net/ssl/SSLParameters;");
10061008
g_SSLEngineGetSupportedProtocols = GetMethod(env, false, g_SSLEngine, "getSupportedProtocols", "()[Ljava/lang/String;");
10071009
g_SSLEngineSetEnabledProtocols = GetMethod(env, false, g_SSLEngine, "setEnabledProtocols", "([Ljava/lang/String;)V");

src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ extern jmethodID g_SSLEngineBeginHandshake;
433433
extern jmethodID g_SSLEngineCloseOutbound;
434434
extern jmethodID g_SSLEngineGetApplicationProtocol;
435435
extern jmethodID g_SSLEngineGetHandshakeStatus;
436+
extern jmethodID g_SSLEngineGetHandshakeSession;
436437
extern jmethodID g_SSLEngineGetSession;
437438
extern jmethodID g_SSLEngineGetSSLParameters;
438439
extern jmethodID g_SSLEngineGetSupportedProtocols;

src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ static bool IsHandshaking(int handshakeStatus)
4040
return handshakeStatus != HANDSHAKE_STATUS__NOT_HANDSHAKING && handshakeStatus != HANDSHAKE_STATUS__FINISHED;
4141
}
4242

43+
static jobject GetSslSessionForHandshakeStatus(JNIEnv* env, SSLStream* sslStream, int handshakeStatus)
44+
{
45+
// SSLEngine.getHandshakeSession() is available since API 24
46+
jobject sslSession = IsHandshaking(handshakeStatus) && g_SSLEngineGetHandshakeSession != NULL
47+
? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession)
48+
: (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
49+
if (CheckJNIExceptions(env))
50+
return NULL;
51+
52+
return sslSession;
53+
}
54+
55+
static jobject GetCurrentSslSession(JNIEnv* env, SSLStream* sslStream)
56+
{
57+
int handshakeStatus = GetEnumAsInt(env, (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeStatus));
58+
if (CheckJNIExceptions(env))
59+
return NULL;
60+
61+
return GetSslSessionForHandshakeStatus(env, sslStream, handshakeStatus);
62+
}
63+
4364
ARGS_NON_NULL_ALL static PAL_SSLStreamStatus Close(JNIEnv* env, SSLStream* sslStream)
4465
{
4566
// Call wrap to clear any remaining data before closing
@@ -523,10 +544,13 @@ PAL_SSLStreamStatus AndroidCryptoNative_SSLStreamHandshake(SSLStream* sslStream)
523544
abort_if_invalid_pointer_argument (sslStream);
524545
JNIEnv* env = GetJNIEnv();
525546

526-
// sslEngine.beginHandshake();
527-
(*env)->CallVoidMethod(env, sslStream->sslEngine, g_SSLEngineBeginHandshake);
528-
if (CheckJNIExceptions(env))
529-
return SSLStreamStatus_Error;
547+
int handshakeStatus = GetEnumAsInt(env, (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeStatus));
548+
if (!IsHandshaking(handshakeStatus)) {
549+
// sslEngine.beginHandshake();
550+
(*env)->CallVoidMethod(env, sslStream->sslEngine, g_SSLEngineBeginHandshake);
551+
if (CheckJNIExceptions(env))
552+
return SSLStreamStatus_Error;
553+
}
530554

531555
return DoHandshake(env, sslStream);
532556
}
@@ -705,14 +729,16 @@ int32_t AndroidCryptoNative_SSLStreamGetCipherSuite(SSLStream* sslStream, uint16
705729
*out = NULL;
706730

707731
// String cipherSuite = sslSession.getCipherSuite();
708-
jstring cipherSuite = (*env)->CallObjectMethod(env, sslStream->sslSession, g_SSLSessionGetCipherSuite);
732+
jobject sslSession = GetCurrentSslSession(env, sslStream);
733+
jstring cipherSuite = (*env)->CallObjectMethod(env, sslSession, g_SSLSessionGetCipherSuite);
709734
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
710735
*out = AllocateString(env, cipherSuite);
711736

712737
ret = SUCCESS;
713738

714739
cleanup:
715-
(*env)->DeleteLocalRef(env, cipherSuite);
740+
ReleaseLRef(env, sslSession);
741+
ReleaseLRef(env, cipherSuite);
716742
return ret;
717743
}
718744

@@ -726,14 +752,16 @@ int32_t AndroidCryptoNative_SSLStreamGetProtocol(SSLStream* sslStream, uint16_t*
726752
*out = NULL;
727753

728754
// String protocol = sslSession.getProtocol();
729-
jstring protocol = (*env)->CallObjectMethod(env, sslStream->sslSession, g_SSLSessionGetProtocol);
755+
jobject sslSession = GetCurrentSslSession(env, sslStream);
756+
jstring protocol = (*env)->CallObjectMethod(env, sslSession, g_SSLSessionGetProtocol);
730757
ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
731758
*out = AllocateString(env, protocol);
732759

733760
ret = SUCCESS;
734761

735762
cleanup:
736-
(*env)->DeleteLocalRef(env, protocol);
763+
ReleaseLRef(env, sslSession);
764+
ReleaseLRef(env, protocol);
737765
return ret;
738766
}
739767

@@ -746,7 +774,8 @@ jobject /*X509Certificate*/ AndroidCryptoNative_SSLStreamGetPeerCertificate(SSLS
746774

747775
// Certificate[] certs = sslSession.getPeerCertificates();
748776
// out = certs[0];
749-
jobjectArray certs = (*env)->CallObjectMethod(env, sslStream->sslSession, g_SSLSessionGetPeerCertificates);
777+
jobject sslSession = GetCurrentSslSession(env, sslStream);
778+
jobjectArray certs = (*env)->CallObjectMethod(env, sslSession, g_SSLSessionGetPeerCertificates);
750779

751780
// If there are no peer certificates, getPeerCertificates will throw. Return null to indicate no certificate.
752781
if (TryClearJNIExceptions(env))
@@ -761,7 +790,8 @@ jobject /*X509Certificate*/ AndroidCryptoNative_SSLStreamGetPeerCertificate(SSLS
761790
}
762791

763792
cleanup:
764-
(*env)->DeleteLocalRef(env, certs);
793+
ReleaseLRef(env, sslSession);
794+
ReleaseLRef(env, certs);
765795
return ret;
766796
}
767797

@@ -779,7 +809,8 @@ void AndroidCryptoNative_SSLStreamGetPeerCertificates(SSLStream* sslStream, jobj
779809
// for (int i = 0; i < certs.length; i++) {
780810
// out[i] = certs[i];
781811
// }
782-
jobjectArray certs = (*env)->CallObjectMethod(env, sslStream->sslSession, g_SSLSessionGetPeerCertificates);
812+
jobject sslSession = GetCurrentSslSession(env, sslStream);
813+
jobjectArray certs = (*env)->CallObjectMethod(env, sslSession, g_SSLSessionGetPeerCertificates);
783814

784815
// If there are no peer certificates, getPeerCertificates will throw. Return null and length of zero to indicate no certificates.
785816
if (TryClearJNIExceptions(env))
@@ -798,7 +829,8 @@ void AndroidCryptoNative_SSLStreamGetPeerCertificates(SSLStream* sslStream, jobj
798829
}
799830

800831
cleanup:
801-
(*env)->DeleteLocalRef(env, certs);
832+
ReleaseLRef(env, sslSession);
833+
ReleaseLRef(env, certs);
802834
}
803835

804836
void AndroidCryptoNative_SSLStreamRequestClientAuthentication(SSLStream* sslStream)
@@ -912,14 +944,15 @@ bool AndroidCryptoNative_SSLStreamVerifyHostname(SSLStream* sslStream, char* hos
912944
JNIEnv* env = GetJNIEnv();
913945

914946
bool ret = false;
915-
INIT_LOCALS(loc, name, verifier);
947+
INIT_LOCALS(loc, name, verifier, sslSession);
916948

917949
// HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
918950
// return verifier.verify(hostname, sslSession);
919951
loc[name] = make_java_string(env, hostname);
952+
loc[sslSession] = GetCurrentSslSession(env, sslStream);
920953
loc[verifier] =
921954
(*env)->CallStaticObjectMethod(env, g_HttpsURLConnection, g_HttpsURLConnectionGetDefaultHostnameVerifier);
922-
ret = (*env)->CallBooleanMethod(env, loc[verifier], g_HostnameVerifierVerify, loc[name], sslStream->sslSession);
955+
ret = (*env)->CallBooleanMethod(env, loc[verifier], g_HostnameVerifierVerify, loc[name], loc[sslSession]);
923956

924957
RELEASE_LOCALS(loc, env);
925958
return ret;

0 commit comments

Comments
 (0)