From 2a652205278f5885c9dda173317edd3fbb902207 Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Fri, 19 Aug 2022 12:21:35 -0700 Subject: [PATCH 1/5] Adding X509_CRL_print() function --- src/crl.c | 21 +- src/x509.c | 664 ++++++++++++++++++++++++++++++++++------ tests/api.c | 31 +- wolfcrypt/src/asn.c | 95 +++++- wolfssl/internal.h | 5 + wolfssl/openssl/ssl.h | 1 + wolfssl/ssl.h | 11 +- wolfssl/wolfcrypt/asn.h | 7 + 8 files changed, 722 insertions(+), 113 deletions(-) diff --git a/src/crl.c b/src/crl.c index 0eab93fff..26a782ad5 100644 --- a/src/crl.c +++ b/src/crl.c @@ -90,10 +90,19 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff, XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE); crle->lastDateFormat = dcrl->lastDateFormat; crle->nextDateFormat = dcrl->nextDateFormat; - + crle->version = dcrl->version; +#if defined(OPENSSL_EXTRA) + crle->issuer = NULL; + wolfSSL_d2i_X509_NAME(&crle->issuer, (unsigned char**)&dcrl->issuer, + XSTRLEN((const char*)dcrl->issuer)); + if (crle->issuer == NULL) { + return WOLFSSL_FAILURE; + } +#endif crle->certs = dcrl->certs; /* take ownsership */ dcrl->certs = NULL; crle->totalCerts = dcrl->totalCerts; + crle->crlNumber = dcrl->crlNumber; crle->verified = verified; if (!verified) { crle->tbsSz = dcrl->sigIndex - dcrl->certBegin; @@ -146,7 +155,12 @@ static void FreeCRL_Entry(CRL_Entry* crle, void* heap) XFREE(crle->signature, heap, DYNAMIC_TYPE_CRL_ENTRY); if (crle->toBeSigned != NULL) XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_CRL_ENTRY); - +#if defined(OPENSSL_EXTRA) + if (crle->issuer != NULL) { + FreeX509Name(crle->issuer); + XFREE(crle->issuer, heap, DYNAMIC_TYPE_X509); + } +#endif (void)heap; } @@ -558,6 +572,9 @@ static RevokedCert *DupRevokedCertList(RevokedCert* in, void* heap) XMEMCPY(tmp->serialNumber, current->serialNumber, EXTERNAL_SERIAL_SIZE); tmp->serialSz = current->serialSz; + XMEMCPY(tmp->revDate, current->revDate, + MAX_DATE_SIZE); + tmp->revDateFormat = current->revDateFormat; tmp->next = NULL; if (prev != NULL) prev->next = tmp; diff --git a/src/x509.c b/src/x509.c index bfa5af079..bd91c419b 100644 --- a/src/x509.c +++ b/src/x509.c @@ -5504,69 +5504,77 @@ static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, /* print serial number out * return WOLFSSL_SUCCESS on success */ -static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) +static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz, + int delimiter, int indent) { - unsigned char serial[32]; - int sz = sizeof(serial); char scratch[MAX_WIDTH]; const int scratchSz = sizeof(scratch); int scratchLen; - XMEMSET(serial, 0, sz); - if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) { - if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:", - indent, "")) >= MAX_WIDTH) { + if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:", + indent, "")) >= MAX_WIDTH) { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { + return WOLFSSL_FAILURE; + } + + if (sz > (int)sizeof(byte)) { + int i; + int valLen; + + /* serial is larger than int size so print off hex values */ + if ((scratchLen = XSNPRINTF( + scratch, MAX_WIDTH, "\n%*s", indent, "")) + >= MAX_WIDTH) { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + for (i = 0; i < sz; i++) { + if ((valLen = XSNPRINTF( + scratch + scratchLen, scratchSz - scratchLen, + "%02x%s", serial[i], (i < sz - 1) ? + (delimiter ? ":" : "") : "\n")) + >= scratchSz - scratchLen) + { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + scratchLen += valLen; + } + if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { + return WOLFSSL_FAILURE; + } + } + + /* 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) + { WOLFSSL_MSG("buffer overrun"); return WOLFSSL_FAILURE; } if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { return WOLFSSL_FAILURE; } - - if (sz > (int)sizeof(byte)) { - int i; - int valLen; - - /* serial is larger than int size so print off hex values */ - if ((scratchLen = XSNPRINTF( - scratch, MAX_WIDTH, "\n%*s", indent, "")) - >= MAX_WIDTH) { - WOLFSSL_MSG("buffer overrun"); - return WOLFSSL_FAILURE; - } - for (i = 0; i < sz; i++) { - if ((valLen = XSNPRINTF( - scratch + scratchLen, scratchSz - scratchLen, - "%02x%s", serial[i], (i < sz - 1) ? ":" : "\n")) - >= scratchSz - scratchLen) - { - WOLFSSL_MSG("buffer overrun"); - return WOLFSSL_FAILURE; - } - scratchLen += valLen; - } - if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { - return WOLFSSL_FAILURE; - } - } - - /* 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) - { - WOLFSSL_MSG("buffer overrun"); - return WOLFSSL_FAILURE; - } - if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { - return WOLFSSL_FAILURE; - } - } } return WOLFSSL_SUCCESS; } +static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) +{ + unsigned char serial[32]; + int sz = sizeof(serial); + + XMEMSET(serial, 0, sz); + if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) { + X509PrintSerial_ex(bio, serial, sz, 1, indent); + } + return WOLFSSL_SUCCESS; +} /* iterate through certificate extensions printing them out in human readable * form @@ -5804,26 +5812,21 @@ static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) * wolfSSL_X509_print() * return WOLFSSL_SUCCESS on success */ -static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) +static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig, int sigSz, int sigNid, + int algOnly, int indent) { char scratch[MAX_WIDTH]; int scratchLen; - unsigned char* sig = NULL; - int sigSz = 0; WOLFSSL_ASN1_OBJECT* obj = NULL; int ret = WOLFSSL_SUCCESS; int i; char tmp[100]; int tmpLen = 0; - int sigNid; - wolfSSL_X509_get_signature(x509, NULL, &sigSz); if (sigSz <= 0) { return WOLFSSL_SUCCESS; } - sigNid = wolfSSL_X509_get_signature_nid(x509); - if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Signature Algorithm: ")) >= MAX_WIDTH) { ret = WOLFSSL_FAILURE; @@ -5859,19 +5862,17 @@ static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) ret = WOLFSSL_FAILURE; } - if (ret == WOLFSSL_SUCCESS) { - sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sig == NULL) - ret = WOLFSSL_FAILURE; + /* Leave function if the desired content to print + * is only the signature algorithm */ + if (algOnly) { + if (obj != NULL) + wolfSSL_ASN1_OBJECT_free(obj); + + return ret; } if (ret == WOLFSSL_SUCCESS) { - if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) - ret = WOLFSSL_FAILURE; - } - - if (ret == WOLFSSL_SUCCESS) { - if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent + 4, "")) + if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent + 5, "")) >= (int)sizeof(tmp)) { ret = WOLFSSL_FAILURE; @@ -5898,7 +5899,7 @@ static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) break; } if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s", - indent + 4, "")) + indent + 5, "")) >= (int)sizeof(tmp)) { ret = WOLFSSL_FAILURE; @@ -5943,10 +5944,41 @@ static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) if (obj != NULL) wolfSSL_ASN1_OBJECT_free(obj); - if (sig != NULL) - XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; +} - return ret; +static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, + int algOnly, int indent) +{ + int sigSz = 0; + wolfSSL_X509_get_signature(x509, NULL, &sigSz); + if (sigSz > 0) { + unsigned char* sig; + int sigNid = wolfSSL_X509_get_signature_nid(x509); + + sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sig == NULL) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) { + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + + if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent) + != WOLFSSL_SUCCESS) { + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + + if (sig != NULL) { + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + } + + return WOLFSSL_SUCCESS; } @@ -6012,17 +6044,11 @@ static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, /* human readable print out of x509 version * return WOLFSSL_SUCCESS on success */ -static int _wolfSSL_X509_version_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, - int indent) +static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent) { - int version; char scratch[MAX_WIDTH]; int scratchLen; - if ((version = wolfSSL_X509_version(x509)) < 0) { - return WOLFSSL_FAILURE; - } - if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:")) >= MAX_WIDTH) @@ -6045,7 +6071,6 @@ static int _wolfSSL_X509_version_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, return WOLFSSL_SUCCESS; } - #ifdef WOLFSSL_CERT_REQ /* Print out of REQ attributes * return WOLFSSL_SUCCESS on success @@ -6127,7 +6152,7 @@ int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) } /* print version of cert */ - if (_wolfSSL_X509_version_print(bio, x509, 8) != WOLFSSL_SUCCESS) { + if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -6157,7 +6182,7 @@ int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) } /* print out signature */ - if (X509PrintSignature(bio, x509, 4) != WOLFSSL_SUCCESS) { + if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -6205,7 +6230,7 @@ int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, } /* print version of cert */ - if (_wolfSSL_X509_version_print(bio, x509, 8) != WOLFSSL_SUCCESS) { + if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -6214,26 +6239,9 @@ int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, return WOLFSSL_FAILURE; } - /* print signature algo */ - { - int oid; - const char* sig; - - if ((oid = wolfSSL_X509_get_signature_type(x509)) <= 0) { - WOLFSSL_MSG("Error getting x509 signature type"); - return WOLFSSL_FAILURE; - } - if (wolfSSL_BIO_write(bio, " Signature Algorithm: ", - (int)XSTRLEN(" Signature Algorithm: ")) <= 0) { - return WOLFSSL_FAILURE; - } - sig = GetSigName(oid); - if (wolfSSL_BIO_write(bio, sig, (int)XSTRLEN(sig)) <= 0) { - return WOLFSSL_FAILURE; - } - if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) { - return WOLFSSL_FAILURE; - } + /* print out signature algo*/ + if (X509PrintSignature(bio, x509, 1, 8) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; } /* print issuer */ @@ -6319,7 +6327,7 @@ int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, } /* print out signature */ - if (X509PrintSignature(bio, x509, 8) != WOLFSSL_SUCCESS) { + if (X509PrintSignature(bio, x509, 0, 8) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -7457,6 +7465,460 @@ WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl, return newcrl; } + +/* Retrieve issuer X509_NAME from CRL + * return X509_NAME* on success + * return NULL on failure + */ +WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL* crl) +{ + if (crl == NULL || crl->crlList == NULL) + return NULL; + + return crl->crlList->issuer; +} + +/* Retrieve version from CRL + * return version on success + * return 0 on failure + */ +int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl) +{ + if (crl == NULL || crl->crlList == NULL) + return 0; + + return crl->crlList->version; +} + +/* Retrieve sig OID from CRL + * return OID on success + * return 0 on failure + */ +int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl) +{ + if (crl == NULL || crl->crlList == NULL) + return 0; + + return crl->crlList->signatureOID; +} + +/* Retrieve sig NID from CRL + * return NID on success + * return 0 on failure + */ +int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl) +{ + if (crl == NULL || crl->crlList == NULL) + return 0; + + return oid2nid(crl->crlList->signatureOID, oidSigType); +} + +/* Retrieve signature from CRL + * return WOLFSSL_SUCCESS on success + */ +int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl, + unsigned char* buf, int* bufSz) +{ + WOLFSSL_ENTER("wolfSSL_X509_CRL_get_signature"); + + if (crl == NULL || crl->crlList == NULL || bufSz == NULL) + return BAD_FUNC_ARG; + + if (buf != NULL) + XMEMCPY(buf, crl->crlList->signature, *bufSz); + *bufSz = (int)crl->crlList->signatureSz; + + return WOLFSSL_SUCCESS; +} + +/* Retrieve serial number from RevokedCert + * return WOLFSSL_SUCCESS on success + */ +int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev, + byte* in, int* inOutSz) +{ + WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_serial_number"); + if (rev == NULL || inOutSz == NULL) { + return BAD_FUNC_ARG; + } + + if (in != NULL) { + if (*inOutSz < rev->serialSz) { + WOLFSSL_MSG("Serial buffer too small"); + return BUFFER_E; + } + XMEMCPY(in, rev->serialNumber, rev->serialSz); + } + *inOutSz = rev->serialSz; + + return WOLFSSL_SUCCESS; +} + +/* print serial number out +* return WOLFSSL_SUCCESS on success +*/ +static int X509RevokedPrintSerial(WOLFSSL_BIO* bio, RevokedCert* rev, + int indent) +{ + unsigned char serial[32]; + int sz = sizeof(serial); + + XMEMSET(serial, 0, sz); + if (wolfSSL_X509_REVOKED_get_serial_number(rev, serial, &sz) + == WOLFSSL_SUCCESS) { + X509PrintSerial_ex(bio, serial, sz, 0, indent); + } + return WOLFSSL_SUCCESS; +} + + +/* print out the signature in human readable format for use with +* wolfSSL_X509_CRL_print() + * return WOLFSSL_SUCCESS on success + */ +static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, + int algOnly, int indent) +{ + int sigSz = 0; + + if (wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz) <= 0) { + return WOLFSSL_FAILURE; + } + + if (sigSz > 0) { + unsigned char* sig; + int sigNid = wolfSSL_X509_CRL_get_signature_nid(crl); + + sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (sig == NULL) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_X509_CRL_get_signature(crl, sig, &sigSz) <= 0) { + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + + if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent) + != WOLFSSL_SUCCESS) { + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + + if (sig != NULL) { + XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + } + + return WOLFSSL_SUCCESS; +} + +/* print out the extensions in human readable format for use with + * wolfSSL_X509_CRL_print() + * return WOLFSSL_SUCCESS on success + */ +static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, + int indent) +{ + char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */ + + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "", + "CRL extensions:") >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (crl->crlList->crlNumber) { + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "", + "X509v3 CRL Number:") >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%d\n", indent + 8, "", + crl->crlList->crlNumber) >= MAX_WIDTH) + { + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + XMEMSET(tmp, 0, sizeof(tmp)); + } + +#if !defined(NO_SKID) + if (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; + } + + XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1); + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + XMEMSET(tmp, 0, MAX_WIDTH); + + if (XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s", + indent + 8, "", "keyid") >= MAX_WIDTH) { + return 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 (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + tmp[0] = '\0'; + } + if (XSNPRINTF(val, valSz, ":%02X", crl->crlList->extAuthKeyId[i]) + >= valSz) + { + WOLFSSL_MSG("buffer overrun"); + return WOLFSSL_FAILURE; + } + XSTRNCAT(tmp, val, valSz); + } + XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1); + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + } +#endif + + return WOLFSSL_SUCCESS; +} + +/* iterate through a CRL's Revoked Certs and print out in human + * readable format for use with wolfSSL_X509_CRL_print() + * return WOLFSSL_SUCCESS on success + */ +static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, + int indent) +{ + char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */ + int i; + + if (crl->crlList->totalCerts > 0) { + RevokedCert* revoked = crl->crlList->certs; + + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "", + "Revoked Certificates:") >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + XMEMSET(tmp, 0, MAX_WIDTH); + + for (i = 0; i < crl->crlList->totalCerts; i++) { + if (revoked->serialSz > 0) { + if (X509RevokedPrintSerial(bio, revoked, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + } + #ifndef NO_ASN_TIME + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 8, "", + "Revocation Date: ") >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (revoked->revDate[0] != 0) { + if (GetTimeString(revoked->revDate, ASN_UTC_TIME, + tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME, + tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error getting revocation date"); + return WOLFSSL_FAILURE; + } + } + } + else { + XSTRNCPY(tmp, "Not Set", MAX_WIDTH-1); + } + tmp[MAX_WIDTH - 1] = '\0'; /* make sure null terminated */ + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) { + return WOLFSSL_FAILURE; + } + #endif + revoked = revoked->next; + } + } + else { + if (wolfSSL_BIO_write(bio, "No Revoked Certificates.\n", + (int)XSTRLEN("No Revoked Certificates.\n")) <= 0) { + return WOLFSSL_FAILURE; + } + } + + return WOLFSSL_SUCCESS; +} + +#ifndef NO_ASN_TIME +/* print out the last/next update times in human readable + * format for use with wolfSSL_X509_CRL_print() + * return WOLFSSL_SUCCESS on success + */ +static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, + int indent) +{ + char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */ + + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "", + "Last Update: ") >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (crl->crlList->lastDate[0] != 0) { + if (GetTimeString(crl->crlList->lastDate, ASN_UTC_TIME, + tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + if (GetTimeString(crl->crlList->lastDate, ASN_GENERALIZED_TIME, + tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error getting last update date"); + return WOLFSSL_FAILURE; + } + } + } + else { + XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1); + } + tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */ + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) { + return WOLFSSL_FAILURE; + } + + if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "", + "Next Update: ") >= MAX_WIDTH) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (crl->crlList->nextDate[0] != 0) { + if (GetTimeString(crl->crlList->nextDate, ASN_UTC_TIME, + tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + if (GetTimeString(crl->crlList->nextDate, ASN_GENERALIZED_TIME, + tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error getting next update date"); + return WOLFSSL_FAILURE; + } + } + } + else { + XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1); + } + tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */ + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) { + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} +#endif + +#if !defined(NO_BIO) && defined(XSNPRINTF) +/* Writes the human readable form of x509 to bio. + * + * bio WOLFSSL_BIO to write to. + * crl Certificate revocation list to write. + * + * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure + */ +int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl) +{ + char issuType[] = "Issuer: "; + + if (bio == NULL || crl == NULL || crl->crlList == NULL) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, "Certificate Revocation List (CRL):\n", + (int)XSTRLEN("Certificate Revocation List (CRL):\n")) <= 0) { + return WOLFSSL_FAILURE; + } + + /* print version */ + if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + /* print signature algo */ + if (X509CRLPrintSignature(bio, crl, 1, 8) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + /* print issuer name */ + if (X509PrintName(bio, wolfSSL_X509_CRL_get_issuer_name(crl), issuType, 8) + != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + +#ifndef NO_ASN_TIME + /* print last and next update times */ + if (X509CRLPrintDates(bio, crl, 8) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } +#endif + + /* print CRL extensions */ + if (X509CRLPrintExtensions(bio, crl, 8) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + /* print CRL Revoked Certs */ + if (X509CRLPrintRevoked(bio, crl, 0) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + if (X509CRLPrintSignature(bio, crl, 0, 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) { + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} +#endif /* !NO_BIO && XSNPRINTF */ #endif /* HAVE_CRL */ #endif /* OPENSSL_EXTRA */ diff --git a/tests/api.c b/tests/api.c index 6b4cad62e..401335e6b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -52533,9 +52533,9 @@ static int test_wolfSSL_X509_print(void) #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME) /* Will print IP address subject alt name. */ - AssertIntEQ(BIO_get_mem_data(bio, NULL), 3240); + AssertIntEQ(BIO_get_mem_data(bio, NULL), 3255); #else - AssertIntEQ(BIO_get_mem_data(bio, NULL), 3218); + AssertIntEQ(BIO_get_mem_data(bio, NULL), 3233); #endif BIO_free(bio); @@ -52562,6 +52562,32 @@ static int test_wolfSSL_X509_print(void) return 0; } +static int test_wolfSSL_X509_CRL_print(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && defined(HAVE_CRL)\ + && !defined(NO_FILESYSTEM) && defined(XSNPRINTF) + X509_CRL* crl; + BIO *bio; + XFILE fp; + + printf(testingFmt, "test_X509_CRL_print"); + + fp = XFOPEN("./certs/crl/crl.pem", "rb"); + AssertTrue((fp != XBADFILE)); + AssertNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, NULL, NULL)); + XFCLOSE(fp); + + AssertNotNull(bio = BIO_new(BIO_s_mem())); + AssertIntEQ(X509_CRL_print(bio, crl), SSL_SUCCESS); + + X509_CRL_free(crl); + BIO_free(bio); + printf(resultFmt, passed); +#endif + + return 0; +} + static int test_wolfSSL_BIO_get_len(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) @@ -57430,6 +57456,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_X509_get_version), #ifndef NO_BIO TEST_DECL(test_wolfSSL_X509_print), + TEST_DECL(test_wolfSSL_X509_CRL_print), TEST_DECL(test_wolfSSL_BIO_get_len), #endif diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 2c35cca5d..c36033025 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -32771,9 +32771,25 @@ int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx) #endif /* WOLFSSL_ASN_TEMPLATE */ } - #ifdef HAVE_CRL +#ifdef OPENSSL_EXTRA +static char* GetNameFromDer(const byte* source, int sz) +{ + char* out; + + out = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL); + if (out == NULL) { + WOLFSSL_MSG("Name malloc failed"); + return NULL; + } + + XMEMCPY(out, source, sz); + + return out; +} +#endif + /* initialize decoded CRL */ void InitDecodedCRL(DecodedCRL* dcrl, void* heap) { @@ -32799,6 +32815,10 @@ void FreeDecodedCRL(DecodedCRL* dcrl) XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED); tmp = next; } +#ifdef OPENSSL_EXTRA + if (dcrl->issuer != NULL) + XFREE(dcrl->issuer, NULL, DYNAMIC_TYPE_OPENSSL); +#endif } @@ -32835,7 +32855,6 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, #ifndef WOLFSSL_ASN_TEMPLATE int ret, len; word32 end; - byte b; RevokedCert* rc; WOLFSSL_ENTER("GetRevoked"); @@ -32864,12 +32883,13 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, dcrl->totalCerts++; /* get date */ - ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx); +#ifndef NO_ASN_TIME + ret = GetBasicDate(buff, idx, rc->revDate, &rc->revDateFormat, maxIdx); if (ret < 0) { WOLFSSL_MSG("Expecting Date"); return ret; } - +#endif /* skip extensions */ *idx = end; @@ -32878,6 +32898,7 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, DECL_ASNGETDATA(dataASN, revokedASN_Length); int ret = 0; word32 serialSz = EXTERNAL_SERIAL_SIZE; + word32 revDateSz = MAX_DATE_SIZE; RevokedCert* rc; /* Allocate a new revoked certificate object. */ @@ -32893,6 +32914,11 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, /* Set buffer to place serial number into. */ GetASN_Buffer(&dataASN[REVOKEDASN_IDX_CERT], rc->serialNumber, &serialSz); + /* Set buffer to store revocation date. */ + GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_UTC], rc->revDate, + &revDateSz); + GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_GT], rc->revDate, + &revDateSz); /* Decode the Revoked */ ret = GetASN_Items(revokedASN, dataASN, revokedASN_Length, 1, buff, idx, maxIdx); @@ -32900,7 +32926,10 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, if (ret == 0) { /* Store size of serial number. */ rc->serialSz = serialSz; - /* TODO: use revocation date */ + rc->revDateFormat = (dataASN[REVOKEDASN_IDX_TIME_UTC].tag != 0) + ? dataASN[REVOKEDASN_IDX_TIME_UTC].tag + : dataASN[REVOKEDASN_IDX_TIME_GT].tag; + /* TODO: use extensions, only v2 */ /* Add revoked certificate to chain. */ rc->next = dcrl->certs; @@ -33056,7 +33085,7 @@ static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf, word32* inOutIdx, int sz, int verify) { word32 oid, dateIdx, idx, checkIdx; - int version; + int length; #ifdef WOLFSSL_NO_CRL_NEXT_DATE int doNextDate = 1; #endif @@ -33071,13 +33100,24 @@ static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf, checkIdx = idx; if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) { - if (GetMyVersion(buf, &idx, &version, sz) < 0) + if (GetMyVersion(buf, &idx, &dcrl->version, sz) < 0) return ASN_PARSE_E; + dcrl->version++; } if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0) return ASN_PARSE_E; + checkIdx = idx; + if (GetSequence(buf, &checkIdx, &length, sz) < 0) { + return ASN_PARSE_E; + } +#ifdef OPENSSL_EXTRA + else { + dcrl->issuer = (byte*)GetNameFromDer(buf + idx, WC_ASN_NAME_MAX); + } +#endif + if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0) return ASN_PARSE_E; @@ -33283,6 +33323,42 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, } #endif } + else if (oid == CRL_NUMBER_OID) { + localIdx = idx; + if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_INTEGER) { + ret = GetASNInt(buf, &idx, &length, sz); + if (ret < 0) { + WOLFSSL_MSG("\tcouldn't parse CRL number extension"); + return ret; + } + else { + if (length > 1) { + mp_int m; + int i; + + mp_init(&m); + ret = mp_read_unsigned_bin(&m, buf + idx, length); + if (ret != MP_OKAY) { + mp_free(&m); + return BUFFER_E; + } + + dcrl->crlNumber = 0; + for (i = 0; i < m.used; ++i) { + if (i > (int)sizeof(word32)) { + break; + } + dcrl->crlNumber |= ((word32)m.dp[i]) << + (DIGIT_BIT * i); + } + mp_free(&m); + } + else { + dcrl->crlNumber = buf[idx]; + } + } + } + } idx += length; } @@ -33551,6 +33627,8 @@ end: ret = ASN_PARSE_E; } if (ret == 0) { + /* Store version */ + dcrl->version = ++version; /* Store offset of to be signed part. */ dcrl->certBegin = dataASN[CRLASN_IDX_TBS].offset; /* Store index of signature. */ @@ -33580,6 +33658,9 @@ end: } if (ret == 0) { #endif + /* Parse and store the issuer name. */ + dcrl->issuer = (byte*)GetNameFromDer((byte*)GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], + buff), ASN_NAME_MAX); /* Calculate the Hash id from the issuer name. */ ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff), GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff), diff --git a/wolfssl/internal.h b/wolfssl/internal.h index e8119c698..5ed8136b3 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2101,6 +2101,7 @@ struct CRL_Entry { byte nextDateFormat; /* next date format */ RevokedCert* certs; /* revoked cert list */ int totalCerts; /* number on list */ + int version; /* version of certficate */ int verified; byte* toBeSigned; word32 tbsSz; @@ -2110,6 +2111,10 @@ struct CRL_Entry { #if !defined(NO_SKID) && !defined(NO_ASN) byte extAuthKeyIdSet; byte extAuthKeyId[KEYID_SIZE]; +#endif + int crlNumber; /* CRL number extension */ +#if defined(OPENSSL_EXTRA) + WOLFSSL_X509_NAME* issuer; /* X509_NAME type issuer */ #endif }; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 1b0aa40aa..f3868dd76 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -496,6 +496,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_print wolfSSL_X509_print #define X509_print_ex wolfSSL_X509_print_ex #define X509_print_fp wolfSSL_X509_print_fp +#define X509_CRL_print wolfSSL_X509_CRL_print #define X509_REQ_print_fp wolfSSL_X509_print_fp #define X509_signature_print wolfSSL_X509_signature_print #define X509_get0_signature wolfSSL_X509_get0_signature diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b1e67c104..24f1067aa 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1413,7 +1413,7 @@ WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); -#ifdef HAVE_OCSP +#if defined(HAVE_OCSP) || defined(HAVE_CRL) #include "wolfssl/wolfcrypt/asn.h" #endif @@ -2787,7 +2787,16 @@ WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp, #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE file, WOLFSSL_X509_CRL **crl); #endif +#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) +WOLFSSL_API int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL *crl); +WOLFSSL_API int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl); +WOLFSSL_API int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl); +WOLFSSL_API int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl, unsigned char* buf, int* bufSz); +WOLFSSL_API int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL *crl); +WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev, byte* in, int* inOutSz); WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl); +#endif #ifndef NO_FILESYSTEM #ifndef NO_STDIO_FILESYSTEM diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 95e6229c8..68f86f4ad 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2391,6 +2391,8 @@ struct RevokedCert { byte serialNumber[EXTERNAL_SERIAL_SIZE]; int serialSz; RevokedCert* next; + byte revDate[MAX_DATE_SIZE]; + byte revDateFormat; }; typedef struct DecodedCRL DecodedCRL; @@ -2408,12 +2410,17 @@ struct DecodedCRL { byte lastDateFormat; /* format of last date */ byte nextDateFormat; /* format of next date */ RevokedCert* certs; /* revoked cert list */ +#if defined(OPENSSL_EXTRA) + byte* issuer; /* full name including common name */ +#endif int totalCerts; /* number on list */ + int version; /* version of cert */ void* heap; #ifndef NO_SKID byte extAuthKeyIdSet; byte extAuthKeyId[SIGNER_DIGEST_SIZE]; /* Authority Key ID */ #endif + int crlNumber; /* CRL number extension */ }; WOLFSSL_LOCAL void InitDecodedCRL(DecodedCRL* dcrl, void* heap); From 2059d05b7aa35a02f23a3b5784d705ac1e8eadb9 Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Fri, 19 Aug 2022 12:40:42 -0700 Subject: [PATCH 2/5] checking some ret values, fix trailing whitespace --- src/x509.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/x509.c b/src/x509.c index bd91c419b..dbf77a4f3 100644 --- a/src/x509.c +++ b/src/x509.c @@ -5534,7 +5534,7 @@ static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz, for (i = 0; i < sz; i++) { if ((valLen = XSNPRINTF( scratch + scratchLen, scratchSz - scratchLen, - "%02x%s", serial[i], (i < sz - 1) ? + "%02x%s", serial[i], (i < sz - 1) ? (delimiter ? ":" : "") : "\n")) >= scratchSz - scratchLen) { @@ -5944,17 +5944,25 @@ static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig, int sigSz, int sig if (obj != NULL) wolfSSL_ASN1_OBJECT_free(obj); - return ret; + return ret; } static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int algOnly, int indent) { int sigSz = 0; - wolfSSL_X509_get_signature(x509, NULL, &sigSz); + if (wolfSSL_X509_get_signature(x509, NULL, &sigSz) <= 0) { + return WOLFSSL_FAILURE; + } + if (sigSz > 0) { unsigned char* sig; - int sigNid = wolfSSL_X509_get_signature_nid(x509); + int sigNid; + + sigNid = wolfSSL_X509_get_signature_nid(x509); + if (sigNid <= 0) { + return WOLFSSL_FAILURE; + } sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (sig == NULL) { From 8f4b467f478ccd0bd57128a7ff70cda439477354 Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Mon, 22 Aug 2022 09:17:23 -0700 Subject: [PATCH 3/5] Fixing line lengths and SMALL_STACK code path --- src/x509.c | 16 ++++++++++------ tests/api.c | 3 ++- wolfcrypt/src/asn.c | 42 ++++++++++++++++++++++++++++++++---------- wolfssl/ssl.h | 15 ++++++++++----- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/x509.c b/src/x509.c index dbf77a4f3..fd7bed0c2 100644 --- a/src/x509.c +++ b/src/x509.c @@ -5812,8 +5812,8 @@ static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) * wolfSSL_X509_print() * return WOLFSSL_SUCCESS on success */ -static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig, int sigSz, int sigNid, - int algOnly, int indent) +static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig, + int sigSz, int sigNid, int algOnly, int indent) { char scratch[MAX_WIDTH]; int scratchLen; @@ -6160,7 +6160,8 @@ int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) } /* print version of cert */ - if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8) != WOLFSSL_SUCCESS) { + if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8) + != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -6238,7 +6239,8 @@ int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, } /* print version of cert */ - if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8) != WOLFSSL_SUCCESS) { + if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8) + != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -7737,7 +7739,8 @@ static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl, for (i = 0; i < crl->crlList->totalCerts; i++) { if (revoked->serialSz > 0) { - if (X509RevokedPrintSerial(bio, revoked, indent + 4) != WOLFSSL_SUCCESS) { + if (X509RevokedPrintSerial(bio, revoked, indent + 4) + != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } } @@ -7884,7 +7887,8 @@ int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl) } /* print version */ - if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8) != WOLFSSL_SUCCESS) { + if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8) + != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } diff --git a/tests/api.c b/tests/api.c index 401335e6b..aa01a2c17 100644 --- a/tests/api.c +++ b/tests/api.c @@ -52574,7 +52574,8 @@ static int test_wolfSSL_X509_CRL_print(void) fp = XFOPEN("./certs/crl/crl.pem", "rb"); AssertTrue((fp != XBADFILE)); - AssertNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, NULL, NULL)); + AssertNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL, + NULL, NULL)); XFCLOSE(fp); AssertNotNull(bio = BIO_new(BIO_s_mem())); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c36033025..9110a4439 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -33325,7 +33325,8 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, } else if (oid == CRL_NUMBER_OID) { localIdx = idx; - if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_INTEGER) { + if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && + tag == ASN_INTEGER) { ret = GetASNInt(buf, &idx, &length, sz); if (ret < 0) { WOLFSSL_MSG("\tcouldn't parse CRL number extension"); @@ -33333,25 +33334,46 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, } else { if (length > 1) { - mp_int m; + #ifdef WOLFSSL_SMALL_STACK + mp_int* m; + #else + mp_int m[1]; + #endif int i; - mp_init(&m); - ret = mp_read_unsigned_bin(&m, buf + idx, length); + #ifdef WOLFSSL_SMALL_STACK + m = (mp_int*)XMALLOC(sizeof(*m), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (m == NULL) { + return MEMORY_E; + } + #endif + if (mp_init(m) != MP_OKAY) { + return MP_INIT_E; + } + + ret = mp_read_unsigned_bin(m, buf + idx, length); if (ret != MP_OKAY) { - mp_free(&m); + mp_free(m); + #ifdef WOLFSSL_SMALL_STACK + XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif return BUFFER_E; } dcrl->crlNumber = 0; - for (i = 0; i < m.used; ++i) { + for (i = 0; i < (*m).used; ++i) { if (i > (int)sizeof(word32)) { break; } - dcrl->crlNumber |= ((word32)m.dp[i]) << + dcrl->crlNumber |= ((word32)(*m).dp[i]) << (DIGIT_BIT * i); } - mp_free(&m); + + #ifdef WOLFSSL_SMALL_STACK + XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + mp_free(m); } else { dcrl->crlNumber = buf[idx]; @@ -33659,8 +33681,8 @@ end: if (ret == 0) { #endif /* Parse and store the issuer name. */ - dcrl->issuer = (byte*)GetNameFromDer((byte*)GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], - buff), ASN_NAME_MAX); + dcrl->issuer = (byte*)GetNameFromDer((byte*)GetASNItem_Addr( + dataASN[CRLASN_IDX_TBS_ISSUER], buff), ASN_NAME_MAX); /* Calculate the Hash id from the issuer name. */ ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff), GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff), diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 24f1067aa..0228abb40 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2790,11 +2790,16 @@ WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE file, WOLFSSL_X509_C #if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) WOLFSSL_API int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL *crl); WOLFSSL_API int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl); -WOLFSSL_API int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl); -WOLFSSL_API int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl, unsigned char* buf, int* bufSz); -WOLFSSL_API int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl); -WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL *crl); -WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev, byte* in, int* inOutSz); +WOLFSSL_API int wolfSSL_X509_CRL_get_signature_nid( + const WOLFSSL_X509_CRL* crl); +WOLFSSL_API int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl, + unsigned char* buf, int* bufSz); +WOLFSSL_API int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, + WOLFSSL_X509_CRL* crl); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name( + WOLFSSL_X509_CRL *crl); +WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev, + byte* in, int* inOutSz); WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl); #endif From 91a7b8067ccb5f68ebe71048510a44b78bc63077 Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Mon, 22 Aug 2022 12:04:15 -0700 Subject: [PATCH 4/5] Addressing some PR feedback --- src/crl.c | 2 +- wolfcrypt/src/asn.c | 24 ++++++++++++++++-------- wolfssl/wolfcrypt/asn.h | 1 + 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/crl.c b/src/crl.c index 26a782ad5..ddc39218a 100644 --- a/src/crl.c +++ b/src/crl.c @@ -94,7 +94,7 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff, #if defined(OPENSSL_EXTRA) crle->issuer = NULL; wolfSSL_d2i_X509_NAME(&crle->issuer, (unsigned char**)&dcrl->issuer, - XSTRLEN((const char*)dcrl->issuer)); + dcrl->issuerSz); if (crle->issuer == NULL) { return WOLFSSL_FAILURE; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9110a4439..0e48073a1 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -32853,7 +32853,10 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, int maxIdx) { #ifndef WOLFSSL_ASN_TEMPLATE - int ret, len; +#ifndef NO_ASN_TIME + int ret; +#endif + int len; word32 end; RevokedCert* rc; @@ -33114,7 +33117,8 @@ static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf, } #ifdef OPENSSL_EXTRA else { - dcrl->issuer = (byte*)GetNameFromDer(buf + idx, WC_ASN_NAME_MAX); + dcrl->issuerSz = length + 3; + dcrl->issuer = (byte*)GetNameFromDer(buf + idx, dcrl->issuerSz); } #endif @@ -33149,6 +33153,8 @@ static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf, WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR); return CRL_CERT_DATE_ERR; } +#else + (void)verify; #endif } @@ -33343,7 +33349,7 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, #ifdef WOLFSSL_SMALL_STACK m = (mp_int*)XMALLOC(sizeof(*m), NULL, - DYNAMIC_TYPE_TMP_BUFFER); + DYNAMIC_TYPE_BIGINT); if (m == NULL) { return MEMORY_E; } @@ -33356,7 +33362,7 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, if (ret != MP_OKAY) { mp_free(m); #ifdef WOLFSSL_SMALL_STACK - XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(m, NULL, DYNAMIC_TYPE_BIGINT); #endif return BUFFER_E; } @@ -33681,12 +33687,14 @@ end: if (ret == 0) { #endif /* Parse and store the issuer name. */ - dcrl->issuer = (byte*)GetNameFromDer((byte*)GetASNItem_Addr( - dataASN[CRLASN_IDX_TBS_ISSUER], buff), ASN_NAME_MAX); + dcrl->issuerSz = GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], + buff); + dcrl->issuer = (byte*)GetNameFromDer((byte*)GetASNItem_Addr( + dataASN[CRLASN_IDX_TBS_ISSUER], buff), + dcrl->issuerSz); /* Calculate the Hash id from the issuer name. */ ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff), - GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff), - dcrl->issuerHash); + dcrl->issuerSz, dcrl->issuerHash); if (ret < 0) { ret = ASN_PARSE_E; } diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 68f86f4ad..6ec817942 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2412,6 +2412,7 @@ struct DecodedCRL { RevokedCert* certs; /* revoked cert list */ #if defined(OPENSSL_EXTRA) byte* issuer; /* full name including common name */ + int issuerSz; /* length of the issuer */ #endif int totalCerts; /* number on list */ int version; /* version of cert */ From f9ca9441068c03fcfebb84af91259757dec76651 Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Mon, 22 Aug 2022 14:47:11 -0700 Subject: [PATCH 5/5] Addressing some more feedback --- wolfcrypt/src/asn.c | 10 ++++------ wolfssl/wolfcrypt/asn.h | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 0e48073a1..59545b94f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -33116,10 +33116,8 @@ static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf, return ASN_PARSE_E; } #ifdef OPENSSL_EXTRA - else { - dcrl->issuerSz = length + 3; - dcrl->issuer = (byte*)GetNameFromDer(buf + idx, dcrl->issuerSz); - } + dcrl->issuerSz = length + (checkIdx - idx); + dcrl->issuer = (byte*)GetNameFromDer(buf + idx, (int)dcrl->issuerSz); #endif if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0) @@ -33377,7 +33375,7 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, } #ifdef WOLFSSL_SMALL_STACK - XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(m, NULL, DYNAMIC_TYPE_BIGINT); #endif mp_free(m); } @@ -33691,7 +33689,7 @@ end: buff); dcrl->issuer = (byte*)GetNameFromDer((byte*)GetASNItem_Addr( dataASN[CRLASN_IDX_TBS_ISSUER], buff), - dcrl->issuerSz); + (int)dcrl->issuerSz); /* Calculate the Hash id from the issuer name. */ ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff), dcrl->issuerSz, dcrl->issuerHash); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 6ec817942..4561805b5 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2412,7 +2412,7 @@ struct DecodedCRL { RevokedCert* certs; /* revoked cert list */ #if defined(OPENSSL_EXTRA) byte* issuer; /* full name including common name */ - int issuerSz; /* length of the issuer */ + word32 issuerSz; /* length of the issuer */ #endif int totalCerts; /* number on list */ int version; /* version of cert */