Skip to content

Commit f8d6403

Browse files
committed
Check for duplicate extensions in a CRL
1 parent 1c56a26 commit f8d6403

File tree

2 files changed

+94
-35
lines changed

2 files changed

+94
-35
lines changed

tests/api.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4209,6 +4209,44 @@ static int test_wolfSSL_CertManagerNameConstraint5(void)
42094209
return EXPECT_RESULT();
42104210
}
42114211

4212+
static int test_wolfSSL_CRL_duplicate_extensions(void)
4213+
{
4214+
EXPECT_DECLS;
4215+
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
4216+
!defined(NO_RSA)
4217+
const unsigned char crl_duplicate_akd[] =
4218+
"-----BEGIN X509 CRL-----\n"
4219+
"MIICCDCB8QIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzETMBEGA1UE\n"
4220+
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK\n"
4221+
"TXkgQ29tcGFueTETMBEGA1UEAwwKTXkgUm9vdCBDQTETMBEGA1UECwwKTXkgUm9v\n"
4222+
"dCBDQRcNMjQwOTAxMDAwMDAwWhcNMjUxMjAxMDAwMDAwWqBEMEIwHwYDVR0jBBgw\n"
4223+
"FoAU72ng99Ud5pns3G3Q9+K5XGRxgzUwHwYDVR0jBBgwFoAU72ng99Ud5pns3G3Q\n"
4224+
"9+K5XGRxgzUwDQYJKoZIhvcNAQELBQADggEBAIFVw4jrS4taSXR/9gPzqGrqFeHr\n"
4225+
"IXCnFtHJTLxqa8vUOAqSwqysvNpepVKioMVoGrLjFMjANjWQqTEiMROAnLfJ/+L8\n"
4226+
"FHZkV/mZwOKAXMhIC9MrJzifxBICwmvD028qnwQm09EP8z4ICZptD6wPdRTDzduc\n"
4227+
"KBuAX+zn8pNrJgyrheRKpPgno9KsbCzK4D/RIt1sTK2M3vVOtY+vpsN70QYUXvQ4\n"
4228+
"r2RZac3omlT43x5lddPxIlcouQpwWcVvr/K+Va770MRrjn88PBrJmvsEw/QYVBXp\n"
4229+
"Gxv2b78HFDacba80sMIm8ltRdqUCa5qIc6OATsz7izCQXEbkTEeESrcK1MA=\n"
4230+
"-----END X509 CRL-----\n";
4231+
4232+
WOLFSSL_CERT_MANAGER* cm = NULL;
4233+
int ret;
4234+
4235+
cm = wolfSSL_CertManagerNew();
4236+
ExpectNotNull(cm);
4237+
4238+
/* Test loading CRL with duplicate extensions */
4239+
WOLFSSL_MSG("Testing CRL with duplicate Authority Key Identifier extensions");
4240+
ret = wolfSSL_CertManagerLoadCRLBuffer(cm, crl_duplicate_akd,
4241+
sizeof(crl_duplicate_akd),
4242+
WOLFSSL_FILETYPE_PEM);
4243+
ExpectIntEQ(ret, ASN_PARSE_E);
4244+
4245+
wolfSSL_CertManagerFree(cm);
4246+
#endif
4247+
return EXPECT_RESULT();
4248+
}
4249+
42124250
static int test_wolfSSL_CertManagerCRL(void)
42134251
{
42144252
EXPECT_DECLS;
@@ -67425,6 +67463,7 @@ TEST_CASE testCases[] = {
6742567463
TEST_DECL(test_wolfSSL_CertManagerNameConstraint4),
6742667464
TEST_DECL(test_wolfSSL_CertManagerNameConstraint5),
6742767465
TEST_DECL(test_wolfSSL_CertManagerCRL),
67466+
TEST_DECL(test_wolfSSL_CRL_duplicate_extensions),
6742867467
TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse),
6742967468
TEST_DECL(test_wolfSSL_CheckOCSPResponse),
6743067469
#ifdef HAVE_CERT_CHAIN_VALIDATION

wolfcrypt/src/asn.c

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -39147,6 +39147,9 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
3914739147
{
3914839148
DECL_ASNGETDATA(dataASN, certExtASN_Length);
3914939149
int ret = 0;
39150+
/* Track if we've seen these extensions already */
39151+
word32 seenAuthKey = 0;
39152+
word32 seenCrlNum = 0;
3915039153

3915139154
ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
3915239155

@@ -39168,47 +39171,64 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
3916839171
/* Length of extension data. */
3916939172
int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
3917039173

39171-
if (oid == AUTH_KEY_OID) {
39172-
#ifndef NO_SKID
39173-
/* Parse Authority Key Id extension.
39174-
* idx is at start of OCTET_STRING data. */
39175-
ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
39176-
if (ret != 0) {
39177-
WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
39178-
}
39179-
#endif
39174+
/* Check for duplicate extension */
39175+
if ((oid == AUTH_KEY_OID && seenAuthKey) ||
39176+
(oid == CRL_NUMBER_OID && seenCrlNum)) {
39177+
WOLFSSL_MSG("Duplicate CRL extension found");
39178+
ret = ASN_PARSE_E;
3918039179
}
39181-
else if (oid == CRL_NUMBER_OID) {
39182-
#ifdef WOLFSSL_SMALL_STACK
39183-
mp_int* m = (mp_int*)XMALLOC(sizeof(*m), NULL,
39184-
DYNAMIC_TYPE_BIGINT);
39185-
if (m == NULL) {
39186-
ret = MEMORY_E;
39187-
}
39188-
#else
39189-
mp_int m[1];
39190-
#endif
3919139180

39192-
if (ret == 0) {
39193-
if (mp_init(m) != MP_OKAY) {
39194-
ret = MP_INIT_E;
39181+
/* Track this extension if no duplicate found */
39182+
if (ret == 0) {
39183+
if (oid == AUTH_KEY_OID)
39184+
seenAuthKey = 1;
39185+
else if (oid == CRL_NUMBER_OID)
39186+
seenCrlNum = 1;
39187+
}
39188+
39189+
if (ret == 0) {
39190+
if (oid == AUTH_KEY_OID) {
39191+
#ifndef NO_SKID
39192+
/* Parse Authority Key Id extension.
39193+
* idx is at start of OCTET_STRING data. */
39194+
ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
39195+
if (ret != 0) {
39196+
WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
3919539197
}
39198+
#endif
3919639199
}
39197-
if (ret == 0) {
39198-
ret = GetInt(m, buf, &idx, maxIdx);
39199-
}
39200-
if (ret == 0) {
39201-
dcrl->crlNumber = (int)m->dp[0];
39202-
}
39200+
else if (oid == CRL_NUMBER_OID) {
39201+
#ifdef WOLFSSL_SMALL_STACK
39202+
mp_int* m = (mp_int*)XMALLOC(sizeof(*m), NULL,
39203+
DYNAMIC_TYPE_BIGINT);
39204+
if (m == NULL) {
39205+
ret = MEMORY_E;
39206+
}
39207+
#else
39208+
mp_int m[1];
39209+
#endif
3920339210

39204-
mp_free(m);
39205-
#ifdef WOLFSSL_SMALL_STACK
39206-
XFREE(m, NULL, DYNAMIC_TYPE_BIGINT);
39207-
#endif
39211+
if (ret == 0) {
39212+
if (mp_init(m) != MP_OKAY) {
39213+
ret = MP_INIT_E;
39214+
}
39215+
}
39216+
if (ret == 0) {
39217+
ret = GetInt(m, buf, &idx, maxIdx);
39218+
}
39219+
if (ret == 0) {
39220+
dcrl->crlNumber = (int)m->dp[0];
39221+
}
39222+
39223+
mp_free(m);
39224+
#ifdef WOLFSSL_SMALL_STACK
39225+
XFREE(m, NULL, DYNAMIC_TYPE_BIGINT);
39226+
#endif
39227+
}
39228+
/* TODO: check criticality */
39229+
/* Move index on to next extension. */
39230+
idx += (word32)length;
3920839231
}
39209-
/* TODO: check criticality */
39210-
/* Move index on to next extension. */
39211-
idx += (word32)length;
3921239232
}
3921339233
}
3921439234

0 commit comments

Comments
 (0)