CertManager verify callback
Execute verify callback from wolfSSL_CertManagerLoadCA
This commit is contained in:
parent
3f13b49fa3
commit
8580bd9937
@ -661,7 +661,7 @@ AC_ARG_ENABLE([leantls],
|
||||
|
||||
if test "$ENABLED_LEANTLS" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LEANTLS -DNO_WRITEV -DHAVE_ECC -DTFM_ECC256 -DECC_USER_CURVES -DNO_WOLFSSL_SERVER -DNO_RABBIT -DNO_RSA -DNO_DSA -DNO_DH -DNO_PWDBASED -DNO_MD5 -DNO_ERROR_STRINGS -DNO_OLD_TLS -DNO_RC4 -DNO_SHA -DNO_PSK -DNO_WOLFSSL_MEMORY"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LEANTLS -DNO_WRITEV -DHAVE_ECC -DTFM_ECC256 -DECC_USER_CURVES -DNO_WOLFSSL_SERVER -DNO_RABBIT -DNO_RSA -DNO_DSA -DNO_DH -DNO_PWDBASED -DNO_MD5 -DNO_ERROR_STRINGS -DNO_OLD_TLS -DNO_RC4 -DNO_SHA -DNO_PSK -DNO_WOLFSSL_MEMORY -DNO_WOLFSSL_CM_VERIFY"
|
||||
enable_lowresource=yes
|
||||
fi
|
||||
|
||||
|
@ -8845,6 +8845,38 @@ WOLFSSL_API int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER*, const char* f,
|
||||
WOLFSSL_API int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm,
|
||||
const unsigned char* buff, long sz, int format);
|
||||
|
||||
/*!
|
||||
\ingroup CertManager
|
||||
\brief The function sets the verifyCallback function in the Certificate
|
||||
Manager. If present, it will be called for each cert loaded. If there is
|
||||
a verification error, the verify callback can be used to over-ride the
|
||||
error.
|
||||
|
||||
\return none No return.
|
||||
|
||||
\param cm a pointer to a WOLFSSL_CERT_MANAGER structure, created using
|
||||
wolfSSL_CertManagerNew().
|
||||
\param vc a VerifyCallback function pointer to the callback routine
|
||||
|
||||
_Example_
|
||||
\code
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
|
||||
{ // do custom verification of certificate }
|
||||
|
||||
WOLFSSL_CTX* ctx = WOLFSSL_CTX_new(Protocol define);
|
||||
WOLFSSL_CERT_MANAGER* cm = wolfSSL_CertManagerNew();
|
||||
...
|
||||
wolfSSL_CertManagerSetVerify(cm, myVerify);
|
||||
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_CertManagerVerify
|
||||
*/
|
||||
WOLFSSL_API void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm,
|
||||
VerifyCallback vc);
|
||||
|
||||
/*!
|
||||
\brief Check CRL if the option is enabled and compares the cert to the
|
||||
CRL list.
|
||||
|
205
src/internal.c
205
src/internal.c
@ -9348,32 +9348,6 @@ int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx)
|
||||
|
||||
|
||||
#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
|
||||
typedef struct ProcPeerCertArgs {
|
||||
buffer* certs;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
buffer* exts; /* extensions */
|
||||
#endif
|
||||
DecodedCert* dCert;
|
||||
word32 idx;
|
||||
word32 begin;
|
||||
int totalCerts; /* number of certs in certs buffer */
|
||||
int count;
|
||||
int certIdx;
|
||||
int lastErr;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
byte ctxSz;
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
char untrustedDepth;
|
||||
#endif
|
||||
word16 fatal:1;
|
||||
word16 verifyErr:1;
|
||||
word16 dCertInit:1;
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
word16 haveTrustPeer:1; /* was cert verified by loaded trusted peer cert */
|
||||
#endif
|
||||
} ProcPeerCertArgs;
|
||||
|
||||
static void DoCertFatalAlert(WOLFSSL* ssl, int ret)
|
||||
{
|
||||
int alertWhy;
|
||||
@ -9405,9 +9379,11 @@ static void DoCertFatalAlert(WOLFSSL* ssl, int ret)
|
||||
* store->error_depth member to determine index (0=peer, >1 intermediates)
|
||||
*/
|
||||
|
||||
static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret,
|
||||
ProcPeerCertArgs* args)
|
||||
{
|
||||
int verify_ok = 0, use_cb = 0;
|
||||
void *heap = (ssl != NULL) ? ssl->heap : cm->heap;
|
||||
|
||||
/* Determine if verify was okay */
|
||||
if (ret == 0) {
|
||||
@ -9416,7 +9392,7 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
|
||||
/* Determine if verify callback should be used */
|
||||
if (ret != 0) {
|
||||
if (!ssl->options.verifyNone) {
|
||||
if ((ssl != NULL) && (!ssl->options.verifyNone)) {
|
||||
use_cb = 1; /* always report errors */
|
||||
}
|
||||
}
|
||||
@ -9434,7 +9410,7 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
/* perform domain name check on the peer certificate */
|
||||
if (args->dCertInit && args->dCert &&
|
||||
if (args->dCertInit && args->dCert && (ssl != NULL) &&
|
||||
ssl->param && ssl->param->hostName[0]) {
|
||||
/* If altNames names is present, then subject common name is ignored */
|
||||
if (args->dCert->altNames != NULL) {
|
||||
@ -9458,7 +9434,7 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
}
|
||||
|
||||
/* perform IP address check on the peer certificate */
|
||||
if ((args->dCertInit != 0) && (args->dCert != NULL) &&
|
||||
if ((args->dCertInit != 0) && (args->dCert != NULL) && (ssl != NULL) &&
|
||||
(ssl->param != NULL) && (XSTRLEN(ssl->param->ipasc) > 0)) {
|
||||
if (CheckIPAddr(args->dCert, ssl->param->ipasc) != 0) {
|
||||
if (ret == 0) {
|
||||
@ -9468,11 +9444,15 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
}
|
||||
#endif
|
||||
/* if verify callback has been set */
|
||||
if (use_cb && (ssl->verifyCallback
|
||||
if ((use_cb && (ssl != NULL) && ((ssl->verifyCallback != NULL)
|
||||
#ifdef OPENSSL_ALL
|
||||
|| ssl->ctx->verifyCertCb
|
||||
|| (ssl->ctx->verifyCertCb != NULL)
|
||||
#endif
|
||||
)) {
|
||||
))
|
||||
#ifndef NO_WOLFSSL_CM_VERIFY
|
||||
|| ((cm != NULL) && (cm->verifyCallback != NULL))
|
||||
#endif
|
||||
) {
|
||||
int verifyFail = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
WOLFSSL_X509_STORE_CTX* store;
|
||||
@ -9490,23 +9470,23 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
|
||||
sizeof(WOLFSSL_X509_STORE_CTX), ssl->heap, DYNAMIC_TYPE_X509_STORE);
|
||||
sizeof(WOLFSSL_X509_STORE_CTX), heap, DYNAMIC_TYPE_X509_STORE);
|
||||
if (store == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), ssl->heap,
|
||||
x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
|
||||
DYNAMIC_TYPE_X509);
|
||||
if (x509 == NULL) {
|
||||
XFREE(store, ssl->heap, DYNAMIC_TYPE_X509);
|
||||
XFREE(store, heap, DYNAMIC_TYPE_X509);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
domain = (char*)XMALLOC(ASN_NAME_MAX, ssl->heap, DYNAMIC_TYPE_STRING);
|
||||
domain = (char*)XMALLOC(ASN_NAME_MAX, heap, DYNAMIC_TYPE_STRING);
|
||||
if (domain == NULL) {
|
||||
XFREE(store, ssl->heap, DYNAMIC_TYPE_X509);
|
||||
XFREE(store, heap, DYNAMIC_TYPE_X509);
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
XFREE(x509, ssl->heap, DYNAMIC_TYPE_X509);
|
||||
XFREE(x509, heap, DYNAMIC_TYPE_X509);
|
||||
#endif
|
||||
return MEMORY_E;
|
||||
}
|
||||
@ -9533,72 +9513,80 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
store->error_depth = args->certIdx;
|
||||
store->discardSessionCerts = 0;
|
||||
store->domain = domain;
|
||||
store->userCtx = ssl->verifyCbCtx;
|
||||
store->userCtx = (ssl != NULL) ? ssl->verifyCbCtx : cm;
|
||||
store->certs = args->certs;
|
||||
store->totalCerts = args->totalCerts;
|
||||
#if defined(HAVE_EX_DATA) || defined(FORTRESS)
|
||||
store->ex_data[0] = ssl;
|
||||
#endif
|
||||
|
||||
if (ssl != NULL) {
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
|
||||
if (ssl->ctx->x509_store_pt != NULL) {
|
||||
store->store = ssl->ctx->x509_store_pt;
|
||||
}
|
||||
else {
|
||||
store->store = &ssl->ctx->x509_store;
|
||||
}
|
||||
|
||||
if (ssl->ctx->x509_store_pt != NULL) {
|
||||
store->store = ssl->ctx->x509_store_pt;
|
||||
}
|
||||
else {
|
||||
store->store = &ssl->ctx->x509_store;
|
||||
}
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
store->depth = args->count;
|
||||
store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
|
||||
sizeof(WOLFSSL_X509_VERIFY_PARAM),
|
||||
ssl->heap, DYNAMIC_TYPE_OPENSSL);
|
||||
if (store->param == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
|
||||
/* Overwrite with non-default param values in SSL */
|
||||
if (ssl->param) {
|
||||
if (ssl->param->check_time)
|
||||
store->param->check_time = ssl->param->check_time;
|
||||
store->depth = args->count;
|
||||
store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
|
||||
sizeof(WOLFSSL_X509_VERIFY_PARAM),
|
||||
heap, DYNAMIC_TYPE_OPENSSL);
|
||||
if (store->param == NULL) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(domain, heap, DYNAMIC_TYPE_STRING);
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
XFREE(x509, heap, DYNAMIC_TYPE_X509);
|
||||
#endif
|
||||
XFREE(store, heap, DYNAMIC_TYPE_X509_STORE);
|
||||
#endif
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
|
||||
/* Overwrite with non-default param values in SSL */
|
||||
if (ssl->param) {
|
||||
if (ssl->param->check_time)
|
||||
store->param->check_time = ssl->param->check_time;
|
||||
|
||||
if (ssl->param->flags)
|
||||
store->param->flags = ssl->param->flags;
|
||||
if (ssl->param->flags)
|
||||
store->param->flags = ssl->param->flags;
|
||||
|
||||
if (ssl->param->hostName[0])
|
||||
XMEMCPY(store->param->hostName, ssl->param->hostName,
|
||||
WOLFSSL_HOST_NAME_MAX);
|
||||
if (ssl->param->hostName[0])
|
||||
XMEMCPY(store->param->hostName, ssl->param->hostName,
|
||||
WOLFSSL_HOST_NAME_MAX);
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* defined(OPENSSL_EXTRA) */
|
||||
#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)*/
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
#ifdef KEEP_PEER_CERT
|
||||
if (args->certIdx == 0) {
|
||||
store->current_cert = &ssl->peerCert; /* use existing X509 */
|
||||
}
|
||||
else
|
||||
if (args->certIdx == 0) {
|
||||
store->current_cert = &ssl->peerCert; /* use existing X509 */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
InitX509(x509, 0, ssl->heap);
|
||||
if (CopyDecodedToX509(x509, args->dCert) == 0) {
|
||||
store->current_cert = x509;
|
||||
{
|
||||
InitX509(x509, 0, heap);
|
||||
if (CopyDecodedToX509(x509, args->dCert) == 0) {
|
||||
store->current_cert = x509;
|
||||
}
|
||||
else {
|
||||
FreeX509(x509);
|
||||
}
|
||||
}
|
||||
else {
|
||||
FreeX509(x509);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef SESSION_CERTS
|
||||
store->sesChain = &ssl->session.chain;
|
||||
store->sesChain = &ssl->session.chain;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_ALL
|
||||
}
|
||||
#ifndef NO_WOLFSSL_CM_VERIFY
|
||||
/* non-zero return code indicates failure override */
|
||||
if (ssl->ctx->verifyCertCb) {
|
||||
if (ssl->ctx->verifyCertCb(store, ssl->ctx->verifyCertCbArg)) {
|
||||
if ((cm != NULL) && (cm->verifyCallback != NULL)) {
|
||||
store->userCtx = cm;
|
||||
if (cm->verifyCallback(verify_ok, store)) {
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Verify Cert callback overriding error!");
|
||||
WOLFSSL_MSG("Verify CM callback overriding error!");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
@ -9608,16 +9596,33 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* non-zero return code indicates failure override */
|
||||
if (ssl->verifyCallback) {
|
||||
if (ssl->verifyCallback(verify_ok, store)) {
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Verify callback overriding error!");
|
||||
ret = 0;
|
||||
if (ssl != NULL) {
|
||||
#ifdef OPENSSL_ALL
|
||||
/* non-zero return code indicates failure override */
|
||||
if (ssl->ctx->verifyCertCb) {
|
||||
if (ssl->ctx->verifyCertCb(store, ssl->ctx->verifyCertCbArg)) {
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Verify Cert callback overriding error!");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
verifyFail = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
verifyFail = 1;
|
||||
#endif
|
||||
|
||||
/* non-zero return code indicates failure override */
|
||||
if (ssl->verifyCallback) {
|
||||
if (ssl->verifyCallback(verify_ok, store)) {
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Verify callback overriding error!");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
verifyFail = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9639,7 +9644,7 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
store->chain = NULL;
|
||||
#endif
|
||||
#ifdef SESSION_CERTS
|
||||
if (store->discardSessionCerts) {
|
||||
if ((ssl != NULL) && (store->discardSessionCerts)) {
|
||||
WOLFSSL_MSG("Verify callback requested discard sess certs");
|
||||
ssl->session.chain.count = 0;
|
||||
#ifdef WOLFSSL_ALT_CERT_CHAINS
|
||||
@ -9648,19 +9653,21 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args)
|
||||
}
|
||||
#endif /* SESSION_CERTS */
|
||||
#ifdef OPENSSL_EXTRA
|
||||
if (store->param){
|
||||
XFREE(store->param, ssl->heap, DYNAMIC_TYPE_OPENSSL);
|
||||
if ((ssl != NULL) && (store->param)) {
|
||||
XFREE(store->param, heap, DYNAMIC_TYPE_OPENSSL);
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(domain, ssl->heap, DYNAMIC_TYPE_STRING);
|
||||
XFREE(domain, heap, DYNAMIC_TYPE_STRING);
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
XFREE(x509, ssl->heap, DYNAMIC_TYPE_X509);
|
||||
XFREE(x509, heap, DYNAMIC_TYPE_X509);
|
||||
#endif
|
||||
XFREE(store, ssl->heap, DYNAMIC_TYPE_X509_STORE);
|
||||
XFREE(store, heap, DYNAMIC_TYPE_X509_STORE);
|
||||
#endif
|
||||
}
|
||||
|
||||
(void)heap;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -10285,7 +10292,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
#endif /* HAVE_OCSP || HAVE_CRL */
|
||||
|
||||
/* Do verify callback */
|
||||
ret = DoVerifyCallback(ssl, ret, args);
|
||||
ret = DoVerifyCallback(ssl->ctx->cm, ssl, ret, args);
|
||||
|
||||
#ifdef WOLFSSL_ALT_CERT_CHAINS
|
||||
/* For alternate cert chain, its okay for a CA cert to fail
|
||||
@ -10912,7 +10919,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
#endif
|
||||
|
||||
/* Do verify callback */
|
||||
ret = DoVerifyCallback(ssl, ret, args);
|
||||
ret = DoVerifyCallback(ssl->ctx->cm, ssl, ret, args);
|
||||
|
||||
if (ssl->options.verifyNone &&
|
||||
(ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
|
||||
|
100
src/ssl.c
100
src/ssl.c
@ -5412,6 +5412,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
{
|
||||
DerBuffer* der = NULL; /* holds DER or RAW (for NTRU) */
|
||||
int ret = 0;
|
||||
int done = 0;
|
||||
int eccKey = 0;
|
||||
int ed25519Key = 0;
|
||||
int rsaKey = 0;
|
||||
@ -5529,18 +5530,22 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
/* check for error */
|
||||
if (ret < 0) {
|
||||
FreeDer(&der);
|
||||
return ret;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if (done == 1) {
|
||||
/* No operation, just skip the next section */
|
||||
}
|
||||
/* Handle DER owner */
|
||||
if (type == CA_TYPE) {
|
||||
else if (type == CA_TYPE) {
|
||||
if (ctx == NULL) {
|
||||
WOLFSSL_MSG("Need context for CA load");
|
||||
FreeDer(&der);
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
/* verify CA unless user set to no verify */
|
||||
return AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
|
||||
ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
|
||||
done = 1;
|
||||
}
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
else if (type == TRUSTED_PEER_TYPE) {
|
||||
@ -5550,7 +5555,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
/* add trusted peer cert */
|
||||
return AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
|
||||
ret = AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
|
||||
done = 1;
|
||||
}
|
||||
#endif /* WOLFSSL_TRUST_PEER_CERT */
|
||||
else if (type == CERT_TYPE) {
|
||||
@ -5605,7 +5611,10 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
return WOLFSSL_BAD_CERTTYPE;
|
||||
}
|
||||
|
||||
if (type == PRIVATEKEY_TYPE && format != WOLFSSL_FILETYPE_RAW) {
|
||||
if (done == 1) {
|
||||
/* No operation, just skip the next section */
|
||||
}
|
||||
else if (type == PRIVATEKEY_TYPE && format != WOLFSSL_FILETYPE_RAW) {
|
||||
#if defined(WOLFSSL_ENCRYPTED_KEYS) || defined(HAVE_PKCS8)
|
||||
/* attempt to detect key type */
|
||||
if (algId == RSAk)
|
||||
@ -5892,10 +5901,26 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (done == 1) {
|
||||
#ifndef NO_WOLFSSL_CM_VERIFY
|
||||
if ((type == CA_TYPE) || (type == CERT_TYPE)) {
|
||||
/* Call to over-ride status */
|
||||
if ((ctx != NULL) && (ctx->cm != NULL) &&
|
||||
(ctx->cm->verifyCallback != NULL)) {
|
||||
ret = CM_VerifyBuffer_ex(ctx->cm, buff,
|
||||
sz, format, (ret == WOLFSSL_SUCCESS ? 0 : ret));
|
||||
}
|
||||
}
|
||||
#endif /* NO_WOLFSSL_CM_VERIFY */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (ssl && resetSuites) {
|
||||
word16 havePSK = 0;
|
||||
word16 haveRSA = 0;
|
||||
@ -6161,9 +6186,21 @@ int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef NO_WOLFSSL_CM_VERIFY
|
||||
void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify");
|
||||
if (cm == NULL)
|
||||
return;
|
||||
|
||||
cm->verifyCallback = vc;
|
||||
}
|
||||
#endif /* NO_WOLFSSL_CM_VERIFY */
|
||||
|
||||
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
|
||||
int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
|
||||
long sz, int format)
|
||||
int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
|
||||
long sz, int format, int err_val)
|
||||
{
|
||||
int ret = 0;
|
||||
DerBuffer* der = NULL;
|
||||
@ -6209,6 +6246,43 @@ int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
|
||||
ret = CheckCertCRL(cm->crl, cert);
|
||||
#endif
|
||||
|
||||
#ifndef NO_WOLFSSL_CM_VERIFY
|
||||
/* if verify callback has been set */
|
||||
if (cm->verifyCallback) {
|
||||
buffer certBuf;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ProcPeerCertArgs* args = NULL;
|
||||
args = (ProcPeerCertArgs*)XMALLOC(
|
||||
sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (args == NULL) {
|
||||
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
ProcPeerCertArgs args[1];
|
||||
#endif
|
||||
|
||||
certBuf.buffer = (byte*)buff;
|
||||
certBuf.length = (unsigned int)sz;
|
||||
XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
|
||||
|
||||
args->totalCerts = 1;
|
||||
args->certs = &certBuf;
|
||||
args->dCert = cert;
|
||||
args->dCertInit = 1;
|
||||
|
||||
if (err_val != 0) {
|
||||
ret = err_val;
|
||||
}
|
||||
ret = DoVerifyCallback(cm, NULL, ret, args);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
(void)err_val;
|
||||
#endif
|
||||
|
||||
FreeDecodedCert(cert);
|
||||
FreeDer(&der);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -6218,7 +6292,12 @@ int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
|
||||
return ret == 0 ? WOLFSSL_SUCCESS : ret;
|
||||
}
|
||||
|
||||
|
||||
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
|
||||
int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
|
||||
long sz, int format)
|
||||
{
|
||||
return CM_VerifyBuffer_ex(cm, buff, sz, format, 0);
|
||||
}
|
||||
/* turn on OCSP if off and compiled in, set options */
|
||||
int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
|
||||
{
|
||||
@ -6655,9 +6734,10 @@ int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
|
||||
}
|
||||
}
|
||||
if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
|
||||
&& format == WOLFSSL_FILETYPE_PEM)
|
||||
&& format == WOLFSSL_FILETYPE_PEM) {
|
||||
ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl,
|
||||
verify);
|
||||
}
|
||||
#ifdef HAVE_CRL
|
||||
else if (type == CRL_TYPE)
|
||||
ret = BufferLoadCRL(crl, myBuffer, sz, format, verify);
|
||||
|
44
tests/api.c
44
tests/api.c
@ -1143,6 +1143,49 @@ static void test_wolfSSL_CertManagerGetCerts(void)
|
||||
!defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
|
||||
defined(WOLFSSL_SIGNER_DER_CERT) */
|
||||
}
|
||||
|
||||
static int test_wolfSSL_CertManagerSetVerify(void)
|
||||
{
|
||||
int ret = 0;
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
|
||||
!defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA)
|
||||
WOLFSSL_CERT_MANAGER* cm = NULL;
|
||||
int tmp = myVerifyFail;
|
||||
const char* ca_cert = "./certs/ca-cert.pem";
|
||||
const char* expiredCert = "./certs/test/expired/expired-cert.pem";
|
||||
|
||||
cm = wolfSSL_CertManagerNew();
|
||||
AssertNotNull(cm);
|
||||
|
||||
wolfSSL_CertManagerSetVerify(cm, myVerify);
|
||||
|
||||
ret = wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL);
|
||||
AssertIntEQ(ret, WOLFSSL_SUCCESS);
|
||||
|
||||
/* Use the test CB that always accepts certs */
|
||||
myVerifyFail = 0;
|
||||
|
||||
ret = wolfSSL_CertManagerVerify(cm, expiredCert, WOLFSSL_FILETYPE_PEM);
|
||||
AssertIntEQ(ret, WOLFSSL_SUCCESS);
|
||||
|
||||
#ifdef WOLFSSL_ALWAYS_VERIFY_CB
|
||||
{
|
||||
const char* verifyCert = "./certs/server-cert.pem";
|
||||
/* Use the test CB that always fails certs */
|
||||
myVerifyFail = 1;
|
||||
|
||||
ret = wolfSSL_CertManagerVerify(cm, verifyCert, WOLFSSL_FILETYPE_PEM);
|
||||
AssertIntEQ(ret, VERIFY_CERT_ERROR);
|
||||
}
|
||||
#endif
|
||||
|
||||
wolfSSL_CertManagerFree(cm);
|
||||
myVerifyFail = tmp;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void test_wolfSSL_CertManagerCRL(void)
|
||||
{
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
|
||||
@ -28799,6 +28842,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_CTX_load_verify_locations();
|
||||
test_wolfSSL_CertManagerLoadCABuffer();
|
||||
test_wolfSSL_CertManagerGetCerts();
|
||||
test_wolfSSL_CertManagerSetVerify();
|
||||
test_wolfSSL_CertManagerCRL();
|
||||
test_wolfSSL_CTX_load_verify_locations_ex();
|
||||
test_wolfSSL_CTX_load_verify_buffer_ex();
|
||||
|
@ -1940,6 +1940,9 @@ struct WOLFSSL_CERT_MANAGER {
|
||||
#endif
|
||||
char* ocspOverrideURL; /* use this responder */
|
||||
void* ocspIOCtx; /* I/O callback CTX */
|
||||
#ifndef NO_WOLFSSL_CM_VERIFY
|
||||
VerifyCallback verifyCallback; /* Verify callback */
|
||||
#endif
|
||||
CallbackCACache caCacheCallback; /* CA cache addition callback */
|
||||
CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */
|
||||
CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */
|
||||
@ -1966,6 +1969,42 @@ WOLFSSL_LOCAL int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER*, const char*);
|
||||
WOLFSSL_LOCAL int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER*, void*, int, int*);
|
||||
WOLFSSL_LOCAL int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER*, const void*, int);
|
||||
WOLFSSL_LOCAL int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER*);
|
||||
WOLFSSL_LOCAL int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
|
||||
long sz, int format, int err_val);
|
||||
|
||||
|
||||
#ifndef NO_CERTS
|
||||
#if !defined NOCERTS &&\
|
||||
(!defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH))
|
||||
typedef struct ProcPeerCertArgs {
|
||||
buffer* certs;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
buffer* exts; /* extensions */
|
||||
#endif
|
||||
DecodedCert* dCert;
|
||||
word32 idx;
|
||||
word32 begin;
|
||||
int totalCerts; /* number of certs in certs buffer */
|
||||
int count;
|
||||
int certIdx;
|
||||
int lastErr;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
byte ctxSz;
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
char untrustedDepth;
|
||||
#endif
|
||||
word16 fatal:1;
|
||||
word16 verifyErr:1;
|
||||
word16 dCertInit:1;
|
||||
#ifdef WOLFSSL_TRUST_PEER_CERT
|
||||
word16 haveTrustPeer:1; /* was cert verified by loaded trusted peer cert */
|
||||
#endif
|
||||
} ProcPeerCertArgs;
|
||||
WOLFSSL_LOCAL int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl,
|
||||
int ret, ProcPeerCertArgs* args);
|
||||
#endif /* !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) */
|
||||
#endif /* !defined NO_CERTS */
|
||||
|
||||
/* wolfSSL Sock Addr */
|
||||
struct WOLFSSL_SOCKADDR {
|
||||
|
@ -2560,6 +2560,8 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER*,
|
||||
int options);
|
||||
WOLFSSL_API int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER*);
|
||||
WOLFSSL_API void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm,
|
||||
VerifyCallback vc);
|
||||
WOLFSSL_API int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER*,
|
||||
const char*, int, int);
|
||||
WOLFSSL_API int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER*,
|
||||
|
@ -525,7 +525,7 @@ enum VerifyType {
|
||||
VERIFY_CRL = 2,
|
||||
VERIFY_OCSP = 3,
|
||||
VERIFY_NAME = 4,
|
||||
VERIFY_SKIP_DATE = 5
|
||||
VERIFY_SKIP_DATE = 5,
|
||||
};
|
||||
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
|
Loading…
x
Reference in New Issue
Block a user