forked from wolfSSL/wolfssl
Merge pull request #8006 from ColtonWilley/crl_update_cb
CRL improvements and update callback
This commit is contained in:
@@ -10012,6 +10012,85 @@ int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
|
|||||||
int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm,
|
int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm,
|
||||||
CbMissingCRL cb);
|
CbMissingCRL cb);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup CertManager
|
||||||
|
\brief This function sets the CRL Update callback. If
|
||||||
|
HAVE_CRL and HAVE_CRL_UPDATE_CB is defined , and an entry with the same
|
||||||
|
issuer and a lower CRL number exists when a CRL is added, then the
|
||||||
|
CbUpdateCRL is called with the details of the existing entry and the
|
||||||
|
new one replacing it.
|
||||||
|
|
||||||
|
\return SSL_SUCCESS returned upon successful execution of the function and
|
||||||
|
subroutines.
|
||||||
|
\return BAD_FUNC_ARG returned if the WOLFSSL_CERT_MANAGER structure is NULL.
|
||||||
|
|
||||||
|
\param cm the WOLFSSL_CERT_MANAGER structure holding the information for
|
||||||
|
the certificate.
|
||||||
|
\param cb a function pointer to (*CbUpdateCRL) that is set to the
|
||||||
|
cbUpdateCRL member of the WOLFSSL_CERT_MANAGER.
|
||||||
|
Signature requirement:
|
||||||
|
void (*CbUpdateCRL)(CrlInfo *old, CrlInfo *new);
|
||||||
|
|
||||||
|
_Example_
|
||||||
|
\code
|
||||||
|
#include <wolfssl/ssl.h>
|
||||||
|
|
||||||
|
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(protocol method);
|
||||||
|
WOLFSSL* ssl = wolfSSL_new(ctx);
|
||||||
|
…
|
||||||
|
void cb(CrlInfo *old, CrlInfo *new){
|
||||||
|
Function body.
|
||||||
|
}
|
||||||
|
…
|
||||||
|
CbUpdateCRL cb = CbUpdateCRL;
|
||||||
|
…
|
||||||
|
if(ctx){
|
||||||
|
return wolfSSL_CertManagerSetCRLUpdate_Cb(SSL_CM(ssl), cb);
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\sa CbUpdateCRL
|
||||||
|
*/
|
||||||
|
int wolfSSL_CertManagerSetCRLUpdate_Cb(WOLFSSL_CERT_MANAGER* cm,
|
||||||
|
CbUpdateCRL cb);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup CertManager
|
||||||
|
\brief This function yields a structure with parsed CRL information from
|
||||||
|
an encoded CRL buffer.
|
||||||
|
|
||||||
|
\return SSL_SUCCESS returned upon successful execution of the function and
|
||||||
|
subroutines.
|
||||||
|
\return BAD_FUNC_ARG returned if the WOLFSSL_CERT_MANAGER structure is NULL.
|
||||||
|
|
||||||
|
\param cm the WOLFSSL_CERT_MANAGER structure..
|
||||||
|
\param info pointer to caller managed CrlInfo structure that will receive
|
||||||
|
the CRL information.
|
||||||
|
\param buff input buffer containing encoded CRL.
|
||||||
|
\param sz the length in bytes of the input CRL data in buff.
|
||||||
|
\param type WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_DER
|
||||||
|
|
||||||
|
_Example_
|
||||||
|
\code
|
||||||
|
#include <wolfssl/ssl.h>
|
||||||
|
|
||||||
|
CrlInfo info;
|
||||||
|
WOLFSSL_CERT_MANAGER* cm = NULL;
|
||||||
|
|
||||||
|
cm = wolfSSL_CertManagerNew();
|
||||||
|
|
||||||
|
// Read crl data from file into buffer
|
||||||
|
|
||||||
|
wolfSSL_CertManagerGetCRLInfo(cm, &info, crlData, crlDataLen,
|
||||||
|
WOLFSSL_FILETYPE_PEM);
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\sa CbUpdateCRL
|
||||||
|
\sa wolfSSL_SetCRL_Cb
|
||||||
|
*/
|
||||||
|
int wolfSSL_CertManagerGetCRLInfo(WOLFSSL_CERT_MANAGER* cm, CrlInfo* info,
|
||||||
|
const byte* buff, long sz, int type)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup CertManager
|
\ingroup CertManager
|
||||||
\brief This function frees the CRL stored in the Cert Manager. An
|
\brief This function frees the CRL stored in the Cert Manager. An
|
||||||
|
154
src/crl.c
154
src/crl.c
@@ -311,7 +311,6 @@ static int FindRevokedSerial(RevokedCert* rc, byte* serial, int serialSz,
|
|||||||
#else
|
#else
|
||||||
(void)totalCerts;
|
(void)totalCerts;
|
||||||
/* search in the linked list*/
|
/* search in the linked list*/
|
||||||
|
|
||||||
while (rc) {
|
while (rc) {
|
||||||
if (serialHash == NULL) {
|
if (serialHash == NULL) {
|
||||||
if (rc->serialSz == serialSz &&
|
if (rc->serialSz == serialSz &&
|
||||||
@@ -560,12 +559,45 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
|
|||||||
NULL, cert->extCrlInfo, cert->extCrlInfoSz, issuerName);
|
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 */
|
/* Add Decoded CRL, 0 on success */
|
||||||
static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
|
static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
|
||||||
int verified)
|
int verified)
|
||||||
{
|
{
|
||||||
CRL_Entry* crle = NULL;
|
CRL_Entry* crle = NULL;
|
||||||
|
CRL_Entry* curr = NULL;
|
||||||
|
CRL_Entry* prev = NULL;
|
||||||
|
#ifdef HAVE_CRL_UPDATE_CB
|
||||||
|
CrlInfo old;
|
||||||
|
CrlInfo cnew;
|
||||||
|
#endif
|
||||||
|
|
||||||
WOLFSSL_ENTER("AddCRL");
|
WOLFSSL_ENTER("AddCRL");
|
||||||
|
|
||||||
@@ -594,8 +626,43 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
|
|||||||
return BAD_MUTEX_E;
|
return BAD_MUTEX_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
crle->next = crl->crlList;
|
for (curr = crl->crlList; curr != NULL; curr = curr->next) {
|
||||||
crl->crlList = crle;
|
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, &cnew);
|
||||||
|
crl->cm->cbUpdateCRL(&old, &cnew);
|
||||||
|
}
|
||||||
|
#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);
|
wc_UnLockRwLock(&crl->crlLock);
|
||||||
/* Avoid heap-use-after-free after crl->crlList is released */
|
/* Avoid heap-use-after-free after crl->crlList is released */
|
||||||
crl->currentEntry = NULL;
|
crl->currentEntry = NULL;
|
||||||
@@ -686,6 +753,87 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
|
|||||||
return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
|
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)
|
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
|
||||||
/* helper function to create a new dynamic WOLFSSL_X509_CRL structure */
|
/* helper function to create a new dynamic WOLFSSL_X509_CRL structure */
|
||||||
static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm)
|
static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm)
|
||||||
|
@@ -1895,6 +1895,41 @@ int wolfSSL_CertManagerSetCRL_ErrorCb(WOLFSSL_CERT_MANAGER* cm, crlErrorCb cb,
|
|||||||
return ret;
|
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
|
#ifdef HAVE_CRL_IO
|
||||||
/* Set the CRL I/O callback.
|
/* Set the CRL I/O callback.
|
||||||
*
|
*
|
||||||
|
152
tests/api.c
152
tests/api.c
@@ -89917,46 +89917,130 @@ static int test_wolfSSL_CTX_LoadCRL(void)
|
|||||||
return EXPECT_RESULT();
|
return EXPECT_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_CRL) && \
|
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
|
||||||
!defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
|
defined(HAVE_CRL_UPDATE_CB)
|
||||||
static int test_multiple_crls_same_issuer_ctx_ready(WOLFSSL_CTX* ctx)
|
int crlUpdateTestStatus = 0;
|
||||||
|
WOLFSSL_CERT_MANAGER* updateCrlTestCm = NULL;
|
||||||
|
static void updateCrlCb(CrlInfo* old, CrlInfo* cnew)
|
||||||
{
|
{
|
||||||
EXPECT_DECLS;
|
const char* crl1 = "./certs/crl/crl.pem";
|
||||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
const char* crlRevoked = "./certs/crl/crl.revoked";
|
||||||
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, "./certs/crl/crl.pem",
|
byte *crl1Buff = NULL;
|
||||||
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
|
word32 crl1Sz;
|
||||||
return EXPECT_RESULT();
|
byte *crlRevBuff = NULL;
|
||||||
|
word32 crlRevSz;
|
||||||
|
WOLFSSL_CERT_MANAGER* cm = updateCrlTestCm;
|
||||||
|
XFILE f;
|
||||||
|
word32 sz;
|
||||||
|
CrlInfo crl1Info;
|
||||||
|
CrlInfo crlRevInfo;
|
||||||
|
|
||||||
|
crlUpdateTestStatus = 0;
|
||||||
|
if (old == NULL || cnew == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertTrue((f = XFOPEN(crl1, "rb")) != XBADFILE);
|
||||||
|
AssertTrue(XFSEEK(f, 0, XSEEK_END) == 0);
|
||||||
|
AssertIntGE(sz = (size_t) XFTELL(f), 1);
|
||||||
|
AssertTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
|
||||||
|
AssertTrue( \
|
||||||
|
(crl1Buff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
|
||||||
|
AssertTrue(XFREAD(crl1Buff, 1, sz, f) == sz);
|
||||||
|
XFCLOSE(f);
|
||||||
|
crl1Sz = sz;
|
||||||
|
|
||||||
|
AssertTrue((f = XFOPEN(crlRevoked, "rb")) != XBADFILE);
|
||||||
|
AssertTrue(XFSEEK(f, 0, XSEEK_END) == 0);
|
||||||
|
AssertIntGE(sz = (size_t) XFTELL(f), 1);
|
||||||
|
AssertTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
|
||||||
|
AssertTrue( \
|
||||||
|
(crlRevBuff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
|
||||||
|
AssertTrue(XFREAD(crlRevBuff, 1, sz, f) == sz);
|
||||||
|
XFCLOSE(f);
|
||||||
|
crlRevSz = sz;
|
||||||
|
|
||||||
|
AssertIntEQ(wolfSSL_CertManagerGetCRLInfo(
|
||||||
|
cm, &crl1Info, crl1Buff, crl1Sz, WOLFSSL_FILETYPE_PEM),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
AssertIntEQ(wolfSSL_CertManagerGetCRLInfo(
|
||||||
|
cm, &crlRevInfo, crlRevBuff, crlRevSz, WOLFSSL_FILETYPE_PEM),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
|
||||||
|
/* Old entry being replaced should match crl1 */
|
||||||
|
AssertIntEQ(crl1Info.issuerHashLen, old->issuerHashLen);
|
||||||
|
AssertIntEQ(crl1Info.lastDateMaxLen, old->lastDateMaxLen);
|
||||||
|
AssertIntEQ(crl1Info.lastDateFormat, old->lastDateFormat);
|
||||||
|
AssertIntEQ(crl1Info.nextDateMaxLen, old->nextDateMaxLen);
|
||||||
|
AssertIntEQ(crl1Info.nextDateFormat, old->nextDateFormat);
|
||||||
|
AssertIntEQ(crl1Info.crlNumber, old->crlNumber);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crl1Info.issuerHash, old->issuerHash, old->issuerHashLen), 0);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crl1Info.lastDate, old->lastDate, old->lastDateMaxLen), 0);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crl1Info.nextDate, old->nextDate, old->nextDateMaxLen), 0);
|
||||||
|
|
||||||
|
/* Newer entry should match crl revoked */
|
||||||
|
AssertIntEQ(crlRevInfo.issuerHashLen, cnew->issuerHashLen);
|
||||||
|
AssertIntEQ(crlRevInfo.lastDateMaxLen, cnew->lastDateMaxLen);
|
||||||
|
AssertIntEQ(crlRevInfo.lastDateFormat, cnew->lastDateFormat);
|
||||||
|
AssertIntEQ(crlRevInfo.nextDateMaxLen, cnew->nextDateMaxLen);
|
||||||
|
AssertIntEQ(crlRevInfo.nextDateFormat, cnew->nextDateFormat);
|
||||||
|
AssertIntEQ(crlRevInfo.crlNumber, cnew->crlNumber);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crlRevInfo.issuerHash, cnew->issuerHash, cnew->issuerHashLen), 0);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crlRevInfo.lastDate, cnew->lastDate, cnew->lastDateMaxLen), 0);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crlRevInfo.nextDate, cnew->nextDate, cnew->nextDateMaxLen), 0);
|
||||||
|
|
||||||
|
XFREE(crl1Buff, NULL, DYNAMIC_TYPE_FILE);
|
||||||
|
XFREE(crlRevBuff, NULL, DYNAMIC_TYPE_FILE);
|
||||||
|
crlUpdateTestStatus = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int test_multiple_crls_same_issuer(void)
|
static int test_wolfSSL_crl_update_cb(void)
|
||||||
{
|
{
|
||||||
EXPECT_DECLS;
|
EXPECT_DECLS;
|
||||||
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_CRL) && \
|
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
|
||||||
!defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
|
defined(HAVE_CRL_UPDATE_CB)
|
||||||
test_ssl_cbf client_cbs, server_cbs;
|
const char* crl1 = "./certs/crl/crl.pem";
|
||||||
struct {
|
const char* crlRevoked = "./certs/crl/crl.revoked";
|
||||||
const char* server_cert;
|
const char* issuerCert = "./certs/client-cert.pem";
|
||||||
const char* server_key;
|
const char* caCert = "./certs/ca-cert.pem";
|
||||||
} test_params[] = {
|
const char* goodCert = "./certs/server-cert.pem";
|
||||||
{ "./certs/server-cert.pem", "./certs/server-key.pem" },
|
const char* revokedCert = "./certs/server-revoked-cert.pem";
|
||||||
{ "./certs/server-revoked-cert.pem", "./certs/server-revoked-key.pem" }
|
int pemType = WOLFSSL_FILETYPE_PEM;
|
||||||
};
|
WOLFSSL_CERT_MANAGER* cm = NULL;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(test_params)/sizeof(*test_params)); i++) {
|
updateCrlTestCm = wolfSSL_CertManagerNew();
|
||||||
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
|
ExpectNotNull(updateCrlTestCm);
|
||||||
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
|
cm = updateCrlTestCm;
|
||||||
|
ExpectIntEQ(wolfSSL_CertManagerSetCRLUpdate_Cb(cm, updateCrlCb),
|
||||||
server_cbs.certPemFile = test_params[i].server_cert;
|
WOLFSSL_SUCCESS);
|
||||||
server_cbs.keyPemFile = test_params[i].server_key;
|
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caCert, NULL),
|
||||||
client_cbs.crlPemFile = "./certs/crl/extra-crls/general-server-crl.pem";
|
WOLFSSL_SUCCESS);
|
||||||
|
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, issuerCert, NULL),
|
||||||
client_cbs.ctx_ready = test_multiple_crls_same_issuer_ctx_ready;
|
WOLFSSL_SUCCESS);
|
||||||
|
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crl1, pemType),
|
||||||
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
|
WOLFSSL_SUCCESS);
|
||||||
&server_cbs, NULL), -1001);
|
/* CRL1 does not have good cert revoked */
|
||||||
}
|
ExpectIntEQ(wolfSSL_CertManagerVerify(cm, goodCert, pemType),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
ExpectIntNE(wolfSSL_CertManagerVerify(cm, revokedCert, pemType),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
/* Load newer CRL from same issuer, callback verifies CRL entry details */
|
||||||
|
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crlRevoked, pemType),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
/* CRL callback verified entry info was as expected */
|
||||||
|
ExpectIntEQ(crlUpdateTestStatus, 1);
|
||||||
|
/* Ensure that both certs fail with newer CRL */
|
||||||
|
ExpectIntNE(wolfSSL_CertManagerVerify(cm, goodCert, pemType),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
ExpectIntNE(wolfSSL_CertManagerVerify(cm, revokedCert, pemType),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
#endif
|
#endif
|
||||||
return EXPECT_RESULT();
|
return EXPECT_RESULT();
|
||||||
}
|
}
|
||||||
@@ -101189,7 +101273,7 @@ TEST_CASE testCases[] = {
|
|||||||
TEST_DECL(test_wolfSSL_use_certificate_chain_file),
|
TEST_DECL(test_wolfSSL_use_certificate_chain_file),
|
||||||
TEST_DECL(test_wolfSSL_CTX_trust_peer_cert),
|
TEST_DECL(test_wolfSSL_CTX_trust_peer_cert),
|
||||||
TEST_DECL(test_wolfSSL_CTX_LoadCRL),
|
TEST_DECL(test_wolfSSL_CTX_LoadCRL),
|
||||||
TEST_DECL(test_multiple_crls_same_issuer),
|
TEST_DECL(test_wolfSSL_crl_update_cb),
|
||||||
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_file),
|
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_file),
|
||||||
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_buffer),
|
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_buffer),
|
||||||
TEST_DECL(test_wolfSSL_CTX_SetMinMaxDhKey_Sz),
|
TEST_DECL(test_wolfSSL_CTX_SetMinMaxDhKey_Sz),
|
||||||
|
@@ -38665,7 +38665,6 @@ static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef WOLFSSL_ASN_TEMPLATE
|
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||||
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
|
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
|
||||||
word32* inOutIdx, word32 sz)
|
word32* inOutIdx, word32 sz)
|
||||||
|
@@ -45,7 +45,10 @@ WOLFSSL_LOCAL int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert);
|
|||||||
WOLFSSL_LOCAL int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash,
|
WOLFSSL_LOCAL int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash,
|
||||||
byte* serial, int serialSz, byte* serialHash, const byte* extCrlInfo,
|
byte* serial, int serialSz, byte* serialHash, const byte* extCrlInfo,
|
||||||
int extCrlInfoSz, void* issuerName);
|
int extCrlInfoSz, void* issuerName);
|
||||||
|
#ifdef HAVE_CRL_UPDATE_CB
|
||||||
|
WOLFSSL_LOCAL int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff,
|
||||||
|
long sz, int type);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@@ -2687,6 +2687,9 @@ struct WOLFSSL_CERT_MANAGER {
|
|||||||
#ifdef WC_ASN_UNKNOWN_EXT_CB
|
#ifdef WC_ASN_UNKNOWN_EXT_CB
|
||||||
wc_UnknownExtCallback unknownExtCallback;
|
wc_UnknownExtCallback unknownExtCallback;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CRL_UPDATE_CB
|
||||||
|
CbUpdateCRL cbUpdateCRL; /* notify thru cb that crl has updated */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm,
|
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm,
|
||||||
|
@@ -3495,6 +3495,22 @@ typedef void (*CbOCSPRespFree)(void*,unsigned char*);
|
|||||||
typedef int (*CbCrlIO)(WOLFSSL_CRL* crl, const char* url, int urlSz);
|
typedef int (*CbCrlIO)(WOLFSSL_CRL* crl, const char* url, int urlSz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CRL_UPDATE_CB
|
||||||
|
typedef struct CrlInfo {
|
||||||
|
byte *issuerHash;
|
||||||
|
word32 issuerHashLen;
|
||||||
|
byte *lastDate;
|
||||||
|
word32 lastDateMaxLen;
|
||||||
|
byte lastDateFormat;
|
||||||
|
byte *nextDate;
|
||||||
|
word32 nextDateMaxLen;
|
||||||
|
byte nextDateFormat;
|
||||||
|
sword32 crlNumber;
|
||||||
|
} CrlInfo;
|
||||||
|
|
||||||
|
typedef void (*CbUpdateCRL)(CrlInfo* old, CrlInfo* cnew);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* User Atomic Record Layer CallBacks */
|
/* User Atomic Record Layer CallBacks */
|
||||||
typedef int (*CallbackMacEncrypt)(WOLFSSL* ssl, unsigned char* macOut,
|
typedef int (*CallbackMacEncrypt)(WOLFSSL* ssl, unsigned char* macOut,
|
||||||
const unsigned char* macIn, unsigned int macInSz, int macContent,
|
const unsigned char* macIn, unsigned int macInSz, int macContent,
|
||||||
@@ -3957,6 +3973,12 @@ WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx,
|
|||||||
WOLFSSL_API int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm,
|
WOLFSSL_API int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm,
|
||||||
CbCrlIO cb);
|
CbCrlIO cb);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CRL_UPDATE_CB
|
||||||
|
WOLFSSL_API int wolfSSL_CertManagerGetCRLInfo(WOLFSSL_CERT_MANAGER* cm, CrlInfo* info,
|
||||||
|
const byte* buff, long sz, int type);
|
||||||
|
WOLFSSL_API int wolfSSL_CertManagerSetCRLUpdate_Cb(WOLFSSL_CERT_MANAGER* cm,
|
||||||
|
CbUpdateCRL cb);
|
||||||
|
#endif
|
||||||
#if defined(HAVE_OCSP)
|
#if defined(HAVE_OCSP)
|
||||||
WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(
|
WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(
|
||||||
WOLFSSL_CERT_MANAGER* cm, unsigned char *response, int responseSz,
|
WOLFSSL_CERT_MANAGER* cm, unsigned char *response, int responseSz,
|
||||||
|
Reference in New Issue
Block a user