From 0f352ecb0848ff549cf6bc255d102e1077bb1eaa Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Wed, 28 Aug 2024 11:09:18 -0500 Subject: [PATCH] Update SSLFDProxy to implement SSLSocketListener Previously SSLFDProxy.c was accessing the fields in SSLFDProxy class directly using JNI to update handshakeComplete and add SSL alert events into inboundAlerts and outboundAlerts. To make it easier to investigate SSL alert issues, SSLFDProxy has been updated to implement SSLSocketListener then SSLFDProxy.c will call SSLSocketListener methods to perform the above operations. --- .../java/org/mozilla/jss/nss/SSLFDProxy.java | 19 ++- .../jss/ssl/SSLHandshakeCompletedEvent.java | 9 +- .../native/org/mozilla/jss/nss/SSLFDProxy.c | 145 ++++++++++++------ .../native/org/mozilla/jss/nss/SSLFDProxy.h | 6 +- .../native/org/mozilla/jss/util/java_ids.h | 5 + 5 files changed, 125 insertions(+), 59 deletions(-) diff --git a/base/src/main/java/org/mozilla/jss/nss/SSLFDProxy.java b/base/src/main/java/org/mozilla/jss/nss/SSLFDProxy.java index 7cbbe2dd1..5c7fa0bb3 100644 --- a/base/src/main/java/org/mozilla/jss/nss/SSLFDProxy.java +++ b/base/src/main/java/org/mozilla/jss/nss/SSLFDProxy.java @@ -5,9 +5,11 @@ import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.pkcs11.PK11Cert; import org.mozilla.jss.ssl.SSLAlertEvent; +import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; +import org.mozilla.jss.ssl.SSLSocketListener; import org.mozilla.jss.util.GlobalRefProxy; -public class SSLFDProxy extends PRFDProxy { +public class SSLFDProxy extends PRFDProxy implements SSLSocketListener { public PK11Cert clientCert; public GlobalRefProxy globalRef; @@ -60,4 +62,19 @@ public int invokeCertAuthHandler() { public int invokeBadCertHandler(int error) { return badCertHandler.check(this, error); } + + @Override + public void handshakeCompleted(SSLHandshakeCompletedEvent event) { + handshakeComplete = true; + } + + @Override + public void alertReceived(SSLAlertEvent event) { + inboundAlerts.add(event); + } + + @Override + public void alertSent(SSLAlertEvent event) { + outboundAlerts.add(event); + } } diff --git a/base/src/main/java/org/mozilla/jss/ssl/SSLHandshakeCompletedEvent.java b/base/src/main/java/org/mozilla/jss/ssl/SSLHandshakeCompletedEvent.java index 00a698be2..f6332e3ed 100644 --- a/base/src/main/java/org/mozilla/jss/ssl/SSLHandshakeCompletedEvent.java +++ b/base/src/main/java/org/mozilla/jss/ssl/SSLHandshakeCompletedEvent.java @@ -9,9 +9,10 @@ package org.mozilla.jss.ssl; -import java.net.*; -import java.util.*; +import java.net.SocketException; +import java.util.EventObject; +import org.mozilla.jss.nss.SSLFDProxy; import org.mozilla.jss.ssl.javax.JSSEngine; /* @@ -30,6 +31,10 @@ public SSLHandshakeCompletedEvent(SSLSocket socket) { super(socket); } + public SSLHandshakeCompletedEvent(SSLFDProxy proxy) { + super(proxy); + } + public SSLHandshakeCompletedEvent(JSSEngine engine) { super(engine); } diff --git a/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.c b/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.c index a7ef33541..925659628 100644 --- a/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.c +++ b/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.c @@ -75,18 +75,6 @@ JSS_NSS_getEventArrayList(JNIEnv *env, jobject sslfd_proxy, const char *which, j return PR_SUCCESS; } -PRStatus -JSS_NSS_getSSLAlertReceivedList(JNIEnv *env, jobject sslfd_proxy, jobject *list) -{ - return JSS_NSS_getEventArrayList(env, sslfd_proxy, "inboundAlerts", list); -} - -PRStatus -JSS_NSS_getSSLAlertSentList(JNIEnv *env, jobject sslfd_proxy, jobject *list) -{ - return JSS_NSS_getEventArrayList(env, sslfd_proxy, "outboundAlerts", list); -} - PRStatus JSS_NSS_getGlobalRef(JNIEnv *env, jobject sslfd_proxy, jobject *global_ref) { @@ -104,53 +92,31 @@ JSS_NSS_getGlobalRef(JNIEnv *env, jobject sslfd_proxy, jobject *global_ref) return PR_SUCCESS; } -PRStatus -JSS_NSS_addSSLAlert(JNIEnv *env, jobject sslfd_proxy, jobject list, - const SSLAlert *alert) +jobject +JSS_NSS_createSSLAlert(JNIEnv *env, jobject sslfd_proxy, const SSLAlert *alert) { jclass eventClass; jmethodID eventConstructor; jobject event; - jclass eventListClass; - jmethodID arrayListAdd; - - PR_ASSERT(env != NULL && sslfd_proxy != NULL && list != NULL && alert != NULL); + PR_ASSERT(env != NULL && sslfd_proxy != NULL && alert != NULL); /* Build the new alert event object (org.mozilla.jss.ssl.SSLAlertEvent). */ eventClass = (*env)->FindClass(env, SSL_ALERT_EVENT_CLASS); if (eventClass == NULL) { - return PR_FAILURE; + return NULL; } eventConstructor = (*env)->GetMethodID(env, eventClass, "", "(L" SSLFD_PROXY_CLASS_NAME ";II)V"); if (eventConstructor == NULL) { - return PR_FAILURE; + return NULL; } event = (*env)->NewObject(env, eventClass, eventConstructor, sslfd_proxy, (int)alert->level, (int)alert->description); - if (event == NULL) { - return PR_FAILURE; - } - - /* Add it to the event list. */ - eventListClass = (*env)->GetObjectClass(env, list); - if (eventListClass == NULL) { - return PR_FAILURE; - } - - arrayListAdd = (*env)->GetMethodID(env, eventListClass, "add", - "(Ljava/lang/Object;)Z"); - if (arrayListAdd == NULL) { - return PR_FAILURE; - } - - // We ignore the return code: ArrayList.add() always returns true. - (void)(*env)->CallBooleanMethod(env, list, arrayListAdd, event); - return PR_SUCCESS; + return event; } void @@ -158,7 +124,9 @@ JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert { JNIEnv *env; jobject sslfd_proxy = (jobject)arg; - jobject list; + jclass sslfdProxyClass; + jmethodID alertReceivedMethod; + jobject event; if (fd == NULL || arg == NULL || alert == NULL || JSS_javaVM == NULL) { return; @@ -168,13 +136,31 @@ JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert return; } - if (JSS_NSS_getSSLAlertReceivedList(env, sslfd_proxy, &list) != PR_SUCCESS) { + sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); + + if (sslfdProxyClass == NULL) { + return; + } + + alertReceivedMethod = (*env)->GetMethodID( + env, + sslfdProxyClass, + "alertReceived", + "(L" SSL_ALERT_EVENT_CLASS ";)V"); + + if (alertReceivedMethod == NULL) { return; } - if (JSS_NSS_addSSLAlert(env, sslfd_proxy, list, alert) != PR_SUCCESS) { + // event = new SSLAlertEvent() + event = JSS_NSS_createSSLAlert(env, sslfd_proxy, alert); + + if (event == NULL) { return; } + + // sslfd_proxy.alertReceived(event) + (void)(*env)->CallVoidMethod(env, sslfd_proxy, alertReceivedMethod, event); } void @@ -182,7 +168,9 @@ JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *ale { JNIEnv *env; jobject sslfd_proxy = (jobject)arg; - jobject list; + jclass sslfdProxyClass; + jmethodID alertSentMethod; + jobject event; if (fd == NULL || arg == NULL || alert == NULL || JSS_javaVM == NULL) { return; @@ -192,13 +180,31 @@ JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *ale return; } - if (JSS_NSS_getSSLAlertSentList(env, sslfd_proxy, &list) != PR_SUCCESS) { + sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); + + if (sslfdProxyClass == NULL) { return; } - if (JSS_NSS_addSSLAlert(env, sslfd_proxy, list, alert) != PR_SUCCESS) { + alertSentMethod = (*env)->GetMethodID( + env, + sslfdProxyClass, + "alertSent", + "(L" SSL_ALERT_EVENT_CLASS ";)V"); + + if (alertSentMethod == NULL) { return; } + + // event = new SSLAlertEvent() + event = JSS_NSS_createSSLAlert(env, sslfd_proxy, alert); + + if (event == NULL) { + return; + } + + // sslfd_proxy.alertSent(event) + (void)(*env)->CallVoidMethod(env, sslfd_proxy, alertSentMethod, event); } SECStatus @@ -248,7 +254,11 @@ JSSL_SSLFDHandshakeComplete(PRFileDesc *fd, void *client_data) JNIEnv *env = NULL; jobject sslfd_proxy = (jobject)client_data; jclass sslfdProxyClass; - jfieldID handshakeCompleteField; + jmethodID handshakeCompletedMethod; + + jclass eventClass; + jmethodID eventConstructor; + jobject event; if (fd == NULL || client_data == NULL || JSS_javaVM == NULL) { return; @@ -259,17 +269,50 @@ JSSL_SSLFDHandshakeComplete(PRFileDesc *fd, void *client_data) } sslfdProxyClass = (*env)->GetObjectClass(env, sslfd_proxy); + if (sslfdProxyClass == NULL) { return; } - handshakeCompleteField = (*env)->GetFieldID(env, sslfdProxyClass, - "handshakeComplete", "Z"); - if (handshakeCompleteField == NULL) { + handshakeCompletedMethod = (*env)->GetMethodID( + env, + sslfdProxyClass, + "handshakeCompleted", + "(L" SSL_HANDSHAKE_COMPLETED_EVENT_CLASS ";)V"); + + if (handshakeCompletedMethod == NULL) { + return; + } + + eventClass = (*env)->FindClass(env, SSL_HANDSHAKE_COMPLETED_EVENT_CLASS); + + if (eventClass == NULL) { + return; + } + + eventConstructor = (*env)->GetMethodID( + env, + eventClass, + "", + "(L" SSLFD_PROXY_CLASS_NAME ";)V"); + + if (eventConstructor == NULL) { + return; + } + + // event = new SSLHandshakeCompletedEvent() + event = (*env)->NewObject( + env, + eventClass, + eventConstructor, + sslfd_proxy); + + if (event == NULL) { return; } - (*env)->SetBooleanField(env, sslfd_proxy, handshakeCompleteField, JNI_TRUE); + // sslfd_proxy.handshakeCompleted(event) + (void)(*env)->CallVoidMethod(env, sslfd_proxy, handshakeCompletedMethod, event); } SECStatus diff --git a/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.h b/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.h index 2185e802e..7563dc96f 100644 --- a/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.h +++ b/native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.h @@ -6,11 +6,7 @@ PRStatus JSS_NSS_getSSLClientCert(JNIEnv *env, jobject sslfd_proxy, CERTCertificate **cert); -PRStatus JSS_NSS_getSSLAlertSentList(JNIEnv *env, jobject sslfd_proxy, jobject *list); - -PRStatus JSS_NSS_getSSLAlertReceivedList(JNIEnv *env, jobject sslfd_proxy, jobject *list); - -PRStatus JSS_NSS_addSSLAlert(JNIEnv *env, jobject sslfd_proxy, jobject list, const SSLAlert *alert); +jobject JSS_NSS_createSSLAlert(JNIEnv *env, jobject sslfd_proxy, const SSLAlert *alert); PRStatus JSS_NSS_getGlobalRef(JNIEnv *env, jobject sslfd_proxy, jobject *global_ref); diff --git a/native/src/main/native/org/mozilla/jss/util/java_ids.h b/native/src/main/native/org/mozilla/jss/util/java_ids.h index 01b165999..9b47ad273 100644 --- a/native/src/main/native/org/mozilla/jss/util/java_ids.h +++ b/native/src/main/native/org/mozilla/jss/util/java_ids.h @@ -285,6 +285,11 @@ PR_BEGIN_EXTERN_C */ #define SSL_ALERT_EVENT_CLASS "org/mozilla/jss/ssl/SSLAlertEvent" +/* + * SSLHandshakeCompletedEvent + */ +#define SSL_HANDSHAKE_COMPLETED_EVENT_CLASS "org/mozilla/jss/ssl/SSLHandshakeCompletedEvent" + /* * SSLCertificateApprovalCallback */