forked from wolfSSL/wolfssl
CRL improvements, add parsing for CRL number, do not allow CRL duplicates, add callback for when CRL entry is updated.
This commit is contained in:
147
src/crl.c
147
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,43 @@ 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 new;
|
||||||
|
#endif
|
||||||
|
|
||||||
WOLFSSL_ENTER("AddCRL");
|
WOLFSSL_ENTER("AddCRL");
|
||||||
|
|
||||||
@@ -594,8 +624,43 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
|
|||||||
return BAD_MUTEX_E;
|
return BAD_MUTEX_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
crle->next = crl->crlList;
|
||||||
crl->crlList = crle;
|
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 +751,86 @@ 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)
|
||||||
|
@@ -1878,6 +1878,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
@@ -85769,46 +85769,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* new)
|
||||||
{
|
{
|
||||||
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 || new == 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, new->issuerHashLen);
|
||||||
|
AssertIntEQ(crlRevInfo.lastDateMaxLen, new->lastDateMaxLen);
|
||||||
|
AssertIntEQ(crlRevInfo.lastDateFormat, new->lastDateFormat);
|
||||||
|
AssertIntEQ(crlRevInfo.nextDateMaxLen, new->nextDateMaxLen);
|
||||||
|
AssertIntEQ(crlRevInfo.nextDateFormat, new->nextDateFormat);
|
||||||
|
AssertIntEQ(crlRevInfo.crlNumber, new->crlNumber);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crlRevInfo.issuerHash, new->issuerHash, new->issuerHashLen), 0);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crlRevInfo.lastDate, new->lastDate, new->lastDateMaxLen), 0);
|
||||||
|
AssertIntEQ(XMEMCMP(
|
||||||
|
crlRevInfo.nextDate, new->nextDate, new->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();
|
||||||
}
|
}
|
||||||
@@ -96461,7 +96545,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),
|
||||||
|
@@ -38280,6 +38280,41 @@ static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_ASN_TEMPLATE
|
||||||
|
|
||||||
|
static const ASNItem crlNumASN[] = {
|
||||||
|
/* CRL NUM */ {0, ASN_INTEGER, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
CRLNUMASN_IDX_CRL_NUM = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Number of items in ASN.1 template for CrlNumber. */
|
||||||
|
#define crlNumASN_Length (sizeof(crlNumASN) / sizeof(ASNItem))
|
||||||
|
|
||||||
|
static int ParseCRL_CrlNumExt(const byte* input, int sz, DecodedCRL* dcrl)
|
||||||
|
{
|
||||||
|
DECL_ASNGETDATA(dataASN, crlNumASN_Length);
|
||||||
|
int ret = 0;
|
||||||
|
word32 idx = 0;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("ParseCRL_CrlNumExt");
|
||||||
|
|
||||||
|
CALLOC_ASNGETDATA(dataASN, crlNumASN_Length, ret, dcrl->heap);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
GetASN_Int32Bit(&dataASN[CRLNUMASN_IDX_CRL_NUM], (word32 *)&dcrl->crlNumber);
|
||||||
|
|
||||||
|
/* Parse a CRL number. */
|
||||||
|
ret = GetASN_Items(crlNumASN, dataASN, crlNumASN_Length, 0, input,
|
||||||
|
&idx, (word32)sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_ASNGETDATA(dataASN, dcrl->heap);
|
||||||
|
return ret;
|
||||||
|
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#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,
|
||||||
@@ -38472,7 +38507,14 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* TODO: Parse CRL Number extension */
|
else if (oid == CRL_NUMBER_OID) {
|
||||||
|
/* Parse CRL Number extension.
|
||||||
|
* idx is at start of OCTET_STRING data. */
|
||||||
|
ret = ParseCRL_CrlNumExt(buf + idx, length, dcrl);
|
||||||
|
if (ret != 0) {
|
||||||
|
WOLFSSL_MSG("\tcouldn't parse CRL Number extension");
|
||||||
|
}
|
||||||
|
}
|
||||||
/* TODO: check criticality */
|
/* TODO: check criticality */
|
||||||
/* Move index on to next extension. */
|
/* Move index on to next extension. */
|
||||||
idx += (word32)length;
|
idx += (word32)length;
|
||||||
|
@@ -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" */
|
||||||
|
@@ -2656,6 +2656,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,
|
||||||
|
@@ -3324,6 +3324,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* new);
|
||||||
|
#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,
|
||||||
@@ -3771,6 +3787,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