Skip to content

Commit 2bba86a

Browse files
committed
JNI: wrap wolfSSL_set_tls13_secret_cb() in WolfSSLSession.setTls13SecretCb(), along with example in Client.java
1 parent ecd67a4 commit 2bba86a

11 files changed

+873
-30
lines changed

examples/Client.java

+24
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public void run(String[] args) {
7272
int logCallback = 0; /* use test logging callback */
7373
int usePsk = 0; /* use pre shared keys */
7474

75+
boolean useSecretCallback = false; /* enable TLS 1.3 secret cb */
76+
String keyLogFile = "sslkeylog.log"; /* output keylog file */
77+
7578
long session = 0; /* pointer to WOLFSSL_SESSION */
7679
boolean resumeSession = false; /* try one session resumption */
7780

@@ -201,6 +204,16 @@ public void run(String[] args) {
201204
} else if (arg.equals("-r")) {
202205
resumeSession = true;
203206

207+
} else if (arg.equals("-tls13secretcb")) {
208+
if (!WolfSSL.secretCallbackEnabled()) {
209+
printUsage();
210+
}
211+
if (args.length < i+2) {
212+
printUsage();
213+
}
214+
useSecretCallback = true;
215+
keyLogFile = args[++i];
216+
204217
} else {
205218
printUsage();
206219
}
@@ -451,6 +464,15 @@ public void run(String[] args) {
451464
}
452465
}
453466

467+
/* Set TLS 1.3 secret callback if enabled */
468+
if (useSecretCallback) {
469+
MyTls13SecretCallback tsc = new MyTls13SecretCallback();
470+
ssl.keepArrays();
471+
ssl.setTls13SecretCb(tsc, null);
472+
System.out.println("Writing TLS 1.3 secrets to keylog file: " +
473+
keyLogFile);
474+
}
475+
454476
/* open Socket */
455477
if (doDTLS == 1) {
456478
dsock = new DatagramSocket();
@@ -757,6 +779,8 @@ void printUsage() {
757779
System.out.println("-U\t\tEnable Atomic User Record Layer Callbacks");
758780
if (WolfSSL.isEnabledPKCallbacks() == 1)
759781
System.out.println("-P\t\tPublic Key Callbacks");
782+
if (WolfSSL.secretCallbackEnabled())
783+
System.out.println("-tls13secretcb\tEnable TLS 1.3 secret callback");
760784
System.exit(1);
761785
}
762786

examples/MyTls13SecretCallback.java

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/* MyTls13SecretCallback.java
2+
*
3+
* Copyright (C) 2006-2024 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
import java.io.FileWriter;
23+
import java.io.PrintWriter;
24+
import java.io.IOException;
25+
26+
import com.wolfssl.WolfSSL;
27+
import com.wolfssl.WolfSSLSession;
28+
import com.wolfssl.WolfSSLTls13SecretCallback;
29+
import com.wolfssl.WolfSSLJNIException;
30+
31+
/**
32+
* Example TLS 1.3 secret callback implementation.
33+
*
34+
* This is provided as an example only, and used with the example JNI
35+
* applications provided in this package. Users in production environments
36+
* should write their own implementation to conform to desired goals.
37+
*/
38+
class MyTls13SecretCallback implements WolfSSLTls13SecretCallback
39+
{
40+
/* SSL keylog file to output secrets to */
41+
private String sslKeyLogFile = "sslkeylog.log";
42+
43+
/**
44+
* Create new MyTls13SecretCallback using default "sslkeylog.log" file
45+
* path.
46+
*/
47+
public MyTls13SecretCallback() {
48+
}
49+
50+
/**
51+
* Create new MyTls13SecretCallback object specifying SSL keylog file
52+
* path.
53+
*
54+
* @param keyLogFile path to output file (ex: sslkeylog.log) to use
55+
* for writing TLS 1.3 secrets into.
56+
*/
57+
public MyTls13SecretCallback(String keyLogFile) {
58+
this.sslKeyLogFile = keyLogFile;
59+
}
60+
61+
/**
62+
* Callback method for printing/saving TLS 1.3 secrets, for use
63+
* with Wireshark. Called by native wolfSSL when each secret is available.
64+
*
65+
* @param ssl the current SSL session object from which the
66+
* callback was initiated.
67+
* @param id Identifier specifying what type of secret this callback
68+
* is being called with, one of the following:
69+
* WolfSSL.CLIENT_EARLY_TRAFFIC_SECRET
70+
* WolfSSL.EARLY_EXPORTER_SECRET
71+
* WolfSSL.CLIENT_HANDSHAKE_TRAFFIC_SECRET
72+
* WolfSSL.SERVER_HANDSHAKE_TRAFFIC_SECRET
73+
* WolfSSL.CLIENT_TRAFFIC_SECRET
74+
* WolfSSL.SERVER_TRAFFIC_SECRET
75+
* WolfSSL.EXPORTER_SECRET
76+
* @param secret Current secret as byte array
77+
* @param ctx Optional user context if set
78+
*
79+
* @return 0 on success, otherwise negative if callback encounters
80+
* an error.
81+
*/
82+
public int tls13SecretCallback(WolfSSLSession ssl, int id, byte[] secret,
83+
Object ctx) {
84+
85+
int i;
86+
String str = null;
87+
FileWriter fw = null;
88+
PrintWriter pw = null;
89+
byte[] clientRandom = null;
90+
91+
try {
92+
/* Open FileWriter in append mode */
93+
fw = new FileWriter(sslKeyLogFile, true);
94+
pw = new PrintWriter(fw);
95+
96+
clientRandom = ssl.getClientRandom();
97+
if (clientRandom == null || clientRandom.length == 0) {
98+
System.out.println("Error getting client random");
99+
}
100+
101+
/* Set secret label based on ID */
102+
if (id == WolfSSL.CLIENT_EARLY_TRAFFIC_SECRET) {
103+
str = "CLIENT_EARLY_TRAFFIC_SECRET";
104+
} else if (id == WolfSSL.EARLY_EXPORTER_SECRET) {
105+
str = "EARLY_EXPORTER_SECRET";
106+
} else if (id == WolfSSL.CLIENT_HANDSHAKE_TRAFFIC_SECRET) {
107+
str = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
108+
} else if (id == WolfSSL.SERVER_HANDSHAKE_TRAFFIC_SECRET) {
109+
str = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
110+
} else if (id == WolfSSL.CLIENT_TRAFFIC_SECRET) {
111+
str = "CLIENT_TRAFFIC_SECRET";
112+
} else if (id == WolfSSL.SERVER_TRAFFIC_SECRET) {
113+
str = "SERVER_TRAFFIC_SECRET";
114+
} else if (id == WolfSSL.EXPORTER_SECRET) {
115+
str = "EXPORTER_SECRET";
116+
} else {
117+
pw.close();
118+
return WolfSSL.TLS13_SECRET_CB_E;
119+
}
120+
121+
pw.printf("%s ", str);
122+
for (i = 0; i < clientRandom.length; i++) {
123+
pw.printf("%02x", clientRandom[i]);
124+
}
125+
pw.printf(" ");
126+
for (i = 0; i < clientRandom.length; i++) {
127+
pw.printf("%02x", secret[i]);
128+
}
129+
pw.printf("\n");
130+
131+
pw.close();
132+
133+
return 0;
134+
135+
} catch (IOException | WolfSSLJNIException e) {
136+
e.printStackTrace();
137+
return WolfSSL.TLS13_SECRET_CB_E;
138+
}
139+
}
140+
}
141+

native/com_wolfssl_WolfSSL.c

+104
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,97 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getBulkCipherAlgorithmEnumCAMELL
298298
return wolfssl_camellia;
299299
}
300300

