Skip to content

Commit 8e46221

Browse files
authored
Merge pull request #10336 from julek-wolfssl/wolfSSL_PEM_read_bio_X509_CRL-multi-crl-fix
src/x509.c: refactor wolfSSL_PEM_read_bio_X509_CRL onto the per-block reader
2 parents 3b7ac9f + b261ee6 commit 8e46221

4 files changed

Lines changed: 94 additions & 29 deletions

File tree

src/x509.c

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13494,36 +13494,35 @@ WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
1349413494
WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
1349513495
{
1349613496
#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
13497-
unsigned char* pem = NULL;
13498-
int pemSz = 0;
13499-
int derSz = 0;
13500-
DerBuffer* der = NULL;
1350113497
WOLFSSL_X509_CRL* crl = NULL;
1350213498

1350313499
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_CRL");
1350413500

13505-
if ((pem = ReadPemFromBioToBuffer(bp, &pemSz)) == NULL) {
13506-
goto err;
13507-
}
13508-
13509-
if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
13510-
goto err;
13511-
}
13512-
derSz = (int)der->length;
13513-
if ((crl = wolfSSL_d2i_X509_CRL(x, der->buffer, derSz)) == NULL) {
13514-
goto err;
13501+
/* OpenSSL's PEM_read_bio_X509_CRL skips intervening cert/key blocks
13502+
* and returns the next CRL in the stream (NULL only at EOF). Mirror
13503+
* that by looping over the per-block reader until we get a CRL or
13504+
* the BIO has nothing left to parse. */
13505+
for (;;) {
13506+
WOLFSSL_X509* x509 = NULL;
13507+
WOLFSSL_X509_PKEY* x_pkey = NULL;
13508+
if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bp, cb,
13509+
&x509, &crl, &x_pkey) != WOLFSSL_SUCCESS) {
13510+
break;
13511+
}
13512+
if (crl != NULL) {
13513+
break;
13514+
}
13515+
wolfSSL_X509_free(x509);
13516+
wolfSSL_X509_PKEY_free(x_pkey);
1351513517
}
1351613518

