Improved PK callback support for ConfirmSignature so certificate verification uses the callbacks. Retained wolfSSL/wolfCrypt isolation (I.E. no wolfSSL references from wolfCrypt).

This commit is contained in:
David Garske
2018-07-05 14:04:06 -07:00
parent ae54bae2fa
commit 3cbcc872c1
6 changed files with 228 additions and 5 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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 {