Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRL improvements and update callback #8006

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
ColtonWilley marked this conversation as resolved.
Show resolved Hide resolved
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
ColtonWilley marked this conversation as resolved.
Show resolved Hide resolved
* 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