Skip to content

Commit

Permalink
Update SSLFDProxy to implement SSLSocketListener
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
edewata committed Aug 28, 2024
1 parent 9e39f0c commit 0f352ec
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 59 deletions.
19 changes: 18 additions & 1 deletion base/src/main/java/org/mozilla/jss/nss/SSLFDProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand All @@ -30,6 +31,10 @@ public SSLHandshakeCompletedEvent(SSLSocket socket) {
super(socket);
}

public SSLHandshakeCompletedEvent(SSLFDProxy proxy) {
super(proxy);
}

public SSLHandshakeCompletedEvent(JSSEngine engine) {
super(engine);
}
Expand Down
145 changes: 94 additions & 51 deletions native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -104,61 +92,41 @@ 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, "<init>",
"(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
JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert)
{
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;
Expand All @@ -168,21 +136,41 @@ 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
JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert)
{
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;
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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,
"<init>",
"(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
Expand Down
6 changes: 1 addition & 5 deletions native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 5 additions & 0 deletions native/src/main/native/org/mozilla/jss/util/java_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit 0f352ec

Please sign in to comment.