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
12 changes: 11 additions & 1 deletion native/com_wolfssl_WolfSSLCRL.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1sign
const WOLFSSL_EVP_MD* md = NULL;
unsigned char* rsaPrivBuf = NULL;
const char* mdName = NULL;
jboolean isCopy = JNI_FALSE;
int ret = WOLFSSL_SUCCESS;
(void)jcl;

if (jenv == NULL || crl == NULL || keyBytes == NULL) {
return WOLFSSL_FAILURE;
}

keyBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, keyBytes, NULL);
keyBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, keyBytes, &isCopy);
if ((*jenv)->ExceptionOccurred(jenv)) {
(*jenv)->ExceptionClear(jenv);
return WOLFSSL_FAILURE;
Expand Down Expand Up @@ -471,6 +472,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1sign
(*jenv)->ReleaseStringUTFChars(jenv, digestAlg, mdName);
}
if (keyBuf != NULL) {
/* Only zero if JVM made a copy */
if (isCopy == JNI_TRUE) {
#if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \
!defined(WOLFSSL_NO_FORCE_ZERO)
wc_ForceZero(keyBuf, keySz);
#else
XMEMSET(keyBuf, 0, keySz);
#endif
}
(*jenv)->ReleaseByteArrayElements(jenv, keyBytes, (jbyte*)keyBuf,
JNI_ABORT);
Comment thread
JeremiahM37 marked this conversation as resolved.
}
Expand Down
12 changes: 11 additions & 1 deletion native/com_wolfssl_WolfSSLCertRequest.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1sign
const WOLFSSL_EVP_MD* md = NULL;
unsigned char* rsaPrivBuf = NULL;
const char* mdName = NULL;
jboolean isCopy = JNI_FALSE;
int ret = WOLFSSL_SUCCESS;
(void)jcl;

Expand All @@ -255,7 +256,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1sign
return WOLFSSL_FAILURE;
}

keyBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, keyBytes, NULL);
keyBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, keyBytes, &isCopy);
keySz = (*jenv)->GetArrayLength(jenv, keyBytes);

if (keyBuf == NULL || keySz == 0) {
Expand Down Expand Up @@ -343,6 +344,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1sign
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
if (keyBuf != NULL) {
/* Only zero if JVM made a copy */
if (isCopy == JNI_TRUE) {
#if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \
!defined(WOLFSSL_NO_FORCE_ZERO)
wc_ForceZero(keyBuf, keySz);
#else
XMEMSET(keyBuf, 0, keySz);
#endif
}
(*jenv)->ReleaseByteArrayElements(jenv, keyBytes,
(jbyte*)keyBuf, JNI_ABORT);
Comment thread
JeremiahM37 marked this conversation as resolved.
}
Expand Down
12 changes: 11 additions & 1 deletion native/com_wolfssl_WolfSSLCertificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1sign
const WOLFSSL_EVP_MD* md = NULL;
unsigned char* rsaPrivBuf = NULL;
const char* mdName = NULL;
jboolean isCopy = JNI_FALSE;

int ret = WOLFSSL_SUCCESS;
(void)jcl;
Expand All @@ -897,7 +898,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1sign
return WOLFSSL_FAILURE;
}

fileBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, fileBytes, NULL);
fileBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, fileBytes, &isCopy);
fileSz = (*jenv)->GetArrayLength(jenv, fileBytes);

if (fileBuf == NULL || fileSz == 0) {
Expand Down Expand Up @@ -990,6 +991,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1sign
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
if (fileBuf != NULL) {
/* Only zero if JVM made a copy */
if (isCopy == JNI_TRUE) {
#if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \
!defined(WOLFSSL_NO_FORCE_ZERO)
wc_ForceZero(fileBuf, fileSz);
#else
XMEMSET(fileBuf, 0, fileSz);
#endif
}
(*jenv)->ReleaseByteArrayElements(jenv, fileBytes,
(jbyte*)fileBuf, JNI_ABORT);
Comment thread
JeremiahM37 marked this conversation as resolved.
}
Expand Down
4 changes: 2 additions & 2 deletions native/com_wolfssl_WolfSSLContext.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ int NativeIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
"NativeIORecvCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return 0;
return WOLFSSL_CBIO_ERR_GENERAL;
}

/* lookup WolfSSLSession class from object */
Expand Down Expand Up @@ -1329,7 +1329,7 @@ int NativeIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
"NativeIOSendCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return 0;
return WOLFSSL_CBIO_ERR_GENERAL;
}

/* lookup WolfSSLSession class from object */
Expand Down
4 changes: 2 additions & 2 deletions native/com_wolfssl_WolfSSLSession.c
Original file line number Diff line number Diff line change
Expand Up @@ -6613,7 +6613,7 @@ int NativeSSLIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
if (needsDetach) {
(*g_vm)->DetachCurrentThread(g_vm);
}
return 0;
return WOLFSSL_CBIO_ERR_GENERAL;
}

