forked from wolfSSL/wolfssl
Fixes for static ephemeral key support with threading and possible use after free.
This commit is contained in:
@@ -2400,16 +2400,19 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
#ifndef NO_DH
|
#ifndef NO_DH
|
||||||
if (ctx->staticKE.dhKey && ctx->staticKE.weOwnDH)
|
FreeDer(&ctx->staticKE.dhKey);
|
||||||
FreeDer(&ctx->staticKE.dhKey);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
if (ctx->staticKE.ecKey && ctx->staticKE.weOwnEC)
|
FreeDer(&ctx->staticKE.ecKey);
|
||||||
FreeDer(&ctx->staticKE.ecKey);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
if (ctx->staticKE.x25519Key && ctx->staticKE.weOwnX25519)
|
FreeDer(&ctx->staticKE.x25519Key);
|
||||||
FreeDer(&ctx->staticKE.x25519Key);
|
#endif
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
if (ctx->staticKELockInit) {
|
||||||
|
wc_FreeMutex(&ctx->staticKELock);
|
||||||
|
ctx->staticKELockInit = 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
(void)heapAtCTXInit;
|
(void)heapAtCTXInit;
|
||||||
@@ -6381,19 +6384,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
|||||||
ssl->options.useClientOrder = ctx->useClientOrder;
|
ssl->options.useClientOrder = ctx->useClientOrder;
|
||||||
ssl->options.mutualAuth = ctx->mutualAuth;
|
ssl->options.mutualAuth = ctx->mutualAuth;
|
||||||
|
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
|
||||||
XMEMCPY(&ssl->staticKE, &ctx->staticKE, sizeof(StaticKeyExchangeInfo_t));
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
ssl->staticKE.weOwnEC = 0;
|
|
||||||
#endif
|
|
||||||
#ifndef NO_DH
|
|
||||||
ssl->staticKE.weOwnDH = 0;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
ssl->staticKE.weOwnX25519 = 0;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
|
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
|
||||||
ssl->options.maxTicketTls13 = ctx->maxTicketTls13;
|
ssl->options.maxTicketTls13 = ctx->maxTicketTls13;
|
||||||
@@ -7207,16 +7197,13 @@ void SSL_ResourceFree(WOLFSSL* ssl)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
#ifndef NO_DH
|
#ifndef NO_DH
|
||||||
if (ssl->staticKE.dhKey && ssl->staticKE.weOwnDH)
|
FreeDer(&ssl->staticKE.dhKey);
|
||||||
FreeDer(&ssl->staticKE.dhKey);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
if (ssl->staticKE.ecKey && ssl->staticKE.weOwnEC)
|
FreeDer(&ssl->staticKE.ecKey);
|
||||||
FreeDer(&ssl->staticKE.ecKey);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
if (ssl->staticKE.x25519Key && ssl->staticKE.weOwnX25519)
|
FreeDer(&ssl->staticKE.x25519Key);
|
||||||
FreeDer(&ssl->staticKE.x25519Key);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
424
src/sniffer.c
424
src/sniffer.c
@@ -2158,32 +2158,19 @@ static void ShowTlsSecrets(SnifferSession* session)
|
|||||||
|
|
||||||
/* Process Keys */
|
/* Process Keys */
|
||||||
|
|
||||||
/* contains static ephemeral keys */
|
|
||||||
typedef struct {
|
|
||||||
#ifndef NO_DH
|
|
||||||
DerBuffer* dhKey;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
DerBuffer* ecKey;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
DerBuffer* x25519Key;
|
|
||||||
#endif
|
|
||||||
#if !defined(NO_RSA) && defined(WOLFSSL_STATIC_RSA)
|
|
||||||
DerBuffer* rsaKey;
|
|
||||||
#endif
|
|
||||||
} KeyBuffers_t;
|
|
||||||
|
|
||||||
static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
||||||
char* error, KeyShareInfo* ksInfo, KeyBuffers_t* keys)
|
char* error, KeyShareInfo* ksInfo)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int ret;
|
int ret;
|
||||||
DerBuffer* keyBuf;
|
DerBuffer* keyBuf = NULL;
|
||||||
|
int keyBufFree = 0;
|
||||||
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
|
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
|
||||||
int useCurveId = 0;
|
int useCurveId = 0;
|
||||||
#endif
|
#endif
|
||||||
int devId = INVALID_DEVID;
|
int devId = INVALID_DEVID;
|
||||||
|
WOLFSSL_CTX* ctx = session->context->ctx;
|
||||||
|
WOLFSSL* ssl = session->sslServer;
|
||||||
|
|
||||||
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
|
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
|
||||||
if (ksInfo && ksInfo->curve_id != 0)
|
if (ksInfo && ksInfo->curve_id != 0)
|
||||||
@@ -2201,15 +2188,18 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
/* Static RSA */
|
/* Static RSA */
|
||||||
if (ksInfo == NULL && keys->rsaKey) {
|
if (ksInfo == NULL && ssl->buffers.key) {
|
||||||
RsaKey key;
|
RsaKey key;
|
||||||
int length;
|
int length;
|
||||||
|
int keyInit = 0;
|
||||||
keyBuf = keys->rsaKey;
|
|
||||||
|
|
||||||
ret = wc_InitRsaKey_ex(&key, NULL, devId);
|
ret = wc_InitRsaKey_ex(&key, NULL, devId);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_RsaPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length);
|
keyInit = 1;
|
||||||
|
keyBuf = ssl->buffers.key;
|
||||||
|
|
||||||
|
ret = wc_RsaPrivateKeyDecode(keyBuf->buffer, &idx, &key,
|
||||||
|
keyBuf->length);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
#ifndef HAVE_ECC
|
#ifndef HAVE_ECC
|
||||||
#ifdef WOLFSSL_SNIFFER_STATS
|
#ifdef WOLFSSL_SNIFFER_STATS
|
||||||
@@ -2217,18 +2207,12 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
#endif
|
#endif
|
||||||
SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||||
#else
|
#else
|
||||||
/* If we can do ECC, this isn't fatal. Not loading an ECC
|
/* If we can do ECC, this isn't fatal. Not loading a key later
|
||||||
* key will be fatal, though. */
|
* will be fatal, though. */
|
||||||
SetError(RSA_DECODE_STR, error, session, 0);
|
SetError(RSA_DECODE_STR, error, session, 0);
|
||||||
if (keys->ecKey == NULL)
|
keyBuf = NULL;
|
||||||
keys->ecKey = session->sslServer->buffers.key; /* try ECC */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
|
|
||||||
else {
|
|
||||||
useCurveId = -1; /* don't try loading further */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -2243,14 +2227,14 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WC_RSA_BLINDING
|
#ifdef WC_RSA_BLINDING
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_RsaSetRNG(&key, session->sslServer->rng);
|
ret = wc_RsaSetRNG(&key, session->sslServer->rng);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
|
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
session->keySz = length * WOLFSSL_BIT_SIZE;
|
session->keySz = length * WOLFSSL_BIT_SIZE;
|
||||||
@@ -2264,8 +2248,8 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
#endif
|
#endif
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
ret = wc_RsaPrivateDecrypt(input, length,
|
ret = wc_RsaPrivateDecrypt(input, length,
|
||||||
session->sslServer->arrays->preMasterSecret,
|
session->sslServer->arrays->preMasterSecret,
|
||||||
session->sslServer->arrays->preMasterSz, &key);
|
session->sslServer->arrays->preMasterSz, &key);
|
||||||
}
|
}
|
||||||
} while (ret == WC_PENDING_E);
|
} while (ret == WC_PENDING_E);
|
||||||
|
|
||||||
@@ -2274,100 +2258,137 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wc_FreeRsaKey(&key);
|
if (keyInit) {
|
||||||
|
wc_FreeRsaKey(&key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* !NO_RSA */
|
#endif /* !NO_RSA */
|
||||||
|
|
||||||
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
|
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
|
||||||
/* Static DH Key */
|
/* Static DH Key */
|
||||||
if (ksInfo && ksInfo->dh_key_bits != 0 && keys->dhKey) {
|
if (ksInfo && ksInfo->dh_key_bits != 0 && keyBuf == NULL) {
|
||||||
DhKey dhKey;
|
DhKey dhKey;
|
||||||
#ifdef HAVE_PUBLIC_FFDHE
|
#ifdef HAVE_PUBLIC_FFDHE
|
||||||
const DhParams* params;
|
const DhParams* params;
|
||||||
word32 privKeySz;
|
#endif
|
||||||
#else
|
|
||||||
word32 privKeySz = 0, p_len = 0;
|
word32 privKeySz = 0, p_len = 0;
|
||||||
#endif
|
|
||||||
byte privKey[52]; /* max for TLS */
|
byte privKey[52]; /* max for TLS */
|
||||||
|
int keyInit = 0;
|
||||||
|
|
||||||
keyBuf = keys->dhKey;
|
/* try and load static ephemeral */
|
||||||
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
int keyLocked = 0;
|
||||||
|
if (ctx->staticKELockInit &&
|
||||||
|
wc_LockMutex(&ctx->staticKELock) == 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
keyLocked = 1;
|
||||||
|
#endif
|
||||||
|
keyBuf = ssl->staticKE.dhKey;
|
||||||
|
if (keyBuf == NULL)
|
||||||
|
keyBuf = ctx->staticKE.dhKey;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
|
ret = 0;
|
||||||
|
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
|
||||||
if (KeyCb != NULL) {
|
if (KeyCb != NULL) {
|
||||||
|
if (keyBuf == NULL) {
|
||||||
|
ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
|
||||||
|
if (ret == 0)
|
||||||
|
keyBufFree = 1;
|
||||||
|
}
|
||||||
ret = KeyCb(session, ksInfo->named_group,
|
ret = KeyCb(session, ksInfo->named_group,
|
||||||
session->srvKs.key, session->srvKs.key_len,
|
session->srvKs.key, session->srvKs.key_len,
|
||||||
session->cliKs.key, session->cliKs.key_len,
|
session->cliKs.key, session->cliKs.key_len,
|
||||||
keyBuf, KeyCbCtx, error);
|
keyBuf, KeyCbCtx, error);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(-1, error, session, FATAL_ERROR_STATE);
|
SetError(-1, error, session, FATAL_ERROR_STATE);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (ret == 0 && keyBuf == NULL) {
|
||||||
#ifdef HAVE_PUBLIC_FFDHE
|
ret = BUFFER_E;
|
||||||
/* get DH params */
|
|
||||||
switch (ksInfo->named_group) {
|
|
||||||
#ifdef HAVE_FFDHE_2048
|
|
||||||
case WOLFSSL_FFDHE_2048:
|
|
||||||
params = wc_Dh_ffdhe2048_Get();
|
|
||||||
privKeySz = 29;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FFDHE_3072
|
|
||||||
case WOLFSSL_FFDHE_3072:
|
|
||||||
params = wc_Dh_ffdhe3072_Get();
|
|
||||||
privKeySz = 34;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FFDHE_4096
|
|
||||||
case WOLFSSL_FFDHE_4096:
|
|
||||||
params = wc_Dh_ffdhe4096_Get();
|
|
||||||
privKeySz = 39;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FFDHE_6144
|
|
||||||
case WOLFSSL_FFDHE_6144:
|
|
||||||
params = wc_Dh_ffdhe6144_Get();
|
|
||||||
privKeySz = 46;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FFDHE_8192
|
|
||||||
case WOLFSSL_FFDHE_8192:
|
|
||||||
params = wc_Dh_ffdhe8192_Get();
|
|
||||||
privKeySz = 52;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return BAD_FUNC_ARG;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = wc_InitDhKey_ex(&dhKey, NULL, devId);
|
#ifdef HAVE_PUBLIC_FFDHE
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
#ifdef HAVE_PUBLIC_FFDHE
|
/* get DH params */
|
||||||
|
switch (ksInfo->named_group) {
|
||||||
|
#ifdef HAVE_FFDHE_2048
|
||||||
|
case WOLFSSL_FFDHE_2048:
|
||||||
|
params = wc_Dh_ffdhe2048_Get();
|
||||||
|
privKeySz = 29;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FFDHE_3072
|
||||||
|
case WOLFSSL_FFDHE_3072:
|
||||||
|
params = wc_Dh_ffdhe3072_Get();
|
||||||
|
privKeySz = 34;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FFDHE_4096
|
||||||
|
case WOLFSSL_FFDHE_4096:
|
||||||
|
params = wc_Dh_ffdhe4096_Get();
|
||||||
|
privKeySz = 39;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FFDHE_6144
|
||||||
|
case WOLFSSL_FFDHE_6144:
|
||||||
|
params = wc_Dh_ffdhe6144_Get();
|
||||||
|
privKeySz = 46;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FFDHE_8192
|
||||||
|
case WOLFSSL_FFDHE_8192:
|
||||||
|
params = wc_Dh_ffdhe8192_Get();
|
||||||
|
privKeySz = 52;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_InitDhKey_ex(&dhKey, NULL, devId);
|
||||||
|
if (ret == 0)
|
||||||
|
keyInit = 1;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
#ifdef HAVE_PUBLIC_FFDHE
|
||||||
ret = wc_DhSetKey(&dhKey,
|
ret = wc_DhSetKey(&dhKey,
|
||||||
(byte*)params->p, params->p_len,
|
(byte*)params->p, params->p_len,
|
||||||
(byte*)params->g, params->g_len);
|
(byte*)params->g, params->g_len);
|
||||||
#else
|
p_len = params->p_len;
|
||||||
|
#else
|
||||||
ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group);
|
ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group);
|
||||||
#endif
|
|
||||||
if (ret == 0) {
|
|
||||||
ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey,
|
|
||||||
keyBuf->length);
|
|
||||||
}
|
|
||||||
#ifndef HAVE_PUBLIC_FFDHE
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group);
|
privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group);
|
||||||
ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group,
|
ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group,
|
||||||
&p_len, NULL, NULL);
|
&p_len, NULL, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ret == 0) {
|
}
|
||||||
ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL,
|
if (ret == 0) {
|
||||||
NULL);
|
ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey,
|
||||||
}
|
keyBuf->length);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
|
||||||
|
if (keyLocked) {
|
||||||
|
wc_UnLockMutex(&ctx->staticKELock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
/* Derive secret from private key and peer's public key */
|
/* Derive secret from private key and peer's public key */
|
||||||
do {
|
do {
|
||||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||||
@@ -2384,71 +2405,86 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
PRIVATE_KEY_LOCK();
|
PRIVATE_KEY_LOCK();
|
||||||
}
|
}
|
||||||
} while (ret == WC_PENDING_E);
|
} while (ret == WC_PENDING_E);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyInit)
|
||||||
wc_FreeDhKey(&dhKey);
|
wc_FreeDhKey(&dhKey);
|
||||||
|
|
||||||
#ifdef WOLFSSL_SNIFFER_STATS
|
#ifdef WOLFSSL_SNIFFER_STATS
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
INC_STAT(SnifferStats.sslKeyFails);
|
INC_STAT(SnifferStats.sslKeyFails);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* left-padded with zeros up to the size of the prime */
|
/* left-padded with zeros up to the size of the prime */
|
||||||
#ifdef HAVE_PUBLIC_FFDHE
|
if (ret == 0 && p_len > session->sslServer->arrays->preMasterSz) {
|
||||||
if (ret == 0 && params->p_len > session->sslServer->arrays->preMasterSz) {
|
word32 diff = p_len - session->sslServer->arrays->preMasterSz;
|
||||||
word32 diff = params->p_len - session->sslServer->arrays->preMasterSz;
|
XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff,
|
||||||
XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff,
|
session->sslServer->arrays->preMasterSecret,
|
||||||
session->sslServer->arrays->preMasterSecret,
|
session->sslServer->arrays->preMasterSz);
|
||||||
session->sslServer->arrays->preMasterSz);
|
XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff);
|
||||||
XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff);
|
session->sslServer->arrays->preMasterSz = p_len;
|
||||||
session->sslServer->arrays->preMasterSz = params->p_len;
|
|
||||||
}
|
|
||||||
#else /* HAVE_PUBLIC_FFDHE */
|
|
||||||
if (ret == 0 && p_len > session->sslServer->arrays->preMasterSz) {
|
|
||||||
word32 diff = p_len - session->sslServer->arrays->preMasterSz;
|
|
||||||
XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff,
|
|
||||||
session->sslServer->arrays->preMasterSecret,
|
|
||||||
session->sslServer->arrays->preMasterSz);
|
|
||||||
XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff);
|
|
||||||
session->sslServer->arrays->preMasterSz = p_len;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_PUBLIC_FFDHE */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !NO_DH && WOLFSSL_DH_EXTRA */
|
#endif /* !NO_DH && WOLFSSL_DH_EXTRA */
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
/* Static ECC Key */
|
/* Static ECC Key */
|
||||||
if (useCurveId >= 0 && keys->ecKey
|
if (useCurveId >= 0 && keyBuf == NULL
|
||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
&& useCurveId != ECC_X25519
|
&& useCurveId != ECC_X25519
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
ecc_key key;
|
ecc_key key, pubKey;
|
||||||
ecc_key pubKey;
|
|
||||||
int length, keyInit = 0, pubKeyInit = 0;
|
int length, keyInit = 0, pubKeyInit = 0;
|
||||||
|
|
||||||
keyBuf = keys->ecKey;
|
/* try and load static ephemeral */
|
||||||
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
int keyLocked = 0;
|
||||||
|
if (ctx->staticKELockInit &&
|
||||||
|
wc_LockMutex(&ctx->staticKELock) == 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
keyLocked = 1;
|
||||||
|
#endif
|
||||||
|
keyBuf = ssl->staticKE.ecKey;
|
||||||
|
if (keyBuf == NULL)
|
||||||
|
keyBuf = ctx->staticKE.ecKey;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
|
/* try static ECC */
|
||||||
|
if (keyBuf == NULL) {
|
||||||
|
keyBuf = session->sslServer->buffers.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
|
||||||
if (KeyCb != NULL && ksInfo) {
|
if (KeyCb != NULL && ksInfo) {
|
||||||
|
if (keyBuf == NULL) {
|
||||||
|
ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
|
||||||
|
if (ret == 0)
|
||||||
|
keyBufFree = 1;
|
||||||
|
}
|
||||||
ret = KeyCb(session, ksInfo->named_group,
|
ret = KeyCb(session, ksInfo->named_group,
|
||||||
session->srvKs.key, session->srvKs.key_len,
|
session->srvKs.key, session->srvKs.key_len,
|
||||||
session->cliKs.key, session->cliKs.key_len,
|
session->cliKs.key, session->cliKs.key_len,
|
||||||
keyBuf, KeyCbCtx, error);
|
keyBuf, KeyCbCtx, error);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(-1, error, session, FATAL_ERROR_STATE);
|
SetError(-1, error, session, FATAL_ERROR_STATE);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
idx = 0;
|
if (ret == 0 && keyBuf == NULL) {
|
||||||
ret = wc_ecc_init_ex(&key, NULL, devId);
|
ret = BUFFER_E;
|
||||||
if (ret == 0) {
|
}
|
||||||
keyInit = 1;
|
if (ret == 0) {
|
||||||
ret = wc_ecc_init(&pubKey);
|
ret = wc_ecc_init_ex(&key, NULL, devId);
|
||||||
|
if (ret == 0)
|
||||||
|
keyInit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
|
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
|
||||||
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
|
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
|
||||||
!defined(HAVE_SELFTEST)
|
!defined(HAVE_SELFTEST)
|
||||||
@@ -2456,15 +2492,20 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
ret = wc_ecc_set_rng(&key, session->sslServer->rng);
|
ret = wc_ecc_set_rng(&key, session->sslServer->rng);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
pubKeyInit = 1;
|
idx = 0;
|
||||||
ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length);
|
ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
|
||||||
|
if (keyLocked) {
|
||||||
|
wc_UnLockMutex(&ctx->staticKELock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
length = wc_ecc_size(&key) * 2 + 1;
|
length = wc_ecc_size(&key) * 2 + 1;
|
||||||
/* The length should be 2 times the key size (x and y), plus 1
|
/* The length should be 2 times the key size (x and y), plus 1
|
||||||
@@ -2483,14 +2524,17 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
useCurveId = key.dp->id;
|
useCurveId = key.dp->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_ecc_init(&pubKey);
|
||||||
|
if (ret == 0)
|
||||||
|
pubKeyInit = 1;
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_ecc_import_x963_ex(input, length, &pubKey, useCurveId);
|
ret = wc_ecc_import_x963_ex(input, length, &pubKey, useCurveId);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
session->keySz = ((length - 1) / 2) * WOLFSSL_BIT_SIZE;
|
session->keySz = ((length - 1) / 2) * WOLFSSL_BIT_SIZE;
|
||||||
/* Length is in bytes. Subtract 1 for the ECC key type. Divide
|
/* Length is in bytes. Subtract 1 for the ECC key type. Divide
|
||||||
@@ -2513,10 +2557,10 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
} while (ret == WC_PENDING_E);
|
} while (ret == WC_PENDING_E);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SNIFFER_STATS
|
#ifdef WOLFSSL_SNIFFER_STATS
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
INC_STAT(SnifferStats.sslKeyFails);
|
INC_STAT(SnifferStats.sslKeyFails);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (keyInit)
|
if (keyInit)
|
||||||
wc_ecc_free(&key);
|
wc_ecc_free(&key);
|
||||||
@@ -2527,15 +2571,34 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
|
|
||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
/* Static Curve25519 Key */
|
/* Static Curve25519 Key */
|
||||||
if (useCurveId == ECC_X25519 && keys->x25519Key) {
|
if (useCurveId == ECC_X25519) {
|
||||||
curve25519_key key;
|
curve25519_key key, pubKey;
|
||||||
curve25519_key pubKey;
|
|
||||||
int length, keyInit = 0, pubKeyInit = 0;
|
int length, keyInit = 0, pubKeyInit = 0;
|
||||||
|
|
||||||
keyBuf = keys->x25519Key;
|
/* try and load static ephemeral */
|
||||||
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
int keyLocked = 0;
|
||||||
|
if (ctx->staticKELockInit &&
|
||||||
|
wc_LockMutex(&ctx->staticKELock) == 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
keyLocked = 1;
|
||||||
|
#endif
|
||||||
|
keyBuf = ssl->staticKE.x25519Key;
|
||||||
|
if (keyBuf == NULL)
|
||||||
|
keyBuf = ctx->staticKE.x25519Key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
|
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
|
||||||
if (KeyCb != NULL && ksInfo) {
|
if (KeyCb != NULL && ksInfo) {
|
||||||
|
if (keyBuf == NULL) {
|
||||||
|
ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL);
|
||||||
|
if (ret == 0)
|
||||||
|
keyBufFree = 1;
|
||||||
|
}
|
||||||
ret = KeyCb(session, ksInfo->named_group,
|
ret = KeyCb(session, ksInfo->named_group,
|
||||||
session->srvKs.key, session->srvKs.key_len,
|
session->srvKs.key, session->srvKs.key_len,
|
||||||
session->cliKs.key, session->cliKs.key_len,
|
session->cliKs.key, session->cliKs.key_len,
|
||||||
@@ -2547,15 +2610,16 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
idx = 0;
|
if (ret == 0 && keyBuf == NULL) {
|
||||||
ret = wc_curve25519_init_ex(&key, NULL, devId);
|
ret = BUFFER_E;
|
||||||
if (ret == 0) {
|
|
||||||
keyInit = 1;
|
|
||||||
ret = wc_curve25519_init(&pubKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
pubKeyInit = 1;
|
ret = wc_curve25519_init_ex(&key, NULL, devId);
|
||||||
|
if (ret == 0)
|
||||||
|
keyInit = 1;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
idx = 0;
|
||||||
ret = wc_Curve25519PrivateKeyDecode(keyBuf->buffer, &idx, &key,
|
ret = wc_Curve25519PrivateKeyDecode(keyBuf->buffer, &idx, &key,
|
||||||
keyBuf->length);
|
keyBuf->length);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -2563,6 +2627,12 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
|
||||||
|
if (keyLocked) {
|
||||||
|
wc_UnLockMutex(&ctx->staticKELock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
length = CURVE25519_KEYSIZE;
|
length = CURVE25519_KEYSIZE;
|
||||||
if (length > *sslBytes) {
|
if (length > *sslBytes) {
|
||||||
@@ -2570,7 +2640,11 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_curve25519_init(&pubKey);
|
||||||
|
if (ret == 0)
|
||||||
|
pubKeyInit = 1;
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_curve25519_import_public_ex(input, length, &pubKey,
|
ret = wc_curve25519_import_public_ex(input, length, &pubKey,
|
||||||
EC25519_LITTLE_ENDIAN);
|
EC25519_LITTLE_ENDIAN);
|
||||||
@@ -2601,6 +2675,10 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_CURVE25519 */
|
#endif /* HAVE_CURVE25519 */
|
||||||
|
|
||||||
|
if (keyBufFree && keyBuf != NULL) {
|
||||||
|
FreeDer(&keyBuf);
|
||||||
|
}
|
||||||
|
|
||||||
/* store for client side as well */
|
/* store for client side as well */
|
||||||
XMEMCPY(session->sslClient->arrays->preMasterSecret,
|
XMEMCPY(session->sslClient->arrays->preMasterSecret,
|
||||||
session->sslServer->arrays->preMasterSecret,
|
session->sslServer->arrays->preMasterSecret,
|
||||||
@@ -2666,12 +2744,13 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Client Key Exchange, static RSA */
|
/* Process Client Key Exchange */
|
||||||
static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
|
static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
|
||||||
SnifferSession* session, char* error)
|
SnifferSession* session, char* error)
|
||||||
{
|
{
|
||||||
KeyBuffers_t keys;
|
int ret;
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_STATIC_EPHEMERAL
|
||||||
if (session->sslServer->buffers.key == NULL ||
|
if (session->sslServer->buffers.key == NULL ||
|
||||||
session->sslServer->buffers.key->buffer == NULL ||
|
session->sslServer->buffers.key->buffer == NULL ||
|
||||||
session->sslServer->buffers.key->length == 0) {
|
session->sslServer->buffers.key->length == 0) {
|
||||||
@@ -2679,23 +2758,11 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
|
|||||||
SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
|
SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
XMEMSET(&keys, 0, sizeof(keys));
|
ret = SetupKeys(input, sslBytes, session, error, NULL);
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
|
||||||
#ifndef NO_DH
|
return ret;
|
||||||
keys.dhKey = session->sslServer->staticKE.dhKey;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
keys.ecKey = session->sslServer->staticKE.ecKey;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
keys.x25519Key = session->sslServer->staticKE.x25519Key;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef NO_RSA
|
|
||||||
keys.rsaKey = session->sslServer->buffers.key;
|
|
||||||
#endif
|
|
||||||
return SetupKeys(input, sslBytes, session, error, NULL, &keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
@@ -3315,25 +3382,8 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes,
|
|||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
/* Setup handshake keys */
|
/* Setup handshake keys */
|
||||||
if (IsAtLeastTLSv1_3(session->sslServer->version) && session->srvKs.key_len > 0) {
|
if (IsAtLeastTLSv1_3(session->sslServer->version) && session->srvKs.key_len > 0) {
|
||||||
KeyBuffers_t keys;
|
|
||||||
XMEMSET(&keys, 0, sizeof(keys));
|
|
||||||
#ifndef NO_RSA
|
|
||||||
keys.rsaKey = session->sslServer->buffers.key;
|
|
||||||
#endif
|
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
|
||||||
#ifndef NO_DH
|
|
||||||
keys.dhKey = session->sslServer->staticKE.dhKey;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
keys.ecKey = session->sslServer->staticKE.ecKey;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
keys.x25519Key = session->sslServer->staticKE.x25519Key;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len,
|
ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len,
|
||||||
session, error, &session->cliKs, &keys);
|
session, error, &session->cliKs);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
||||||
return ret;
|
return ret;
|
||||||
|
214
src/ssl.c
214
src/ssl.c
@@ -55597,8 +55597,82 @@ int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
|
|||||||
#endif /* OPENSSL_ALL && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
|
#endif /* OPENSSL_ALL && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
|
||||||
|
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
|
int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
|
||||||
const char* key, unsigned int keySz, int format, void* heap)
|
{
|
||||||
|
int ret = BUFFER_E;
|
||||||
|
word32 idx = 0;
|
||||||
|
DerBuffer* der = NULL;
|
||||||
|
|
||||||
|
if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
if (!ssl->ctx->staticKELockInit) {
|
||||||
|
return BUFFER_E; /* no keys set */
|
||||||
|
}
|
||||||
|
ret = wc_LockMutex(&ssl->ctx->staticKELock);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (keyAlgo) {
|
||||||
|
#ifndef NO_DH
|
||||||
|
case WC_PK_TYPE_DH:
|
||||||
|
if (ssl != NULL)
|
||||||
|
der = ssl->staticKE.dhKey;
|
||||||
|
if (der == NULL)
|
||||||
|
der = ssl->ctx->staticKE.dhKey;
|
||||||
|
if (der != NULL) {
|
||||||
|
DhKey* key = (DhKey*)keyPtr;
|
||||||
|
WOLFSSL_MSG("Using static DH key");
|
||||||
|
ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case WC_PK_TYPE_ECDH:
|
||||||
|
if (ssl != NULL)
|
||||||
|
der = ssl->staticKE.ecKey;
|
||||||
|
if (der == NULL)
|
||||||
|
der = ssl->ctx->staticKE.ecKey;
|
||||||
|
if (der != NULL) {
|
||||||
|
ecc_key* key = (ecc_key*)keyPtr;
|
||||||
|
WOLFSSL_MSG("Using static ECDH key");
|
||||||
|
ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key, der->length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
case WC_PK_TYPE_CURVE25519:
|
||||||
|
if (ssl != NULL)
|
||||||
|
der = ssl->staticKE.x25519Key;
|
||||||
|
if (der == NULL)
|
||||||
|
der = ssl->ctx->staticKE.x25519Key;
|
||||||
|
if (der != NULL) {
|
||||||
|
curve25519_key* key = (curve25519_key*)keyPtr;
|
||||||
|
WOLFSSL_MSG("Using static X25519 key");
|
||||||
|
ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
|
||||||
|
der->length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
/* not supported */
|
||||||
|
ret = NOT_COMPILED_IN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
wc_UnLockMutex(&ssl->ctx->staticKELock);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
|
||||||
|
StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
|
||||||
|
unsigned int keySz, int format, void* heap)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
DerBuffer* der = NULL;
|
DerBuffer* der = NULL;
|
||||||
@@ -55711,53 +55785,55 @@ static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* if key is already allocated then set free it */
|
#ifndef SINGLE_THREADED
|
||||||
#ifndef NO_DH
|
if (ret == 0 && !ctx->staticKELockInit) {
|
||||||
if (keyAlgo == WC_PK_TYPE_DH && staticKE->dhKey && staticKE->weOwnDH) {
|
ret = wc_InitMutex(&ctx->staticKELock);
|
||||||
FreeDer(&staticKE->dhKey);
|
if (ret == 0) {
|
||||||
}
|
ctx->staticKELockInit = 1;
|
||||||
#endif
|
}
|
||||||
#ifdef HAVE_ECC
|
|
||||||
if (keyAlgo == WC_PK_TYPE_ECDH && staticKE->ecKey && staticKE->weOwnEC) {
|
|
||||||
FreeDer(&staticKE->ecKey);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
if (keyAlgo == WC_PK_TYPE_CURVE25519 && staticKE->x25519Key &&
|
|
||||||
staticKE->weOwnX25519) {
|
|
||||||
FreeDer(&staticKE->x25519Key);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (ret == 0
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
&& (ret = wc_LockMutex(&ctx->staticKELock)) == 0
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
switch (keyAlgo) {
|
||||||
|
#ifndef NO_DH
|
||||||
|
case WC_PK_TYPE_DH:
|
||||||
|
FreeDer(&staticKE->dhKey);
|
||||||
|
staticKE->dhKey = der; der = NULL;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case WC_PK_TYPE_ECDH:
|
||||||
|
FreeDer(&staticKE->ecKey);
|
||||||
|
staticKE->ecKey = der; der = NULL;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
case WC_PK_TYPE_CURVE25519:
|
||||||
|
FreeDer(&staticKE->x25519Key);
|
||||||
|
staticKE->x25519Key = der; der = NULL;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
/* not supported */
|
||||||
|
ret = NOT_COMPILED_IN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (keyAlgo) {
|
#ifndef SINGLE_THREADED
|
||||||
#ifndef NO_DH
|
wc_UnLockMutex(&ctx->staticKELock);
|
||||||
case WC_PK_TYPE_DH:
|
|
||||||
staticKE->dhKey = der; der = NULL;
|
|
||||||
staticKE->weOwnDH = 1;
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ECC
|
|
||||||
case WC_PK_TYPE_ECDH:
|
|
||||||
staticKE->ecKey = der; der = NULL;
|
|
||||||
staticKE->weOwnEC = 1;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
case WC_PK_TYPE_CURVE25519:
|
|
||||||
staticKE->x25519Key = der; der = NULL;
|
|
||||||
staticKE->weOwnX25519 = 1;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
/* not supported */
|
|
||||||
ret = NOT_COMPILED_IN;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
FreeDer(&der);
|
FreeDer(&der);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void)ctx; /* not used for single threaded */
|
||||||
|
|
||||||
WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
|
WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -55769,48 +55845,58 @@ int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
|
|||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
|
||||||
return SetStaticEphemeralKey(&ctx->staticKE, keyAlgo, key, keySz, format,
|
key, keySz, format, ctx->heap);
|
||||||
ctx->heap);
|
|
||||||
}
|
}
|
||||||
int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
|
int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
|
||||||
const char* key, unsigned int keySz, int format)
|
const char* key, unsigned int keySz, int format)
|
||||||
{
|
{
|
||||||
if (ssl == NULL) {
|
if (ssl == NULL || ssl->ctx == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
|
||||||
return SetStaticEphemeralKey(&ssl->staticKE, keyAlgo, key, keySz, format,
|
key, keySz, format, ssl->heap);
|
||||||
ssl->heap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
|
static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
|
||||||
const unsigned char** key, unsigned int* keySz)
|
int keyAlgo, const unsigned char** key, unsigned int* keySz)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
DerBuffer* der = NULL;
|
DerBuffer* der = NULL;
|
||||||
|
|
||||||
if (staticKE == NULL || key == NULL || keySz == NULL) {
|
if (key) *key = NULL;
|
||||||
return BAD_FUNC_ARG;
|
if (keySz) *keySz = 0;
|
||||||
}
|
|
||||||
|
|
||||||
*key = NULL;
|
#ifndef SINGLE_THREADED
|
||||||
*keySz = 0;
|
if (ctx->staticKELockInit &&
|
||||||
|
(ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (keyAlgo) {
|
switch (keyAlgo) {
|
||||||
#ifndef NO_DH
|
#ifndef NO_DH
|
||||||
case WC_PK_TYPE_DH:
|
case WC_PK_TYPE_DH:
|
||||||
der = staticKE->dhKey;
|
if (ssl != NULL)
|
||||||
|
der = ssl->staticKE.dhKey;
|
||||||
|
if (der == NULL)
|
||||||
|
der = ctx->staticKE.dhKey;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
case WC_PK_TYPE_ECDH:
|
case WC_PK_TYPE_ECDH:
|
||||||
der = staticKE->ecKey;
|
if (ssl != NULL)
|
||||||
|
der = ssl->staticKE.ecKey;
|
||||||
|
if (der == NULL)
|
||||||
|
der = ctx->staticKE.ecKey;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
case WC_PK_TYPE_CURVE25519:
|
case WC_PK_TYPE_CURVE25519:
|
||||||
der = staticKE->x25519Key;
|
if (ssl != NULL)
|
||||||
|
der = ssl->staticKE.x25519Key;
|
||||||
|
if (der == NULL)
|
||||||
|
der = ctx->staticKE.x25519Key;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
@@ -55820,10 +55906,16 @@ static int GetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (der) {
|
if (der) {
|
||||||
*key = der->buffer;
|
if (key)
|
||||||
*keySz = der->length;
|
*key = der->buffer;
|
||||||
|
if (keySz)
|
||||||
|
*keySz = der->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
wc_UnLockMutex(&ctx->staticKELock);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55836,16 +55928,16 @@ int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetStaticEphemeralKey(&ctx->staticKE, keyAlgo, key, keySz);
|
return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
|
||||||
}
|
}
|
||||||
int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
|
int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
|
||||||
const unsigned char** key, unsigned int* keySz)
|
const unsigned char** key, unsigned int* keySz)
|
||||||
{
|
{
|
||||||
if (ssl == NULL) {
|
if (ssl == NULL || ssl->ctx == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetStaticEphemeralKey(&ssl->staticKE, keyAlgo, key, keySz);
|
return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WOLFSSL_STATIC_EPHEMERAL */
|
#endif /* WOLFSSL_STATIC_EPHEMERAL */
|
||||||
|
41
src/tls.c
41
src/tls.c
@@ -6217,18 +6217,12 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
|
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
|
||||||
if (ssl->staticKE.dhKey) {
|
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_DH, kse->key);
|
||||||
DerBuffer* keyDer = ssl->staticKE.dhKey;
|
if (ret == 0) {
|
||||||
word32 idx = 0;
|
ret = wc_DhExportKeyPair(dhKey,
|
||||||
WOLFSSL_MSG("Using static DH key");
|
(byte*)kse->privKey, &kse->keyLen, /* private */
|
||||||
ret = wc_DhKeyDecode(keyDer->buffer, &idx,
|
kse->pubKey, &kse->pubKeyLen /* public */
|
||||||
dhKey, keyDer->length);
|
);
|
||||||
if (ret == 0) {
|
|
||||||
ret = wc_DhExportKeyPair(dhKey,
|
|
||||||
(byte*)kse->privKey, &kse->keyLen, /* private */
|
|
||||||
kse->pubKey, &kse->pubKeyLen /* public */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -6329,16 +6323,12 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
|
ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
|
||||||
INVALID_DEVID);
|
INVALID_DEVID);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
/* setting "key" means okay to call wc_curve25519_free */
|
||||||
key = (curve25519_key*)kse->key;
|
key = (curve25519_key*)kse->key;
|
||||||
|
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
if (ssl->staticKE.x25519Key) {
|
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key);
|
||||||
DerBuffer* keyDer = ssl->staticKE.x25519Key;
|
if (ret != 0)
|
||||||
word32 idx = 0;
|
|
||||||
WOLFSSL_MSG("Using static X25519 key");
|
|
||||||
ret = wc_Curve25519PrivateKeyDecode(keyDer->buffer, &idx, key,
|
|
||||||
keyDer->length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
|
ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
|
||||||
@@ -6536,17 +6526,12 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
|||||||
/* Make an ECC key */
|
/* Make an ECC key */
|
||||||
ret = wc_ecc_init_ex((ecc_key*)kse->key, ssl->heap, ssl->devId);
|
ret = wc_ecc_init_ex((ecc_key*)kse->key, ssl->heap, ssl->devId);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
/* setting eccKey means okay to call wc_ecc_free */
|
||||||
eccKey = (ecc_key*)kse->key;
|
eccKey = (ecc_key*)kse->key;
|
||||||
|
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
if (ssl->staticKE.ecKey) {
|
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key);
|
||||||
DerBuffer* keyDer = ssl->staticKE.ecKey;
|
if (ret != 0)
|
||||||
word32 idx = 0;
|
|
||||||
WOLFSSL_MSG("Using static ECDH key");
|
|
||||||
ret = wc_EccPrivateKeyDecode(keyDer->buffer, &idx, eccKey,
|
|
||||||
keyDer->length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* set curve info for EccMakeKey "peer" info */
|
/* set curve info for EccMakeKey "peer" info */
|
||||||
|
@@ -2731,19 +2731,8 @@ typedef struct {
|
|||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
DerBuffer* x25519Key;
|
DerBuffer* x25519Key;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* bits */
|
|
||||||
#ifndef NO_DH
|
|
||||||
byte weOwnDH:1;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
byte weOwnEC:1;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_CURVE25519
|
|
||||||
byte weOwnX25519:1;
|
|
||||||
#endif
|
|
||||||
} StaticKeyExchangeInfo_t;
|
} StaticKeyExchangeInfo_t;
|
||||||
#endif
|
#endif /* WOLFSSL_STATIC_EPHEMERAL */
|
||||||
|
|
||||||
|
|
||||||
/* wolfSSL context type */
|
/* wolfSSL context type */
|
||||||
@@ -2846,6 +2835,10 @@ struct WOLFSSL_CTX {
|
|||||||
#ifdef WOLFSSL_STATIC_MEMORY
|
#ifdef WOLFSSL_STATIC_MEMORY
|
||||||
byte onHeapHint:1; /* whether the ctx/method is put on heap hint */
|
byte onHeapHint:1; /* whether the ctx/method is put on heap hint */
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED)
|
||||||
|
byte staticKELockInit:1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_MULTICAST
|
#ifdef WOLFSSL_MULTICAST
|
||||||
byte haveMcast; /* multicast requested */
|
byte haveMcast; /* multicast requested */
|
||||||
byte mcastID; /* multicast group ID */
|
byte mcastID; /* multicast group ID */
|
||||||
@@ -3074,6 +3067,9 @@ struct WOLFSSL_CTX {
|
|||||||
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
|
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
|
||||||
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
StaticKeyExchangeInfo_t staticKE;
|
StaticKeyExchangeInfo_t staticKE;
|
||||||
|
#ifndef SINGLE_THREADED
|
||||||
|
wolfSSL_Mutex staticKELock;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5029,6 +5025,10 @@ WOLFSSL_LOCAL int oid2nid(word32 oid, int grp);
|
|||||||
WOLFSSL_LOCAL word32 nid2oid(int nid, int grp);
|
WOLFSSL_LOCAL word32 nid2oid(int nid, int grp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_STATIC_EPHEMERAL
|
||||||
|
WOLFSSL_LOCAL int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user