Merge pull request #2241 from ejohnstown/sniffer

Sniffer Update
This commit is contained in:
David Garske
2019-05-15 18:52:44 -07:00
committed by GitHub
3 changed files with 151 additions and 52 deletions

View File

@@ -246,7 +246,9 @@ static const char* const msgTable[] =
/* 81 */ /* 81 */
"Bad Decrypt Size", "Bad Decrypt Size",
"Extended Master Secret Hash Error", "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,12 +1478,12 @@ 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, static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
SnifferSession* session, char* error) SnifferSession* session, char* error)
{ {
word32 idx = 0; word32 idx = 0;
RsaKey key; int tryEcc = 0;
int ret; int ret;
if (session->sslServer->buffers.key == NULL || if (session->sslServer->buffers.key == NULL ||
@@ -1491,75 +1493,163 @@ 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;
} }
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)) {
RsaKey key;
int length;
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 */ input += 2; /* tls pre length */
}
if (length > *sslBytes) { if (length > *sslBytes) {
SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
wc_FreeRsaKey(&key); ret = -1;
return -1;
} }
}
if (ret == 0) {
#ifdef WC_RSA_BLINDING #ifdef WC_RSA_BLINDING
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);
return -1;
} }
#endif #endif
}
if (ret == 0) {
do { do {
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); ret = wc_AsyncWait(ret, &key.asyncDev,
WC_ASYNC_FLAG_CALL_AGAIN);
#endif #endif
if (ret >= 0) { if (ret >= 0) {
ret = wc_RsaPrivateDecrypt(input, length, ret = wc_RsaPrivateDecrypt(input, length,
session->sslServer->arrays->preMasterSecret, SECRET_LEN, session->sslServer->arrays->preMasterSecret,
&key); SECRET_LEN, &key);
} }
} while (ret == WC_PENDING_E); } while (ret == WC_PENDING_E);
if (ret != SECRET_LEN) { if (ret != SECRET_LEN) {
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
wc_FreeRsaKey(&key);
return -1;
} }
}
session->sslServer->arrays->preMasterSz = SECRET_LEN; session->sslServer->arrays->preMasterSz = SECRET_LEN;
wc_FreeRsaKey(&key);
}
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 */ /* store for client side as well */
XMEMCPY(session->sslClient->arrays->preMasterSecret, XMEMCPY(session->sslClient->arrays->preMasterSecret,
session->sslServer->arrays->preMasterSecret, SECRET_LEN); session->sslServer->arrays->preMasterSecret,
session->sslClient->arrays->preMasterSz = SECRET_LEN; session->sslServer->arrays->preMasterSz);
session->sslClient->arrays->preMasterSz =
session->sslServer->arrays->preMasterSz;
#ifdef SHOW_SECRETS #ifdef SHOW_SECRETS
{ {
int i; int i;
printf("pre master secret: "); printf("pre master secret: ");
for (i = 0; i < SECRET_LEN; i++) for (i = 0; i < session->sslServer->arrays->preMasterSz; i++)
printf("%02x", session->sslServer->arrays->preMasterSecret[i]); printf("%02x", session->sslServer->arrays->preMasterSecret[i]);
printf("\n"); printf("\n");
} }
#endif #endif
}
else {
SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
wc_FreeRsaKey(&key);
return -1;
}
if (SetCipherSpecs(session->sslServer) != 0) { if (SetCipherSpecs(session->sslServer) != 0) {
SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wc_FreeRsaKey(&key);
return -1; return -1;
} }
if (SetCipherSpecs(session->sslClient) != 0) { if (SetCipherSpecs(session->sslClient) != 0) {
SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
wc_FreeRsaKey(&key);
return -1; return -1;
} }
@@ -1591,7 +1681,6 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
} }
#endif #endif
wc_FreeRsaKey(&key);
return ret; return ret;
} }
@@ -2267,6 +2356,12 @@ static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
break; break;
#endif #endif
#ifdef HAVE_NULL_CIPHER
case wolfssl_cipher_null:
XMEMCPY(output, input, sz);
break;
#endif
default: default:
Trace(BAD_DECRYPT_TYPE); Trace(BAD_DECRYPT_TYPE);
ret = -1; ret = -1;

View File

@@ -119,6 +119,8 @@
#define BAD_DECRYPT_SIZE 81 #define BAD_DECRYPT_SIZE 81
#define EXTENDED_MASTER_HASH_STR 82 #define EXTENDED_MASTER_HASH_STR 82
#define SPLIT_HANDSHAKE_MSG_STR 83 #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 !!!! */ /* !!!! also add to msgTable in sniffer.c and .rc file !!!! */

View File

@@ -100,5 +100,7 @@ STRINGTABLE
81, "Bad Decrypt Size" 81, "Bad Decrypt Size"
82, "Extended Master Secret Hash Error" 82, "Extended Master Secret Hash Error"
83, "Handshake Message Split Across TLS Records" 83, "Handshake Message Split Across TLS Records"
84, "ECC Private Decode Error"
85, "ECC Public Decode Error"
} }