Skip to content
Merged
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
5 changes: 2 additions & 3 deletions native/com_wolfssl_WolfSSLCertificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1pubkey_1na
(void)jcl;
(void)x509Ptr;
(void)keyType;
(void)filePath;
(void)fileBytes;
(void)fileFormat;
return (jint)NOT_COMPILED_IN;
#endif
Expand Down Expand Up @@ -825,10 +825,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1CRL_1add_1dist_
if (uriStr != NULL) {
ret = wolfSSL_X509_CRL_add_dist_point(x509, uriStr,
(critical == JNI_TRUE) ? 1 : 0);
(*jenv)->ReleaseStringUTFChars(jenv, uri, uriStr);
}

(*jenv)->ReleaseStringUTFChars(jenv, uri, uriStr);

return (jint)ret;
#else
(void)jenv;
Expand Down
24 changes: 18 additions & 6 deletions native/com_wolfssl_WolfSSLContext.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_memrestoreCertCache
ret = wolfSSL_CTX_memrestore_cert_cache(ctx, buff, buffSz);
}

(*jenv)->ReleaseByteArrayElements(jenv, mem, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, mem, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
#else
Expand Down Expand Up @@ -888,7 +890,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_loadVerifyBuffer
ret = wolfSSL_CTX_load_verify_buffer(ctx, buff, buffSz, format);
}

(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
}
Expand All @@ -915,7 +919,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useCertificateBuffer
ret = wolfSSL_CTX_use_certificate_buffer(ctx, buff, buffSz, format);
}

(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
}
Expand Down Expand Up @@ -952,7 +958,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_usePrivateKeyBuffer
XMEMSET(buff, 0, buffSz);
#endif
}
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
}
Expand All @@ -978,7 +986,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useCertificateChainBuffer
ret = wolfSSL_CTX_use_certificate_chain_buffer(ctx, buff, buffSz);
}

(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
}
Expand All @@ -1005,7 +1015,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_useCertificateChainBuffer
ctx, buff, buffSz, format);
}

(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
}
Expand Down
35 changes: 26 additions & 9 deletions native/com_wolfssl_WolfSSLSession.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write__J_3BIII
(*jenv)->ExceptionClear(jenv);
return SSL_FAILURE;
}
if (data == NULL) {
return SSL_FAILURE;
}

ret = SSLWriteNonblockingWithSelectPoll(ssl, data + offset,
(int)length, (int)timeout);
Expand Down Expand Up @@ -1495,6 +1498,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__J_3BIII
(*jenv)->ExceptionClear(jenv);
return SSL_FAILURE;
}
if (data == NULL) {
return SSL_FAILURE;
}

size = SSLReadNonblockingWithSelectPoll(ssl, data + offset,
(int)length, (int)timeout);
Expand Down Expand Up @@ -2422,7 +2428,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setServerID
ret = wolfSSL_SetServerID(ssl, idBuf, idBufSz, (int)newSess);
}

(*jenv)->ReleaseByteArrayElements(jenv, id, (jbyte*)idBuf, JNI_ABORT);
if (idBuf != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, id, (jbyte*)idBuf, JNI_ABORT);
}

return ret;
#else
Expand Down Expand Up @@ -2804,7 +2812,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_sendHrrCookie

ret = wolfSSL_send_hrr_cookie(ssl, secretBuf, secretSz);

if (secret != NULL) {
if (secret != NULL && secretBuf != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, secret,
(jbyte*)secretBuf, JNI_ABORT);
}
Expand Down Expand Up @@ -3770,7 +3778,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useCertificateChainBuffer
ssl, buff, buffSz, format);
}

(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, in, (jbyte*)buff, JNI_ABORT);
}

return (jint)ret;
}
Expand Down Expand Up @@ -5206,7 +5216,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSNI
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
(void)jcl;

if (jenv == NULL || ssl == NULL) {
if (jenv == NULL || ssl == NULL || data == NULL) {
return BAD_FUNC_ARG;
}

Expand All @@ -5221,7 +5231,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSNI
ret = wolfSSL_UseSNI(ssl, (byte)type, dataBuf, (word16)dataSz);
}

(*jenv)->ReleaseByteArrayElements(jenv, data, (jbyte*)dataBuf, JNI_ABORT);
if (dataBuf != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, data, (jbyte*)dataBuf,
JNI_ABORT);
}

#else
ret = NOT_COMPILED_IN;
Expand Down Expand Up @@ -5404,8 +5417,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setSessionTicket
else {
ret = BAD_FUNC_ARG;
}
(*jenv)->ReleaseByteArrayElements(jenv, dataBuf,
(jbyte*)data, JNI_ABORT);
if (data != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, dataBuf,
(jbyte*)data, JNI_ABORT);
}
(void)jcl;
#else
(void)jenv;
Expand Down Expand Up @@ -5473,8 +5488,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_sslSetAlpnProtos
#endif
}

