diff --git a/src/internal.c b/src/internal.c index b9ce10fb3e..a5485493be 100644 --- a/src/internal.c +++ b/src/internal.c @@ -293,12 +293,32 @@ int wolfssl_priv_der_blind(WC_RNG* rng, DerBuffer* key, DerBuffer** mask) return ret; } -void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask) +void wolfssl_priv_der_blind_toggle(DerBuffer* key, const DerBuffer* mask) { - if (key != NULL) { + if ((key != NULL) && (mask != NULL)) { xorbuf(key->buffer, mask->buffer, mask->length); } } + +DerBuffer *wolfssl_priv_der_unblind(const DerBuffer* key, const DerBuffer* mask) +{ + DerBuffer *ret; + if ((key == NULL) || (mask == NULL)) + return NULL; + if (mask->length > key->length) + return NULL; + if (AllocDer(&ret, key->length, key->type, key->heap) != 0) + return NULL; + xorbufout(ret->buffer, key->buffer, mask->buffer, mask->length); + return ret; +} + +void wolfssl_priv_der_unblind_free(DerBuffer* key) +{ + if (key != NULL) + FreeDer(&key); +} + #endif /* !NO_CERT && WOLFSSL_BLIND_PRIVATE_KEY */ @@ -7090,7 +7110,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) } ssl->buffers.weOwnKey = 1; /* Blind the private key for the SSL with new random mask. */ - wolfssl_priv_der_unblind(ssl->buffers.key, ctx->privateKeyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask); ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key, &ssl->buffers.keyMask); if (ret != 0) { @@ -7115,7 +7135,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) return ret; } /* Blind the private key for the SSL with new random mask. */ - wolfssl_priv_der_unblind(ssl->buffers.altKey, ctx->altPrivateKeyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.altKey, + ctx->altPrivateKeyMask); ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey, &ssl->buffers.altKeyMask); if (ret != 0) { @@ -30281,7 +30302,7 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) } #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.altKey, ssl->buffers.altKeyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.altKey, ssl->buffers.altKeyMask); #endif #ifdef WOLF_PRIVATE_KEY_ID @@ -30691,7 +30712,7 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) &ssl->buffers.altKeyMask); } else { - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); } #endif @@ -34386,7 +34407,7 @@ int SendCertificateVerify(WOLFSSL* ssl) WOLFSSL_ENTER("SendCertificateVerify"); #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif #ifdef WOLFSSL_ASYNC_IO @@ -34436,7 +34457,7 @@ int SendCertificateVerify(WOLFSSL* ssl) { if (ssl->options.sendVerify == SEND_BLANK_CERT) { #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif return 0; /* sent blank cert, can't verify */ @@ -34864,7 +34885,7 @@ int SendCertificateVerify(WOLFSSL* ssl) &ssl->buffers.keyMask); } else { - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); } #endif @@ -35538,7 +35559,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_ENTER("SendServerKeyExchange"); #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif #ifdef WOLFSSL_ASYNC_IO @@ -37123,7 +37144,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, &ssl->buffers.keyMask); } else { - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, + ssl->buffers.keyMask); } #endif @@ -41041,7 +41063,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], WOLFSSL_ENTER("DoClientKeyExchange"); #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -41848,7 +41870,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], &ssl->buffers.keyMask); } else { - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, + ssl->buffers.keyMask); } #endif diff --git a/src/ssl.c b/src/ssl.c index cd9035de39..9b695976d8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7361,9 +7361,9 @@ static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz, * * Returns WOLFSSL_SUCCESS on good private key * WOLFSSL_FAILURE if mismatched */ -static int check_cert_key(DerBuffer* cert, DerBuffer* key, DerBuffer* altKey, - void* heap, int devId, int isKeyLabel, int isKeyId, int altDevId, - int isAltKeyLabel, int isAltKeyId) +static int check_cert_key(const DerBuffer* cert, const DerBuffer* key, + const DerBuffer* altKey, void* heap, int devId, int isKeyLabel, int isKeyId, + int altDevId, int isAltKeyLabel, int isAltKeyId) { WC_DECLARE_VAR(der, DecodedCert, 1, 0); word32 size; @@ -7498,7 +7498,18 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, DerBuffer* altKey, * WOLFSSL_FAILURE if mismatched. */ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) { - int res; + int res = WOLFSSL_SUCCESS; +#ifdef WOLFSSL_BLIND_PRIVATE_KEY + DerBuffer *privateKey; +#ifdef WOLFSSL_DUAL_ALG_CERTS + DerBuffer *altPrivateKey; +#endif +#else + const DerBuffer *privateKey; +#ifdef WOLFSSL_DUAL_ALG_CERTS + const DerBuffer *altPrivateKey; +#endif +#endif if (ctx == NULL) { return WOLFSSL_FAILURE; @@ -7506,42 +7517,42 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) #ifdef WOLFSSL_DUAL_ALG_CERTS #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); - wolfssl_priv_der_unblind(ctx->altPrivateKey, ctx->altPrivateKeyMask); + privateKey = wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); + altPrivateKey = wolfssl_priv_der_unblind(ctx->altPrivateKey, + ctx->altPrivateKeyMask); + if ((privateKey == NULL) || (altPrivateKey == NULL)) { + res = WOLFSSL_FAILURE; + } +#else + privateKey = ctx->privateKey; + altPrivateKey = ctx->altPrivateKey; #endif - res = check_cert_key(ctx->certificate, ctx->privateKey, ctx->altPrivateKey, - ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel, - ctx->privateKeyId, ctx->altPrivateKeyDevId, ctx->altPrivateKeyLabel, - ctx->altPrivateKeyId) != 0; -#ifdef WOLFSSL_BLIND_PRIVATE_KEY - { - int ret; - ret = wolfssl_priv_der_blind(NULL, ctx->privateKey, - (DerBuffer**)&ctx->privateKeyMask); - if (ret == 0) { - ret = wolfssl_priv_der_blind(NULL, ctx->altPrivateKey, - (DerBuffer**)&ctx->altPrivateKeyMask); - } - if (ret != 0) { - res = WOLFSSL_FAILURE; - } + if (res == WOLFSSL_SUCCESS) { + res = check_cert_key(ctx->certificate, privateKey, altPrivateKey, + ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel, + ctx->privateKeyId, ctx->altPrivateKeyDevId, + ctx->altPrivateKeyLabel, ctx->altPrivateKeyId) != 0; } +#ifdef WOLFSSL_BLIND_PRIVATE_KEY + wolfssl_priv_der_unblind_free(privateKey); + wolfssl_priv_der_unblind_free(altPrivateKey); #endif #else #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); + privateKey = wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); + if (privateKey == NULL) { + res = WOLFSSL_FAILURE; + } +#else + privateKey = ctx->privateKey; #endif - res = check_cert_key(ctx->certificate, ctx->privateKey, NULL, ctx->heap, - ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId, - INVALID_DEVID, 0, 0); -#ifdef WOLFSSL_BLIND_PRIVATE_KEY - { - int ret = wolfssl_priv_der_blind(NULL, ctx->privateKey, - (DerBuffer**)&ctx->privateKeyMask); - if (ret != 0) { - res = WOLFSSL_FAILURE; - } + if (res == WOLFSSL_SUCCESS) { + res = check_cert_key(ctx->certificate, privateKey, NULL, ctx->heap, + ctx->privateKeyDevId, ctx->privateKeyLabel, + ctx->privateKeyId, INVALID_DEVID, 0, 0); } +#ifdef WOLFSSL_BLIND_PRIVATE_KEY + wolfssl_priv_der_unblind_free(privateKey); #endif #endif @@ -7558,8 +7569,12 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) /** * Return the private key of the WOLFSSL_CTX struct * @return WOLFSSL_EVP_PKEY* The caller doesn *NOT*` free the returned object. + * + * Note, even though the supplied ctx pointer is designated const, on success + * ctx->privateKeyPKey is changed by this call. The change is done safely using + * a hardware-synchronized store. */ -WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx) +WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx) { WOLFSSL_EVP_PKEY* res; const unsigned char *key; @@ -7596,19 +7611,23 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx) return NULL; } - key = ctx->privateKey->buffer; - if (ctx->privateKeyPKey != NULL) { res = ctx->privateKeyPKey; } else { #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); + DerBuffer *unblinded_privateKey = + wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); + if (unblinded_privateKey == NULL) + return NULL; + key = unblinded_privateKey->buffer; + #else + key = ctx->privateKey->buffer; #endif res = wolfSSL_d2i_PrivateKey(type, NULL, &key, (long)ctx->privateKey->length); #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); + wolfssl_priv_der_unblind_free(unblinded_privateKey); #endif if (res) { #ifdef WOLFSSL_ATOMIC_OPS @@ -7621,7 +7640,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx) res = current_pkey; } #else - ctx->privateKeyPKey = res; + ((WOLFSSL_CTX *)ctx)->privateKeyPKey = res; #endif } } @@ -8874,7 +8893,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) #endif #else #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif res = check_cert_key(ssl->buffers.certificate, ssl->buffers.key, NULL, ssl->heap, ssl->buffers.keyDevId, ssl->buffers.keyLabel, @@ -20971,7 +20990,7 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) return NULL; } /* Blind the private key for the SSL with new random mask. */ - wolfssl_priv_der_unblind(ssl->buffers.key, ctx->privateKeyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask); ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key, &ssl->buffers.keyMask); if (ret != 0) { diff --git a/src/tls13.c b/src/tls13.c index 517a97cbfb..918f96407d 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -9131,7 +9131,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) WOLFSSL_ENTER("SendTls13CertificateVerify"); #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif ssl->options.buildingMsg = 1; @@ -9187,7 +9187,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) { if (ssl->options.sendVerify == SEND_BLANK_CERT) { #ifdef WOLFSSL_BLIND_PRIVATE_KEY - wolfssl_priv_der_unblind(ssl->buffers.key, + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); #endif return 0; /* sent blank cert, can't verify */ @@ -9882,7 +9882,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) &ssl->buffers.keyMask); } else { - wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask); + wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask); } #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 08549f6b52..988e4c371d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2183,7 +2183,11 @@ WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length, #ifdef WOLFSSL_BLIND_PRIVATE_KEY WOLFSSL_LOCAL int wolfssl_priv_der_blind(WC_RNG* rng, DerBuffer* key, DerBuffer** mask); -WOLFSSL_LOCAL void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask); +WOLFSSL_LOCAL void wolfssl_priv_der_blind_toggle(DerBuffer* key, + const DerBuffer* mask); +WOLFSSL_LOCAL WARN_UNUSED_RESULT DerBuffer *wolfssl_priv_der_unblind( + const DerBuffer* key, const DerBuffer* mask); +WOLFSSL_LOCAL void wolfssl_priv_der_unblind_free(DerBuffer* key); #endif WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word32* length); #ifdef WOLFSSL_DUAL_ALG_CERTS diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3f3a984561..ca8f4f81db 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3228,7 +3228,7 @@ WOLFSSL_API int wolfSSL_want_write(WOLFSSL* ssl); #ifdef OPENSSL_EXTRA WOLFSSL_API int wolfSSL_want(WOLFSSL* ssl); -WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx); #include /* var_arg */ WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format,