301+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1CLIENT_1EARLY_1TRAFFIC_1SECRET
302+
(JNIEnv* jenv, jclass jcl)
303+
{
304+
(void)jenv;
305+
(void)jcl;
306+
307+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
308+
return CLIENT_EARLY_TRAFFIC_SECRET;
309+
#else
310+
return NOT_COMPILED_IN;
311+
#endif
312+
}
313+
314+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1CLIENT_1HANDSHAKE_1TRAFFIC_1SECRET
315+
(JNIEnv* jenv, jclass jcl)
316+
{
317+
(void)jenv;
318+
(void)jcl;
319+
320+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
321+
return CLIENT_HANDSHAKE_TRAFFIC_SECRET;
322+
#else
323+
return NOT_COMPILED_IN;
324+
#endif
325+
}
326+
327+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1SERVER_1HANDSHAKE_1TRAFFIC_1SECRET
328+
(JNIEnv* jenv, jclass jcl)
329+
{
330+
(void)jenv;
331+
(void)jcl;
332+
333+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
334+
return SERVER_HANDSHAKE_TRAFFIC_SECRET;
335+
#else
336+
return NOT_COMPILED_IN;
337+
#endif
338+
}
339+
340+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1CLIENT_1TRAFFIC_1SECRET
341+
(JNIEnv* jenv, jclass jcl)
342+
{
343+
(void)jenv;
344+
(void)jcl;
345+
346+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
347+
return CLIENT_TRAFFIC_SECRET;
348+
#else
349+
return NOT_COMPILED_IN;
350+
#endif
351+
}
352+
353+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1SERVER_1TRAFFIC_1SECRET
354+
(JNIEnv* jenv, jclass jcl)
355+
{
356+
(void)jenv;
357+
(void)jcl;
358+
359+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
360+
return SERVER_TRAFFIC_SECRET;
361+
#else
362+
return NOT_COMPILED_IN;
363+
#endif
364+
}
365+
366+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1EARLY_1EXPORTER_1SECRET
367+
(JNIEnv* jenv, jclass jcl)
368+
{
369+
(void)jenv;
370+
(void)jcl;
371+
372+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
373+
return EARLY_EXPORTER_SECRET;
374+
#else
375+
return NOT_COMPILED_IN;
376+
#endif
377+
}
378+
379+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getTls13SecretEnum_1EXPORTER_1SECRET
380+
(JNIEnv* jenv, jclass jcl)
381+
{
382+
(void)jenv;
383+
(void)jcl;
384+
385+
#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
386+
return EXPORTER_SECRET;
387+
#else
388+
return NOT_COMPILED_IN;
389+
#endif
390+
}
391+
301392
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_TLSv1Enabled
302393
(JNIEnv* jenv, jclass jcl)
303394
{
@@ -519,6 +610,19 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_sessionTicketEnabled
519610
#endif
520611
}
521612

613+
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_secretCallbackEnabled
614+
(JNIEnv* jenv, jclass jcl)
615+
{
616+
(void)jenv;
617+
(void)jcl;
618+
619+
#ifdef HAVE_SECRET_CALLBACK
620+
return JNI_TRUE;
621+
#else
622+
return JNI_FALSE;
623+
#endif
624+
}
625+
522626
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSL_SSLv3_1ServerMethod
523627
(JNIEnv* jenv, jclass jcl)
524628
{

native/com_wolfssl_WolfSSL.h

+66
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)