13517-
err:
13518-
if (pemSz == 0) {
13519-
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
13520-
}
13521-
XFREE(pem, 0, DYNAMIC_TYPE_PEM);
13522-
if (der != NULL) {
13523-
FreeDer(&der);
13519+
if (x != NULL) {
13520+
if (*x != NULL && *x != crl) {
13521+
wolfSSL_X509_CRL_free(*x);
13522+
}
13523+
*x = crl;
1352413524
}
1352513525

13526-
(void)cb;
1352713526
(void)u;
1352813527

1352913528
return crl;
@@ -13686,7 +13685,7 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
1368613685
#endif /* !NO_FILESYSTEM */
1368713686

1368813687
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
13689-
#ifdef OPENSSL_ALL
13688+
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
1369013689

1369113690
#ifndef NO_BIO
1369213691
/* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
@@ -13706,7 +13705,7 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
1370613705

1370713706

1370813707
/* free up all memory used by "xPkey" passed in */
13709-
static void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
13708+
void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
1371013709
{
1371113710
if (xPkey != NULL) {
1371213711
wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
@@ -13732,7 +13731,7 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
1373213731
* @param x_pkey Output
1373313732
* @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
1373413733
*/
13735-
static int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
13734+
int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
1373613735
WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
1373713736
WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
1373813737
{
@@ -13762,7 +13761,11 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
1376213761
return WOLFSSL_FAILURE;
1376313762
}
1376413763

13765-
if (l <= pem_struct_min_sz) {
13764+
if (l == 0) {
13765+
/* Streaming BIO (pipe/FIFO/socket): size unknown, use the cap. */
13766+
l = MAX_BIO_READ_BUFFER;
13767+
}
13768+
else if (l <= pem_struct_min_sz) {
1376613769
/* No certificate in buffer */
1376713770
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
1376813771
return WOLFSSL_FAILURE;
@@ -13916,6 +13919,9 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
1391613919
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
1391713920
}
1391813921

13922+
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
13923+
#ifdef OPENSSL_ALL
13924+
1391913925
#ifndef NO_FILESYSTEM
1392013926
WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
1392113927
XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
@@ -14053,7 +14059,7 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
1405314059
return localSk;
1405414060
}
1405514061
#endif /* !NO_BIO */
14056-
#endif /* OPENSSL_ALL */
14062+
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
1405714063

1405814064
void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
1405914065
{

tests/api/test_ossl_x509_lu.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,17 @@ int test_wolfSSL_X509_load_crl_file(void)
312312
#endif
313313
""
314314
};
315+
int pemCount[] = {
316+
1,
317+
2,
318+
1,
319+
1,
320+
1,
321+
#ifdef WC_RSA_PSS
322+
1,
323+
#endif
324+
0
325+
};
315326
char der[][100] = {
316327
"./certs/crl/crl.der",
317328
"./certs/crl/crl2.der",
@@ -342,7 +353,7 @@ int test_wolfSSL_X509_load_crl_file(void)
342353
ExpectIntEQ(X509_load_crl_file(lookup, pem[0], 0), 0);
343354
for (i = 0; pem[i][0] != '\0'; i++) {
344355
ExpectIntEQ(X509_load_crl_file(lookup, pem[i], WOLFSSL_FILETYPE_PEM),
345-
1);
356+
pemCount[i]);
346357
}
347358

348359
if (store) {
@@ -394,6 +405,45 @@ int test_wolfSSL_X509_load_crl_file(void)
394405

395406
X509_STORE_free(store);
396407
store = NULL;
408+
409+
/* Combine crl.pem (1 CRL), a server cert, and crl2.pem (2 CRLs) into a
410+
* single memory BIO. wolfSSL_PEM_read_bio_X509_CRL must walk past the
411+
* intervening certificate and hand back all three CRLs before NULL,
412+
* matching OpenSSL's PEM_read_bio_X509_CRL behaviour. */
413+
{
414+
WOLFSSL_BIO* fileBio = NULL;
415+
WOLFSSL_BIO* memBio = NULL;
416+
WOLFSSL_X509_CRL* crl = NULL;
417+
unsigned char buf[4096];
418+
int n;
419+
int crlCount = 0;
420+
const char* sources[] = {
421+
"./certs/crl/crl.pem",
422+
"./certs/server-cert.pem",
423+
"./certs/crl/crl2.pem",
424+
NULL
425+
};
426+
427+
ExpectNotNull(memBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
428+
for (i = 0; sources[i] != NULL; i++) {
429+
ExpectNotNull(fileBio = wolfSSL_BIO_new_file(sources[i], "rb"));
430+
while (fileBio != NULL &&
431+
(n = wolfSSL_BIO_read(fileBio, buf, sizeof(buf))) > 0) {
432+
ExpectIntEQ(wolfSSL_BIO_write(memBio, buf, n), n);
433+
}
434+
wolfSSL_BIO_free(fileBio);
435+
fileBio = NULL;
436+
}
437+
438+
while ((crl = wolfSSL_PEM_read_bio_X509_CRL(memBio, NULL, NULL, NULL))
439+
!= NULL) {
440+
crlCount++;
441+
wolfSSL_X509_CRL_free(crl);
442+
}
443+
ExpectIntEQ(crlCount, 3);
444+
445+
wolfSSL_BIO_free(memBio);
446+
}
397447
#endif
398448
return EXPECT_RESULT();
399449
}

tests/api/test_ossl_x509_lu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int test_X509_LOOKUP_add_dir(void);
3434
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_load_file), \
3535
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_file), \
3636
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_hash_dir), \
37-
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_LOOKUP_ctrl_hash_dir), \
37+
TEST_DECL_GROUP("ossl_x509_lu", test_wolfSSL_X509_load_crl_file), \
3838
TEST_DECL_GROUP("ossl_x509_lu", test_X509_LOOKUP_add_dir)
3939

4040
#endif /* WOLFCRYPT_TEST_OSSL_X509_LU_H */

wolfssl/internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7470,6 +7470,15 @@ WOLFSSL_LOCAL int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
74707470
word32* keySz);
74717471
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
74727472

7473+
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && !defined(NO_BIO)
7474+
WOLFSSL_LOCAL int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
7475+
WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
7476+
WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey);
7477+
#endif
7478+
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
7479+
WOLFSSL_LOCAL void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey);
7480+
#endif
7481+
74737482
WOLFSSL_LOCAL void wolfssl_local_MaybeCheckAlertOnErr(WOLFSSL* ssl, int err);
74747483

74757484
#ifdef __cplusplus

0 commit comments

Comments
 (0)