@@ -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