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,7 @@ jmethodID g_SSLParametersSetServerNames;
// com/android/org/conscrypt/OpenSSLEngineImpl
jclass g_ConscryptOpenSSLEngineImplClass;
jfieldID g_ConscryptOpenSSLEngineImplSslParametersField;
jfieldID g_ConscryptOpenSSLEngineImplHandshakeSessionField;

// com/android/org/conscrypt/SSLParametersImpl
jclass g_ConscryptSSLParametersImplClass;
Expand Down Expand Up @@ -627,6 +628,17 @@ jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, co
return fid;
}

jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig)
{
jfieldID fid = isStatic ? (*env)->GetStaticFieldID(env, klass, name, sig) : (*env)->GetFieldID(env, klass, name, sig);
if (!fid) {
LOG_INFO("optional field %s %s was not found", name, sig);
// Failing to find an optional field causes an exception state, which we need to clear.
TryClearJNIExceptions(env);
}
return fid;
}

static void DetachThreadFromJNI(void* unused)
{
LOG_DEBUG("Detaching thread from JNI");
Expand Down Expand Up @@ -761,6 +773,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved)
if (g_ConscryptOpenSSLEngineImplClass != NULL)
{
g_ConscryptOpenSSLEngineImplSslParametersField = GetField(env, false, g_ConscryptOpenSSLEngineImplClass, "sslParameters", "Lcom/android/org/conscrypt/SSLParametersImpl;");
g_ConscryptOpenSSLEngineImplHandshakeSessionField = GetOptionalField(env, false, g_ConscryptOpenSSLEngineImplClass, "handshakeSession", "Lcom/android/org/conscrypt/OpenSSLSessionImpl;");

g_ConscryptSSLParametersImplClass = GetClassGRef(env, "com/android/org/conscrypt/SSLParametersImpl");
g_ConscryptSSLParametersImplSetUseSni = GetMethod(env, false, g_ConscryptSSLParametersImplClass, "setUseSni", "(Z)V");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ extern jmethodID g_SSLParametersSetServerNames;
// com/android/org/conscrypt/OpenSSLEngineImpl
extern jclass g_ConscryptOpenSSLEngineImplClass;
extern jfieldID g_ConscryptOpenSSLEngineImplSslParametersField;
extern jfieldID g_ConscryptOpenSSLEngineImplHandshakeSessionField;

// com/android/org/conscrypt/SSLParametersImpl
extern jclass g_ConscryptSSLParametersImplClass;
Expand Down Expand Up @@ -590,6 +591,7 @@ bool TryGetJNIException(JNIEnv* env, jthrowable *ex, bool printException) ARGS_N
jmethodID GetMethod(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL;
jmethodID GetOptionalMethod(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL;
jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL;
jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL;
JNIEnv* GetJNIEnv(void);

int GetEnumAsInt(JNIEnv *env, jobject enumObj) ARGS_NON_NULL_ALL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,38 @@ static bool IsHandshaking(int handshakeStatus)
ARGS_NON_NULL(1, 2) static jobject GetSslSession(JNIEnv* env, SSLStream* sslStream, int handshakeStatus)
{
// During the initial handshake our sslStream->sslSession doesn't have access to the peer certificates
// which we need for hostname verification. Luckily, the SSLEngine has a getter for the handshake SSLSession.
// which we need for hostname verification. There are different ways to access the handshake session
// in different Android API levels.
// SSLEngine.getHandshakeSession() is available since API 24.
// In older Android versions (API 21-23) we need to access the handshake session by accessing
// a private field instead.

jobject sslSession = IsHandshaking(handshakeStatus) && g_SSLEngineGetHandshakeSession != NULL
? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession)
: (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
if (CheckJNIExceptions(env))
return NULL;
if (g_SSLEngineGetHandshakeSession != NULL)
{
jobject sslSession = IsHandshaking(handshakeStatus)
? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession)
: (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
if (CheckJNIExceptions(env))
return NULL;

return sslSession;
return sslSession;
}
else if (g_ConscryptOpenSSLEngineImplHandshakeSessionField != NULL)
{
jobject sslSession = IsHandshaking(handshakeStatus)
? (*env)->GetObjectField(env, sslStream->sslEngine, g_ConscryptOpenSSLEngineImplHandshakeSessionField)
: (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
if (CheckJNIExceptions(env))
return NULL;

return sslSession;
}
else
{
LOG_ERROR("Unable to get the current SSLSession from SSLEngine.");
assert(false && "Unable to get the current SSLSession from SSLEngine.");
return NULL;
}
}

ARGS_NON_NULL_ALL static jobject GetCurrentSslSession(JNIEnv* env, SSLStream* sslStream)
Expand Down