mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
Merge pull request #8608 from anhu/2akid
Check for duplicate extensions in a CRL
This commit is contained in:
39
tests/api.c
39
tests/api.c
@ -4257,6 +4257,44 @@ static int test_wolfSSL_CertManagerNameConstraint5(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_wolfSSL_CRL_duplicate_extensions(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS) && \
|
||||
defined(HAVE_CRL) && !defined(NO_RSA) && !defined(WOLFSSL_NO_ASN_STRICT)
|
||||
const unsigned char crl_duplicate_akd[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIICCDCB8QIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK\n"
|
||||
"TXkgQ29tcGFueTETMBEGA1UEAwwKTXkgUm9vdCBDQTETMBEGA1UECwwKTXkgUm9v\n"
|
||||
"dCBDQRcNMjQwOTAxMDAwMDAwWhcNMjUxMjAxMDAwMDAwWqBEMEIwHwYDVR0jBBgw\n"
|
||||
"FoAU72ng99Ud5pns3G3Q9+K5XGRxgzUwHwYDVR0jBBgwFoAU72ng99Ud5pns3G3Q\n"
|
||||
"9+K5XGRxgzUwDQYJKoZIhvcNAQELBQADggEBAIFVw4jrS4taSXR/9gPzqGrqFeHr\n"
|
||||
"IXCnFtHJTLxqa8vUOAqSwqysvNpepVKioMVoGrLjFMjANjWQqTEiMROAnLfJ/+L8\n"
|
||||
"FHZkV/mZwOKAXMhIC9MrJzifxBICwmvD028qnwQm09EP8z4ICZptD6wPdRTDzduc\n"
|
||||
"KBuAX+zn8pNrJgyrheRKpPgno9KsbCzK4D/RIt1sTK2M3vVOtY+vpsN70QYUXvQ4\n"
|
||||
"r2RZac3omlT43x5lddPxIlcouQpwWcVvr/K+Va770MRrjn88PBrJmvsEw/QYVBXp\n"
|
||||
"Gxv2b78HFDacba80sMIm8ltRdqUCa5qIc6OATsz7izCQXEbkTEeESrcK1MA=\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
WOLFSSL_CERT_MANAGER* cm = NULL;
|
||||
int ret;
|
||||
|
||||
cm = wolfSSL_CertManagerNew();
|
||||
ExpectNotNull(cm);
|
||||
|
||||
/* Test loading CRL with duplicate extensions */
|
||||
WOLFSSL_MSG("Testing CRL with duplicate Authority Key Identifier extensions");
|
||||
ret = wolfSSL_CertManagerLoadCRLBuffer(cm, crl_duplicate_akd,
|
||||
sizeof(crl_duplicate_akd),
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
ExpectIntEQ(ret, ASN_PARSE_E);
|
||||
|
||||
wolfSSL_CertManagerFree(cm);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_wolfSSL_CertManagerCRL(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@ -68150,6 +68188,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_wolfSSL_CertManagerNameConstraint4),
|
||||
TEST_DECL(test_wolfSSL_CertManagerNameConstraint5),
|
||||
TEST_DECL(test_wolfSSL_CertManagerCRL),
|
||||
TEST_DECL(test_wolfSSL_CRL_duplicate_extensions),
|
||||
TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse),
|
||||
TEST_DECL(test_wolfSSL_CheckOCSPResponse),
|
||||
#ifdef HAVE_CERT_CHAIN_VALIDATION
|
||||
|
@ -40566,6 +40566,9 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
|
||||
{
|
||||
DECL_ASNGETDATA(dataASN, certExtASN_Length);
|
||||
int ret = 0;
|
||||
/* Track if we've seen these extensions already */
|
||||
word32 seenAuthKey = 0;
|
||||
word32 seenCrlNum = 0;
|
||||
|
||||
ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
|
||||
|
||||
@ -40588,47 +40591,71 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
|
||||
/* Length of extension data. */
|
||||
int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
|
||||
|
||||
if (oid == AUTH_KEY_OID) {
|
||||
#ifndef NO_SKID
|
||||
/* Parse Authority Key Id extension.
|
||||
* idx is at start of OCTET_STRING data. */
|
||||
ret = ParseCRL_AuthKeyIdExt(buf + localIdx, length, dcrl);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
|
||||
}
|
||||
#endif
|
||||
/* Check for duplicate extension. RFC 5280 Section 4.2 states that
|
||||
* a certificate must not include more than one instance of a
|
||||
* particular extension. Note that the same guidance does not appear
|
||||
* for CRLs but the same reasoning should apply. */
|
||||
if ((oid == AUTH_KEY_OID && seenAuthKey) ||
|
||||
(oid == CRL_NUMBER_OID && seenCrlNum)) {
|
||||
WOLFSSL_MSG("Duplicate CRL extension found");
|
||||
/* Gating !WOLFSSL_NO_ASN_STRICT will allow wolfCLU to have same
|
||||
* behaviour as OpenSSL */
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
ret = ASN_PARSE_E;
|
||||
#endif
|
||||
}
|
||||
else if (oid == CRL_NUMBER_OID) {
|
||||
DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ * CHAR_BIT,
|
||||
CRL_MAX_NUM_SZ * CHAR_BIT);
|
||||
NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
#ifdef MP_INT_SIZE_CHECK_NULL
|
||||
if (m == NULL) {
|
||||
ret = MEMORY_E;
|
||||
/* Track this extension if no duplicate found */
|
||||
if (ret == 0) {
|
||||
if (oid == AUTH_KEY_OID)
|
||||
seenAuthKey = 1;
|
||||
else if (oid == CRL_NUMBER_OID)
|
||||
seenCrlNum = 1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (oid == AUTH_KEY_OID) {
|
||||
#ifndef NO_SKID
|
||||
/* Parse Authority Key Id extension.
|
||||
* idx is at start of OCTET_STRING data. */
|
||||
ret = ParseCRL_AuthKeyIdExt(buf + localIdx, length, dcrl);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
else if (oid == CRL_NUMBER_OID) {
|
||||
DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ * CHAR_BIT,
|
||||
CRL_MAX_NUM_SZ * CHAR_BIT);
|
||||
NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
if (ret == 0 && (INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT)
|
||||
!= MP_OKAY)) {
|
||||
#ifdef MP_INT_SIZE_CHECK_NULL
|
||||
if (m == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0 && (INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ *
|
||||
CHAR_BIT) != MP_OKAY)) {
|
||||
ret = MP_INIT_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = GetInt(m, buf, &localIdx, maxIdx);
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_toradix(m, (char*)dcrl->crlNumber,
|
||||
MP_RADIX_HEX) != MP_OKAY)
|
||||
ret = BUFFER_E;
|
||||
|
||||
if (ret == 0) {
|
||||
dcrl->crlNumberSet = 1;
|
||||
}
|
||||
|
||||
mp_free(m);
|
||||
FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = GetInt(m, buf, &localIdx, maxIdx);
|
||||
}
|
||||
|
||||
if (ret == 0 && mp_toradix(m, (char*)dcrl->crlNumber,
|
||||
MP_RADIX_HEX) != MP_OKAY)
|
||||
ret = BUFFER_E;
|
||||
|
||||
if (ret == 0) {
|
||||
dcrl->crlNumberSet = 1;
|
||||
}
|
||||
|
||||
mp_free(m);
|
||||
FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
/* TODO: check criticality */
|
||||
/* Move index on to next extension. */
|
||||
|
Reference in New Issue
Block a user