Skip to content

Commit ca41a36

Browse files
authored
Merge pull request #359 from rlm2002/fenrir
Fenrir fixes
2 parents 4f5cb15 + 837436c commit ca41a36

7 files changed

Lines changed: 165 additions & 22 deletions

File tree

native/com_wolfssl_WolfSSLCertificate.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1pubkey_1na
274274
(void)jcl;
275275
(void)x509Ptr;
276276
(void)keyType;
277-
(void)filePath;
277+
(void)fileBytes;
278278
(void)fileFormat;
279279
return (jint)NOT_COMPILED_IN;
280280
#endif
@@ -825,10 +825,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1CRL_1add_1dist_
825825
if (uriStr != NULL) {
826826
ret = wolfSSL_X509_CRL_add_dist_point(x509, uriStr,
827827
(critical == JNI_TRUE) ? 1 : 0);
828+
(*jenv)->ReleaseStringUTFChars(jenv, uri, uriStr);
828829
}
829830

830-
(*jenv)->ReleaseStringUTFChars(jenv, uri, uriStr);
831-
832831
return (jint)ret;
833832
#else
834833
(void)jenv;

native/com_wolfssl_WolfSSLContext.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_memrestoreCertCache
785785
ret = wolfSSL_CTX_memrestore_cert_cache(ctx, buff, buffSz);
786786
}
787787

788-
(*jenv)->ReleaseByteArrayElements(jenv, mem, (jbyte*)buff, JNI_ABORT);
788+
if (buff != NULL) {
789+
(*jenv)->ReleaseByteArrayElements(jenv, mem, (jbyte*)buff, JNI_ABORT);
790+
}
789791

790792
return (jint)ret;
791793
#else
@@ -888,7 +890,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_loadVerifyBuffer
888890
ret = wolfSSL_CTX_load_verify_buffer(ctx, buff, buffSz, format);
889891
}
890892

891-
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
893+
if (buff != NULL) {
894+
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
895+
}
892896

893897
return (jint)ret;
894898
}
@@ -915,7 +919,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useCertificateBuffer
915919
ret = wolfSSL_CTX_use_certificate_buffer(ctx, buff, buffSz, format);
916920
}
917921

918-
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
922+
if (buff != NULL) {
923+
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
924+
}
919925

920926
return (jint)ret;
921927
}
@@ -952,7 +958,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_usePrivateKeyBuffer
952958
XMEMSET(buff, 0, buffSz);
953959
#endif
954960
}
955-
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
961+
if (buff != NULL) {
962+
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
963+
}
956964

957965
return (jint)ret;
958966
}
@@ -978,7 +986,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useCertificateChainBuffer
978986
ret = wolfSSL_CTX_use_certificate_chain_buffer(ctx, buff, buffSz);
979987
}
980988

981-
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
989+
if (buff != NULL) {
990+
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
991+
}
982992

983993
return (jint)ret;
984994
}
@@ -1005,7 +1015,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useCertificateChainBuffer
10051015
ctx, buff, buffSz, format);
10061016
}
10071017

1008-
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
1018+
if (buff != NULL) {
1019+
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
1020+
}
10091021

10101022
return (jint)ret;
10111023
}

native/com_wolfssl_WolfSSLSession.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write__J_3BIII
12801280
(*jenv)->ExceptionClear(jenv);
12811281
return SSL_FAILURE;
12821282
}
1283+
if (data == NULL) {
1284+
return SSL_FAILURE;
1285+
}
12831286

12841287
ret = SSLWriteNonblockingWithSelectPoll(ssl, data + offset,
12851288
(int)length, (int)timeout);
@@ -1499,6 +1502,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__J_3BIII
14991502
(*jenv)->ExceptionClear(jenv);
15001503
return SSL_FAILURE;
15011504
}
1505+
if (data == NULL) {
1506+
return SSL_FAILURE;
1507+
}
15021508

15031509
size = SSLReadNonblockingWithSelectPoll(ssl, data + offset,
15041510
(int)length, (int)timeout);
@@ -2426,7 +2432,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setServerID
24262432
ret = wolfSSL_SetServerID(ssl, idBuf, idBufSz, (int)newSess);
24272433
}
24282434

2429-
(*jenv)->ReleaseByteArrayElements(jenv, id, (jbyte*)idBuf, JNI_ABORT);
2435+
if (idBuf != NULL) {
2436+
(*jenv)->ReleaseByteArrayElements(jenv, id, (jbyte*)idBuf, JNI_ABORT);
2437+
}
24302438

24312439
return ret;
24322440
#else
@@ -2808,7 +2816,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_sendHrrCookie
28082816

28092817
ret = wolfSSL_send_hrr_cookie(ssl, secretBuf, secretSz);
28102818

