Skip to content

Commit

Permalink
CRL improvements, add parsing for CRL number, do not allow CRL duplic…
Browse files Browse the repository at this point in the history
…ates, add callback for when CRL entry is updated.
  • Loading branch information
ColtonWilley committed Sep 23, 2024
1 parent baab334 commit 183aef2
Show file tree
Hide file tree
Showing 7 changed files with 376 additions and 42 deletions.
151 changes: 148 additions & 3 deletions src/crl.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ static int FindRevokedSerial(RevokedCert* rc, byte* serial, int serialSz,
#else
(void)totalCerts;
/* search in the linked list*/

while (rc) {
if (serialHash == NULL) {
if (rc->serialSz == serialSz &&
Expand Down Expand Up @@ -560,12 +559,43 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
NULL, cert->extCrlInfo, cert->extCrlInfoSz, issuerName);
}

#ifdef HAVE_CRL_UPDATE_CB
static void SetCrlInfo(CRL_Entry* entry, CrlInfo *info) {
info->issuerHash = (byte *)entry->issuerHash;
info->issuerHashLen = CRL_DIGEST_SIZE;
info->lastDate = (byte *)entry->lastDate;
info->lastDateMaxLen = MAX_DATE_SIZE;
info->lastDateFormat = entry->lastDateFormat;
info->nextDate = (byte *)entry->nextDate;
info->nextDateMaxLen = MAX_DATE_SIZE;
info->nextDateFormat = entry->nextDateFormat;
info->crlNumber = (sword32)entry->crlNumber;
}

static void SetCrlInfoFromDecoded(DecodedCRL* entry, CrlInfo *info) {
info->issuerHash = (byte *)entry->issuerHash;
info->issuerHashLen = SIGNER_DIGEST_SIZE;
info->lastDate = (byte *)entry->lastDate;
info->lastDateMaxLen = MAX_DATE_SIZE;
info->lastDateFormat = entry->lastDateFormat;
info->nextDate = (byte *)entry->nextDate;
info->nextDateMaxLen = MAX_DATE_SIZE;
info->nextDateFormat = entry->nextDateFormat;
info->crlNumber = (sword32)entry->crlNumber;
}
#endif

/* Add Decoded CRL, 0 on success */
static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
int verified)
{
CRL_Entry* crle = NULL;
CRL_Entry* curr = NULL;
CRL_Entry* prev = NULL;
#ifdef HAVE_CRL_UPDATE_CB
CrlInfo old;
CrlInfo new;
#endif

WOLFSSL_ENTER("AddCRL");

Expand Down Expand Up @@ -594,8 +624,43 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
return BAD_MUTEX_E;
}

crle->next = crl->crlList;
crl->crlList = crle;
for (curr = crl->crlList; curr != NULL; curr = curr->next) {
if (XMEMCMP(curr->issuerHash, crle->issuerHash, CRL_DIGEST_SIZE) == 0) {
if (crle->crlNumber <= curr->crlNumber) {
WOLFSSL_MSG("Same or newer CRL entry already exists");
CRL_Entry_free(crle, crl->heap);
wc_UnLockRwLock(&crl->crlLock);
return BAD_FUNC_ARG;
}

crle->next = curr->next;
if (prev != NULL) {
prev->next = crle;
}
else {
crl->crlList = crle;
}

#ifdef HAVE_CRL_UPDATE_CB
if (crl->cm && crl->cm->cbUpdateCRL != NULL) {
SetCrlInfo(curr, &old);
SetCrlInfo(crle, &new);
crl->cm->cbUpdateCRL(&old, &new);
}
#endif

break;
}
prev = curr;
}

if (curr != NULL) {
CRL_Entry_free(curr, crl->heap);
}
else {
crle->next = crl->crlList;
crl->crlList = crle;
}
wc_UnLockRwLock(&crl->crlLock);
/* Avoid heap-use-after-free after crl->crlList is released */
crl->currentEntry = NULL;
Expand Down Expand Up @@ -686,6 +751,86 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
}

