diff --git a/src/internal.c b/src/internal.c index 825415bc4..aa02ba71f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4877,7 +4877,7 @@ int Ed25519CheckPubKey(WOLFSSL* ssl) int ret = 0; /* Public key required for signing. */ - if (!key->pubKeySet) { + if (key != NULL && !key->pubKeySet) { DerBuffer* leaf = ssl->buffers.certificate; DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert), ssl->heap, DYNAMIC_TYPE_DCERT); @@ -5211,7 +5211,7 @@ int Ed448CheckPubKey(WOLFSSL* ssl) int ret = 0; /* Public key required for signing. */ - if (!key->pubKeySet) { + if (key != NULL && !key->pubKeySet) { DerBuffer* leaf = ssl->buffers.certificate; DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert), ssl->heap, DYNAMIC_TYPE_DCERT); @@ -5775,16 +5775,22 @@ int InitSSL_Suites(WOLFSSL* ssl) return NO_PRIVATE_KEY; } - /* allow no private key if using PK callbacks and CB is set */ - #ifdef HAVE_PK_CALLBACKS - if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { - WOLFSSL_MSG("Using PK for server private key"); - } - else - #endif if (!ssl->buffers.key || !ssl->buffers.key->buffer) { - WOLFSSL_MSG("Server missing private key"); - return NO_PRIVATE_KEY; + /* allow no private key if using existing key */ + #ifdef WOLF_PRIVATE_KEY_ID + if (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + ) { + WOLFSSL_MSG("Allowing no server private key (external)"); + } + else + #endif + { + WOLFSSL_MSG("Server missing private key"); + return NO_PRIVATE_KEY; + } } } #endif @@ -22381,19 +22387,24 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) int keySz; word32 idx; -#ifdef HAVE_PK_CALLBACKS - /* allow no private key if using PK callbacks and CB is set */ - if (wolfSSL_IsPrivatePkSet(ssl)) { - *length = GetPrivateKeySigSize(ssl); - return 0; - } - else -#endif - /* make sure private key exists */ if (ssl->buffers.key == NULL || ssl->buffers.key->buffer == NULL) { - WOLFSSL_MSG("Private key missing!"); - ERROR_OUT(NO_PRIVATE_KEY, exit_dpk); + /* allow no private key if using external */ + #ifdef WOLF_PRIVATE_KEY_ID + if (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + ) { + *length = GetPrivateKeySigSize(ssl); + return 0; + } + else + #endif + { + WOLFSSL_MSG("Private key missing!"); + ERROR_OUT(NO_PRIVATE_KEY, exit_dpk); + } } #ifdef WOLF_PRIVATE_KEY_ID @@ -22480,8 +22491,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, (RsaKey*)ssl->hsKey, ssl->buffers.key->length); #ifdef WOLF_PRIVATE_KEY_ID - /* if using crypto or PK callbacks allow using a public key */ - if (ret != 0 && ssl->devId != INVALID_DEVID) { + /* if using external key then allow using a public key */ + if (ret != 0 && (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + )) { WOLFSSL_MSG("Trying RSA public key with crypto callbacks"); idx = 0; ret = wc_RsaPublicKeyDecode(ssl->buffers.key->buffer, &idx, @@ -22535,8 +22550,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) (ecc_key*)ssl->hsKey, ssl->buffers.key->length); #ifdef WOLF_PRIVATE_KEY_ID - /* if using crypto or PK callbacks allow using a public key */ - if (ret != 0 && ssl->devId != INVALID_DEVID) { + /* if using external key then allow using a public key */ + if (ret != 0 && (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + )) { WOLFSSL_MSG("Trying ECC public key with crypto callbacks"); idx = 0; ret = wc_EccPublicKeyDecode(ssl->buffers.key->buffer, &idx, @@ -22588,13 +22607,17 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) (ed25519_key*)ssl->hsKey, ssl->buffers.key->length); #ifdef WOLF_PRIVATE_KEY_ID - /* if using crypto or PK callbacks allow using a public key */ - if (ret != 0 && ssl->devId != INVALID_DEVID) { + /* if using external key then allow using a public key */ + if (ret != 0 && (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + )) { WOLFSSL_MSG("Trying ED25519 public key with crypto callbacks"); idx = 0; ret = wc_Ed25519PublicKeyDecode(ssl->buffers.key->buffer, &idx, - (ed25519_key*)ssl->hsKey, - ssl->buffers.key->length); + (ed25519_key*)ssl->hsKey, + ssl->buffers.key->length); } #endif if (ret == 0) { @@ -22641,6 +22664,20 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) ret = wc_Ed448PrivateKeyDecode(ssl->buffers.key->buffer, &idx, (ed448_key*)ssl->hsKey, ssl->buffers.key->length); + #ifdef WOLF_PRIVATE_KEY_ID + /* if using external key then allow using a public key */ + if (ret != 0 && (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + )) { + WOLFSSL_MSG("Trying ED25519 public key with crypto callbacks"); + idx = 0; + ret = wc_Ed448PublicKeyDecode(ssl->buffers.key->buffer, &idx, + (ed448_key*)ssl->hsKey, + ssl->buffers.key->length); + } + #endif if (ret == 0) { WOLFSSL_MSG("Using ED448 private key"); @@ -26881,7 +26918,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifndef NO_CERTS -#ifdef HAVE_PK_CALLBACKS +#ifdef WOLF_PRIVATE_KEY_ID int GetPrivateKeySigSize(WOLFSSL* ssl) { int sigSz = 0; diff --git a/src/ssl.c b/src/ssl.c index 773c5ae05..ce5719974 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5697,7 +5697,11 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der *idx = 0; ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length); #ifdef WOLF_PRIVATE_KEY_ID - if (ret != 0 && devId != INVALID_DEVID) { + if (ret != 0 && (devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ctx) + #endif + )) { /* if using crypto or PK callbacks, try public key decode */ *idx = 0; ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length); @@ -5769,7 +5773,11 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der *idx = 0; ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length); #ifdef WOLF_PRIVATE_KEY_ID - if (ret != 0 && devId != INVALID_DEVID) { + if (ret != 0 && (devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ctx) + #endif + )) { /* if using crypto or PK callbacks, try public key decode */ *idx = 0; ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length); @@ -5836,10 +5844,15 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der *idx = 0; ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length); #ifdef WOLF_PRIVATE_KEY_ID - if (ret != 0 && devId != INVALID_DEVID) { + if (ret != 0 && (devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ctx) + #endif + )) { /* if using crypto or PK callbacks, try public key decode */ *idx = 0; - ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key, der->length); + ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key, + der->length); } #endif if (ret == 0) { @@ -5905,6 +5918,18 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der if (ret == 0) { *idx = 0; ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length); + #ifdef WOLF_PRIVATE_KEY_ID + if (ret != 0 && (devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ctx) + #endif + )) { + /* if using crypto or PK callbacks, try public key decode */ + *idx = 0; + ret = wc_Ed448PublicKeyDecode(der->buffer, idx, key, + der->length); + } + #endif if (ret == 0) { /* check for minimum key size and then free */ int minKeySz = ssl ? ssl->options.minEccKeySz : @@ -6108,7 +6133,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #ifdef HAVE_PKCS8 /* if private key try and remove PKCS8 header */ if (type == PRIVATEKEY_TYPE) { - if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) { + if ((ret = ToTraditional_ex(der->buffer, der->length, + &algId)) > 0) { /* Found PKCS8 header */ /* ToTraditional_ex moves buff and returns adjusted length */ der->length = ret; @@ -14831,7 +14857,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #ifndef NO_CERTS /* in case used set_accept_state after init */ - /* allow no private key if using PK callbacks and CB is set */ if (!havePSK && !haveAnon && !haveMcast) { #ifdef OPENSSL_EXTRA if (ssl->ctx->certSetupCb != NULL) { @@ -14850,17 +14875,24 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return WOLFSSL_FATAL_ERROR; } - #ifdef HAVE_PK_CALLBACKS - if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { - WOLFSSL_MSG("Using PK for server private key"); - } - else - #endif if (!ssl->buffers.key || !ssl->buffers.key->buffer) { - WOLFSSL_MSG("accept error: server key required"); - ssl->error = NO_PRIVATE_KEY; - WOLFSSL_ERROR(ssl->error); - return WOLFSSL_FATAL_ERROR; + /* allow no private key if using existing key */ + #ifdef WOLF_PRIVATE_KEY_ID + if (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + ) { + WOLFSSL_MSG("Allowing no server private key " + "(external)"); + } + else + #endif + { + WOLFSSL_MSG("accept error: server key required"); + WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY); + return WOLFSSL_FATAL_ERROR; + } } } } diff --git a/src/tls13.c b/src/tls13.c index fcfa6f033..1aed814e5 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -9525,7 +9525,6 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) #endif /* WOLFSSL_WOLFSENTRY_HOOKS */ #ifndef NO_CERTS - /* allow no private key if using PK callbacks and CB is set */ #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) if (!havePSK) #endif @@ -9547,16 +9546,23 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } - #ifdef HAVE_PK_CALLBACKS - if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { - WOLFSSL_MSG("Using PK for server private key"); - } - else - #endif if (!ssl->buffers.key || !ssl->buffers.key->buffer) { - WOLFSSL_MSG("accept error: server key required"); - WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY); - return WOLFSSL_FATAL_ERROR; + /* allow no private key if using existing key */ + #ifdef WOLF_PRIVATE_KEY_ID + if (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + ) { + WOLFSSL_MSG("Allowing no server private key (external)"); + } + else + #endif + { + WOLFSSL_MSG("accept error: server key required"); + WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY); + return WOLFSSL_FATAL_ERROR; + } } } } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6a38d0c48..6964957bc 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -19802,7 +19802,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } #endif else { - #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS) + #ifdef WOLF_PRIVATE_KEY_ID /* allow loading a public key for use with crypto or PK callbacks */ type = PUBLICKEY_TYPE; header = BEGIN_PUB_KEY; @@ -19926,7 +19926,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, *keyFormat = DSAk; #endif } - #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS) + #ifdef WOLF_PRIVATE_KEY_ID else if (type == PUBLICKEY_TYPE) { #ifndef NO_RSA if (header == BEGIN_RSA_PUB) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 85893b1e2..3ccf851ee 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1735,7 +1735,7 @@ WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length, void* heap, int devId); #endif WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); -#ifdef HAVE_PK_CALLBACKS +#ifdef WOLF_PRIVATE_KEY_ID WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); #ifndef NO_ASN WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); diff --git a/wolfssl/test.h b/wolfssl/test.h index d0abe2dfd..d3f57ad46 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3729,14 +3729,9 @@ typedef struct PkCbInfo { #ifdef TEST_PK_PRIVKEY union { #ifdef HAVE_ECC + /* only ECC PK callback with TLS v1.2 needs this */ ecc_key ecc; #endif - #ifdef HAVE_CURVE25519 - curve25519_key curve; - #endif - #ifdef HAVE_CURVE448 - curve448_key curve; - #endif } keyGen; int hasKeyGen; #endif @@ -4032,8 +4027,13 @@ static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, ret = wc_ed25519_init(&myKey); if (ret == 0) { ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz); - if (ret == 0) + if (ret == 0) { + ret = wc_ed25519_make_public(&myKey, myKey.p, ED25519_PUB_KEY_SIZE); + } + if (ret == 0) { + myKey.pubKeySet = 1; ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey); + } wc_ed25519_free(&myKey); } @@ -4196,8 +4196,13 @@ static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, ret = wc_ed448_init(&myKey); if (ret == 0) { ret = wc_Ed448PrivateKeyDecode(keyBuf, &idx, &myKey, keySz); - if (ret == 0) + if (ret == 0) { + ret = wc_ed448_make_public(&myKey, myKey.p, ED448_PUB_KEY_SIZE); + } + if (ret == 0) { + myKey.pubKeySet = 1; ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey, NULL, 0); + } wc_ed448_free(&myKey); }