2811-
if (secret != NULL) {
2819+
if (secret != NULL && secretBuf != NULL) {
28122820
(*jenv)->ReleaseByteArrayElements(jenv, secret,
28132821
(jbyte*)secretBuf, JNI_ABORT);
28142822
}
@@ -3774,7 +3782,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useCertificateChainBuffer
37743782
ssl, buff, buffSz, format);
37753783
}
37763784

3777-
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
3785+
if (buff != NULL) {
3786+
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
3787+
}
37783788

37793789
return (jint)ret;
37803790
}
@@ -5210,7 +5220,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSNI
52105220
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
52115221
(void)jcl;
52125222

5213-
if (jenv == NULL || ssl == NULL) {
5223+
if (jenv == NULL || ssl == NULL || data == NULL) {
52145224
return BAD_FUNC_ARG;
52155225
}
52165226

@@ -5225,7 +5235,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSNI
52255235
ret = wolfSSL_UseSNI(ssl, (byte)type, dataBuf, (word16)dataSz);
52265236
}
52275237

5228-
(*jenv)->ReleaseByteArrayElements(jenv, data, (jbyte*)dataBuf, JNI_ABORT);
5238+
if (dataBuf != NULL) {
5239+
(*jenv)->ReleaseByteArrayElements(jenv, data, (jbyte*)dataBuf,
5240+
JNI_ABORT);
5241+
}
52295242

52305243
#else
52315244
ret = NOT_COMPILED_IN;
@@ -5408,8 +5421,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setSessionTicket
54085421
else {
54095422
ret = BAD_FUNC_ARG;
54105423
}
5411-
(*jenv)->ReleaseByteArrayElements(jenv, dataBuf,
5412-
(jbyte*)data, JNI_ABORT);
5424+
if (data != NULL) {
5425+
(*jenv)->ReleaseByteArrayElements(jenv, dataBuf,
5426+
(jbyte*)data, JNI_ABORT);
5427+
}
54135428
(void)jcl;
54145429
#else
54155430
(void)jenv;
@@ -5477,8 +5492,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_sslSetAlpnProtos
54775492
#endif
54785493
}
54795494

5480-
(*jenv)->ReleaseByteArrayElements(jenv, alpnProtos,
5481-
(jbyte*)buff, JNI_ABORT);
5495+
if (buff != NULL) {
5496+
(*jenv)->ReleaseByteArrayElements(jenv, alpnProtos,
5497+
(jbyte*)buff, JNI_ABORT);
5498+
}
54825499
#else
54835500
(void)jenv;
54845501
(void)jcl;

