Skip to content

Commit 1dff767

Browse files
committed
Check for duplicate extensions in a CRL
1 parent 978a29d commit 1dff767

2 files changed

Lines changed: 95 additions & 33 deletions

File tree

tests/api.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4256,6 +4256,44 @@ static int test_wolfSSL_CertManagerNameConstraint5(void)
42564256
return EXPECT_RESULT();
42574257
}
42584258

4259+
static int test_wolfSSL_CRL_duplicate_extensions(void)
4260+
{
4261+
EXPECT_DECLS;
4262+
#if defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS) && \
4263+
defined(HAVE_CRL) && !defined(NO_RSA) && !defined(WOLFSSL_NO_ASN_STRICT)
4264+
const unsigned char crl_duplicate_akd[] =
4265+
"-----BEGIN X509 CRL-----\n"
4266+
"MIICCDCB8QIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzETMBEGA1UE\n"
4267+
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK\n"
4268+
"TXkgQ29tcGFueTETMBEGA1UEAwwKTXkgUm9vdCBDQTETMBEGA1UECwwKTXkgUm9v\n"
4269+
"dCBDQRcNMjQwOTAxMDAwMDAwWhcNMjUxMjAxMDAwMDAwWqBEMEIwHwYDVR0jBBgw\n"
4270+
"FoAU72ng99Ud5pns3G3Q9+K5XGRxgzUwHwYDVR0jBBgwFoAU72ng99Ud5pns3G3Q\n"
4271+
"9+K5XGRxgzUwDQYJKoZIhvcNAQELBQADggEBAIFVw4jrS4taSXR/9gPzqGrqFeHr\n"
4272+
"IXCnFtHJTLxqa8vUOAqSwqysvNpepVKioMVoGrLjFMjANjWQqTEiMROAnLfJ/+L8\n"
4273+
"FHZkV/mZwOKAXMhIC9MrJzifxBICwmvD028qnwQm09EP8z4ICZptD6wPdRTDzduc\n"
4274+
"KBuAX+zn8pNrJgyrheRKpPgno9KsbCzK4D/RIt1sTK2M3vVOtY+vpsN70QYUXvQ4\n"
4275+
"r2RZac3omlT43x5lddPxIlcouQpwWcVvr/K+Va770MRrjn88PBrJmvsEw/QYVBXp\n"
4276+
"Gxv2b78HFDacba80sMIm8ltRdqUCa5qIc6OATsz7izCQXEbkTEeESrcK1MA=\n"
4277+
"-----END X509 CRL-----\n";
4278+
4279+
WOLFSSL_CERT_MANAGER* cm = NULL;
4280+
int ret;
4281+
4282+
cm = wolfSSL_CertManagerNew();
4283+
ExpectNotNull(cm);
4284+
4285+
/* Test loading CRL with duplicate extensions */
4286+
WOLFSSL_MSG("Testing CRL with duplicate Authority Key Identifier extensions");
4287+
ret = wolfSSL_CertManagerLoadCRLBuffer(cm, crl_duplicate_akd,
4288+
sizeof(crl_duplicate_akd),
4289+
WOLFSSL_FILETYPE_PEM);
4290+
ExpectIntEQ(ret, ASN_PARSE_E);
4291+
4292+
wolfSSL_CertManagerFree(cm);
4293+
#endif
4294+
return EXPECT_RESULT();
4295+
}
4296+
42594297
static int test_wolfSSL_CertManagerCRL(void)
42604298
{
42614299
EXPECT_DECLS;
@@ -68143,6 +68181,7 @@ TEST_CASE testCases[] = {
6814368181
TEST_DECL(test_wolfSSL_CertManagerNameConstraint4),
6814468182
TEST_DECL(test_wolfSSL_CertManagerNameConstraint5),
6814568183
TEST_DECL(test_wolfSSL_CertManagerCRL),
68184+
TEST_DECL(test_wolfSSL_CRL_duplicate_extensions),
6814668185
TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse),
6814768186
TEST_DECL(test_wolfSSL_CheckOCSPResponse),
6814868187
#ifdef HAVE_CERT_CHAIN_VALIDATION

wolfcrypt/src/asn.c

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -40540,6 +40540,9 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
4054040540
{
4054140541
DECL_ASNGETDATA(dataASN, certExtASN_Length);
4054240542
int ret = 0;
40543+
/* Track if we've seen these extensions already */
40544+
word32 seenAuthKey = 0;
40545+
word32 seenCrlNum = 0;
4054340546

4054440547
ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
4054540548

@@ -40562,49 +40565,69 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
4056240565
/* Length of extension data. */
4056340566
int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
4056440567

40565-
if (oid == AUTH_KEY_OID) {
40566-
#ifndef NO_SKID
40567-
/* Parse Authority Key Id extension.
40568-
* idx is at start of OCTET_STRING data. */
40569-
ret = ParseCRL_AuthKeyIdExt(buf + localIdx, length, dcrl);
40570-
if (ret != 0) {
40571-
WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
40572-
}
40573-
#endif
40568+
/* Check for duplicate extension */
40569+
if ((oid == AUTH_KEY_OID && seenAuthKey) ||
40570+
(oid == CRL_NUMBER_OID && seenCrlNum)) {
40571+
WOLFSSL_MSG("Duplicate CRL extension found");
40572+
/* Gating !WOLFSSL_NO_ASN_STRICT will allow wolfCLU to have same
40573+
* behaviour as OpenSSL */
40574+
#ifndef WOLFSSL_NO_ASN_STRICT
40575+
ret = ASN_PARSE_E;
40576+
#endif
4057440577
}
40575-
else if (oid == CRL_NUMBER_OID) {
40576-
DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ * CHAR_BIT,
40577-
CRL_MAX_NUM_SZ * CHAR_BIT);
40578-
NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
40579-
DYNAMIC_TYPE_TMP_BUFFER);
4058040578

40581-
#ifdef MP_INT_SIZE_CHECK_NULL
40582-
if (m == NULL) {
40583-
ret = MEMORY_E;
40579+
/* Track this extension if no duplicate found */
40580+
if (ret == 0) {
40581+
if (oid == AUTH_KEY_OID)
40582+
seenAuthKey = 1;
40583+
else if (oid == CRL_NUMBER_OID)
40584+
seenCrlNum = 1;
40585+
}
40586+
40587+
if (ret == 0) {
40588+
if (oid == AUTH_KEY_OID) {
40589+
#ifndef NO_SKID
40590+
/* Parse Authority Key Id extension.
40591+
* idx is at start of OCTET_STRING data. */
40592+
ret = ParseCRL_AuthKeyIdExt(buf + localIdx, length, dcrl);
40593+
if (ret != 0) {
40594+
WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
40595+
}
40596+
#endif
4058440597
}
40585-
#endif
40598+
else if (oid == CRL_NUMBER_OID) {
40599+
DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ * CHAR_BIT,
40600+
CRL_MAX_NUM_SZ * CHAR_BIT);
40601+
NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
40602+
DYNAMIC_TYPE_TMP_BUFFER);
40603+
40604+
#ifdef MP_INT_SIZE_CHECK_NULL
40605+
if (m == NULL) {
40606+
ret = MEMORY_E;
40607+
}
40608+
#endif
4058640609

40587-
if (ret == 0 && (INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT)
40588-
!= MP_OKAY)) {
40610+
if (ret == 0 && (INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ *
40611+
CHAR_BIT) != MP_OKAY)) {
4058940612
ret = MP_INIT_E;
40590-
}
40613+
}
4059140614

40592-
if (ret == 0) {
40593-
ret = GetInt(m, buf, &localIdx, maxIdx);
40594-
}
40615+
if (ret == 0) {
40616+
ret = GetInt(m, buf, &localIdx, maxIdx);
40617+
}
4059540618

40596-
if (ret == 0 && mp_toradix(m, (char*)dcrl->crlNumber,
40597-
MP_RADIX_HEX) != MP_OKAY)
40598-
ret = BUFFER_E;
40619+
if (ret == 0 && mp_toradix(m, (char*)dcrl->crlNumber,
40620+
MP_RADIX_HEX) != MP_OKAY)
40621+
ret = BUFFER_E;
4059940622

40600-
if (ret == 0) {
40601-
dcrl->crlNumberSet = 1;
40602-
}
40623+
if (ret == 0) {
40624+
dcrl->crlNumberSet = 1;
40625+
}
4060340626

40604-
mp_free(m);
40605-
FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40627+
mp_free(m);
40628+
FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40629+
}
4060640630
}
40607-
/* TODO: check criticality */
4060840631
/* Move index on to next extension. */
4060940632
idx += (word32)length;
4061040633
}

0 commit comments

Comments
 (0)