Fix bug in ParseCRL_Extensions

This commit is contained in:
Lealem Amedie
2025-05-30 10:20:02 -06:00
parent 7898823d42
commit 02a49693e2
7 changed files with 228 additions and 116 deletions

View File

@@ -135,7 +135,10 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff,
#endif
dcrl->certs = NULL;
crle->totalCerts = dcrl->totalCerts;
crle->crlNumber = dcrl->crlNumber;
crle->crlNumberSet = dcrl->crlNumberSet;
if (crle->crlNumberSet) {
XMEMCPY(crle->crlNumber, dcrl->crlNumber, CRL_MAX_NUM_SZ);
}
crle->verified = verified;
if (!verified) {
crle->tbsSz = dcrl->sigIndex - dcrl->certBegin;
@@ -587,7 +590,9 @@ static void SetCrlInfo(CRL_Entry* entry, CrlInfo *info)
info->nextDate = (byte *)entry->nextDate;
info->nextDateMaxLen = MAX_DATE_SIZE;
info->nextDateFormat = entry->nextDateFormat;
info->crlNumber = (sword32)entry->crlNumber;
info->crlNumberSet = entry->crlNumberSet;
if (info->crlNumberSet)
XMEMCPY(info->crlNumber, entry->crlNumber, CRL_MAX_NUM_SZ);
}
static void SetCrlInfoFromDecoded(DecodedCRL* entry, CrlInfo *info)
@@ -600,10 +605,55 @@ static void SetCrlInfoFromDecoded(DecodedCRL* entry, CrlInfo *info)
info->nextDate = (byte *)entry->nextDate;
info->nextDateMaxLen = MAX_DATE_SIZE;
info->nextDateFormat = entry->nextDateFormat;
info->crlNumber = (sword32)entry->crlNumber;
info->crlNumberSet = entry->crlNumberSet;
if (info->crlNumberSet)
XMEMCPY(info->crlNumber, entry->crlNumber, CRL_MAX_NUM_SZ);
}
#endif
/* Returns MP_GT if prev crlNumber is smaller
* MP_EQ if equal
* MP_LT if prev crlNumber is larger */
static int CompareCRLnumber(CRL_Entry* prev, CRL_Entry* curr)
{
int ret = 0;
DECL_MP_INT_SIZE_DYN(prev_num, CRL_MAX_NUM_SZ * CHAR_BIT,
CRL_MAX_NUM_SZ * CHAR_BIT);
DECL_MP_INT_SIZE_DYN(curr_num, CRL_MAX_NUM_SZ * CHAR_BIT,
CRL_MAX_NUM_SZ * CHAR_BIT);
NEW_MP_INT_SIZE(prev_num, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
NEW_MP_INT_SIZE(curr_num, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
#ifdef MP_INT_SIZE_CHECK_NULL
if ((prev_num == NULL) || (curr_num == NULL)) {
ret = MEMORY_E;
}
#endif
if (ret == 0 && ((INIT_MP_INT_SIZE(prev_num, CRL_MAX_NUM_SZ * CHAR_BIT)
!= MP_OKAY) || (INIT_MP_INT_SIZE(curr_num,
CRL_MAX_NUM_SZ * CHAR_BIT)) != MP_OKAY)) {
ret = MP_INIT_E;
}
if (ret == 0 && (mp_read_radix(prev_num, (char*)prev->crlNumber,
MP_RADIX_HEX) != MP_OKAY ||
mp_read_radix(curr_num, (char*)curr->crlNumber,
MP_RADIX_HEX) != MP_OKAY)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0)
ret = mp_cmp(prev_num, curr_num);
FREE_MP_INT_SIZE(prev_num, NULL, DYNAMIC_TYPE_TMP_BUFFER);
FREE_MP_INT_SIZE(curr_num, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
/* Add Decoded CRL, 0 on success */
static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
int verified)
@@ -615,6 +665,7 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
CrlInfo old;
CrlInfo cnew;
#endif
int ret = 0;
WOLFSSL_ENTER("AddCRL");
@@ -645,12 +696,19 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
for (curr = crl->crlList; curr != NULL; curr = curr->next) {
if (XMEMCMP(curr->issuerHash, crle->issuerHash, CRL_DIGEST_SIZE) == 0) {
if (crle->crlNumber <= curr->crlNumber) {
ret = CompareCRLnumber(crle, curr);
/* Error out if the CRL we're attempting to add isn't more
* authoritative than the existing entry */
if (ret == MP_LT || ret == MP_EQ) {
WOLFSSL_MSG("Same or newer CRL entry already exists");
CRL_Entry_free(crle, crl->heap);
wc_UnLockRwLock(&crl->crlLock);
return BAD_FUNC_ARG;
}
else if (ret < 0) {
WOLFSSL_MSG("Error comparing CRL Numbers");
return ret;
}
crle->next = curr->next;
if (prev != NULL) {

View File

@@ -6414,8 +6414,7 @@ static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
scratch + scratchLen, scratchSz - scratchLen,
"%02x%s", serial[i], (i < sz - 1) ?
(delimiter ? ":" : "") : "\n"))
>= scratchSz - scratchLen)
{
>= scratchSz - scratchLen) {
WOLFSSL_MSG("buffer overrun");
return WOLFSSL_FAILURE;
}
@@ -6428,10 +6427,8 @@ static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
/* if serial can fit into byte then print on the same line */
else {
if ((scratchLen = XSNPRINTF(
scratch, MAX_WIDTH, " %d (0x%x)\n", serial[0], serial[0]))
>= MAX_WIDTH)
{
if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
(char)serial[0], serial[0])) >= MAX_WIDTH) {
WOLFSSL_MSG("buffer overrun");
return WOLFSSL_FAILURE;
}
@@ -8870,85 +8867,135 @@ static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
int indent)
{
char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
int ret = 0;
if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
"CRL extensions:") >= MAX_WIDTH) {
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (crl->crlList->crlNumber) {
if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
if (ret == 0 && crl->crlList->crlNumberSet) {
char dec_string[49]; /* 20 octets can express numbers up to approx
49 decimal digits */
int freeMp = 0;
#ifdef WOLFSSL_SMALL_STACK
mp_int* dec_num = (mp_int*)XMALLOC(sizeof(*dec_num), NULL,
DYNAMIC_TYPE_BIGINT);
if (dec_num == NULL) {
ret = MEMORY_E;
}
#else
mp_int dec_num[1];
#endif
if (ret == 0 && (mp_init(dec_num) != MP_OKAY)) {
ret = MP_INIT_E;
}
else if (ret == 0) {
freeMp = 1;
}
if (ret == 0 && mp_read_radix(dec_num, (char *)crl->crlList->crlNumber,
MP_RADIX_HEX) != MP_OKAY) {
ret = WOLFSSL_FAILURE;
}
if (ret == 0 && mp_toradix(dec_num, dec_string, MP_RADIX_DEC)
!= MP_OKAY) {
ret = WOLFSSL_FAILURE;
}
if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
"X509v3 CRL Number:") >= MAX_WIDTH) {
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
ret = WOLFSSL_FAILURE;
}
if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%d\n", indent + 8, "",
crl->crlList->crlNumber) >= MAX_WIDTH)
{
return WOLFSSL_FAILURE;
if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 8, "",
dec_string) >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
ret = WOLFSSL_FAILURE;
}
XMEMSET(tmp, 0, sizeof(tmp));
if (freeMp) {
mp_free(dec_num);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(dec_num, NULL, DYNAMIC_TYPE_BIGINT);
#endif
}
#if !defined(NO_SKID)
if (crl->crlList->extAuthKeyIdSet && crl->crlList->extAuthKeyId[0] != 0) {
if (ret == 0 && crl->crlList->extAuthKeyIdSet &&
crl->crlList->extAuthKeyId[0] != 0) {
word32 i;
char val[5];
int valSz = 5;
if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 4, "",
"X509v3 Authority Key Identifier:") >= MAX_WIDTH) {
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
if (ret == 0) {
XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
}
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
ret = WOLFSSL_FAILURE;
}
XMEMSET(tmp, 0, MAX_WIDTH);
if (XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
indent + 8, "", "keyid") >= MAX_WIDTH) {
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
for (i = 0; i < XSTRLEN((char*)crl->crlList->extAuthKeyId); i++) {
/* check if buffer is almost full */
if (XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
if (ret == 0 && XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
tmp[0] = '\0';
}
if (XSNPRINTF(val, (size_t)valSz, ":%02X",
crl->crlList->extAuthKeyId[i]) >= valSz)
{
if (ret == 0 && XSNPRINTF(val, (size_t)valSz, ":%02X",
crl->crlList->extAuthKeyId[i]) >= valSz) {
WOLFSSL_MSG("buffer overrun");
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
if (ret == 0) {
XSTRNCAT(tmp, val, valSz);
}
XSTRNCAT(tmp, val, valSz);
}
XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
if (ret == 0) {
XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
}
if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
ret = WOLFSSL_FAILURE;
}
}
#endif
return WOLFSSL_SUCCESS;
if (ret == 0) {
ret = WOLFSSL_SUCCESS;
}
return ret;
}
/* iterate through a CRL's Revoked Certs and print out in human
@@ -9180,7 +9227,7 @@ void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
}
#endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
#ifdef OPENSSL_EXTRA
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
{
if ((crl != NULL) && (crl->crlList != NULL) &&
@@ -9210,7 +9257,7 @@ int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
return 0;
}
#endif
#endif /* OPENSSL_EXTRA */
#endif /* HAVE_CRL && OPENSSL_EXTRA */
#ifdef OPENSSL_EXTRA