Skip to content

Commit

Permalink
Add more details to SSLHandshakeException (java-native-access#183)
Browse files Browse the repository at this point in the history
Motivation:

At the moment we dont provide a lot of details in the SSLHandshakeException which makes it hard to understand why a handshake fails.

Modifications:

- Add native method which will peek into the error queue and provide more details if possible
- Use these details when constructing the exception message

Result:

Easier to debug SSLHandshakeException causes
  • Loading branch information
normanmaurer authored Feb 12, 2021
1 parent b8808d5 commit 9488b03
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
16 changes: 15 additions & 1 deletion src/main/c/netty_quic_boringssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#define STATICALLY_CLASSNAME "io/netty/incubator/codec/quic/BoringSSLNativeStaticallyReferencedJniMethods"
#define CLASSNAME "io/netty/incubator/codec/quic/BoringSSL"

#define ERR_LEN 256

static jclass verifyCallbackClass = NULL;
static jmethodID verifyCallbackMethod = NULL;

Expand Down Expand Up @@ -699,6 +701,17 @@ void netty_boringssl_CRYPTO_BUFFER_stack_free(JNIEnv* env, jclass clazz, jlong c
sk_CRYPTO_BUFFER_pop_free((STACK_OF(CRYPTO_BUFFER) *) chain, CRYPTO_BUFFER_free);
}

jstring netty_boringssl_ERR_last_error(JNIEnv* env, jclass clazz) {
char buf[ERR_LEN];
unsigned long err = ERR_get_error();
if (err == 0) {
return NULL;
}
ERR_error_string_n(err, buf, ERR_LEN);
return (*env)->NewStringUTF(env, buf);
}


// JNI Registered Methods End

// JNI Method Registration Table Begin
Expand All @@ -724,7 +737,8 @@ static const JNINativeMethod fixed_method_table[] = {
{ "EVP_PKEY_parse", "([BLjava/lang/String;)J", (void *) netty_boringssl_EVP_PKEY_parse },
{ "EVP_PKEY_free", "(J)V", (void *) netty_boringssl_EVP_PKEY_free },
{ "CRYPTO_BUFFER_stack_new", "(J[[B)J", (void *) netty_boringssl_CRYPTO_BUFFER_stack_new },
{ "CRYPTO_BUFFER_stack_free", "(J)V", (void *) netty_boringssl_CRYPTO_BUFFER_stack_free }
{ "CRYPTO_BUFFER_stack_free", "(J)V", (void *) netty_boringssl_CRYPTO_BUFFER_stack_free },
{ "ERR_last_error", "()Ljava/lang/String;", (void *) netty_boringssl_ERR_last_error }
};

static const jint fixed_method_table_size = sizeof(fixed_method_table) / sizeof(fixed_method_table[0]);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/io/netty/incubator/codec/quic/BoringSSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ static long SSL_new(long context, boolean server, String hostname) {
static native long CRYPTO_BUFFER_stack_new(long ssl, byte[][] bytes);
static native void CRYPTO_BUFFER_stack_free(long chain);

static native String ERR_last_error();

private static String tlsExtHostName(String hostname) {
if (hostname != null && hostname.endsWith(".")) {
// Strip trailing dot if included.
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/io/netty/incubator/codec/quic/Quiche.java
Original file line number Diff line number Diff line change
Expand Up @@ -526,15 +526,18 @@ static ByteBuf allocateNativeOrder(int capacity) {
return PlatformDependent.BIG_ENDIAN_NATIVE_ORDER ? buffer : buffer.order(ByteOrder.LITTLE_ENDIAN);
}

static String errorAsString(int err) {
return QuicError.valueOf(err).message();
}

static Exception newException(int err) {
final QuicError error = QuicError.valueOf(err);
final QuicException reason = new QuicException(error);
if (err == QUICHE_ERR_TLS_FAIL) {
final SSLHandshakeException sslExc = new SSLHandshakeException(error.message());
String lastSslError = BoringSSL.ERR_last_error();
final String message;
if (lastSslError != null) {
message = error.message() + ": " + lastSslError;
} else {
message = error.message();
}
final SSLHandshakeException sslExc = new SSLHandshakeException(message);
sslExc.initCause(reason);
return sslExc;
}
Expand Down

0 comments on commit 9488b03

Please sign in to comment.