From 3cbcc872c1166b6697fc0eb497c9935bc69fd990 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 5 Jul 2018 14:04:06 -0700 Subject: [PATCH 1/4] Improved PK callback support for ConfirmSignature so certificate verification uses the callbacks. Retained wolfSSL/wolfCrypt isolation (I.E. no wolfSSL references from wolfCrypt). --- src/internal.c | 144 ++++++++++++++++++++++++++++++++++++++++ src/ssl.c | 14 ++++ wolfcrypt/src/asn.c | 32 +++++++-- wolfssl/internal.h | 4 ++ wolfssl/ssl.h | 11 ++- wolfssl/wolfcrypt/asn.h | 28 ++++++++ 6 files changed, 228 insertions(+), 5 deletions(-) diff --git a/src/internal.c b/src/internal.c index 8c6afbd39..ef33f4f26 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8162,6 +8162,112 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif + +#ifdef HAVE_PK_CALLBACKS + + typedef struct wolfPkCbInfo { + WOLFSSL* ssl; + #ifdef HAVE_ECC + struct { + CallbackEccVerify pk; + void* ctx; + } ecc; + #endif + #ifndef NO_RSA + struct { + CallbackRsaVerify pk; + void* ctx; + } rsa; + #endif + } wolfPkCbInfo; + +#ifdef HAVE_ECC + static int SigPkCbEccVerify(const unsigned char* sig, unsigned int sigSz, + const unsigned char* hash, unsigned int hashSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx) + { + int ret = NOT_COMPILED_IN; + wolfPkCbInfo* info = (wolfPkCbInfo*)ctx; + + if (info && info->ecc.pk) { + ret = info->ecc.pk(info->ssl, sig, sigSz, hash, hashSz, + keyDer, keySz, result, info->ecc.ctx); + } + return ret; + } +#endif +#ifndef NO_RSA + static int SigPkCbRsaVerify(unsigned char* sig, unsigned int sigSz, + unsigned char** out, const unsigned char* keyDer, unsigned int keySz, + void* ctx) + { + int ret = NOT_COMPILED_IN; + wolfPkCbInfo* info = (wolfPkCbInfo*)ctx; + + if (info && info->rsa.pk) { + ret = info->rsa.pk(info->ssl, sig, sigSz, out, keyDer, keySz, + info->rsa.ctx); + } + return ret; + } +#endif + +int InitSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx) +{ + wolfPkCbInfo* info; + int setupPk = 0; + + if (ssl == NULL || sigCtx == NULL) + return BAD_FUNC_ARG; + + /* only setup the verify callback if a PK is set */ +#ifdef HAVE_ECC + if (ssl->ctx->EccVerifyCb) + setupPk = 1; +#endif +#ifndef NO_RSA + if (ssl->ctx->RsaVerifyCb) + setupPk = 1; +#endif + + if (setupPk) { + info = (wolfPkCbInfo*)XMALLOC(sizeof(wolfPkCbInfo), ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) { + return MEMORY_E; + } + + XMEMSET(info, 0, sizeof(wolfPkCbInfo)); + sigCtx->pkCtx = info; + #ifdef HAVE_ECC + info->ecc.pk = ssl->ctx->EccVerifyCb; + info->ecc.ctx = ssl->EccVerifyCtx; + sigCtx->pkCbEcc = SigPkCbEccVerify; + #endif + #ifndef NO_RSA + info->rsa.pk = ssl->ctx->RsaVerifyCb; + info->rsa.ctx = ssl->RsaVerifyCtx; + sigCtx->pkCbRsa = SigPkCbRsaVerify; + #endif + } + + return 0; +} + +void FreeSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx) +{ + if (ssl == NULL || sigCtx == NULL) + return; + + if (sigCtx->pkCtx) { + XFREE(sigCtx->pkCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + sigCtx->pkCtx = NULL; + } +} +#endif /* HAVE_PK_CALLBACKS */ + + typedef struct ProcPeerCertArgs { buffer* certs; #ifdef WOLFSSL_TLS13 @@ -8213,6 +8319,9 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) #endif if (args->dCert) { if (args->dCertInit) { + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &args->dCert->sigCtx); + #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; } @@ -8479,6 +8588,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->dCert->sigCtx.asyncCtx = ssl; #endif args->dCertInit = 1; + #ifdef HAVE_PK_CALLBACKS + ret = InitSigPkCb(ssl, &args->dCert->sigCtx); + if (ret != 0) + goto exit_ppc; + #endif } ret = ParseCertRelative(args->dCert, CERT_TYPE, 0, @@ -8512,6 +8626,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* no trusted peer cert */ WOLFSSL_MSG("No matching trusted peer cert. " "Checking CAs"); + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &args->dCert->sigCtx); + #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; #ifdef OPENSSL_EXTRA @@ -8522,6 +8639,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, haveTrustPeer = 1; } else { WOLFSSL_MSG("Trusted peer cert did not match!"); + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &args->dCert->sigCtx); + #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; #ifdef OPENSSL_EXTRA @@ -8546,6 +8666,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->dCert->sigCtx.asyncCtx = ssl; #endif args->dCertInit = 1; + #ifdef HAVE_PK_CALLBACKS + ret = InitSigPkCb(ssl, &args->dCert->sigCtx); + if (ret != 0) + goto exit_ppc; + #endif } ret = ParseCertRelative(args->dCert, CERT_TYPE, 0, @@ -8568,6 +8693,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif if (!AlreadySigner(ssl->ctx->cm, subjectHash)) args->untrustedDepth = 1; + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &args->dCert->sigCtx); + #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; } @@ -8593,6 +8721,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->dCert->sigCtx.asyncCtx = ssl; #endif args->dCertInit = 1; + #ifdef HAVE_PK_CALLBACKS + ret = InitSigPkCb(ssl, &args->dCert->sigCtx); + if (ret != 0) + goto exit_ppc; + #endif } /* check if returning from non-blocking OCSP */ @@ -8974,6 +9107,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = 0; /* reset error */ } + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &args->dCert->sigCtx); + #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; args->count--; @@ -9007,6 +9143,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->dCert->sigCtx.asyncCtx = ssl; #endif args->dCertInit = 1; + #ifdef HAVE_PK_CALLBACKS + ret = InitSigPkCb(ssl, &args->dCert->sigCtx); + if (ret != 0) + goto exit_ppc; + #endif } #ifdef WOLFSSL_TRUST_PEER_CERT @@ -9466,6 +9607,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &args->dCert->sigCtx); + #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; diff --git a/src/ssl.c b/src/ssl.c index a3e0ceee1..29e2f2bd9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6680,7 +6680,18 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) size = ssl->buffers.certificate->length; buff = ssl->buffers.certificate->buffer; InitDecodedCert(&der, buff, size, ssl->heap); +#ifdef HAVE_PK_CALLBACKS + ret = InitSigPkCb(ssl, &der.sigCtx); + if (ret != 0) { + FreeDecodedCert(&der); + return ret; + } +#endif + if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) { + #ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &der.sigCtx); + #endif FreeDecodedCert(&der); return WOLFSSL_FAILURE; } @@ -6688,6 +6699,9 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) size = ssl->buffers.key->length; buff = ssl->buffers.key->buffer; ret = wc_CheckPrivateKey(buff, size, &der); +#ifdef HAVE_PK_CALLBACKS + FreeSigPkCb(ssl, &der.sigCtx); +#endif FreeDecodedCert(&der); return ret; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 697d3158e..aa6000720 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5348,16 +5348,40 @@ static int ConfirmSignature(SignatureCtx* sigCtx, #ifndef NO_RSA case RSAk: { - ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz, - &sigCtx->out, sigCtx->key.rsa); + #ifdef HAVE_PK_CALLBACKS + if (sigCtx->pkCbRsa) { + ret = sigCtx->pkCbRsa( + sigCtx->plain, sigSz, &sigCtx->out, + key, keySz, + sigCtx->pkCtx); + } + else + #endif /* HAVE_PK_CALLBACKS */ + { + ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz, + &sigCtx->out, sigCtx->key.rsa); + } break; } #endif /* !NO_RSA */ #ifdef HAVE_ECC case ECDSAk: { - ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest, - sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc); + #ifdef HAVE_PK_CALLBACKS + if (sigCtx->pkCbEcc) { + ret = sigCtx->pkCbEcc( + sig, sigSz, + sigCtx->digest, sigCtx->digestSz, + key, keySz, &sigCtx->verify, + sigCtx->pkCtx); + } + else + #endif /* HAVE_PK_CALLBACKS */ + { + ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest, + sigCtx->digestSz, &sigCtx->verify, + sigCtx->key.ecc); + } break; } #endif /* HAVE_ECC */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 690b9f254..c4ac9f2c4 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1529,6 +1529,10 @@ WOLFSSL_LOCAL void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); #ifdef HAVE_PK_CALLBACKS WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); +#ifndef NO_ASN + WOLFSSL_LOCAL int InitSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx); + WOLFSSL_LOCAL void FreeSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx); +#endif #endif WOLFSSL_LOCAL void FreeKeyExchange(WOLFSSL* ssl); WOLFSSL_LOCAL int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 13a092ee9..4bfa335d4 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1840,6 +1840,8 @@ enum KDF_MacAlgorithm { /* Public Key Callback support */ +#ifdef HAVE_PK_CALLBACKS +#ifdef HAVE_ECC typedef int (*CallbackEccSign)(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz, unsigned char* out, unsigned int* outSz, @@ -1866,6 +1868,7 @@ typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, struct ecc_key* otherKey, WOLFSSL_API void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX*, CallbackEccSharedSecret); WOLFSSL_API void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl); +#endif #ifndef NO_DH /* Public DH Key Callback support */ @@ -1880,6 +1883,7 @@ WOLFSSL_API void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl); #endif /* !NO_DH */ +#ifdef HAVE_ED25519 struct ed25519_key; typedef int (*CallbackEd25519Sign)(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz, @@ -1900,7 +1904,9 @@ WOLFSSL_API void wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX*, CallbackEd25519Verify); WOLFSSL_API void wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl); +#endif +#ifdef HAVE_CURVE25519 struct curve25519_key; typedef int (*CallbackX25519SharedSecret)(WOLFSSL* ssl, struct curve25519_key* otherKey, @@ -1912,7 +1918,9 @@ WOLFSSL_API void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX*, CallbackX25519SharedSecret); WOLFSSL_API void wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl); +#endif +#ifndef NO_RSA typedef int (*CallbackRsaSign)(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz, unsigned char* out, unsigned int* outSz, @@ -1976,7 +1984,8 @@ typedef int (*CallbackRsaDec)(WOLFSSL* ssl, WOLFSSL_API void wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX*, CallbackRsaDec); WOLFSSL_API void wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); - +#endif +#endif /* HAVE_PK_CALLBACKS */ #ifndef NO_CERTS WOLFSSL_API void wolfSSL_CTX_SetCACb(WOLFSSL_CTX*, CallbackCACache); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index d87f17ee9..886c72e83 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -492,6 +492,24 @@ enum SignatureState { SIG_STATE_CHECK, }; + +#ifdef HAVE_PK_CALLBACKS +#ifdef HAVE_ECC + typedef int (*wc_CallbackEccVerify)( + const unsigned char* sig, unsigned int sigSz, + const unsigned char* hash, unsigned int hashSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx); +#endif +#ifndef NO_RSA + typedef int (*wc_CallbackRsaVerify)( + unsigned char* sig, unsigned int sigSz, + unsigned char** out, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +#endif +#endif /* HAVE_PK_CALLBACKS */ + struct SignatureCtx { void* heap; byte* digest; @@ -523,6 +541,16 @@ struct SignatureCtx { WC_ASYNC_DEV* asyncDev; void* asyncCtx; #endif + +#ifdef HAVE_PK_CALLBACKS + void* pkCtx; +#ifdef HAVE_ECC + wc_CallbackEccVerify pkCbEcc; +#endif +#ifndef NO_RSA + wc_CallbackRsaVerify pkCbRsa; +#endif +#endif /* HAVE_PK_CALLBACKS */ }; enum CertSignState { From 32f1b0a9c227e965f1eb66ce9fc5473597341f06 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 6 Jul 2018 09:28:46 -0700 Subject: [PATCH 2/4] Added separate context for each `SignatureCtx` verify callback. Added missing `ssl` info to callback context. --- src/internal.c | 112 ++++++++++++++++++++-------------------- wolfcrypt/src/asn.c | 4 +- wolfssl/internal.h | 4 +- wolfssl/wolfcrypt/asn.h | 3 +- 4 files changed, 63 insertions(+), 60 deletions(-) diff --git a/src/internal.c b/src/internal.c index ef33f4f26..3fc707b3d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8165,105 +8165,107 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_PK_CALLBACKS - typedef struct wolfPkCbInfo { - WOLFSSL* ssl; - #ifdef HAVE_ECC - struct { - CallbackEccVerify pk; - void* ctx; - } ecc; - #endif - #ifndef NO_RSA - struct { - CallbackRsaVerify pk; - void* ctx; - } rsa; - #endif - } wolfPkCbInfo; - #ifdef HAVE_ECC + typedef struct wolfPkCbEccInfo { + WOLFSSL* ssl; + CallbackEccVerify pk; + void* ctx; + } wolfPkCbEccInfo; static int SigPkCbEccVerify(const unsigned char* sig, unsigned int sigSz, const unsigned char* hash, unsigned int hashSz, const unsigned char* keyDer, unsigned int keySz, int* result, void* ctx) { int ret = NOT_COMPILED_IN; - wolfPkCbInfo* info = (wolfPkCbInfo*)ctx; + wolfPkCbEccInfo* info = (wolfPkCbEccInfo*)ctx; - if (info && info->ecc.pk) { - ret = info->ecc.pk(info->ssl, sig, sigSz, hash, hashSz, - keyDer, keySz, result, info->ecc.ctx); + if (info && info->pk) { + ret = info->pk(info->ssl, sig, sigSz, hash, hashSz, + keyDer, keySz, result, info->ctx); } return ret; } #endif #ifndef NO_RSA + typedef struct wolfPkCbRsaInfo { + WOLFSSL* ssl; + CallbackRsaVerify pk; + void* ctx; + } wolfPkCbRsaInfo; static int SigPkCbRsaVerify(unsigned char* sig, unsigned int sigSz, unsigned char** out, const unsigned char* keyDer, unsigned int keySz, void* ctx) { int ret = NOT_COMPILED_IN; - wolfPkCbInfo* info = (wolfPkCbInfo*)ctx; + wolfPkCbRsaInfo* info = (wolfPkCbRsaInfo*)ctx; - if (info && info->rsa.pk) { - ret = info->rsa.pk(info->ssl, sig, sigSz, out, keyDer, keySz, - info->rsa.ctx); + if (info && info->pk) { + ret = info->pk(info->ssl, sig, sigSz, out, keyDer, keySz, + info->ctx); } return ret; } #endif -int InitSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx) +int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx) { - wolfPkCbInfo* info; - int setupPk = 0; - if (ssl == NULL || sigCtx == NULL) return BAD_FUNC_ARG; /* only setup the verify callback if a PK is set */ #ifdef HAVE_ECC - if (ssl->ctx->EccVerifyCb) - setupPk = 1; -#endif -#ifndef NO_RSA - if (ssl->ctx->RsaVerifyCb) - setupPk = 1; -#endif - - if (setupPk) { - info = (wolfPkCbInfo*)XMALLOC(sizeof(wolfPkCbInfo), ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); + if (ssl->ctx->EccVerifyCb) { + wolfPkCbEccInfo* info = (wolfPkCbEccInfo*)XMALLOC( + sizeof(wolfPkCbEccInfo), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (info == NULL) { return MEMORY_E; } - - XMEMSET(info, 0, sizeof(wolfPkCbInfo)); - sigCtx->pkCtx = info; - #ifdef HAVE_ECC - info->ecc.pk = ssl->ctx->EccVerifyCb; - info->ecc.ctx = ssl->EccVerifyCtx; + XMEMSET(info, 0, sizeof(wolfPkCbEccInfo)); + info->ssl = ssl; + info->pk = ssl->ctx->EccVerifyCb; + info->ctx = ssl->EccVerifyCtx; sigCtx->pkCbEcc = SigPkCbEccVerify; - #endif - #ifndef NO_RSA - info->rsa.pk = ssl->ctx->RsaVerifyCb; - info->rsa.ctx = ssl->RsaVerifyCtx; - sigCtx->pkCbRsa = SigPkCbRsaVerify; - #endif + sigCtx->pkCtxEcc = info; } +#endif +#ifndef NO_RSA + /* only setup the verify callback if a PK is set */ + if (ssl->ctx->RsaVerifyCb) { + wolfPkCbRsaInfo* info = (wolfPkCbRsaInfo*)XMALLOC( + sizeof(wolfPkCbRsaInfo), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) { + FreeSigPkCb(ssl, sigCtx); + return MEMORY_E; + } + XMEMSET(info, 0, sizeof(wolfPkCbRsaInfo)); + info->ssl = ssl; + info->pk = ssl->ctx->RsaVerifyCb; + info->ctx = ssl->RsaVerifyCtx; + sigCtx->pkCbRsa = SigPkCbRsaVerify; + sigCtx->pkCtxRsa = info; + } +#endif return 0; } -void FreeSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx) +void FreeSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx) { if (ssl == NULL || sigCtx == NULL) return; - if (sigCtx->pkCtx) { - XFREE(sigCtx->pkCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - sigCtx->pkCtx = NULL; +#ifdef HAVE_ECC + if (sigCtx->pkCtxEcc) { + XFREE(sigCtx->pkCtxEcc, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + sigCtx->pkCtxEcc = NULL; } +#endif +#ifndef NO_RSA + if (sigCtx->pkCtxRsa) { + XFREE(sigCtx->pkCtxRsa, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + sigCtx->pkCtxRsa = NULL; + } +#endif } #endif /* HAVE_PK_CALLBACKS */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index aa6000720..76d05fc5a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5353,7 +5353,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, ret = sigCtx->pkCbRsa( sigCtx->plain, sigSz, &sigCtx->out, key, keySz, - sigCtx->pkCtx); + sigCtx->pkCtxRsa); } else #endif /* HAVE_PK_CALLBACKS */ @@ -5373,7 +5373,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, sig, sigSz, sigCtx->digest, sigCtx->digestSz, key, keySz, &sigCtx->verify, - sigCtx->pkCtx); + sigCtx->pkCtxEcc); } else #endif /* HAVE_PK_CALLBACKS */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c4ac9f2c4..398028d3e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1530,8 +1530,8 @@ WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); #ifdef HAVE_PK_CALLBACKS WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); #ifndef NO_ASN - WOLFSSL_LOCAL int InitSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx); - WOLFSSL_LOCAL void FreeSigPkCb(const WOLFSSL* ssl, SignatureCtx* sigCtx); + WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); + WOLFSSL_LOCAL void FreeSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); #endif #endif WOLFSSL_LOCAL void FreeKeyExchange(WOLFSSL* ssl); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 886c72e83..1a06a4fbe 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -543,12 +543,13 @@ struct SignatureCtx { #endif #ifdef HAVE_PK_CALLBACKS - void* pkCtx; #ifdef HAVE_ECC wc_CallbackEccVerify pkCbEcc; + void* pkCtxEcc; #endif #ifndef NO_RSA wc_CallbackRsaVerify pkCbRsa; + void* pkCtxRsa; #endif #endif /* HAVE_PK_CALLBACKS */ }; From 595beb3fecb77606b5cb7ad1c03ba575c6183f27 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 6 Jul 2018 09:35:00 -0700 Subject: [PATCH 3/4] Fixup for the removal of `const`. --- src/ssl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 29e2f2bd9..5a6ee7bc9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6681,7 +6681,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) buff = ssl->buffers.certificate->buffer; InitDecodedCert(&der, buff, size, ssl->heap); #ifdef HAVE_PK_CALLBACKS - ret = InitSigPkCb(ssl, &der.sigCtx); + ret = InitSigPkCb((WOLFSSL*)ssl, &der.sigCtx); if (ret != 0) { FreeDecodedCert(&der); return ret; @@ -6690,7 +6690,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) { #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &der.sigCtx); + FreeSigPkCb((WOLFSSL*)ssl, &der.sigCtx); #endif FreeDecodedCert(&der); return WOLFSSL_FAILURE; @@ -6700,7 +6700,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) buff = ssl->buffers.key->buffer; ret = wc_CheckPrivateKey(buff, size, &der); #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &der.sigCtx); + FreeSigPkCb((WOLFSSL*)ssl, &der.sigCtx); #endif FreeDecodedCert(&der); return ret; From 9c2a5d2906788fd0e3704e78e3d023b85ae30674 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 6 Jul 2018 16:21:43 -0700 Subject: [PATCH 4/4] Further simplification of the PK verify wrapping to avoid malloc/free. Thanks Todd! --- src/internal.c | 85 ++++++---------------------------------------- src/ssl.c | 6 ---- wolfssl/internal.h | 1 - 3 files changed, 10 insertions(+), 82 deletions(-) diff --git a/src/internal.c b/src/internal.c index 3fc707b3d..6b238e6db 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8166,42 +8166,32 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_PK_CALLBACKS #ifdef HAVE_ECC - typedef struct wolfPkCbEccInfo { - WOLFSSL* ssl; - CallbackEccVerify pk; - void* ctx; - } wolfPkCbEccInfo; static int SigPkCbEccVerify(const unsigned char* sig, unsigned int sigSz, const unsigned char* hash, unsigned int hashSz, const unsigned char* keyDer, unsigned int keySz, int* result, void* ctx) { int ret = NOT_COMPILED_IN; - wolfPkCbEccInfo* info = (wolfPkCbEccInfo*)ctx; + WOLFSSL* ssl = (WOLFSSL*)ctx; - if (info && info->pk) { - ret = info->pk(info->ssl, sig, sigSz, hash, hashSz, - keyDer, keySz, result, info->ctx); + if (ssl && ssl->ctx->EccVerifyCb) { + ret = ssl->ctx->EccVerifyCb(ssl, sig, sigSz, hash, hashSz, + keyDer, keySz, result, ssl->EccVerifyCtx); } return ret; } #endif #ifndef NO_RSA - typedef struct wolfPkCbRsaInfo { - WOLFSSL* ssl; - CallbackRsaVerify pk; - void* ctx; - } wolfPkCbRsaInfo; static int SigPkCbRsaVerify(unsigned char* sig, unsigned int sigSz, unsigned char** out, const unsigned char* keyDer, unsigned int keySz, void* ctx) { int ret = NOT_COMPILED_IN; - wolfPkCbRsaInfo* info = (wolfPkCbRsaInfo*)ctx; + WOLFSSL* ssl = (WOLFSSL*)ctx; - if (info && info->pk) { - ret = info->pk(info->ssl, sig, sigSz, out, keyDer, keySz, - info->ctx); + if (ssl && ssl->ctx->RsaVerifyCb) { + ret = ssl->ctx->RsaVerifyCb(ssl, sig, sigSz, out, keyDer, keySz, + ssl->RsaVerifyCtx); } return ret; } @@ -8215,58 +8205,21 @@ int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx) /* only setup the verify callback if a PK is set */ #ifdef HAVE_ECC if (ssl->ctx->EccVerifyCb) { - wolfPkCbEccInfo* info = (wolfPkCbEccInfo*)XMALLOC( - sizeof(wolfPkCbEccInfo), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (info == NULL) { - return MEMORY_E; - } - XMEMSET(info, 0, sizeof(wolfPkCbEccInfo)); - info->ssl = ssl; - info->pk = ssl->ctx->EccVerifyCb; - info->ctx = ssl->EccVerifyCtx; sigCtx->pkCbEcc = SigPkCbEccVerify; - sigCtx->pkCtxEcc = info; + sigCtx->pkCtxEcc = ssl; } #endif #ifndef NO_RSA /* only setup the verify callback if a PK is set */ if (ssl->ctx->RsaVerifyCb) { - wolfPkCbRsaInfo* info = (wolfPkCbRsaInfo*)XMALLOC( - sizeof(wolfPkCbRsaInfo), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (info == NULL) { - FreeSigPkCb(ssl, sigCtx); - return MEMORY_E; - } - XMEMSET(info, 0, sizeof(wolfPkCbRsaInfo)); - info->ssl = ssl; - info->pk = ssl->ctx->RsaVerifyCb; - info->ctx = ssl->RsaVerifyCtx; sigCtx->pkCbRsa = SigPkCbRsaVerify; - sigCtx->pkCtxRsa = info; + sigCtx->pkCtxRsa = ssl; } #endif return 0; } -void FreeSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx) -{ - if (ssl == NULL || sigCtx == NULL) - return; - -#ifdef HAVE_ECC - if (sigCtx->pkCtxEcc) { - XFREE(sigCtx->pkCtxEcc, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - sigCtx->pkCtxEcc = NULL; - } -#endif -#ifndef NO_RSA - if (sigCtx->pkCtxRsa) { - XFREE(sigCtx->pkCtxRsa, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - sigCtx->pkCtxRsa = NULL; - } -#endif -} #endif /* HAVE_PK_CALLBACKS */ @@ -8321,9 +8274,6 @@ static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) #endif if (args->dCert) { if (args->dCertInit) { - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &args->dCert->sigCtx); - #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; } @@ -8628,9 +8578,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* no trusted peer cert */ WOLFSSL_MSG("No matching trusted peer cert. " "Checking CAs"); - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &args->dCert->sigCtx); - #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; #ifdef OPENSSL_EXTRA @@ -8641,9 +8588,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, haveTrustPeer = 1; } else { WOLFSSL_MSG("Trusted peer cert did not match!"); - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &args->dCert->sigCtx); - #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; #ifdef OPENSSL_EXTRA @@ -8695,9 +8639,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif if (!AlreadySigner(ssl->ctx->cm, subjectHash)) args->untrustedDepth = 1; - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &args->dCert->sigCtx); - #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; } @@ -9109,9 +9050,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = 0; /* reset error */ } - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &args->dCert->sigCtx); - #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; args->count--; @@ -9609,9 +9547,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb(ssl, &args->dCert->sigCtx); - #endif FreeDecodedCert(args->dCert); args->dCertInit = 0; diff --git a/src/ssl.c b/src/ssl.c index 5a6ee7bc9..bb5a99ea6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6689,9 +6689,6 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) #endif if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) { - #ifdef HAVE_PK_CALLBACKS - FreeSigPkCb((WOLFSSL*)ssl, &der.sigCtx); - #endif FreeDecodedCert(&der); return WOLFSSL_FAILURE; } @@ -6699,9 +6696,6 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) size = ssl->buffers.key->length; buff = ssl->buffers.key->buffer; ret = wc_CheckPrivateKey(buff, size, &der); -#ifdef HAVE_PK_CALLBACKS - FreeSigPkCb((WOLFSSL*)ssl, &der.sigCtx); -#endif FreeDecodedCert(&der); return ret; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 398028d3e..93a3ba4a0 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1531,7 +1531,6 @@ WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); #ifndef NO_ASN WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); - WOLFSSL_LOCAL void FreeSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); #endif #endif WOLFSSL_LOCAL void FreeKeyExchange(WOLFSSL* ssl);