mirror of
https://github.com/adulau/ssldump.git
synced 2024-12-03 14:57:13 +00:00
Compare commits
9 commits
56b61030ab
...
d1180e396d
Author | SHA1 | Date | |
---|---|---|---|
|
d1180e396d | ||
61e0071572 | |||
b31ef76274 | |||
d70855020e | |||
|
c339dda2f7 | ||
|
00171e1bf9 | ||
|
5c20a7401b | ||
|
ad330211e2 | ||
|
594de65d62 |
4 changed files with 111 additions and 71 deletions
4
.github/workflows/scorecard.yml
vendored
4
.github/workflows/scorecard.yml
vendored
|
@ -37,7 +37,7 @@ jobs:
|
|||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
|
@ -59,7 +59,7 @@ jobs:
|
|||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
|
|
|
@ -244,7 +244,7 @@ static int decode_HandshakeType_ClientHello(ssl_obj *ssl,
|
|||
SSL_DECODE_UINT16(ssl, "extensions len", 0, data, &exlen);
|
||||
if(exlen) {
|
||||
explain(ssl, "extensions\n");
|
||||
while(data->len) {
|
||||
while(data->len > 0) {
|
||||
SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex);
|
||||
if(!ja3_ex_str)
|
||||
ja3_ex_str = calloc(7, 1);
|
||||
|
@ -1714,6 +1714,7 @@ decoder extension_decoder[] = {
|
|||
{55, "external_id_hash", decode_extension},
|
||||
{56, "external_session_id", decode_extension},
|
||||
{13172, "next_protocol_negotiation", decode_extension},
|
||||
{0xfe0d, "encrypted_client_hello", decode_extension},
|
||||
{0xff01, "renegotiation_info", decode_extension},
|
||||
{-1}};
|
||||
|
||||
|
|
|
@ -412,42 +412,53 @@ static int tls_check_mac(ssl_rec_decoder *d,
|
|||
UCHAR *iv,
|
||||
UINT4 ivlen,
|
||||
UCHAR *mac) {
|
||||
HMAC_CTX *hm = HMAC_CTX_new();
|
||||
if(!hm)
|
||||
ERETURN(R_NO_MEMORY);
|
||||
const EVP_MD *md;
|
||||
UINT4 l;
|
||||
size_t l;
|
||||
UCHAR buf[128];
|
||||
|
||||
OSSL_PARAM params[2];
|
||||
EVP_MAC *hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||
EVP_MAC_CTX *mac_ctx = EVP_MAC_CTX_new(hmac);
|
||||
EVP_MAC_free(hmac);
|
||||
|
||||
if(!mac_ctx)
|
||||
ERETURN(R_NO_MEMORY);
|
||||
|
||||
md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]);
|
||||
HMAC_Init_ex(hm, d->mac_key->data, d->mac_key->len, md, NULL);
|
||||
if(!md)
|
||||
ERETURN(R_NOT_FOUND);
|
||||
|
||||
params[0] = OSSL_PARAM_construct_utf8_string("digest", digests[d->cs->dig - 0x40], 0);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
EVP_MAC_init(mac_ctx, d->mac_key->data, d->mac_key->len, params);
|
||||
|
||||
fmt_seq(d->seq, buf);
|
||||
d->seq++;
|
||||
HMAC_Update(hm, buf, 8);
|
||||
EVP_MAC_update(mac_ctx, buf, 8);
|
||||
buf[0] = ct;
|
||||
HMAC_Update(hm, buf, 1);
|
||||
EVP_MAC_update(mac_ctx, buf, 1);
|
||||
|
||||
buf[0] = MSB(ver);
|
||||
buf[1] = LSB(ver);
|
||||
HMAC_Update(hm, buf, 2);
|
||||
EVP_MAC_update(mac_ctx, buf, 2);
|
||||
|
||||
buf[0] = MSB(datalen);
|
||||
buf[1] = LSB(datalen);
|
||||
HMAC_Update(hm, buf, 2);
|
||||
EVP_MAC_update(mac_ctx, buf, 2);
|
||||
|
||||
/* for encrypt-then-mac with an explicit IV */
|
||||
if(ivlen && iv) {
|
||||
HMAC_Update(hm, iv, ivlen);
|
||||
HMAC_Update(hm, data, datalen - ivlen);
|
||||
EVP_MAC_update(mac_ctx, iv, ivlen);
|
||||
EVP_MAC_update(mac_ctx, data, datalen - ivlen);
|
||||
} else
|
||||
HMAC_Update(hm, data, datalen);
|
||||
EVP_MAC_update(mac_ctx, data, datalen);
|
||||
|
||||
HMAC_Final(hm, buf, &l);
|
||||
EVP_MAC_final(mac_ctx, buf, &l, sizeof(buf));
|
||||
if(memcmp(mac, buf, l))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
|
||||
HMAC_CTX_free(hm);
|
||||
EVP_MAC_CTX_free(mac_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
136
ssl/ssldecode.c
136
ssl/ssldecode.c
|
@ -108,7 +108,7 @@ struct ssl_decoder_ {
|
|||
|
||||
#ifdef OPENSSL
|
||||
static int tls_P_hash PROTO_LIST(
|
||||
(ssl_obj * ssl, Data *secret, Data *seed, const EVP_MD *md, Data *out));
|
||||
(ssl_obj * ssl, Data *secret, Data *seed, char *md_name, Data *out));
|
||||
static int tls12_prf PROTO_LIST((ssl_obj * ssl,
|
||||
Data *secret,
|
||||
char *usage,
|
||||
|
@ -555,6 +555,7 @@ int ssl_restore_session(ssl_obj *ssl, ssl_decoder *d) {
|
|||
case TLSV1_VERSION:
|
||||
case TLSV11_VERSION:
|
||||
case TLSV12_VERSION:
|
||||
case TLSV13_VERSION:
|
||||
if((r = ssl_generate_keying_material(ssl, d)))
|
||||
ABORT(r);
|
||||
break;
|
||||
|
@ -612,9 +613,9 @@ int ssl_process_client_key_exchange(ssl_obj *ssl,
|
|||
int len) {
|
||||
#ifdef OPENSSL
|
||||
int r, _status;
|
||||
int i;
|
||||
size_t i;
|
||||
EVP_PKEY *pk;
|
||||
const BIGNUM *n;
|
||||
BIGNUM *n;
|
||||
|
||||
/* Remove the master secret if it was there
|
||||
to force keying material regeneration in
|
||||
|
@ -635,12 +636,15 @@ int ssl_process_client_key_exchange(ssl_obj *ssl,
|
|||
if(EVP_PKEY_id(pk) != EVP_PKEY_RSA)
|
||||
return -1;
|
||||
|
||||
RSA_get0_key(EVP_PKEY_get0_RSA(pk), &n, NULL, NULL);
|
||||
EVP_PKEY_get_bn_param(pk, "priv", &n);
|
||||
if((r = r_data_alloc(&d->PMS, BN_num_bytes(n))))
|
||||
ABORT(r);
|
||||
|
||||
i = RSA_private_decrypt(len, msg, d->PMS->data, EVP_PKEY_get0_RSA(pk),
|
||||
RSA_PKCS1_PADDING);
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pk, NULL);
|
||||
EVP_PKEY_decrypt_init(ctx);
|
||||
EVP_PKEY_decrypt(ctx, d->PMS->data, &i, msg, len);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pk);
|
||||
|
||||
if(i != 48)
|
||||
ABORT(SSL_BAD_PMS);
|
||||
|
@ -655,6 +659,7 @@ int ssl_process_client_key_exchange(ssl_obj *ssl,
|
|||
case TLSV1_VERSION:
|
||||
case TLSV11_VERSION:
|
||||
case TLSV12_VERSION:
|
||||
case TLSV13_VERSION:
|
||||
if((r = ssl_generate_keying_material(ssl, d)))
|
||||
ABORT(r);
|
||||
break;
|
||||
|
@ -678,15 +683,22 @@ abort:
|
|||
static int tls_P_hash(ssl_obj *ssl,
|
||||
Data *secret,
|
||||
Data *seed,
|
||||
const EVP_MD *md,
|
||||
char *md_name,
|
||||
Data *out) {
|
||||
UCHAR *ptr = out->data;
|
||||
int left = out->len;
|
||||
int tocpy;
|
||||
UCHAR *A;
|
||||
UCHAR _A[128], tmp[128];
|
||||
unsigned int A_l, tmp_l;
|
||||
HMAC_CTX *hm = HMAC_CTX_new();
|
||||
size_t A_l, tmp_l;
|
||||
|
||||
OSSL_PARAM params[2];
|
||||
EVP_MAC *hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||
EVP_MAC_CTX *mac_ctx = EVP_MAC_CTX_new(hmac);
|
||||
EVP_MAC_free(hmac);
|
||||
|
||||
params[0] = OSSL_PARAM_construct_utf8_string("digest", md_name, 0);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
CRDUMPD("P_hash secret", secret);
|
||||
CRDUMPD("P_hash seed", seed);
|
||||
|
@ -695,15 +707,15 @@ static int tls_P_hash(ssl_obj *ssl,
|
|||
A_l = seed->len;
|
||||
|
||||
while(left) {
|
||||
HMAC_Init_ex(hm, secret->data, secret->len, md, NULL);
|
||||
HMAC_Update(hm, A, A_l);
|
||||
HMAC_Final(hm, _A, &A_l);
|
||||
EVP_MAC_init(mac_ctx, secret->data, secret->len, params);
|
||||
EVP_MAC_update(mac_ctx, A, A_l);
|
||||
EVP_MAC_final(mac_ctx, (unsigned char *) &_A, &A_l, sizeof(_A));
|
||||
A = _A;
|
||||
|
||||
HMAC_Init_ex(hm, secret->data, secret->len, md, NULL);
|
||||
HMAC_Update(hm, A, A_l);
|
||||
HMAC_Update(hm, seed->data, seed->len);
|
||||
HMAC_Final(hm, tmp, &tmp_l);
|
||||
EVP_MAC_init(mac_ctx, secret->data, secret->len, params);
|
||||
EVP_MAC_update(mac_ctx, A, A_l);
|
||||
EVP_MAC_update(mac_ctx, seed->data, seed->len);
|
||||
EVP_MAC_final(mac_ctx, (unsigned char *) &tmp, &tmp_l, sizeof(tmp));
|
||||
|
||||
tocpy = MIN(left, tmp_l);
|
||||
memcpy(ptr, tmp, tocpy);
|
||||
|
@ -711,7 +723,7 @@ static int tls_P_hash(ssl_obj *ssl,
|
|||
left -= tocpy;
|
||||
}
|
||||
|
||||
HMAC_CTX_free(hm);
|
||||
EVP_MAC_CTX_free(mac_ctx);
|
||||
CRDUMPD("P_hash out", out);
|
||||
|
||||
return 0;
|
||||
|
@ -754,9 +766,9 @@ static int tls_prf(ssl_obj *ssl,
|
|||
memcpy(S1->data, secret->data, S_l);
|
||||
memcpy(S2->data, secret->data + (secret->len - S_l), S_l);
|
||||
|
||||
if((r = tls_P_hash(ssl, S1, seed, EVP_get_digestbyname("MD5"), md5_out)))
|
||||
if((r = tls_P_hash(ssl, S1, seed, "MD5", md5_out)))
|
||||
ABORT(r);
|
||||
if((r = tls_P_hash(ssl, S2, seed, EVP_get_digestbyname("SHA1"), sha_out)))
|
||||
if((r = tls_P_hash(ssl, S2, seed, "SHA1", sha_out)))
|
||||
ABORT(r);
|
||||
|
||||
for(i = 0; i < out->len; i++)
|
||||
|
@ -808,7 +820,7 @@ static int tls12_prf(ssl_obj *ssl,
|
|||
digests[dgi]));
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
if((r = tls_P_hash(ssl, secret, seed, md, sha_out)))
|
||||
if((r = tls_P_hash(ssl, secret, seed, digests[dgi], sha_out)))
|
||||
ABORT(r);
|
||||
|
||||
for(i = 0; i < out->len; i++)
|
||||
|
@ -826,15 +838,18 @@ static int ssl3_generate_export_iv(ssl_obj *ssl,
|
|||
Data *r1,
|
||||
Data *r2,
|
||||
Data *out) {
|
||||
MD5_CTX md5;
|
||||
UCHAR tmp[16];
|
||||
unsigned int tmp_len;
|
||||
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, r1->data, r1->len);
|
||||
MD5_Update(&md5, r2->data, r2->len);
|
||||
MD5_Final(tmp, &md5);
|
||||
EVP_MD_CTX *mdctx;
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(mdctx, EVP_get_digestbyname("MD5"));
|
||||
EVP_DigestUpdate(mdctx, r1->data, r1->len);
|
||||
EVP_DigestUpdate(mdctx, r2->data, r2->len);
|
||||
EVP_DigestFinal_ex(mdctx, tmp, &tmp_len);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
|
||||
memcpy(out->data, tmp, out->len);
|
||||
memcpy(out->data, tmp, tmp_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -845,12 +860,13 @@ static int ssl3_prf(ssl_obj *ssl,
|
|||
Data *r1,
|
||||
Data *r2,
|
||||
Data *out) {
|
||||
MD5_CTX md5;
|
||||
SHA_CTX sha;
|
||||
EVP_MD_CTX *md5_ctx;
|
||||
EVP_MD_CTX *sha1_ctx;
|
||||
Data *rnd1, *rnd2;
|
||||
int off;
|
||||
int i = 0, j;
|
||||
UCHAR buf[20];
|
||||
unsigned int buf_len;
|
||||
|
||||
rnd1 = r1;
|
||||
rnd2 = r2;
|
||||
|
@ -859,12 +875,14 @@ static int ssl3_prf(ssl_obj *ssl,
|
|||
CRDUMPD("RND1", rnd1);
|
||||
CRDUMPD("RND2", rnd2);
|
||||
|
||||
MD5_Init(&md5);
|
||||
memset(&sha, 0, sizeof(sha));
|
||||
SHA1_Init(&sha);
|
||||
md5_ctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(md5_ctx, EVP_get_digestbyname("MD5"));
|
||||
sha1_ctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(sha1_ctx, EVP_get_digestbyname("SHA1"));
|
||||
|
||||
for(off = 0; off < out->len; off += 16) {
|
||||
char outbuf[16];
|
||||
unsigned int outbuf_len;
|
||||
int tocpy;
|
||||
i++;
|
||||
|
||||
|
@ -873,38 +891,43 @@ static int ssl3_prf(ssl_obj *ssl,
|
|||
buf[j] = 64 + i;
|
||||
}
|
||||
|
||||
SHA1_Update(&sha, buf, i);
|
||||
EVP_DigestUpdate(sha1_ctx, buf, i);
|
||||
CRDUMP("BUF", buf, i);
|
||||
if(secret)
|
||||
SHA1_Update(&sha, secret->data, secret->len);
|
||||
EVP_DigestUpdate(sha1_ctx, secret->data, secret->len);
|
||||
CRDUMPD("secret", secret);
|
||||
|
||||
if(!strcmp(usage, "client write key") ||
|
||||
!strcmp(usage, "server write key")) {
|
||||
SHA1_Update(&sha, rnd2->data, rnd2->len);
|
||||
EVP_DigestUpdate(sha1_ctx, rnd2->data, rnd2->len);
|
||||
CRDUMPD("rnd2", rnd2);
|
||||
SHA1_Update(&sha, rnd1->data, rnd1->len);
|
||||
EVP_DigestUpdate(sha1_ctx, rnd1->data, rnd1->len);
|
||||
CRDUMPD("rnd1", rnd1);
|
||||
} else {
|
||||
SHA1_Update(&sha, rnd1->data, rnd1->len);
|
||||
EVP_DigestUpdate(sha1_ctx, rnd1->data, rnd1->len);
|
||||
CRDUMPD("rnd1", rnd1);
|
||||
SHA1_Update(&sha, rnd2->data, rnd2->len);
|
||||
EVP_DigestUpdate(sha1_ctx, rnd2->data, rnd2->len);
|
||||
CRDUMPD("rnd2", rnd2);
|
||||
}
|
||||
|
||||
SHA1_Final(buf, &sha);
|
||||
EVP_DigestFinal_ex(sha1_ctx, buf, &buf_len);
|
||||
|
||||
EVP_MD_CTX_free(sha1_ctx);
|
||||
CRDUMP("SHA out", buf, 20);
|
||||
|
||||
SHA1_Init(&sha);
|
||||
sha1_ctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(sha1_ctx, EVP_get_digestbyname("SHA1"));
|
||||
|
||||
MD5_Update(&md5, secret->data, secret->len);
|
||||
MD5_Update(&md5, buf, 20);
|
||||
MD5_Final((unsigned char *)outbuf, &md5);
|
||||
EVP_DigestUpdate(md5_ctx, secret->data, secret->len);
|
||||
EVP_DigestUpdate(md5_ctx, buf, 20);
|
||||
EVP_DigestFinal_ex(md5_ctx, outbuf, &outbuf_len);
|
||||
EVP_MD_CTX_free(md5_ctx);
|
||||
tocpy = MIN(out->len - off, 16);
|
||||
memcpy(out->data + off, outbuf, tocpy);
|
||||
CRDUMP("MD5 out", (UCHAR *)outbuf, 16);
|
||||
|
||||
MD5_Init(&md5);
|
||||
md5_ctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(md5_ctx, EVP_get_digestbyname("MD5"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -914,6 +937,7 @@ static int ssl_generate_keying_material(ssl_obj *ssl, ssl_decoder *d) {
|
|||
Data *key_block = 0, temp;
|
||||
UCHAR _iv_c[8], _iv_s[8];
|
||||
UCHAR _key_c[16], _key_s[16];
|
||||
unsigned int _key_c_len, _key_s_len;
|
||||
int needed;
|
||||
int r, _status;
|
||||
UCHAR *ptr, *c_wk, *s_wk, *c_mk = NULL, *s_mk = NULL, *c_iv = NULL,
|
||||
|
@ -1017,20 +1041,24 @@ static int ssl_generate_keying_material(ssl_obj *ssl, ssl_decoder *d) {
|
|||
}
|
||||
|
||||
if(ssl->version == SSLV3_VERSION) {
|
||||
MD5_CTX md5;
|
||||
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, c_wk, ssl->cs->eff_bits / 8);
|
||||
MD5_Update(&md5, d->client_random->data, d->client_random->len);
|
||||
MD5_Update(&md5, d->server_random->data, d->server_random->len);
|
||||
MD5_Final(_key_c, &md5);
|
||||
EVP_MD_CTX *mdctx;
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(mdctx, EVP_get_digestbyname("MD5"));
|
||||
EVP_DigestUpdate(mdctx, c_wk, ssl->cs->eff_bits / 8);
|
||||
EVP_DigestUpdate(mdctx, d->client_random->data, d->client_random->len);
|
||||
EVP_DigestUpdate(mdctx, d->server_random->data, d->server_random->len);
|
||||
EVP_DigestFinal_ex(mdctx, _key_c, &_key_c_len);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
c_wk = _key_c;
|
||||
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, s_wk, ssl->cs->eff_bits / 8);
|
||||
MD5_Update(&md5, d->server_random->data, d->server_random->len);
|
||||
MD5_Update(&md5, d->client_random->data, d->client_random->len);
|
||||
MD5_Final(_key_s, &md5);
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit(mdctx, EVP_get_digestbyname("MD5"));
|
||||
EVP_DigestUpdate(mdctx, s_wk, ssl->cs->eff_bits / 8);
|
||||
EVP_DigestUpdate(mdctx, d->server_random->data, d->server_random->len);
|
||||
EVP_DigestUpdate(mdctx, d->client_random->data, d->client_random->len);
|
||||
EVP_DigestFinal_ex(mdctx, _key_s, &_key_s_len);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
s_wk = _key_s;
|
||||
} else {
|
||||
ATTACH_DATA(key_c, _key_c);
|
||||
|
|
Loading…
Reference in a new issue