#ifdef HAVE_CRL_UPDATE_CB
/* Fill out CRL info structure, WOLFSSL_SUCCESS on ok */
int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff,
long sz, int type)
{
int ret = WOLFSSL_SUCCESS;
const byte* myBuffer = buff; /* if DER ok, otherwise switch */
DerBuffer* der = NULL;
CRL_Entry* crle = NULL;
#ifdef WOLFSSL_SMALL_STACK
DecodedCRL* dcrl;
#else
DecodedCRL dcrl[1];
#endif

WOLFSSL_ENTER("GetCRLInfo");

if (crl == NULL || info == NULL || buff == NULL || sz == 0)
return BAD_FUNC_ARG;

if (type == WOLFSSL_FILETYPE_PEM) {
#ifdef WOLFSSL_PEM_TO_DER
ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, NULL, NULL);
if (ret == 0) {
myBuffer = der->buffer;
sz = der->length;
}
else {
WOLFSSL_MSG("Pem to Der failed");
FreeDer(&der);
return -1;
}
#else
ret = NOT_COMPILED_IN;
#endif
}

#ifdef WOLFSSL_SMALL_STACK
dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (dcrl == NULL) {
FreeDer(&der);
return MEMORY_E;
}
#endif

crle = CRL_Entry_new(crl->heap);
if (crle == NULL) {
WOLFSSL_MSG("alloc CRL Entry failed");
#ifdef WOLFSSL_SMALL_STACK
XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
FreeDer(&der);
return MEMORY_E;
}

InitDecodedCRL(dcrl, crl->heap);
ret = ParseCRL(crle->certs, dcrl, myBuffer, (word32)sz,
0, crl->cm);
if (ret != 0 && !(ret == WC_NO_ERR_TRACE(ASN_CRL_NO_SIGNER_E))) {
WOLFSSL_MSG("ParseCRL error");
CRL_Entry_free(crle, crl->heap);
crle = NULL;
}
else {
SetCrlInfoFromDecoded((DecodedCRL*)dcrl, info);
}

FreeDecodedCRL(dcrl);

#ifdef WOLFSSL_SMALL_STACK
XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

FreeDer(&der);
CRL_Entry_free(crle, crl->heap);

return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
}
#endif

#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
/* helper function to create a new dynamic WOLFSSL_X509_CRL structure */
static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm)
Expand Down
35 changes: 35 additions & 0 deletions src/ssl_certman.c
Original file line number Diff line number Diff line change
Expand Up @@ -1878,6 +1878,41 @@ int wolfSSL_CertManagerSetCRL_ErrorCb(WOLFSSL_CERT_MANAGER* cm, crlErrorCb cb,
return ret;
}

#ifdef HAVE_CRL_UPDATE_CB
int wolfSSL_CertManagerGetCRLInfo(WOLFSSL_CERT_MANAGER* cm, CrlInfo* info,
const byte* buff, long sz, int type)
{
return GetCRLInfo(cm->crl, info, buff, sz, type);
}

/* Set the callback to be called when a CRL entry has
* been updated (new entry had the same issuer hash and
* a newer CRL number).
*
* @param [in] cm Certificate manager.
* @param [in] cb CRL update callback.
* @return WOLFSSL_SUCCESS on success.
* @return BAD_FUNC_ARG when cm is NULL.
*/
int wolfSSL_CertManagerSetCRLUpdate_Cb(WOLFSSL_CERT_MANAGER* cm, CbUpdateCRL cb)
{
int ret = WOLFSSL_SUCCESS;

WOLFSSL_ENTER("wolfSSL_CertManagerSetCRLUpdate_Cb");

/* Validate parameters. */
if (cm == NULL) {
ret = BAD_FUNC_ARG;
}
if (ret == WOLFSSL_SUCCESS) {
/* Store callback. */
cm->cbUpdateCRL = cb;
}

return ret;
}
#endif

#ifdef HAVE_CRL_IO
/* Set the CRL I/O callback.
*
Expand Down
Loading

0 comments on commit 183aef2

Please sign in to comment.