merge in lmp-mr1-release history after reset to lmp-mr1-dev
diff --git a/src/main/native/org_conscrypt_NativeCrypto.cpp b/src/main/native/org_conscrypt_NativeCrypto.cpp
index af9cf3d..8797060 100644
--- a/src/main/native/org_conscrypt_NativeCrypto.cpp
+++ b/src/main/native/org_conscrypt_NativeCrypto.cpp
@@ -984,6 +984,16 @@
}
/**
+ * Safely clear SSL sessions and throw an error if there was something already
+ * in the error stack.
+ */
+static void safeSslClear(SSL* ssl) {
+ if (SSL_clear(ssl) != 1) {
+ freeOpenSslErrorState();
+ }
+}
+
+/**
* To avoid the round-trip to ASN.1 and back in X509_dup, we just up the reference count.
*/
static X509* X509_dup_nocopy(X509* x509) {
@@ -7312,7 +7322,7 @@
if (ret != 1L) {
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error enabling Channel ID");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id => error", ssl);
return;
}
@@ -7347,7 +7357,7 @@
} else if (ret != 64) {
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error getting Channel ID");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_get_tls_channel_id => error, returned %ld", ssl, ret);
return NULL;
}
@@ -7382,7 +7392,7 @@
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(
env, ssl, SSL_ERROR_NONE, "Error setting private key for Channel ID");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => error", ssl);
return;
}
@@ -7412,7 +7422,7 @@
if (ret != 1) {
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p SSL_use_PrivateKey => error", ssl);
return;
}
@@ -7474,7 +7484,7 @@
if (cert.get() == NULL || !sk_X509_push(chain.get(), cert.get())) {
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
return;
}
@@ -7485,7 +7495,7 @@
if (ret != 1) {
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
return;
}
@@ -7513,7 +7523,7 @@
int ret = SSL_check_private_key(ssl);
if (ret != 1) {
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
return;
}
@@ -7568,7 +7578,7 @@
if (principalX509Name.get() == NULL) {
ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
ssl);
return;
@@ -7700,7 +7710,7 @@
if (ret != 1) {
int sslErrorCode = SSL_get_error(ssl, ret);
throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Failed to set PSK identity hint");
- SSL_clear(ssl);
+ safeSslClear(ssl);
}
}
@@ -7882,7 +7892,7 @@
int sslErrorCode = SSL_get_error(ssl, ret);
if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
- SSL_clear(ssl);
+ safeSslClear(ssl);
}
}
}
@@ -7922,7 +7932,7 @@
int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
if (ret != 1) {
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
return;
}
@@ -8211,7 +8221,7 @@
AppData* appData = toAppData(ssl);
if (appData == NULL) {
throwSSLExceptionStr(env, "Unable to retrieve application data");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
return 0;
}
@@ -8224,8 +8234,8 @@
errno = 0;
if (!appData->setCallbackState(env, shc, NULL, npnProtocols, alpnProtocols)) {
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio setCallbackState => 0", ssl);
return 0;
}
@@ -8233,8 +8243,8 @@
appData->clearCallbackState();
// cert_verify_callback threw exception
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio exception => 0", ssl);
return 0;
}
@@ -8253,12 +8263,12 @@
if (sslError.get() == SSL_ERROR_NONE ||
(sslError.get() == SSL_ERROR_SYSCALL && errno == 0)) {
throwSSLHandshakeExceptionStr(env, "Connection closed by peer");
- SSL_clear(ssl);
+ safeSslClear(ssl);
} else if (sslError.get() != SSL_ERROR_WANT_READ &&
sslError.get() != SSL_ERROR_WANT_WRITE) {
throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
"SSL handshake terminated", throwSSLHandshakeExceptionStr);
- SSL_clear(ssl);
+ safeSslClear(ssl);
}
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio error => 0", ssl);
return 0;
@@ -8299,7 +8309,7 @@
NetFd fd(env, fdObject);
if (fd.isClosed()) {
// SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
return 0;
}
@@ -8310,7 +8320,7 @@
if (ret != 1) {
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
"Error setting the file descriptor");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
return 0;
}
@@ -8321,7 +8331,7 @@
*/
if (!setBlocking(fd.get(), false)) {
throwSSLExceptionStr(env, "Unable to make socket non blocking");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
return 0;
}
@@ -8329,7 +8339,7 @@
AppData* appData = toAppData(ssl);
if (appData == NULL) {
throwSSLExceptionStr(env, "Unable to retrieve application data");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
return 0;
}
@@ -8350,7 +8360,7 @@
if (!appData->setCallbackState(env, shc, fdObject, npnProtocols, alpnProtocols)) {
// SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
return 0;
}
@@ -8358,7 +8368,8 @@
appData->clearCallbackState();
// cert_verify_callback threw exception
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
+ freeOpenSslErrorState();
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
return 0;
}
@@ -8389,21 +8400,21 @@
if (selectResult == THROWN_EXCEPTION) {
// SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
return 0;
}
if (selectResult == -1) {
throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error",
throwSSLHandshakeExceptionStr);
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
return 0;
}
if (selectResult == 0) {
throwSocketTimeoutException(env, "SSL handshake timed out");
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
return 0;
}
@@ -8427,7 +8438,7 @@
throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
"SSL handshake terminated", throwSSLHandshakeExceptionStr);
}
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
return 0;
}
@@ -8440,7 +8451,7 @@
*/
throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "SSL handshake aborted",
throwSSLHandshakeExceptionStr);
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
return 0;
}
@@ -8609,7 +8620,7 @@
appData->clearCallbackState();
// callbacks can happen if server requests renegotiation
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
return THROWN_EXCEPTION;
}
@@ -8734,7 +8745,7 @@
AppData* appData = toAppData(ssl);
if (appData == NULL) {
throwSSLExceptionStr(env, "Unable to retrieve application data");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => appData == NULL", ssl);
return -1;
}
@@ -8748,7 +8759,7 @@
if (!appData->setCallbackState(env, shc, NULL, NULL, NULL)) {
MUTEX_UNLOCK(appData->mutex);
throwSSLExceptionStr(env, "Unable to set callback state");
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => set callback state failed", ssl);
return -1;
}
@@ -8759,7 +8770,7 @@
appData->clearCallbackState();
// callbacks can happen if server requests renegotiation
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => threw exception", ssl);
return THROWN_EXCEPTION;
}
@@ -8929,7 +8940,7 @@
appData->clearCallbackState();
// callbacks can happen if server requests renegotiation
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
return THROWN_EXCEPTION;
}
@@ -9050,7 +9061,7 @@
AppData* appData = toAppData(ssl);
if (appData == NULL) {
throwSSLExceptionStr(env, "Unable to retrieve application data");
- SSL_clear(ssl);
+ safeSslClear(ssl);
freeOpenSslErrorState();
JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO appData => NULL", ssl);
return -1;
@@ -9065,8 +9076,8 @@
if (!appData->setCallbackState(env, shc, NULL, NULL, NULL)) {
MUTEX_UNLOCK(appData->mutex);
throwSSLExceptionStr(env, "Unable to set appdata callback");
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => appData can't set callback", ssl);
return -1;
}
@@ -9084,8 +9095,8 @@
appData->clearCallbackState();
// callbacks can happen if server requests renegotiation
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO exception => exception pending (reneg)", ssl);
return -1;
}
@@ -9239,8 +9250,8 @@
if (appData != NULL) {
if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
// SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
return;
}
@@ -9257,7 +9268,7 @@
appData->clearCallbackState();
// callbacks can happen if server requests renegotiation
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
return;
}
@@ -9290,8 +9301,8 @@
}
}
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
}
/**
@@ -9321,8 +9332,8 @@
if (appData != NULL) {
if (!appData->setCallbackState(env, shc, NULL, NULL, NULL)) {
// SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
return;
}
@@ -9332,7 +9343,7 @@
appData->clearCallbackState();
// callbacks can happen if server requests renegotiation
if (env->ExceptionCheck()) {
- SSL_clear(ssl);
+ safeSslClear(ssl);
JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
return;
}
@@ -9365,8 +9376,8 @@
}
}
- SSL_clear(ssl);
freeOpenSslErrorState();
+ safeSslClear(ssl);
}
static jint NativeCrypto_SSL_get_shutdown(JNIEnv* env, jclass, jlong ssl_address) {