(*jenv)->ReleaseByteArrayElements(jenv, alpnProtos,
(jbyte*)buff, JNI_ABORT);
if (buff != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, alpnProtos,
(jbyte*)buff, JNI_ABORT);
}
#else
(void)jenv;
(void)jcl;
Expand Down
6 changes: 4 additions & 2 deletions src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,10 @@ private int CopyOutPacket(ByteBuffer out) {

if (sendSz != this.internalIOSendBufOffset) {
System.arraycopy(this.internalIOSendBuf, sendSz,
this.internalIOSendBuf, 0,
this.internalIOSendBufOffset - sendSz);
this.internalIOSendBuf, 0,
this.internalIOSendBufOffset - sendSz);
this.internalIOSendBufOffset =
this.internalIOSendBufOffset - sendSz;
}
else {
/* reset internalIOSendBufOffset to zero, no data left */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ public synchronized void setSNIServerNames(List<SNIServerName> serverNames) {
* @return list of stored SNI server names, may be null
*/
public synchronized List<SNIServerName> getSNIServerNames() {
return this.sniServerNames;
return (this.sniServerNames == null) ? null :
Collections.unmodifiableList(this.sniServerNames);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public boolean equals(Object other) {
* @return hash code value specific to this type and encoded name
*/
public int hashCode() {
return Objects.hash(this.type, this.encoded);
return Objects.hash(this.type, Arrays.hashCode(this.encoded));
}

/**
Expand Down
112 changes: 112 additions & 0 deletions src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.wolfssl.provider.jsse.WolfSSLProvider;
import java.io.EOFException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
Expand Down Expand Up @@ -3508,4 +3509,115 @@ public void testBufferOverflowSmallOutput()

pass("\t\t... passed");
}

@Test
public void testWrapPartialDrainOffsetUpdate()
throws NoSuchProviderException, NoSuchAlgorithmException,
KeyManagementException, KeyStoreException,
CertificateException, IOException,
UnrecoverableKeyException,
NoSuchFieldException, IllegalAccessException {

/* CopyOutPacket() must decrement internalIOSendBufOffset after a
* partial drain, otherwise stale ciphertext gets re-emitted. */
System.out.print("\tTesting wrap() partial drain offset");

this.ctx = tf.createSSLContext("TLS", engineProvider);
SSLEngine server = this.ctx.createSSLEngine();
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);

server.setUseClientMode(false);
server.setNeedClientAuth(false);
client.setUseClientMode(true);

server.beginHandshake();
client.beginHandshake();

int ret = tf.testConnection(server, client, null, null,
"partial drain test");
if (ret != 0) {
error("\t... failed");
fail("failed to create connection");
}

/* Inject marker of size packetSz + 1000 so first drain copies
* packetSz bytes and leaves 1000 bytes queued. */
int packetSz = client.getSession().getPacketBufferSize();
int queuedSz = packetSz + 1000;
byte[] marker = new byte[queuedSz];
for (int i = 0; i < queuedSz; i++) {
marker[i] = (byte)((i * 31) & 0xFF);
}

Field bufField =
WolfSSLEngine.class.getDeclaredField("internalIOSendBuf");
Field bufSzField =
WolfSSLEngine.class.getDeclaredField("internalIOSendBufSz");
Field offField =
WolfSSLEngine.class.getDeclaredField(
"internalIOSendBufOffset");
bufField.setAccessible(true);
bufSzField.setAccessible(true);
offField.setAccessible(true);

bufField.set(client, marker);
bufSzField.setInt(client, queuedSz);
offField.setInt(client, queuedSz);

/* First wrap: out buffer sized exactly to packetBufferSize so
* the guard passes but CopyOutPacket partial-drains. */
ByteBuffer empty = ByteBuffer.allocate(0);
ByteBuffer firstOut = ByteBuffer.allocate(packetSz);
SSLEngineResult result = client.wrap(empty, firstOut);

if (result.bytesProduced() != packetSz) {
error("\t... failed");
fail("first wrap expected " + packetSz +
" produced, got " + result.bytesProduced());
}

/* Fix-sensitive check: unfixed code leaves offset at queuedSz. */
int offAfterFirst = offField.getInt(client);
if (offAfterFirst != queuedSz - packetSz) {
error("\t... failed");
fail("internalIOSendBufOffset not decremented after " +
"partial drain: expected " + (queuedSz - packetSz) +
", got " + offAfterFirst);
}

/* Second wrap: must drain only the remainder; unfixed code
* would re-emit packetSz stale bytes instead. */
ByteBuffer secondOut = ByteBuffer.allocate(packetSz);
result = client.wrap(empty, secondOut);

int expectedRemainder = queuedSz - packetSz;
if (result.bytesProduced() != expectedRemainder) {
error("\t... failed");
fail("second wrap expected " + expectedRemainder +
" produced (remainder only), got " +
result.bytesProduced() +
" - stale bytes re-sent after partial drain");
}

if (offField.getInt(client) != 0) {
error("\t... failed");
fail("internalIOSendBufOffset not reset to 0 after " +
"remainder drained");
}

/* Full integrity check: concatenated drained output must equal
* the original injected marker exactly. */
firstOut.flip();
secondOut.flip();
byte[] drained = new byte[queuedSz];
firstOut.get(drained, 0, packetSz);
Comment thread
rlm2002 marked this conversation as resolved.
secondOut.get(drained, packetSz, expectedRemainder);
if (!Arrays.equals(marker, drained)) {
error("\t... failed");
fail("drained output does not match injected queue");
}

pass("\t... passed");
}

}
Loading