mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Merge pull request #4306 from dgarske/pk_tls13
Fixes for PK callbacks with TLS v1.3
This commit is contained in:
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
11
src/tls.c
11
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);
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user