Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround for SSL events in JSSEngine #1022

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
34 changes: 34 additions & 0 deletions base/src/main/java/org/mozilla/jss/nss/SSLFDProxy.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
package org.mozilla.jss.nss;

import java.util.ArrayList;
import java.util.List;

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 PK11Cert clientCert;
public GlobalRefProxy globalRef;

// inboundAlerts and outboundAlerts do not seem to be working properly
// TODO: investigate the problem
public ArrayList<SSLAlertEvent> inboundAlerts;
public int inboundOffset;

public ArrayList<SSLAlertEvent> outboundAlerts;
public int outboundOffset;

// temporary workaround for inboundAlerts and outboundAlerts
public List<SSLSocketListener> socketListeners = new ArrayList<>();

public boolean needCertValidation;
public boolean needBadCertValidation;
public int badCertError;
Expand Down Expand Up @@ -53,11 +61,37 @@ protected synchronized void releaseNativeResources() throws Exception {
}
}

public void addSocketListener(SSLSocketListener socketListener) {
socketListeners.add(socketListener);
}

public void removeSocketListener(SSLSocketListener socketListener) {
socketListeners.remove(socketListener);
}

public int invokeCertAuthHandler() {
return certAuthHandler.check(this);
}

public int invokeBadCertHandler(int error) {
return badCertHandler.check(this, error);
}

public void fireHandshakeCompleted(SSLHandshakeCompletedEvent event) {
for (SSLSocketListener socketListener : socketListeners) {
socketListener.handshakeCompleted(event);
}
}

public void fireAlertReceived(SSLAlertEvent event) {
for (SSLSocketListener socketListener : socketListeners) {
socketListener.alertReceived(event);
}
}

public void fireAlertSent(SSLAlertEvent event) {
for (SSLSocketListener socketListener : socketListeners) {
socketListener.alertSent(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
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.mozilla.jss.ssl.SSLAlertLevel;
import org.mozilla.jss.ssl.SSLCipher;
import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent;
import org.mozilla.jss.ssl.SSLSocketListener;
import org.mozilla.jss.ssl.SSLVersion;
import org.mozilla.jss.ssl.SSLVersionRange;

Expand Down Expand Up @@ -285,6 +286,8 @@ private void init() throws SSLException {
// certificate.
applyTrustManagers();

configureSocketListener();

// Finally, set up any debug logging necessary.
createLoggingSocket();
}
Expand Down Expand Up @@ -534,6 +537,27 @@ private void applyHosts() throws SSLException {
}
}

private void configureSocketListener() {

// register a listener in SSLFDProxy
ssl_fd.addSocketListener(new SSLSocketListener() {
@Override
public void handshakeCompleted(SSLHandshakeCompletedEvent event) {
fireHandshakeComplete(event);
}

@Override
public void alertReceived(SSLAlertEvent event) {
fireAlertReceived(event);
}

@Override
public void alertSent(SSLAlertEvent event) {
fireAlertSent(event);
}
});
}

private void applyTrustManagers() throws SSLException {
debug("JSSEngine: applyTrustManagers()");

Expand Down
121 changes: 107 additions & 14 deletions native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,37 +104,40 @@ 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;
}
return event;
}

PRStatus
JSS_NSS_addSSLAlert(JNIEnv *env, jobject list, jobject event)
{
jclass eventListClass;
jmethodID arrayListAdd;

PR_ASSERT(env != NULL && list != NULL && event != NULL);

/* Add it to the event list. */
eventListClass = (*env)->GetObjectClass(env, list);
Expand All @@ -160,6 +163,11 @@ JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert
jobject sslfd_proxy = (jobject)arg;
jobject list;

jobject event;

jclass proxyClass;
jmethodID proxyFireAlertReceivedMethod;

if (fd == NULL || arg == NULL || alert == NULL || JSS_javaVM == NULL) {
return;
}
Expand All @@ -172,9 +180,32 @@ JSSL_SSLFDAlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert
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.inboundAlerts.add(event)
if (JSS_NSS_addSSLAlert(env, list, event) != PR_SUCCESS) {
return;
}

proxyClass = (*env)->GetObjectClass(env, sslfd_proxy);
if (proxyClass == NULL) {
return;
}

proxyFireAlertReceivedMethod = (*env)->GetMethodID(
env, proxyClass, "fireAlertReceived",
"(L" SSL_ALERT_EVENT_CLASS ";)V");
if (proxyFireAlertReceivedMethod == NULL) {
return;
}

// sslfd_proxy.fireAlertReceived(event)
(void)(*env)->CallVoidMethod(env, sslfd_proxy, proxyFireAlertReceivedMethod, event);
}

void
Expand All @@ -184,6 +215,11 @@ JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *ale
jobject sslfd_proxy = (jobject)arg;
jobject list;

jobject event;

jclass proxyClass;
jmethodID proxyFireAlertSentMethod;

if (fd == NULL || arg == NULL || alert == NULL || JSS_javaVM == NULL) {
return;
}
Expand All @@ -196,9 +232,32 @@ JSSL_SSLFDAlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *ale
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.outboundAlerts.add(event)
if (JSS_NSS_addSSLAlert(env, list, event) != PR_SUCCESS) {
return;
}

proxyClass = (*env)->GetObjectClass(env, sslfd_proxy);
if (proxyClass == NULL) {
return;
}

proxyFireAlertSentMethod = (*env)->GetMethodID(
env, proxyClass, "fireAlertSent",
"(L" SSL_ALERT_EVENT_CLASS ";)V");
if (proxyFireAlertSentMethod == NULL) {
return;
}

// sslfd_proxy.fireAlertSent(event)
(void)(*env)->CallVoidMethod(env, sslfd_proxy, proxyFireAlertSentMethod, event);
}

SECStatus
Expand Down Expand Up @@ -250,6 +309,12 @@ JSSL_SSLFDHandshakeComplete(PRFileDesc *fd, void *client_data)
jclass sslfdProxyClass;
jfieldID handshakeCompleteField;

jclass eventClass;
jmethodID eventConstructor;
jobject event;

jmethodID proxyFireHandshakeCompletedMethod;

if (fd == NULL || client_data == NULL || JSS_javaVM == NULL) {
return;
}
Expand All @@ -270,6 +335,34 @@ JSSL_SSLFDHandshakeComplete(PRFileDesc *fd, void *client_data)
}

(*env)->SetBooleanField(env, sslfd_proxy, handshakeCompleteField, JNI_TRUE);

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;
}

proxyFireHandshakeCompletedMethod = (*env)->GetMethodID(
env, sslfdProxyClass, "fireHandshakeCompleted",
"(L" SSL_HANDSHAKE_COMPLETED_EVENT_CLASS ";)V");
if (proxyFireHandshakeCompletedMethod == NULL) {
return;
}

// sslfd_proxy.fireHandshakeCompleted(event)
(void)(*env)->CallVoidMethod(env, sslfd_proxy, proxyFireHandshakeCompletedMethod, event);
}

SECStatus
Expand Down
3 changes: 2 additions & 1 deletion native/src/main/native/org/mozilla/jss/nss/SSLFDProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ PRStatus JSS_NSS_getSSLAlertSentList(JNIEnv *env, jobject sslfd_proxy, jobject *

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_addSSLAlert(JNIEnv *env, jobject list, jobject event);

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
Loading