@@ -40,6 +40,27 @@ static bool IsHandshaking(int handshakeStatus)
40
40
return handshakeStatus != HANDSHAKE_STATUS__NOT_HANDSHAKING && handshakeStatus != HANDSHAKE_STATUS__FINISHED ;
41
41
}
42
42
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
+
43
64
ARGS_NON_NULL_ALL static PAL_SSLStreamStatus Close (JNIEnv * env , SSLStream * sslStream )
44
65
{
45
66
// Call wrap to clear any remaining data before closing
@@ -523,10 +544,13 @@ PAL_SSLStreamStatus AndroidCryptoNative_SSLStreamHandshake(SSLStream* sslStream)
523
544
abort_if_invalid_pointer_argument (sslStream );
524
545
JNIEnv * env = GetJNIEnv ();
525
546
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
+ }
530
554
531
555
return DoHandshake (env , sslStream );
532
556
}
@@ -705,14 +729,16 @@ int32_t AndroidCryptoNative_SSLStreamGetCipherSuite(SSLStream* sslStream, uint16
705
729
* out = NULL ;
706
730
707
731
// 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 );
709
734
ON_EXCEPTION_PRINT_AND_GOTO (cleanup );
710
735
* out = AllocateString (env , cipherSuite );
711
736
712
737
ret = SUCCESS ;
713
738
714
739
cleanup :
715
- (* env )-> DeleteLocalRef (env , cipherSuite );
740
+ ReleaseLRef (env , sslSession );
741
+ ReleaseLRef (env , cipherSuite );
716
742
return ret ;
717
743
}
718
744
@@ -726,14 +752,16 @@ int32_t AndroidCryptoNative_SSLStreamGetProtocol(SSLStream* sslStream, uint16_t*
726
752
* out = NULL ;
727
753
728
754
// 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 );
730
757
ON_EXCEPTION_PRINT_AND_GOTO (cleanup );
731
758
* out = AllocateString (env , protocol );
732
759
733
760
ret = SUCCESS ;
734
761
735
762
cleanup :
736
- (* env )-> DeleteLocalRef (env , protocol );
763
+ ReleaseLRef (env , sslSession );
764
+ ReleaseLRef (env , protocol );
737
765
return ret ;
738
766
}
739
767
@@ -746,7 +774,8 @@ jobject /*X509Certificate*/ AndroidCryptoNative_SSLStreamGetPeerCertificate(SSLS
746
774
747
775
// Certificate[] certs = sslSession.getPeerCertificates();
748
776
// 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 );
750
779
751
780
// If there are no peer certificates, getPeerCertificates will throw. Return null to indicate no certificate.
752
781
if (TryClearJNIExceptions (env ))
@@ -761,7 +790,8 @@ jobject /*X509Certificate*/ AndroidCryptoNative_SSLStreamGetPeerCertificate(SSLS
761
790
}
762
791
763
792
cleanup :
764
- (* env )-> DeleteLocalRef (env , certs );
793
+ ReleaseLRef (env , sslSession );
794
+ ReleaseLRef (env , certs );
765
795
return ret ;
766
796
}
767
797
@@ -779,7 +809,8 @@ void AndroidCryptoNative_SSLStreamGetPeerCertificates(SSLStream* sslStream, jobj
779
809
// for (int i = 0; i < certs.length; i++) {
780
810
// out[i] = certs[i];
781
811
// }
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 );
783
814
784
815
// If there are no peer certificates, getPeerCertificates will throw. Return null and length of zero to indicate no certificates.
785
816
if (TryClearJNIExceptions (env ))
@@ -798,7 +829,8 @@ void AndroidCryptoNative_SSLStreamGetPeerCertificates(SSLStream* sslStream, jobj
798
829
}
799
830
800
831
cleanup :
801
- (* env )-> DeleteLocalRef (env , certs );
832
+ ReleaseLRef (env , sslSession );
833
+ ReleaseLRef (env , certs );
802
834
}
803
835
804
836
void AndroidCryptoNative_SSLStreamRequestClientAuthentication (SSLStream * sslStream )
@@ -912,14 +944,15 @@ bool AndroidCryptoNative_SSLStreamVerifyHostname(SSLStream* sslStream, char* hos
912
944
JNIEnv * env = GetJNIEnv ();
913
945
914
946
bool ret = false;
915
- INIT_LOCALS (loc , name , verifier );
947
+ INIT_LOCALS (loc , name , verifier , sslSession );
916
948
917
949
// HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
918
950
// return verifier.verify(hostname, sslSession);
919
951
loc [name ] = make_java_string (env , hostname );
952
+ loc [sslSession ] = GetCurrentSslSession (env , sslStream );
920
953
loc [verifier ] =
921
954
(* 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 ] );
923
956
924
957
RELEASE_LOCALS (loc , env );
925
958
return ret ;
0 commit comments