Skip to content

Commit 2bdb243

Browse files
committed
F-4851 / F-5065: honor caller sz and bound it to the array in CertManager buffer loaders
1 parent 9caa54a commit 2bdb243

3 files changed

Lines changed: 69 additions & 6 deletions

File tree

native/com_wolfssl_WolfSSLCertManager.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,13 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerLoadCABuff
116116
return BAD_FUNC_ARG;
117117
}
118118

119+
/* number of bytes to parse and must fit within the array */
120+
if (sz > (jlong)(*jenv)->GetArrayLength(jenv, in)) {
121+
return BAD_FUNC_ARG;
122+
}
123+
119124
buff = (byte*)(*jenv)->GetByteArrayElements(jenv, in, NULL);
120-
buffSz = (*jenv)->GetArrayLength(jenv, in);
125+
buffSz = (word32)sz;
121126

122127
if (buff != NULL) {
123128
ret = wolfSSL_CertManagerLoadCABuffer(cm, buff, buffSz, format);
@@ -159,8 +164,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerVerifyBuff
159164
if (jenv == NULL || in == NULL || (sz < 0))
160165
return BAD_FUNC_ARG;
161166

167+
/* number of bytes to parse and must fit within the array */
168+
if (sz > (jlong)(*jenv)->GetArrayLength(jenv, in))
169+
return BAD_FUNC_ARG;
170+
162171
buff = (byte*)(*jenv)->GetByteArrayElements(jenv, in, NULL);
163-
buffSz = (*jenv)->GetArrayLength(jenv, in);
172+
buffSz = (word32)sz;
164173

165174
if (buff != NULL) {
166175
ret = wolfSSL_CertManagerVerifyBuffer(cm, buff, buffSz, format);

src/java/com/wolfssl/WolfSSLCertManager.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,14 @@ public synchronized int CertManagerLoadCA(String f, String d)
116116
* Load CA into CertManager from byte array
117117
*
118118
* @param in byte array holding X.509 certificate to load
119-
* @param sz size of input byte array, bytes
119+
* @param sz number of bytes to parse from the start of in.
120+
* Must not exceed in.length.
120121
* @param format format of input certificate, either
121122
* WolfSSL.SSL_FILETYPE_PEM (PEM formatted) or
122123
* WolfSSL.SSL_FILETYPE_ASN1 (ASN.1/DER).
123124
*
124-
* @return WolfSSL.SSL_SUCCESS on success, negative on error
125+
* @return WolfSSL.SSL_SUCCESS on success, negative on error including
126+
* BAD_FUNC_ARG when sz exceeds in.length
125127
* @throws IllegalStateException WolfSSLContext has been freed
126128
*/
127129
public synchronized int CertManagerLoadCABuffer(
@@ -225,13 +227,15 @@ public synchronized int CertManagerUnloadCAs()
225227
* Verify X.509 certificate held in byte array
226228
*
227229
* @param in input X.509 certificate as byte array
228-
* @param sz size of input certificate array, bytes
230+
* @param sz number of bytes to parse from the start of in.
231+
* Must not exceed in.length.
229232
* @param format format of input certificate, either
230233
* WolfSSL.SSL_FILETYPE_PEM (PEM formatted) or
231234
* WolfSSL.SSL_FILETYPE_ASN1 (ASN.1/DER).
232235
*
233236
* @return WolfSSL.SSL_SUCCESS on successful verification, otherwise
234-
* negative on error.
237+
* negative on error including BAD_FUNC_ARG when sz exceeds
238+
* in.length.
235239
* @throws IllegalStateException WolfSSLContext has been freed
236240
*/
237241
public synchronized int CertManagerVerifyBuffer(

src/test/com/wolfssl/test/WolfSSLCertManagerTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,56 @@ public void testCertManagerLoadCA() throws Exception {
565565
}
566566
}
567567

568+
/* The buffer load/verify calls must parse exactly sz bytes from the start
569+
* of the array. A sz beyond the array is rejected instead of being
570+
* ignored and the whole backing array parsed. */
571+
@Test
572+
public void testCertManagerBufferHonorsSz() throws Exception {
573+
574+
WolfSSLCertManager cm = null;
575+
576+
try {
577+
byte[] caCertPem =
578+
Files.readAllBytes(new File(ocspRootCaCert).toPath());
579+
byte[] peerPem = Files.readAllBytes(new File(serverCert).toPath());
580+
581+
cm = new WolfSSLCertManager();
582+
583+
/* Exact length is the normal, supported call. */
584+
assertEquals("exact-length load should succeed",
585+
WolfSSL.SSL_SUCCESS,
586+
cm.CertManagerLoadCABuffer(caCertPem, caCertPem.length,
587+
WolfSSL.SSL_FILETYPE_PEM));
588+
589+
assertEquals("load sz past end of array must be rejected",
590+
WolfSSL.BAD_FUNC_ARG,
591+
cm.CertManagerLoadCABuffer(caCertPem, caCertPem.length + 1,
592+
WolfSSL.SSL_FILETYPE_PEM));
593+
594+
assertEquals("verify sz past end of array must be rejected",
595+
WolfSSL.BAD_FUNC_ARG,
596+
cm.CertManagerVerifyBuffer(peerPem, peerPem.length + 1,
597+
WolfSSL.SSL_FILETYPE_PEM));
598+
599+
/* A shorter sz must parse only the first sz bytes, not the whole
600+
* array. Half the PEM is malformed, so the load must fail. The
601+
* old code ignored sz and parsed the full array, succeeding. */
602+
assertTrue("a shorter sz must not parse the whole array",
603+
cm.CertManagerLoadCABuffer(caCertPem, caCertPem.length / 2,
604+
WolfSSL.SSL_FILETYPE_PEM) != WolfSSL.SSL_SUCCESS);
605+
606+
/* sz of zero parses nothing and must not succeed. */
607+
assertTrue("sz of zero must not succeed",
608+
cm.CertManagerLoadCABuffer(caCertPem, 0,
609+
WolfSSL.SSL_FILETYPE_PEM) != WolfSSL.SSL_SUCCESS);
610+
611+
} finally {
612+
if (cm != null) {
613+
cm.free();
614+
}
615+
}
616+
}
617+
568618
@Test
569619
public void testCertManagerCheckOCSPResponse()
570620
throws Exception {

0 commit comments

Comments
 (0)