/* Detect if we should use ByteBuffer or byte[] I/O callbacks */
Expand Down Expand Up @@ -6789,7 +6789,7 @@ int NativeSSLIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
if (needsDetach) {
(*g_vm)->DetachCurrentThread(g_vm);
}
return 0;
return WOLFSSL_CBIO_ERR_GENERAL;
}

/* Detect if we should use ByteBuffer or byte[] I/O callbacks */
Expand Down
11 changes: 8 additions & 3 deletions src/java/com/wolfssl/WolfSSLCRL.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
Expand Down Expand Up @@ -561,9 +562,13 @@ else if (key instanceof ECPrivateKey) {
"PrivateKey does not support encoding");
}

synchronized (crlLock) {
ret = X509_CRL_sign(this.crlPtr, evpKeyType, encodedKey,
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
try {
synchronized (crlLock) {
ret = X509_CRL_sign(this.crlPtr, evpKeyType, encodedKey,
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
}
} finally {
Arrays.fill(encodedKey, (byte)0);
}

return ret;
Expand Down
17 changes: 13 additions & 4 deletions src/java/com/wolfssl/WolfSSLCertRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
Expand Down Expand Up @@ -634,7 +635,11 @@ public void signRequest(String filePath, int keyType, int format,
"Failed to read bytes from file: " + filePath);
}

signRequest(fileBytes, keyType, format, digestAlg);
try {
signRequest(fileBytes, keyType, format, digestAlg);
} finally {
Arrays.fill(fileBytes, (byte)0);
}
}

/**
Expand Down Expand Up @@ -751,9 +756,13 @@ else if (key instanceof ECPrivateKey) {
throw new WolfSSLException("PrivateKey does not support encoding");
}

synchronized (x509ReqLock) {
ret = X509_REQ_sign(this.x509ReqPtr, evpKeyType, encodedKey,
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
try {
synchronized (x509ReqLock) {
ret = X509_REQ_sign(this.x509ReqPtr, evpKeyType, encodedKey,
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
}
} finally {
Arrays.fill(encodedKey, (byte)0);
}

if (ret != WolfSSL.SSL_SUCCESS) {
Expand Down
16 changes: 12 additions & 4 deletions src/java/com/wolfssl/WolfSSLCertificate.java
Original file line number Diff line number Diff line change
Expand Up @@ -1345,7 +1345,11 @@ public void signCert(String filePath, int keyType, int format,
"Failed to read bytes from file: " + filePath);
}

signCert(fileBytes, keyType, format, digestAlg);
try {
signCert(fileBytes, keyType, format, digestAlg);
} finally {
Arrays.fill(fileBytes, (byte)0);
}
}

/**
Expand Down Expand Up @@ -1461,9 +1465,13 @@ else if (key instanceof ECPrivateKey) {
throw new WolfSSLException("PrivateKey does not support encoding");
}

synchronized (x509Lock) {
ret = X509_sign(this.x509Ptr, evpKeyType, encodedKey,
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
try {
synchronized (x509Lock) {
ret = X509_sign(this.x509Ptr, evpKeyType, encodedKey,
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
}
} finally {
Arrays.fill(encodedKey, (byte)0);
}

if (ret != WolfSSL.SSL_SUCCESS) {
Expand Down
10 changes: 5 additions & 5 deletions src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ private synchronized int RecvAppData(ByteBuffer[] out, int ofst, int length)

/* Copy from intermediate buffer to output bufs */
for (i = 0; i < ret;) {
if (idx + ofst >= length) {
if (idx >= length) {
/* no more output buffers left */
break;
}
Expand Down Expand Up @@ -1585,9 +1585,9 @@ else if (hs == SSLEngineResult.HandshakeStatus.NEED_WRAP &&
if (outputSpace >= this.pendingAppDataLen) {
/* Serve stashed data to output buffers */
int idx2 = 0;
for (int pos = 0;
pos < this.pendingAppDataLen;) {
if (idx2 + ofst >= length) break;
int pos = 0;
for (; pos < this.pendingAppDataLen;) {
if (idx2 >= length) break;
int space = out[idx2 + ofst].remaining();
if (space == 0) { idx2++; continue; }
int sz2 = Math.min(space,
Expand All @@ -1597,7 +1597,7 @@ else if (hs == SSLEngineResult.HandshakeStatus.NEED_WRAP &&
pos += sz2;
if (pos < this.pendingAppDataLen) idx2++;
}
produced += this.pendingAppDataLen;
produced += pos;
/* Advance past previously consumed bytes */
synchronized (netDataLock) {
in.position(in.position() +
Expand Down
121 changes: 121 additions & 0 deletions src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3419,5 +3419,126 @@ public void testUnwrapRejectsReadOnlyAtOffset() throws Exception {
s.unwrap(ByteBuffer.allocateDirect(
s.getSession().getPacketBufferSize()), out, 1, 1);
}

/* Verify unwrap() with ofst > 0 placed all `data` bytes into
* out[2] and out[3], and that bytesProduced matches. Regression
* for the `idx + ofst >= length` copy-loop bound in unwrap. */
private void assertOffsetUnwrapOk(SSLEngineResult result,
ByteBuffer[] outArr, byte[] data) {

assertEquals(data.length, result.bytesProduced());
assertEquals(0, outArr[0].position());
assertEquals(0, outArr[1].position());

outArr[2].flip();
outArr[3].flip();
int n2 = outArr[2].remaining();
int n3 = outArr[3].remaining();
assertEquals(data.length, n2 + n3);

byte[] got = new byte[n2 + n3];
outArr[2].get(got, 0, n2);
outArr[3].get(got, n2, n3);
assertTrue(java.util.Arrays.equals(got, data));
}

/* Wrap `data` from client and return server's network buffer
* positioned for unwrap(). */
private ByteBuffer wrapForServer(SSLEngine client, byte[] data)
throws SSLException {

ByteBuffer netBuf = ByteBuffer.allocateDirect(
client.getSession().getPacketBufferSize());
SSLEngineResult r = client.wrap(ByteBuffer.wrap(data), netBuf);
assertEquals(SSLEngineResult.Status.OK, r.getStatus());
netBuf.flip();
return netBuf;
}

@Test
public void testUnwrapOffsetMultipleBuffers() throws Exception {

this.ctx = tf.createSSLContext("TLS", engineProvider);
SSLEngine server = this.ctx.createSSLEngine();
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);
server.setUseClientMode(false);
client.setUseClientMode(true);
assertEquals(0, tf.testConnection(server, client, null, null, "x"));

byte[] data = new byte[1024];
new Random().nextBytes(data);
ByteBuffer netBuf = wrapForServer(client, data);

ByteBuffer[] outArr = new ByteBuffer[] {
ByteBuffer.allocate(600), ByteBuffer.allocate(600),
ByteBuffer.allocate(600), ByteBuffer.allocate(600)
};
SSLEngineResult r = server.unwrap(netBuf, outArr, 2, 2);
assertEquals(SSLEngineResult.Status.OK, r.getStatus());
assertOffsetUnwrapOk(r, outArr, data);
}

@Test
public void testUnwrapPendingAppDataWithOffset() throws Exception {

this.ctx = tf.createSSLContext("TLS", engineProvider);
SSLEngine server = this.ctx.createSSLEngine();
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);
server.setUseClientMode(false);
client.setUseClientMode(true);
assertEquals(0, tf.testConnection(server, client, null, null, "x"));

byte[] data = new byte[1024];
new Random().nextBytes(data);
ByteBuffer netBuf = wrapForServer(client, data);

/* First unwrap into too-small output stashes pendingAppData */
SSLEngineResult r = server.unwrap(netBuf, ByteBuffer.allocate(64));
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, r.getStatus());

ByteBuffer[] outArr = new ByteBuffer[] {
ByteBuffer.allocate(600), ByteBuffer.allocate(600),
ByteBuffer.allocate(600), ByteBuffer.allocate(600)
};
r = server.unwrap(netBuf, outArr, 2, 2);
assertOffsetUnwrapOk(r, outArr, data);
}

@Test
public void testUnwrapPendingAppDataReStashWithOffset()
throws Exception {

this.ctx = tf.createSSLContext("TLS", engineProvider);
SSLEngine server = this.ctx.createSSLEngine();
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);
server.setUseClientMode(false);
client.setUseClientMode(true);
assertEquals(0, tf.testConnection(server, client, null, null, "x"));

byte[] data = new byte[1024];
new Random().nextBytes(data);
ByteBuffer netBuf = wrapForServer(client, data);

/* First unwrap stashes pendingAppData */
SSLEngineResult r = server.unwrap(netBuf, ByteBuffer.allocate(64));
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, r.getStatus());

/* Second unwrap: ofst > 0 but total still too small;
* pendingAppData must survive intact for a later call */
ByteBuffer[] tooSmall = new ByteBuffer[] {
ByteBuffer.allocate(200), ByteBuffer.allocate(200),
ByteBuffer.allocate(200), ByteBuffer.allocate(200)
};
r = server.unwrap(netBuf, tooSmall, 2, 2);
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, r.getStatus());

/* Third unwrap: ofst > 0 with room drains the stash */
ByteBuffer[] outArr = new ByteBuffer[] {
ByteBuffer.allocate(600), ByteBuffer.allocate(600),
ByteBuffer.allocate(600), ByteBuffer.allocate(600)
};
r = server.unwrap(netBuf, outArr, 2, 2);
assertOffsetUnwrapOk(r, outArr, data);
}
}

Loading