diff --git a/src/crl.c b/src/crl.c index 6da5e8d2c..e771c43a0 100644 --- a/src/crl.c +++ b/src/crl.c @@ -536,6 +536,13 @@ int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, crl->cm->cbMissingCRL(url); } + + if (crl->cm != NULL && crl->cm->crlCb && + crl->cm->crlCb(ret, crl, crl->cm, crl->cm->crlCbCtx)) { + if (ret != 0) + WOLFSSL_MSG("Overriding CRL error"); + ret = 0; + } } return ret; diff --git a/src/ssl.c b/src/ssl.c index ccb32cc16..8db3f182b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6007,6 +6007,17 @@ int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb) return BAD_FUNC_ARG; } +int wolfSSL_SetCRL_ErrorCb(WOLFSSL* ssl, crlErrorCb cb, void* ctx) +{ + WOLFSSL_ENTER("wolfSSL_SetCRL_Cb"); + if (ssl) { + SSL_CM_WARNING(ssl); + return wolfSSL_CertManagerSetCRL_ErrorCb(SSL_CM(ssl), cb, ctx); + } + else + return BAD_FUNC_ARG; +} + #ifdef HAVE_CRL_IO int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb) { @@ -6072,6 +6083,15 @@ int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb) return BAD_FUNC_ARG; } +int wolfSSL_CTX_SetCRL_ErrorCb(WOLFSSL_CTX* ctx, crlErrorCb cb, void* cbCtx) +{ + WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_ErrorCb"); + if (ctx) + return wolfSSL_CertManagerSetCRL_ErrorCb(ctx->cm, cb, cbCtx); + else + return BAD_FUNC_ARG; +} + #ifdef HAVE_CRL_IO int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb) { diff --git a/src/ssl_certman.c b/src/ssl_certman.c index 09f2607ee..a5b622ded 100644 --- a/src/ssl_certman.c +++ b/src/ssl_certman.c @@ -1858,6 +1858,26 @@ int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb) return ret; } +int wolfSSL_CertManagerSetCRL_ErrorCb(WOLFSSL_CERT_MANAGER* cm, crlErrorCb cb, + void* ctx) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb"); + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { + /* Store callback. */ + cm->crlCb = cb; + cm->crlCbCtx = ctx; + } + + return ret; +} + #ifdef HAVE_CRL_IO /* Set the CRL I/O callback. * diff --git a/tests/api.c b/tests/api.c index 7ade479cb..d84dc6a49 100644 --- a/tests/api.c +++ b/tests/api.c @@ -93450,6 +93450,40 @@ static int test_revoked_loaded_int_cert_ctx_ready2(WOLFSSL_CTX* ctx) WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); return EXPECT_RESULT(); } + +static int test_revoked_loaded_int_cert_ctx_ready3_crl_missing_cb(int ret, + WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm, void* ctx) +{ + (void)crl; + (void)cm; + (void)ctx; + if (ret == WC_NO_ERR_TRACE(CRL_MISSING)) + return 1; + return 0; +} + +/* Here we are allowing missing CRL's but want to error out when its revoked */ +static int test_revoked_loaded_int_cert_ctx_ready3(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify); + myVerifyAction = VERIFY_USE_PREVERFIY; + ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, + "./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, + "./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, + "./certs/intermediate/ca-int2-cert.pem", NULL, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL), + WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, + "./certs/crl/extra-crls/ca-int-cert-revoked.pem", + WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_SetCRL_ErrorCb(ctx, + test_revoked_loaded_int_cert_ctx_ready3_crl_missing_cb, NULL), + WOLFSSL_SUCCESS); + return EXPECT_RESULT(); +} #endif static int test_revoked_loaded_int_cert(void) @@ -93471,6 +93505,8 @@ static int test_revoked_loaded_int_cert(void) "./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready2}, {"./certs/intermediate/server-chain-short.pem", "./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready2}, + {"./certs/intermediate/server-chain-short.pem", + "./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready3}, }; size_t i; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d5d798672..21c4cb336 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2617,6 +2617,8 @@ struct WOLFSSL_CERT_MANAGER { #endif CallbackCACache caCacheCallback; /* CA cache addition callback */ CbMissingCRL cbMissingCRL; /* notify thru cb of missing crl */ + crlErrorCb crlCb; /* Allow user to override error */ + void* crlCbCtx; CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */ CbOCSPRespFree ocspRespFreeCb; /* Frees OCSP Response from IO Cb */ wolfSSL_Mutex caLock; /* CA list lock */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 5788b2f14..90f711589 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3314,6 +3314,8 @@ WOLFSSL_API int wolfSSL_SetVersion(WOLFSSL* ssl, int version); typedef void (*CallbackCACache)(unsigned char* der, int sz, int type); typedef void (*CbMissingCRL)(const char* url); +typedef int (*crlErrorCb)(int ret, WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm, + void* ctx); typedef int (*CbOCSPIO)(void*, const char*, int, unsigned char*, int, unsigned char**); typedef void (*CbOCSPRespFree)(void*,unsigned char*); @@ -3762,6 +3764,8 @@ WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz, int type); WOLFSSL_API int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb); + WOLFSSL_API int wolfSSL_CertManagerSetCRL_ErrorCb(WOLFSSL_CERT_MANAGER* cm, + crlErrorCb cb, void* ctx); WOLFSSL_API int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm); #ifdef HAVE_CRL_IO WOLFSSL_API int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, @@ -3805,6 +3809,8 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( WOLFSSL_API int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff, long sz, int type); WOLFSSL_API int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb); + WOLFSSL_API int wolfSSL_SetCRL_ErrorCb(WOLFSSL* ssl, crlErrorCb cb, + void* ctx); #ifdef HAVE_CRL_IO WOLFSSL_API int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb); #endif @@ -3822,6 +3828,8 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( WOLFSSL_API int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz, int type); WOLFSSL_API int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb); + WOLFSSL_API int wolfSSL_CTX_SetCRL_ErrorCb(WOLFSSL_CTX* ctx, crlErrorCb cb, + void* cbCtx); #ifdef HAVE_CRL_IO WOLFSSL_API int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb); #endif