JSSE: enable native wolfSSL debug logs at SSLContext and WolfSSLProvider levels, register Java logging callback to push native logs over System.out.println and include thread ID

pull/166/head
Chris Conlon 2024-01-15 16:45:14 -07:00
parent 37692e7855
commit 47d36cb0cc
7 changed files with 138 additions and 13 deletions

View File

@ -800,19 +800,24 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_setLoggingCb
ret = wolfSSL_SetLoggingCb(NativeLoggingCallback);
}
else {
/* reset back to null */
ret = wolfSSL_SetLoggingCb(NULL);
}
return ret;
}
void NativeLoggingCallback(const int logLevel, const char *const logMessage)
{
JNIEnv* jenv;
JNIEnv* jenv = NULL;
jint vmret = 0;
jclass excClass;
jclass logClass;
jmethodID logMethod;
jstring logMsg;
int needsDetach = 0; /* Should we explicitly detach? */
jobjectRefType refcheck;
jstring logMsg;
/* get JNIEnv from JavaVM */
vmret = (int)((*g_vm)->GetEnv(g_vm, (void**) &jenv, JNI_VERSION_1_6));
@ -822,11 +827,16 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
#else
vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL);
#endif
if (vmret) {
printf("Failed to attach JNIEnv to thread\n");
/* (*jenv) may be NULL if JVM is shutting down */
if ((vmret != JNI_OK) || (jenv == NULL) || (*jenv == NULL)) {
printf("Failed to attach to thread in NativeLoggingCallback\n");
return;
}
needsDetach = 1;
} else if (vmret != JNI_OK) {
printf("Unable to get JNIEnv from JavaVM\n");
printf("Unable to get JNIEnv from JavaVM in NativeLoggingCallback\n");
return;
}
/* find exception class */
@ -834,6 +844,9 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
if ((*jenv)->ExceptionOccurred(jenv)) {
(*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv);
if (needsDetach == 1) {
(*g_vm)->DetachCurrentThread(g_vm);
}
return;
}
@ -851,6 +864,10 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
(*jenv)->ThrowNew(jenv, excClass,
"Can't get native WolfSSLLoggingCallback class reference");
if (needsDetach == 1) {
(*g_vm)->DetachCurrentThread(g_vm);
}
return;
}
@ -864,6 +881,9 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
}
(*jenv)->ThrowNew(jenv, excClass,
"Error getting loggingCallback method from JNI");
if (needsDetach == 1) {
(*g_vm)->DetachCurrentThread(g_vm);
}
return;
}
@ -879,6 +899,9 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
(*jenv)->ThrowNew(jenv, excClass,
"Error calling logging callback from JNI");
if (needsDetach == 1) {
(*g_vm)->DetachCurrentThread(g_vm);
}
return;
}
@ -891,6 +914,10 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
(*jenv)->ThrowNew(jenv, excClass,
"Object reference invalid in NativeLoggingCallback");
}
if (needsDetach == 1) {
(*g_vm)->DetachCurrentThread(g_vm);
}
}
void NativeFIPSErrorCallback(const int ok, const int err,

View File

@ -57,6 +57,7 @@ infer run -- javac \
src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java \
src/java/com/wolfssl/provider/jsse/WolfSSLKeyManager.java \
src/java/com/wolfssl/provider/jsse/WolfSSLKeyX509.java \
src/java/com/wolfssl/provider/jsse/WolfSSLNativeLoggingCallback.java \
src/java/com/wolfssl/provider/jsse/WolfSSLParametersHelper.java \
src/java/com/wolfssl/provider/jsse/WolfSSLParameters.java \
src/java/com/wolfssl/provider/jsse/WolfSSLProvider.java \

View File

@ -1482,6 +1482,9 @@ public class WolfSSL {
{
synchronized(cleanupLock) {
if (this.active == true) {
/* reset logging callback before calling cleanup() */
this.setLoggingCb(null);
/* free resources, set state */
this.cleanup();
this.active = false;

View File

@ -66,6 +66,12 @@ public class WolfSSLContext extends SSLContextSpi {
long method;
String[] ciphersIana = null;
/* Enable native wolfSSL debug logging if 'wolfssl.debug'
* System property is set. Also attempted in WolfSSLProvider
* but System property may not have been set by user yet at that
* point. */
WolfSSLDebug.setNativeWolfSSLDebugging();
/* Get available wolfSSL cipher suites in IANA format */
ciphersIana = WolfSSL.getCiphersAvailableIana(this.currentVersion);

View File

@ -24,6 +24,9 @@ package com.wolfssl.provider.jsse;
import java.util.Date;
import java.sql.Timestamp;
import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLLoggingCallback;
/**
* Central location for all debugging messages
*
@ -48,6 +51,13 @@ public class WolfSSLDebug {
*/
public static final String INFO = "INFO";
/**
* Native wolfSSL logging callback.
* Used to print native wolfSSL debug logs when 'wolfssl.debug' System
* property is set to "true".
*/
private static WolfSSLNativeLoggingCallback nativeLogCb = null;
private static boolean checkProperty() {
String enabled = System.getProperty("wolfjsse.debug");
@ -119,5 +129,40 @@ public class WolfSSLDebug {
System.out.println("");
}
}
/**
* Enable native wolfSSL debug logging based on value of the
* 'wolfssl.debug' System property.
*
* Native wolfSSL must ben compiled with "--enable-debug" or
* DEBUG_WOLFSSL defined in order for debug logs to print.
*/
protected static synchronized void setNativeWolfSSLDebugging() {
String wolfsslDebug = System.getProperty("wolfssl.debug");
if ((wolfsslDebug != null) && (wolfsslDebug.equalsIgnoreCase("true"))) {
WolfSSL.debuggingON();
}
/* Register our default logging callback for native wolfSSL logs */
setDefaultNativeLoggingCallback();
}
/**
* Register default native wolfSSL logging callback.
* Default callback class is WolfSSLNativeLoggingCallback. This could be
* modified in the future to allow a custom user-registerable callback.
*/
protected static synchronized void setDefaultNativeLoggingCallback() {
/* Only create one logging callback object */
if (nativeLogCb == null) {
nativeLogCb = new WolfSSLNativeLoggingCallback();
}
WolfSSL.setLoggingCb(nativeLogCb);
}
}

View File

@ -0,0 +1,47 @@
/* WolfSSLNativeLoggingCallback.java
*
* Copyright (C) 2006-2023 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
package com.wolfssl.provider.jsse;
import java.util.Date;
import java.sql.Timestamp;
import com.wolfssl.WolfSSLLoggingCallback;
/**
* Utility class to help with JSSE-level functionality.
*
* Native logging callback class, implements com.wolfssl.WolfSSLLoggingCallback.
* loggingCallback() method is called by native wolfSSL debug logging
* mechanism.
*
* @author wolfSSL
*/
class WolfSSLNativeLoggingCallback implements WolfSSLLoggingCallback
{
public synchronized void loggingCallback(int logLevel, String logMessage) {
System.out.println(new Timestamp(new java.util.Date().getTime()) +
" [wolfSSL: TID " +
Thread.currentThread().getId() +
"] " + logMessage);
}
}

View File

@ -28,9 +28,7 @@ import com.wolfssl.WolfSSLFIPSErrorCallback;
/**
* wolfSSL JSSE Provider implementation
*
* @author wolfSSL
* @version 1.8
*/
public final class WolfSSLProvider extends Provider {
@ -103,12 +101,10 @@ public final class WolfSSLProvider extends Provider {
"Failed to initialize native wolfSSL library");
}
/* enable native wolfSSL debug logging, native wolfSSL must be
* compiled with --enable-debug */
String wolfsslDebug = System.getProperty("wolfssl.debug");
if ((wolfsslDebug != null) && (wolfsslDebug.equalsIgnoreCase("true"))) {
WolfSSL.debuggingON();
}
/* Enable native wolfSSL debug logging if 'wolfssl.debug' System
* property has been set to "true" and native wolfSSL compiled with
* '--enable-debug' */
WolfSSLDebug.setNativeWolfSSLDebugging();
/* Key Factory */
put("KeyManagerFactory.PKIX",