diff --git a/examples/client/client.c b/examples/client/client.c index 6cdd84a03..c137a0206 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3110,6 +3110,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_KeepArrays(ssl); #endif +#ifdef HAVE_PK_CALLBACKS + /* This must be before SetKeyShare */ + if (pkCallbacks) { + SetupPkCallbackContexts(ssl, &pkCbInfo); + } +#endif + #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) fprintf(stderr, "After creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) @@ -3288,10 +3295,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (atomicUser) SetupAtomicUser(ctx, ssl); #endif -#ifdef HAVE_PK_CALLBACKS - if (pkCallbacks) - SetupPkCallbackContexts(ssl, &pkCbInfo); -#endif + if (matchName && doPeerCheck) wolfSSL_check_domain_name(ssl, domain); #ifndef WOLFSSL_CALLBACKS @@ -3744,6 +3748,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (!doDhKeyCheck) wolfSSL_SetEnableDhKeyTest(sslResume, 0); #endif +#ifdef HAVE_PK_CALLBACKS + if (pkCallbacks) { + SetupPkCallbackContexts(sslResume, &pkCbInfo); + } +#endif if (dtlsUDP) { TEST_DELAY(); diff --git a/examples/server/server.c b/examples/server/server.c index a242685c1..23bc835a9 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2401,16 +2401,17 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } #ifdef HAVE_PK_CALLBACKS - if (pkCallbacks) - SetupPkCallbacks(ctx); + if (pkCallbacks) + SetupPkCallbacks(ctx); #endif - ssl = SSL_new(ctx); - if (ssl == NULL) - err_sys_ex(catastrophic, "unable to create an SSL object"); - #ifdef OPENSSL_EXTRA - wolfSSL_KeepArrays(ssl); - #endif + ssl = SSL_new(ctx); + if (ssl == NULL) + err_sys_ex(catastrophic, "unable to create an SSL object"); + +#ifdef OPENSSL_EXTRA + wolfSSL_KeepArrays(ssl); +#endif /* Support for loading private key and cert using WOLFSSL object */ #if !defined(NO_CERTS) @@ -2594,10 +2595,12 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif /* NO_RSA */ #endif /* HAVE_OCSP */ -#ifdef HAVE_PK_CALLBACKS - if (pkCallbacks) + #ifdef HAVE_PK_CALLBACKS + /* This must be before SetKeyShare */ + if (pkCallbacks) { SetupPkCallbackContexts(ssl, &pkCbInfo); -#endif + } + #endif #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) if (version >= 4) { diff --git a/src/internal.c b/src/internal.c index e90dc970b..e992c5294 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4550,70 +4550,13 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, return ret; } -#ifdef HAVE_PK_CALLBACKS - /* Gets ECC key for shared secret callback testing - * Client side: returns peer key - * Server side: returns private key - */ - static int EccGetKey(WOLFSSL* ssl, ecc_key** otherKey) - { - int ret = NO_PEER_KEY; - ecc_key* tmpKey = NULL; - - if (ssl == NULL || otherKey == NULL) { - return BAD_FUNC_ARG; - } - - if (ssl->options.side == WOLFSSL_CLIENT_END) { - if (ssl->specs.static_ecdh) { - if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || - !ssl->peerEccDsaKey->dp) { - return NO_PEER_KEY; - } - tmpKey = (struct ecc_key*)ssl->peerEccDsaKey; - } - else { - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { - return NO_PEER_KEY; - } - tmpKey = (struct ecc_key*)ssl->peerEccKey; - } - } - else if (ssl->options.side == WOLFSSL_SERVER_END) { - if (ssl->specs.static_ecdh) { - if (ssl->hsKey == NULL) { - return NO_PRIVATE_KEY; - } - tmpKey = (struct ecc_key*)ssl->hsKey; - } - else { - if (!ssl->eccTempKeyPresent) { - return NO_PRIVATE_KEY; - } - tmpKey = (struct ecc_key*)ssl->eccTempKey; - } - } - - if (tmpKey) { - *otherKey = tmpKey; - ret = 0; - } - - return ret; - } -#endif /* HAVE_PK_CALLBACKS */ - int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen, int side) { int ret; -#ifdef HAVE_PK_CALLBACKS - ecc_key* otherKey = NULL; -#endif #ifdef WOLFSSL_ASYNC_CRYPT - WC_ASYNC_DEV* asyncDev = &priv_key->asyncDev; + WC_ASYNC_DEV* asyncDev = NULL; #endif (void)ssl; @@ -4623,19 +4566,11 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, WOLFSSL_ENTER("EccSharedSecret"); -#ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb) { - ret = EccGetKey(ssl, &otherKey); - if (ret != 0) - return ret; - #ifdef WOLFSSL_ASYNC_CRYPT - asyncDev = &otherKey->asyncDev; - #endif - } -#endif - #ifdef WOLFSSL_ASYNC_CRYPT /* initialize event */ + if (priv_key != NULL) { + asyncDev = &priv_key->asyncDev; + } ret = wolfSSL_AsyncInit(ssl, asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); if (ret != 0) return ret; @@ -4644,6 +4579,7 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->EccSharedSecretCb) { void* ctx = wolfSSL_GetEccSharedSecretCtx(ssl); + ecc_key* otherKey = (side == WOLFSSL_CLIENT_END) ? pub_key : priv_key; ret = ssl->ctx->EccSharedSecretCb(ssl, otherKey, pubKeyDer, pubKeySz, out, outlen, side, ctx); } @@ -22685,6 +22621,12 @@ exit_dpk: ssl->options.cipherSuite0 = cs0; ssl->options.cipherSuite = cs1; + #ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Chosen cipher suite:"); + WOLFSSL_MSG(GetCipherNameInternal(ssl->options.cipherSuite0, + ssl->options.cipherSuite)); + #endif + compression = input[i++]; #ifndef WOLFSSL_NO_STRICT_CIPHER_SUITE diff --git a/src/tls.c b/src/tls.c index 17ceb3302..e5aa0afc8 100644 --- a/src/tls.c +++ b/src/tls.c @@ -7415,6 +7415,7 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, if (ssl->peerEccKey != NULL) { wc_ecc_free(ssl->peerEccKey); ssl->peerEccKey = NULL; + ssl->peerEccKeyPresent = 0; } #endif @@ -7491,6 +7492,7 @@ static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) if (ssl->peerEccKey != NULL) { wc_ecc_free(ssl->peerEccKey); ssl->peerEccKey = NULL; + ssl->peerEccKeyPresent = 0; } #endif @@ -7607,6 +7609,7 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) if (ssl->peerEccKey != NULL) { wc_ecc_free(ssl->peerEccKey); XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC); + ssl->peerEccKeyPresent = 0; } ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap, @@ -7631,6 +7634,7 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) if (ret == 0) { ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum; + ssl->peerEccKeyPresent = 1; } } @@ -7649,10 +7653,15 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) } /* done with key share, release resources */ - if (ssl->peerEccKey != NULL) { + if (ssl->peerEccKey != NULL + #ifdef HAVE_PK_CALLBACKS + && ssl->ctx->EccSharedSecretCb == NULL + #endif + ) { wc_ecc_free(ssl->peerEccKey); XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC); ssl->peerEccKey = NULL; + ssl->peerEccKeyPresent = 0; } if (keyShareEntry->key) { wc_ecc_free((ecc_key*)keyShareEntry->key); diff --git a/wolfssl/test.h b/wolfssl/test.h index f885972bc..32641f428 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3475,6 +3475,7 @@ typedef struct PkCbInfo { curve448_key curve; #endif } keyGen; + int hasKeyGen; #endif } PkCbInfo; @@ -3490,14 +3491,11 @@ static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, int ecc_curve, void* ctx) { int ret; - WC_RNG rng; PkCbInfo* cbInfo = (PkCbInfo*)ctx; ecc_key* new_key; -#ifdef TEST_PK_PRIVKEY - byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES]; - word32 qxLen = sizeof(qx), qyLen = sizeof(qy); - new_key = &cbInfo->keyGen.ecc; +#ifdef TEST_PK_PRIVKEY + new_key = cbInfo ? &cbInfo->keyGen.ecc : key; #else new_key = key; #endif @@ -3507,17 +3505,18 @@ static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, WOLFSSL_PKMSG("PK ECC KeyGen: keySz %d, Curve ID %d\n", keySz, ecc_curve); - ret = wc_InitRng(&rng); - if (ret != 0) - return ret; - ret = wc_ecc_init(new_key); if (ret == 0) { + WC_RNG *rng = wolfSSL_GetRNG(ssl); + /* create new key */ - ret = wc_ecc_make_key_ex(&rng, keySz, new_key, ecc_curve); + ret = wc_ecc_make_key_ex(rng, keySz, new_key, ecc_curve); #ifdef TEST_PK_PRIVKEY - if (ret == 0) { + if (ret == 0 && new_key != key) { + byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES]; + word32 qxLen = sizeof(qx), qyLen = sizeof(qy); + /* extract public portion from new key into `key` arg */ ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen); if (ret == 0) { @@ -3527,13 +3526,14 @@ static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, (void)qxLen; (void)qyLen; } + if (ret == 0 && cbInfo != NULL) { + cbInfo->hasKeyGen = 1; + } #endif } WOLFSSL_PKMSG("PK ECC KeyGen: ret %d\n", ret); - wc_FreeRng(&rng); - return ret; } @@ -3541,7 +3541,6 @@ static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) { int ret; - WC_RNG rng; word32 idx = 0; ecc_key myKey; byte* keyBuf = (byte*)key; @@ -3558,20 +3557,17 @@ static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz, return ret; #endif - ret = wc_InitRng(&rng); - if (ret != 0) - return ret; - ret = wc_ecc_init(&myKey); if (ret == 0) { ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); if (ret == 0) { + WC_RNG *rng = wolfSSL_GetRNG(ssl); + WOLFSSL_PKMSG("PK ECC Sign: Curve ID %d\n", myKey.dp->id); - ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey); + ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng, &myKey); } wc_ecc_free(&myKey); } - wc_FreeRng(&rng); #ifdef TEST_PK_PRIVKEY free(keyBuf); @@ -3634,29 +3630,27 @@ static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, /* for client: create and export public key */ if (side == WOLFSSL_CLIENT_END) { - WC_RNG rng; - + #ifdef TEST_PK_PRIVKEY + privKey = cbInfo ? &cbInfo->keyGen.ecc : &tmpKey; + #else privKey = &tmpKey; + #endif pubKey = otherKey; - ret = wc_InitRng(&rng); - if (ret == 0) { - ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id); - #ifdef WOLFSSL_ASYNC_CRYPT - if (ret == WC_PENDING_E) { - ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_NONE); - } - #endif - if (ret == 0) + /* TLS v1.2 and older we must generate a key here for the client ony. + * TLS v1.3 calls key gen early with key share */ + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + ret = myEccKeyGen(ssl, privKey, 0, otherKey->dp->id, ctx); + if (ret == 0) { ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); - wc_FreeRng(&rng); + } } } /* for server: import public key */ else if (side == WOLFSSL_SERVER_END) { #ifdef TEST_PK_PRIVKEY - privKey = &cbInfo->keyGen.ecc; + privKey = cbInfo ? &cbInfo->keyGen.ecc : otherKey; #else privKey = otherKey; #endif @@ -3669,6 +3663,10 @@ static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, ret = BAD_FUNC_ARG; } + if (privKey == NULL || pubKey == NULL) { + ret = BAD_FUNC_ARG; + } + #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_FIPS) && \ !defined(HAVE_SELFTEST) if (ret == 0) { @@ -3688,8 +3686,9 @@ static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, } #ifdef TEST_PK_PRIVKEY - if (side == WOLFSSL_SERVER_END) { + if (cbInfo && cbInfo->hasKeyGen) { wc_ecc_free(&cbInfo->keyGen.ecc); + cbInfo->hasKeyGen = 0; } #endif