mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Sniffer
1. Refactor `ProcessClientKeyExchange()` so it can be expanded to handle ECC keys for ECDH support. 2. Add support to the sniffer for ECDH based cipher suites.
This commit is contained in:
193
src/sniffer.c
193
src/sniffer.c
@ -246,7 +246,9 @@ static const char* const msgTable[] =
|
||||
/* 81 */
|
||||
"Bad Decrypt Size",
|
||||
"Extended Master Secret Hash Error",
|
||||
"Handshake Message Split Across TLS Records"
|
||||
"Handshake Message Split Across TLS Records",
|
||||
"ECC Private Decode Error",
|
||||
"ECC Public Decode Error"
|
||||
};
|
||||
|
||||
|
||||
@ -1476,13 +1478,13 @@ static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
|
||||
}
|
||||
|
||||
|
||||
/* Process Client Key Exchange, RSA only */
|
||||
/* Process Client Key Exchange, RSA or static ECDH */
|
||||
static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
|
||||
SnifferSession* session, char* error)
|
||||
{
|
||||
word32 idx = 0;
|
||||
RsaKey key;
|
||||
int ret;
|
||||
int tryEcc = 0;
|
||||
int ret;
|
||||
|
||||
if (session->sslServer->buffers.key == NULL ||
|
||||
session->sslServer->buffers.key->buffer == NULL ||
|
||||
@ -1491,75 +1493,163 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
|
||||
SetError(RSA_KEY_MISSING_STR, error, session, FATAL_ERROR_STATE);
|
||||
return -1;
|
||||
}
|
||||
ret = wc_InitRsaKey(&key, 0);
|
||||
if (ret == 0)
|
||||
ret = wc_RsaPrivateKeyDecode(session->sslServer->buffers.key->buffer,
|
||||
&idx, &key, session->sslServer->buffers.key->length);
|
||||
if (ret == 0) {
|
||||
int length = wc_RsaEncryptSize(&key);
|
||||
|
||||
if (IsTLS(session->sslServer))
|
||||
input += 2; /* tls pre length */
|
||||
{
|
||||
RsaKey key;
|
||||
int length;
|
||||
|
||||
if (length > *sslBytes) {
|
||||
SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
||||
wc_FreeRsaKey(&key);
|
||||
return -1;
|
||||
ret = wc_InitRsaKey(&key, 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPrivateKeyDecode(
|
||||
session->sslServer->buffers.key->buffer,
|
||||
&idx, &key, session->sslServer->buffers.key->length);
|
||||
if (ret != 0) {
|
||||
tryEcc = 1;
|
||||
#ifndef HAVE_ECC
|
||||
SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||
#else
|
||||
/* If we can do ECC, this isn't fatal. Not loading an ECC
|
||||
* key will be fatal, though. */
|
||||
SetError(RSA_DECODE_STR, error, session, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
length = wc_RsaEncryptSize(&key);
|
||||
if (IsTLS(session->sslServer)) {
|
||||
input += 2; /* tls pre length */
|
||||
}
|
||||
|
||||
if (length > *sslBytes) {
|
||||
SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
#ifdef WC_RSA_BLINDING
|
||||
ret = wc_RsaSetRNG(&key, session->sslServer->rng);
|
||||
if (ret != 0) {
|
||||
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
||||
#endif
|
||||
if (ret >= 0) {
|
||||
ret = wc_RsaPrivateDecrypt(input, length,
|
||||
session->sslServer->arrays->preMasterSecret, SECRET_LEN,
|
||||
&key);
|
||||
}
|
||||
} while (ret == WC_PENDING_E);
|
||||
if (ret != SECRET_LEN) {
|
||||
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
|
||||
wc_FreeRsaKey(&key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
do {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ret = wc_AsyncWait(ret, &key.asyncDev,
|
||||
WC_ASYNC_FLAG_CALL_AGAIN);
|
||||
#endif
|
||||
if (ret >= 0) {
|
||||
ret = wc_RsaPrivateDecrypt(input, length,
|
||||
session->sslServer->arrays->preMasterSecret,
|
||||
SECRET_LEN, &key);
|
||||
}
|
||||
} while (ret == WC_PENDING_E);
|
||||
|
||||
if (ret != SECRET_LEN) {
|
||||
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
session->sslServer->arrays->preMasterSz = SECRET_LEN;
|
||||
|
||||
/* store for client side as well */
|
||||
XMEMCPY(session->sslClient->arrays->preMasterSecret,
|
||||
session->sslServer->arrays->preMasterSecret, SECRET_LEN);
|
||||
session->sslClient->arrays->preMasterSz = SECRET_LEN;
|
||||
|
||||
#ifdef SHOW_SECRETS
|
||||
{
|
||||
int i;
|
||||
printf("pre master secret: ");
|
||||
for (i = 0; i < SECRET_LEN; i++)
|
||||
printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||
wc_FreeRsaKey(&key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tryEcc) {
|
||||
#ifdef HAVE_ECC
|
||||
ecc_key key;
|
||||
ecc_key pubKey;
|
||||
int length, keyInit = 0, pubKeyInit = 0;
|
||||
|
||||
idx = 0;
|
||||
ret = wc_ecc_init(&key);
|
||||
if (ret == 0) {
|
||||
keyInit = 1;
|
||||
ret = wc_ecc_init(&pubKey);
|
||||
}
|
||||
if (ret == 0) {
|
||||
pubKeyInit = 1;
|
||||
ret = wc_EccPrivateKeyDecode(
|
||||
session->sslServer->buffers.key->buffer,
|
||||
&idx, &key, session->sslServer->buffers.key->length);
|
||||
if (ret != 0) {
|
||||
SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
length = wc_ecc_size(&key) * 2 + 1;
|
||||
/* The length should be 2 times the key size (x and y), plus 1
|
||||
* for the type byte. */
|
||||
if (IsTLS(session->sslServer)) {
|
||||
input += 1; /* Don't include the TLS length for the key. */
|
||||
}
|
||||
|
||||
if (length + 1 > *sslBytes) {
|
||||
SetError(PARTIAL_INPUT_STR,
|
||||
error, session, FATAL_ERROR_STATE);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_import_x963_ex(input, length, &pubKey, ECC_CURVE_DEF);
|
||||
if (ret != 0) {
|
||||
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
session->sslServer->arrays->preMasterSz = ENCRYPT_LEN;
|
||||
|
||||
do {
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ret = wc_AsyncWait(ret, &key.asyncDev,
|
||||
WC_ASYNC_FLAG_CALL_AGAIN);
|
||||
#endif
|
||||
if (ret >= 0) {
|
||||
ret = wc_ecc_shared_secret(&key, &pubKey,
|
||||
session->sslServer->arrays->preMasterSecret,
|
||||
&session->sslServer->arrays->preMasterSz);
|
||||
}
|
||||
} while (ret == WC_PENDING_E);
|
||||
}
|
||||
|
||||
if (keyInit)
|
||||
wc_ecc_free(&key);
|
||||
if (pubKeyInit)
|
||||
wc_ecc_free(&pubKey);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* store for client side as well */
|
||||
XMEMCPY(session->sslClient->arrays->preMasterSecret,
|
||||
session->sslServer->arrays->preMasterSecret,
|
||||
session->sslServer->arrays->preMasterSz);
|
||||
session->sslClient->arrays->preMasterSz =
|
||||
session->sslServer->arrays->preMasterSz;
|
||||
|
||||
#ifdef SHOW_SECRETS
|
||||
{
|
||||
int i;
|
||||
printf("pre master secret: ");
|
||||
for (i = 0; i < session->sslServer->arrays->preMasterSz; i++)
|
||||
printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SetCipherSpecs(session->sslServer) != 0) {
|
||||
SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
|
||||
wc_FreeRsaKey(&key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SetCipherSpecs(session->sslClient) != 0) {
|
||||
SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
|
||||
wc_FreeRsaKey(&key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1591,7 +1681,6 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
|
||||
}
|
||||
#endif
|
||||
|
||||
wc_FreeRsaKey(&key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,8 @@
|
||||
#define BAD_DECRYPT_SIZE 81
|
||||
#define EXTENDED_MASTER_HASH_STR 82
|
||||
#define SPLIT_HANDSHAKE_MSG_STR 83
|
||||
#define ECC_DECODE_STR 84
|
||||
#define ECC_PUB_DECODE_STR 85
|
||||
/* !!!! also add to msgTable in sniffer.c and .rc file !!!! */
|
||||
|
||||
|
||||
|
@ -100,5 +100,7 @@ STRINGTABLE
|
||||
81, "Bad Decrypt Size"
|
||||
82, "Extended Master Secret Hash Error"
|
||||
83, "Handshake Message Split Across TLS Records"
|
||||
84, "ECC Private Decode Error"
|
||||
85, "ECC Public Decode Error"
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user