diff --git a/src/internal.c b/src/internal.c index 8c6afbd39..6b238e6db 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8162,6 +8162,67 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif + +#ifdef HAVE_PK_CALLBACKS + +#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; + WOLFSSL* ssl = (WOLFSSL*)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 + 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; + WOLFSSL* ssl = (WOLFSSL*)ctx; + + if (ssl && ssl->ctx->RsaVerifyCb) { + ret = ssl->ctx->RsaVerifyCb(ssl, sig, sigSz, out, keyDer, keySz, + ssl->RsaVerifyCtx); + } + return ret; + } +#endif + +int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx) +{ + 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) { + sigCtx->pkCbEcc = SigPkCbEccVerify; + sigCtx->pkCtxEcc = ssl; + } +#endif +#ifndef NO_RSA + /* only setup the verify callback if a PK is set */ + if (ssl->ctx->RsaVerifyCb) { + sigCtx->pkCbRsa = SigPkCbRsaVerify; + sigCtx->pkCtxRsa = ssl; + } +#endif + + return 0; +} + +#endif /* HAVE_PK_CALLBACKS */ + + typedef struct ProcPeerCertArgs { buffer* certs; #ifdef WOLFSSL_TLS13 @@ -8479,6 +8540,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, @@ -8546,6 +8612,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, @@ -8593,6 +8664,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 */ @@ -9007,6 +9083,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 diff --git a/src/ssl.c b/src/ssl.c index a3e0ceee1..bb5a99ea6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6680,6 +6680,14 @@ 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((WOLFSSL*)ssl, &der.sigCtx); + if (ret != 0) { + FreeDecodedCert(&der); + return ret; + } +#endif + if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) { FreeDecodedCert(&der); return WOLFSSL_FAILURE; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 697d3158e..76d05fc5a 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->pkCtxRsa); + } + 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->pkCtxEcc); + } + 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..93a3ba4a0 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1529,6 +1529,9 @@ 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(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..1a06a4fbe 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,17 @@ struct SignatureCtx { WC_ASYNC_DEV* asyncDev; void* asyncCtx; #endif + +#ifdef HAVE_PK_CALLBACKS +#ifdef HAVE_ECC + wc_CallbackEccVerify pkCbEcc; + void* pkCtxEcc; +#endif +#ifndef NO_RSA + wc_CallbackRsaVerify pkCbRsa; + void* pkCtxRsa; +#endif +#endif /* HAVE_PK_CALLBACKS */ }; enum CertSignState {