src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,8 +498,10 @@ private int CopyOutPacket(ByteBuffer out) {
498498

499499
if (sendSz != this.internalIOSendBufOffset) {
500500
System.arraycopy(this.internalIOSendBuf, sendSz,
501-
this.internalIOSendBuf, 0,
502-
this.internalIOSendBufOffset - sendSz);
501+
this.internalIOSendBuf, 0,
502+
this.internalIOSendBufOffset - sendSz);
503+
this.internalIOSendBufOffset =
504+
this.internalIOSendBufOffset - sendSz;
503505
}
504506
else {
505507
/* reset internalIOSendBufOffset to zero, no data left */

src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ public synchronized void setSNIServerNames(List<SNIServerName> serverNames) {
140140
* @return list of stored SNI server names, may be null
141141
*/
142142
public synchronized List<SNIServerName> getSNIServerNames() {
143-
return this.sniServerNames;
143+
return (this.sniServerNames == null) ? null :
144+
Collections.unmodifiableList(this.sniServerNames);
144145
}
145146

146147
/**

src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public boolean equals(Object other) {
111111
* @return hash code value specific to this type and encoded name
112112
*/
113113
public int hashCode() {
114-
return Objects.hash(this.type, this.encoded);
114+
return Objects.hash(this.type, Arrays.hashCode(this.encoded));
115115
}
116116

117117
/**

src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.wolfssl.provider.jsse.WolfSSLProvider;
2727
import java.io.EOFException;
2828
import java.io.IOException;
29+
import java.lang.reflect.Field;
2930
import java.net.InetAddress;
3031
import java.nio.ByteBuffer;
3132
import java.nio.channels.ServerSocketChannel;
@@ -3508,4 +3509,115 @@ public void testBufferOverflowSmallOutput()
35083509

35093510
pass("\t\t... passed");
35103511
}
3512+
3513+
@Test
3514+
public void testWrapPartialDrainOffsetUpdate()
3515+
throws NoSuchProviderException, NoSuchAlgorithmException,
3516+
KeyManagementException, KeyStoreException,
3517+
CertificateException, IOException,
3518+
UnrecoverableKeyException,
3519+
NoSuchFieldException, IllegalAccessException {
3520+
3521+
/* CopyOutPacket() must decrement internalIOSendBufOffset after a
3522+
* partial drain, otherwise stale ciphertext gets re-emitted. */
3523+
System.out.print("\tTesting wrap() partial drain offset");
3524+
3525+
this.ctx = tf.createSSLContext("TLS", engineProvider);
3526+
SSLEngine server = this.ctx.createSSLEngine();
3527+
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);
3528+
3529+
server.setUseClientMode(false);
3530+
server.setNeedClientAuth(false);
3531+
client.setUseClientMode(true);
3532+
3533+
server.beginHandshake();
3534+
client.beginHandshake();
3535+
3536+
int ret = tf.testConnection(server, client, null, null,
3537+
"partial drain test");
3538+
if (ret != 0) {
3539+
error("\t... failed");
3540+
fail("failed to create connection");
3541+
}
3542+
3543+
/* Inject marker of size packetSz + 1000 so first drain copies
3544+
* packetSz bytes and leaves 1000 bytes queued. */
3545+
int packetSz = client.getSession().getPacketBufferSize();
3546+
int queuedSz = packetSz + 1000;
3547+
byte[] marker = new byte[queuedSz];
3548+
for (int i = 0; i < queuedSz; i++) {
3549+
marker[i] = (byte)((i * 31) & 0xFF);
3550+
}
3551+
3552+
Field bufField =
3553+
WolfSSLEngine.class.getDeclaredField("internalIOSendBuf");
3554+
Field bufSzField =
3555+
WolfSSLEngine.class.getDeclaredField("internalIOSendBufSz");
3556+
Field offField =
3557+
WolfSSLEngine.class.getDeclaredField(
3558+
"internalIOSendBufOffset");
3559+
bufField.setAccessible(true);
3560+
bufSzField.setAccessible(true);
3561+
offField.setAccessible(true);
3562+
3563+
bufField.set(client, marker);
3564+
bufSzField.setInt(client, queuedSz);
3565+
offField.setInt(client, queuedSz);
3566+
3567+
/* First wrap: out buffer sized exactly to packetBufferSize so
3568+
* the guard passes but CopyOutPacket partial-drains. */
3569+
ByteBuffer empty = ByteBuffer.allocate(0);
3570+
ByteBuffer firstOut = ByteBuffer.allocate(packetSz);
3571+
SSLEngineResult result = client.wrap(empty, firstOut);
3572+
3573+
if (result.bytesProduced() != packetSz) {
3574+
error("\t... failed");
3575+
fail("first wrap expected " + packetSz +
3576+
" produced, got " + result.bytesProduced());
3577+
}
3578+
3579+
/* Fix-sensitive check: unfixed code leaves offset at queuedSz. */
3580+
int offAfterFirst = offField.getInt(client);
3581+
if (offAfterFirst != queuedSz - packetSz) {
3582+
error("\t... failed");
3583+
fail("internalIOSendBufOffset not decremented after " +
3584+
"partial drain: expected " + (queuedSz - packetSz) +
3585+
", got " + offAfterFirst);
3586+
}
3587+
3588+
/* Second wrap: must drain only the remainder; unfixed code
3589+
* would re-emit packetSz stale bytes instead. */
3590+
ByteBuffer secondOut = ByteBuffer.allocate(packetSz);
3591+
result = client.wrap(empty, secondOut);
3592+
3593+
int expectedRemainder = queuedSz - packetSz;
3594+
if (result.bytesProduced() != expectedRemainder) {
3595+
error("\t... failed");
3596+
fail("second wrap expected " + expectedRemainder +
3597+
" produced (remainder only), got " +
3598+
result.bytesProduced() +
3599+
" - stale bytes re-sent after partial drain");
3600+
}
3601+
3602+
if (offField.getInt(client) != 0) {
3603+
error("\t... failed");
3604+
fail("internalIOSendBufOffset not reset to 0 after " +
3605+
"remainder drained");
3606+
}
3607+
3608+
/* Full integrity check: concatenated drained output must equal
3609+
* the original injected marker exactly. */
3610+
firstOut.flip();
3611+
secondOut.flip();
3612+
byte[] drained = new byte[queuedSz];
3613+
firstOut.get(drained, 0, packetSz);
3614+
secondOut.get(drained, packetSz, expectedRemainder);
3615+
if (!Arrays.equals(marker, drained)) {
3616+
error("\t... failed");
3617+
fail("drained output does not match injected queue");
3618+
}
3619+
3620+
pass("\t... passed");
3621+
}
3622+
35113623
}

0 commit comments

Comments
 (0)