|
@@ -9,6 +9,66 @@
|
|
|
#include "flow.h"
|
|
|
#include "slitheen.h"
|
|
|
|
|
|
+#define NID_sect163k1 721
|
|
|
+#define NID_sect163r1 722
|
|
|
+#define NID_sect163r2 723
|
|
|
+#define NID_sect193r1 724
|
|
|
+#define NID_sect193r2 725
|
|
|
+#define NID_sect233k1 726
|
|
|
+#define NID_sect233r1 727
|
|
|
+#define NID_sect239k1 728
|
|
|
+#define NID_sect283k1 729
|
|
|
+#define NID_sect283r1 730
|
|
|
+#define NID_sect409k1 731
|
|
|
+#define NID_sect409r1 732
|
|
|
+#define NID_sect571k1 733
|
|
|
+#define NID_sect571r1 734
|
|
|
+#define NID_secp160k1 708
|
|
|
+#define NID_secp160r1 709
|
|
|
+#define NID_secp160r2 710
|
|
|
+#define NID_secp192k1 711
|
|
|
+#define NID_X9_62_prime192v1 409
|
|
|
+#define NID_secp224k1 712
|
|
|
+#define NID_secp224r1 713
|
|
|
+#define NID_secp256k1 714
|
|
|
+#define NID_X9_62_prime256v1 415
|
|
|
+#define NID_secp384r1 715
|
|
|
+#define NID_secp521r1 716
|
|
|
+#define NID_brainpoolP256r1 927
|
|
|
+#define NID_brainpoolP384r1 931
|
|
|
+#define NID_brainpoolP512r1 933
|
|
|
+
|
|
|
+static int nid_list[] = {
|
|
|
+ NID_sect163k1, /* sect163k1 (1) */
|
|
|
+ NID_sect163r1, /* sect163r1 (2) */
|
|
|
+ NID_sect163r2, /* sect163r2 (3) */
|
|
|
+ NID_sect193r1, /* sect193r1 (4) */
|
|
|
+ NID_sect193r2, /* sect193r2 (5) */
|
|
|
+ NID_sect233k1, /* sect233k1 (6) */
|
|
|
+ NID_sect233r1, /* sect233r1 (7) */
|
|
|
+ NID_sect239k1, /* sect239k1 (8) */
|
|
|
+ NID_sect283k1, /* sect283k1 (9) */
|
|
|
+ NID_sect283r1, /* sect283r1 (10) */
|
|
|
+ NID_sect409k1, /* sect409k1 (11) */
|
|
|
+ NID_sect409r1, /* sect409r1 (12) */
|
|
|
+ NID_sect571k1, /* sect571k1 (13) */
|
|
|
+ NID_sect571r1, /* sect571r1 (14) */
|
|
|
+ NID_secp160k1, /* secp160k1 (15) */
|
|
|
+ NID_secp160r1, /* secp160r1 (16) */
|
|
|
+ NID_secp160r2, /* secp160r2 (17) */
|
|
|
+ NID_secp192k1, /* secp192k1 (18) */
|
|
|
+ NID_X9_62_prime192v1, /* secp192r1 (19) */
|
|
|
+ NID_secp224k1, /* secp224k1 (20) */
|
|
|
+ NID_secp224r1, /* secp224r1 (21) */
|
|
|
+ NID_secp256k1, /* secp256k1 (22) */
|
|
|
+ NID_X9_62_prime256v1, /* secp256r1 (23) */
|
|
|
+ NID_secp384r1, /* secp384r1 (24) */
|
|
|
+ NID_secp521r1, /* secp521r1 (25) */
|
|
|
+ NID_brainpoolP256r1, /* brainpoolP256r1 (26) */
|
|
|
+ NID_brainpoolP384r1, /* brainpoolP384r1 (27) */
|
|
|
+ NID_brainpoolP512r1 /* brainpool512r1 (28) */
|
|
|
+};
|
|
|
+
|
|
|
/** Updates the hash of all TLS handshake messages upon the
|
|
|
* receipt of a new message. This hash is eventually used
|
|
|
* to verify the TLS Finished message
|
|
@@ -44,41 +104,156 @@ int update_finish_hash(flow *f, uint8_t *hs){
|
|
|
* 0 on success, 1 on failure
|
|
|
*/
|
|
|
int extract_parameters(flow *f, uint8_t *hs){
|
|
|
- DH *dh;
|
|
|
uint8_t *p;
|
|
|
long i;
|
|
|
|
|
|
+ int ok=1;
|
|
|
+
|
|
|
p = hs + HANDSHAKE_HEADER_LEN;
|
|
|
|
|
|
- if((dh = DH_new()) == NULL){
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ if(f->keyex_alg == 1){
|
|
|
+ DH *dh;
|
|
|
|
|
|
- /* Extract prime modulus */
|
|
|
- n2s(p,i);
|
|
|
+ if((dh = DH_new()) == NULL){
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
|
|
|
- if(!(dh->p = BN_bin2bn(p,i,NULL))){
|
|
|
- return 1;
|
|
|
- }
|
|
|
- p += i;
|
|
|
+ /* Extract prime modulus */
|
|
|
+ n2s(p,i);
|
|
|
|
|
|
- /* Extract generator */
|
|
|
- n2s(p,i);
|
|
|
+ if(!(dh->p = BN_bin2bn(p,i,NULL))){
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ p += i;
|
|
|
|
|
|
- if(!(dh->g = BN_bin2bn(p,i,NULL))){
|
|
|
- return 1;
|
|
|
- }
|
|
|
- p += i;
|
|
|
+ /* Extract generator */
|
|
|
+ n2s(p,i);
|
|
|
|
|
|
- /* Extract server public value */
|
|
|
- n2s(p,i);
|
|
|
+ if(!(dh->g = BN_bin2bn(p,i,NULL))){
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ p += i;
|
|
|
|
|
|
- if(!(dh->pub_key = BN_bin2bn(p,i,NULL))){
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ /* Extract server public value */
|
|
|
+ n2s(p,i);
|
|
|
|
|
|
- f->dh = dh;
|
|
|
- return 0;
|
|
|
+ if(!(dh->pub_key = BN_bin2bn(p,i,NULL))){
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ f->dh = dh;
|
|
|
+ } else if (f->keyex_alg == 2){
|
|
|
+ EC_KEY *ecdh;
|
|
|
+ EC_GROUP *ngroup;
|
|
|
+ const EC_GROUP *group;
|
|
|
+
|
|
|
+ BN_CTX *bn_ctx = NULL;
|
|
|
+ EC_POINT *srvr_ecpoint = NULL;
|
|
|
+ int curve_nid = 0;
|
|
|
+ int encoded_pt_len = 0;
|
|
|
+
|
|
|
+ if((ecdh = EC_KEY_new()) == NULL) {
|
|
|
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
|
|
|
+ printf("HERE1\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(p[0] != 0x03){//not a named curve
|
|
|
+ printf("HERE2\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ //int curve_id = (p[1] << 8) + p[2];
|
|
|
+ int curve_id = *(p+2);
|
|
|
+ if((curve_id < 0) || ((unsigned int)curve_id >
|
|
|
+ sizeof(nid_list) / sizeof(nid_list[0]))){
|
|
|
+ printf("HERE3\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ curve_nid = nid_list[curve_id-1];
|
|
|
+
|
|
|
+ /* Extract curve
|
|
|
+ if(!tls1_check_curve(s, p, 3)) {
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if((*(p+2) < 1) || ((unsigned int) (*(p+2)) > sizeof(nid_list) / sizeof(nid_list[0]))){
|
|
|
+
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ curve_nid = nid_list[*(p+2)];
|
|
|
+ */
|
|
|
+
|
|
|
+ ngroup = EC_GROUP_new_by_curve_name(curve_nid);
|
|
|
+
|
|
|
+ if(ngroup == NULL){
|
|
|
+ printf("HERE4\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ if(EC_KEY_set_group(ecdh, ngroup) == 0){
|
|
|
+ printf("HERE5\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ EC_GROUP_free(ngroup);
|
|
|
+
|
|
|
+ group = EC_KEY_get0_group(ecdh);
|
|
|
+ printf("Curve name is %d\n", EC_GROUP_get_curve_name(group));
|
|
|
+
|
|
|
+ p += 3;
|
|
|
+
|
|
|
+ /* Get EC point */
|
|
|
+ if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
|
|
|
+ ((bn_ctx = BN_CTX_new()) == NULL)) {
|
|
|
+ printf("HERE6\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ encoded_pt_len = *p;
|
|
|
+ p += 1;
|
|
|
+
|
|
|
+ printf("point len: %d, message len: %x %x %x\n",encoded_pt_len, hs[1], hs[2], hs[3]);
|
|
|
+
|
|
|
+ if(EC_POINT_oct2point(group, srvr_ecpoint, p, encoded_pt_len,
|
|
|
+ bn_ctx) == 0){
|
|
|
+ printf("HERE7\n");
|
|
|
+ fflush(stdout);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ p += encoded_pt_len;
|
|
|
+
|
|
|
+ EC_KEY_set_public_key(ecdh, srvr_ecpoint);
|
|
|
+
|
|
|
+ f->ecdh = ecdh;
|
|
|
+ ecdh = NULL;
|
|
|
+ BN_CTX_free(bn_ctx);
|
|
|
+ bn_ctx = NULL;
|
|
|
+ EC_POINT_free(srvr_ecpoint);
|
|
|
+ srvr_ecpoint = NULL;
|
|
|
+ ok=0;
|
|
|
+
|
|
|
+err:
|
|
|
+ if(bn_ctx != NULL){
|
|
|
+ BN_CTX_free(bn_ctx);
|
|
|
+ }
|
|
|
+ if(srvr_ecpoint != NULL){
|
|
|
+ EC_POINT_free(srvr_ecpoint);
|
|
|
+ }
|
|
|
+ if(ecdh != NULL){
|
|
|
+ EC_KEY_free(ecdh);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return ok;
|
|
|
}
|
|
|
|
|
|
/** MAC a message
|
|
@@ -214,9 +389,9 @@ int verify_finish_hash(flow *f, uint8_t *p, int32_t incoming){
|
|
|
//now use pseudorandom function
|
|
|
uint8_t *output = calloc(1, fin_length);
|
|
|
if(incoming){
|
|
|
- PRF(f->master_secret, SSL3_MASTER_SECRET_SIZE, (uint8_t *) TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE , hash, hash_len, NULL, 0, NULL, 0, output, fin_length);
|
|
|
+ PRF(f, f->master_secret, SSL3_MASTER_SECRET_SIZE, (uint8_t *) TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE , hash, hash_len, NULL, 0, NULL, 0, output, fin_length);
|
|
|
} else {
|
|
|
- PRF(f->master_secret, SSL3_MASTER_SECRET_SIZE, (uint8_t *) TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE , hash, hash_len, NULL, 0, NULL, 0, output, fin_length);
|
|
|
+ PRF(f, f->master_secret, SSL3_MASTER_SECRET_SIZE, (uint8_t *) TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE , hash, hash_len, NULL, 0, NULL, 0, output, fin_length);
|
|
|
}
|
|
|
|
|
|
//now compare
|
|
@@ -244,102 +419,230 @@ int verify_finish_hash(flow *f, uint8_t *p, int32_t incoming){
|
|
|
*/
|
|
|
int compute_master_secret(flow *f){
|
|
|
printf("Computing master secret (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
|
|
|
+
|
|
|
DH *dh_srvr = NULL;
|
|
|
DH *dh_clnt = NULL;
|
|
|
- BN_CTX *ctx;
|
|
|
- BN_MONT_CTX *mont = NULL;
|
|
|
- BIGNUM *pub_key = NULL, *priv_key = NULL;
|
|
|
+ BN_CTX *ctx = NULL;
|
|
|
+ BIGNUM *pub_key = NULL, *priv_key = NULL, *order = NULL;
|
|
|
|
|
|
- ctx = BN_CTX_new();
|
|
|
+ EC_KEY *clnt_ecdh = NULL;
|
|
|
+ EC_POINT *e_pub_key = NULL;
|
|
|
|
|
|
- dh_srvr = f->dh;
|
|
|
- dh_clnt = DHparams_dup(dh_srvr);
|
|
|
+ int ok =1;
|
|
|
|
|
|
- uint32_t l = dh_clnt->length ? dh_clnt->length : BN_num_bits(dh_clnt->p) - 1;
|
|
|
- int32_t bytes = (l+7) / 8;
|
|
|
- printf("length of dh param: %d\n", bytes);
|
|
|
+ uint8_t *pre_master_secret = calloc(1, PRE_MASTER_MAX_LEN);//TODO: find right length
|
|
|
+ int32_t pre_master_len;
|
|
|
+ uint32_t l;
|
|
|
+ int32_t bytes;
|
|
|
|
|
|
- uint8_t *buf = (uint8_t *)OPENSSL_malloc(bytes);
|
|
|
- if (buf == NULL){
|
|
|
- BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
|
|
|
- goto err;
|
|
|
- }
|
|
|
+ uint8_t *buf = NULL;
|
|
|
|
|
|
- pub_key = BN_new();
|
|
|
- priv_key = BN_new();
|
|
|
+ if(f->keyex_alg == 1){
|
|
|
+ BN_MONT_CTX *mont = NULL;
|
|
|
|
|
|
- printf("key =");
|
|
|
- for(int i=0; i< 16; i++)
|
|
|
- printf(" %02x", f->key[i]);
|
|
|
- printf("\n");
|
|
|
+ ctx = BN_CTX_new();
|
|
|
|
|
|
- PRF(f->key, 16,
|
|
|
- (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
|
|
|
- NULL, 0, NULL, 0, NULL, 0,
|
|
|
- buf, bytes);
|
|
|
+ dh_srvr = f->dh;
|
|
|
+ dh_clnt = DHparams_dup(dh_srvr);
|
|
|
|
|
|
-//#ifdef DEBUG
|
|
|
- printf("Generated the following rand bytes: ");
|
|
|
- for(int i=0; i< bytes; i++){
|
|
|
- printf(" %02x ", buf[i]);
|
|
|
- }
|
|
|
- printf("\n");
|
|
|
-//#endif
|
|
|
+ l = dh_clnt->length ? dh_clnt->length : BN_num_bits(dh_clnt->p) - 1;
|
|
|
+ bytes = (l+7) / 8;
|
|
|
+ printf("length of dh param: %d\n", bytes);
|
|
|
|
|
|
- if (!BN_bin2bn(buf, bytes, priv_key))
|
|
|
- goto err;
|
|
|
+ buf = (uint8_t *)OPENSSL_malloc(bytes);
|
|
|
+ if (buf == NULL){
|
|
|
+ BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
|
|
|
- {
|
|
|
- BIGNUM *prk;
|
|
|
+ pub_key = BN_new();
|
|
|
+ priv_key = BN_new();
|
|
|
|
|
|
- prk = priv_key;
|
|
|
+ printf("key =");
|
|
|
+ for(int i=0; i< 16; i++)
|
|
|
+ printf(" %02x", f->key[i]);
|
|
|
+ printf("\n");
|
|
|
|
|
|
- if (!dh_clnt->meth->bn_mod_exp(dh_clnt, pub_key, dh_clnt->g, prk, dh_clnt->p, ctx, mont)){
|
|
|
+ PRF(f, f->key, 16,
|
|
|
+ (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
|
|
|
+ NULL, 0, NULL, 0, NULL, 0,
|
|
|
+ buf, bytes);
|
|
|
+
|
|
|
+ //#ifdef DEBUG
|
|
|
+ printf("Generated the following rand bytes: ");
|
|
|
+ for(int i=0; i< bytes; i++){
|
|
|
+ printf(" %02x ", buf[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+ //#endif
|
|
|
+
|
|
|
+ if (!BN_bin2bn(buf, bytes, priv_key))
|
|
|
goto err;
|
|
|
+
|
|
|
+ {
|
|
|
+ BIGNUM *prk;
|
|
|
+
|
|
|
+ prk = priv_key;
|
|
|
+
|
|
|
+ if (!dh_clnt->meth->bn_mod_exp(dh_clnt, pub_key, dh_clnt->g, prk, dh_clnt->p, ctx, mont)){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- dh_clnt->pub_key = pub_key;
|
|
|
- dh_clnt->priv_key = priv_key;
|
|
|
+ dh_clnt->pub_key = pub_key;
|
|
|
+ dh_clnt->priv_key = priv_key;
|
|
|
|
|
|
- // Compute master key
|
|
|
- uint8_t *pre_master_secret = calloc(1, PRE_MASTER_MAX_LEN);//TODO: find right length
|
|
|
+ pre_master_len = DH_compute_key(pre_master_secret, dh_srvr->pub_key, dh_clnt);
|
|
|
+
|
|
|
+ } else if(f->keyex_alg == 2){
|
|
|
+ const EC_GROUP *srvr_group = NULL;
|
|
|
+ const EC_POINT *srvr_ecpoint = NULL;
|
|
|
+ EC_KEY *tkey;
|
|
|
+
|
|
|
+ tkey = f->ecdh;
|
|
|
+ if(tkey == NULL){
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ srvr_group = EC_KEY_get0_group(tkey);
|
|
|
+ srvr_ecpoint = EC_KEY_get0_public_key(tkey);
|
|
|
+
|
|
|
+ if((srvr_group == NULL) || (srvr_ecpoint == NULL)) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if((clnt_ecdh = EC_KEY_new()) == NULL) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
|
|
|
- int32_t pre_master_len = DH_compute_key(pre_master_secret, dh_srvr->pub_key, dh_clnt);
|
|
|
+ /* Now generate key from tag */
|
|
|
+
|
|
|
+ if((order = BN_new()) == NULL){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ if((ctx = BN_CTX_new()) == NULL){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if((priv_key = BN_new()) == NULL){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!EC_GROUP_get_order(srvr_group, order, ctx)){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ l = BN_num_bits(order)-1;
|
|
|
+ bytes = (l+7)/8;
|
|
|
+
|
|
|
+ buf = (unsigned char *)OPENSSL_malloc(bytes);
|
|
|
+ if(buf == NULL){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ PRF(f, f->key, 16, (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
|
|
|
+ NULL, 0, NULL, 0, NULL, 0, buf, bytes);
|
|
|
+
|
|
|
+ //#ifdef DEBUG
|
|
|
+ printf("Generated the following rand bytes: ");
|
|
|
+ for(int i=0; i< bytes; i++){
|
|
|
+ printf("%02x ", buf[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+//#endif
|
|
|
+
|
|
|
+ if(!BN_bin2bn(buf, bytes, priv_key)){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(EC_KEY_get0_public_key(clnt_ecdh) == NULL){
|
|
|
+ if((e_pub_key = EC_POINT_new(srvr_group)) == NULL){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ e_pub_key = EC_KEY_get0_public_key(clnt_ecdh);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!EC_POINT_mul(EC_KEY_get0_group(clnt_ecdh), e_pub_key, priv_key, NULL, NULL, ctx)){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ EC_KEY_set_private_key(clnt_ecdh, priv_key);
|
|
|
+ EC_KEY_set_public_key(clnt_ecdh, e_pub_key);
|
|
|
+
|
|
|
+
|
|
|
+ /*Compute the master secret */
|
|
|
+ int32_t field_size = EC_GROUP_get_degree(srvr_group);
|
|
|
+ if(field_size <= 0){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ pre_master_len = ECDH_compute_key(pre_master_secret, (field_size + 7) / 8,
|
|
|
+ srvr_ecpoint, clnt_ecdh, NULL);
|
|
|
+ if(pre_master_len <= 0) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /*Generate master secret */
|
|
|
|
|
|
- PRF(pre_master_secret, pre_master_len, (uint8_t *) TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, f->client_random, SSL3_RANDOM_SIZE, f->server_random, SSL3_RANDOM_SIZE, NULL, 0, f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
|
+ PRF(f, pre_master_secret, pre_master_len, (uint8_t *) TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, f->client_random, SSL3_RANDOM_SIZE, f->server_random, SSL3_RANDOM_SIZE, NULL, 0, f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
|
|
|
|
if(f->current_session != NULL)
|
|
|
memcpy(f->current_session, f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
- fprintf(stdout, "Premaster Secret:\n");
|
|
|
- BIO_dump_fp(stdout, (char *)pre_master_secret, pre_master_len);
|
|
|
- fprintf(stdout, "Client Random:\n");
|
|
|
- BIO_dump_fp(stdout, (char *)f->client_random, SSL3_RANDOM_SIZE);
|
|
|
- fprintf(stdout, "Server Random:\n");
|
|
|
- BIO_dump_fp(stdout, (char *)f->server_random, SSL3_RANDOM_SIZE);
|
|
|
- fprintf(stdout, "Master Secret:\n");
|
|
|
- BIO_dump_fp(stdout, (char *)f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
|
+ fprintf(stdout, "Premaster Secret:\n");
|
|
|
+ BIO_dump_fp(stdout, (char *)pre_master_secret, pre_master_len);
|
|
|
+ fprintf(stdout, "Client Random:\n");
|
|
|
+ BIO_dump_fp(stdout, (char *)f->client_random, SSL3_RANDOM_SIZE);
|
|
|
+ fprintf(stdout, "Server Random:\n");
|
|
|
+ BIO_dump_fp(stdout, (char *)f->server_random, SSL3_RANDOM_SIZE);
|
|
|
+ fprintf(stdout, "Master Secret:\n");
|
|
|
+ BIO_dump_fp(stdout, (char *)f->master_secret, SSL3_MASTER_SECRET_SIZE);
|
|
|
#endif
|
|
|
|
|
|
//remove pre_master_secret from memory
|
|
|
memset(pre_master_secret, 0, PRE_MASTER_MAX_LEN);
|
|
|
+ ok = 0;
|
|
|
|
|
|
err:
|
|
|
if((pub_key != NULL) && (dh_srvr == NULL)){
|
|
|
BN_free(pub_key);
|
|
|
}
|
|
|
- if((priv_key != NULL) && (dh_clnt == NULL)){
|
|
|
+ if((priv_key != NULL) && (dh_clnt == NULL) && (EC_KEY_get0_private_key(clnt_ecdh) == NULL)){
|
|
|
BN_free(priv_key);
|
|
|
}
|
|
|
- BN_CTX_free(ctx);
|
|
|
+
|
|
|
+ if(ctx != NULL){
|
|
|
+ BN_CTX_free(ctx);
|
|
|
+ }
|
|
|
|
|
|
OPENSSL_free(buf);
|
|
|
free(pre_master_secret);
|
|
|
- DH_free(dh_srvr);
|
|
|
- DH_free(dh_clnt);
|
|
|
- return 0;
|
|
|
+ if(dh_srvr != NULL){
|
|
|
+ DH_free(dh_srvr);
|
|
|
+ }
|
|
|
+ if(dh_clnt != NULL) {
|
|
|
+ DH_free(dh_clnt);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(order){
|
|
|
+ BN_free(order);
|
|
|
+ }
|
|
|
+ if(e_pub_key != NULL && EC_KEY_get0_public_key(clnt_ecdh) == NULL){
|
|
|
+ EC_POINT_free(e_pub_key);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(clnt_ecdh != NULL){
|
|
|
+ EC_KEY_free(clnt_ecdh);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ok;
|
|
|
}
|
|
|
|
|
|
/** Saves the random none from the server hello message
|
|
@@ -360,6 +663,50 @@ void extract_server_random(flow *f, uint8_t *hs){
|
|
|
p+=2; //skip version
|
|
|
|
|
|
memcpy(f->server_random, p, SSL3_RANDOM_SIZE);
|
|
|
+ p += SSL3_RANDOM_SIZE;
|
|
|
+
|
|
|
+ //skip session id
|
|
|
+ uint8_t id_len = (uint8_t) p[0];
|
|
|
+ p ++;
|
|
|
+ p += id_len;
|
|
|
+
|
|
|
+ //now extract ciphersuite
|
|
|
+ printf("Checking cipher\n");
|
|
|
+
|
|
|
+ if(((p[0] <<8) + p[1]) == 0x9E){
|
|
|
+
|
|
|
+ printf("USING DHE-RSA-AES128-GCM-SHA256\n");
|
|
|
+ f->keyex_alg = 1;
|
|
|
+ f->cipher = EVP_aes_128_gcm();
|
|
|
+ f->message_digest = EVP_sha256();
|
|
|
+ fflush(stdout);
|
|
|
+
|
|
|
+ } else if(((p[0] <<8) + p[1]) == 0x9F){
|
|
|
+ printf("USING DHE-RSA-AES256-GCM-SHA384\n");
|
|
|
+ fflush(stdout);
|
|
|
+ f->keyex_alg = 1;
|
|
|
+ f->cipher = EVP_aes_256_gcm();
|
|
|
+ f->message_digest = EVP_sha384();
|
|
|
+
|
|
|
+ } else if(((p[0] <<8) + p[1]) == 0xC02F){
|
|
|
+ printf("USING ECDHE-RSA-AES128-GCM-SHA256\n");
|
|
|
+ fflush(stdout);
|
|
|
+ f->keyex_alg = 2;
|
|
|
+ f->cipher = EVP_aes_128_gcm();
|
|
|
+ f->message_digest = EVP_sha256();
|
|
|
+
|
|
|
+ } else if(((p[0] <<8) + p[1]) == 0xC030){
|
|
|
+ printf("USING ECDHE-RSA-AES256-GCM-SHA384\n");
|
|
|
+ fflush(stdout);
|
|
|
+ f->keyex_alg = 2;
|
|
|
+ f->cipher = EVP_aes_256_gcm();
|
|
|
+ f->message_digest = EVP_sha384();
|
|
|
+
|
|
|
+ } else {
|
|
|
+ printf("%x %x = %x\n", p[0], p[1], ((p[0] <<8) + p[1]));
|
|
|
+ printf("Error: unsupported cipher\n");
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -377,7 +724,7 @@ void extract_server_random(flow *f, uint8_t *hs){
|
|
|
* Output:
|
|
|
* 0 on success, 1 on failure
|
|
|
*/
|
|
|
-int PRF(uint8_t *secret, int32_t secret_len,
|
|
|
+int PRF(flow *f, uint8_t *secret, int32_t secret_len,
|
|
|
uint8_t *seed1, int32_t seed1_len,
|
|
|
uint8_t *seed2, int32_t seed2_len,
|
|
|
uint8_t *seed3, int32_t seed3_len,
|
|
@@ -386,7 +733,7 @@ int PRF(uint8_t *secret, int32_t secret_len,
|
|
|
|
|
|
EVP_MD_CTX ctx, ctx_tmp, ctx_init;
|
|
|
EVP_PKEY *mac_key;
|
|
|
- const EVP_MD *md = EVP_sha384();
|
|
|
+ const EVP_MD *md = f->message_digest;
|
|
|
|
|
|
uint8_t A[EVP_MAX_MD_SIZE];
|
|
|
size_t len, A_len;
|
|
@@ -474,7 +821,7 @@ int init_ciphers(flow *f){
|
|
|
EVP_CIPHER_CTX *w_ctx;
|
|
|
EVP_CIPHER_CTX *w_ctx_srvr;
|
|
|
EVP_CIPHER_CTX *r_ctx_srvr;
|
|
|
- const EVP_CIPHER *c = EVP_aes_256_gcm();
|
|
|
+ const EVP_CIPHER *c = f->cipher;
|
|
|
|
|
|
/* Generate Keys */
|
|
|
uint8_t *write_key, *write_iv;
|
|
@@ -483,12 +830,12 @@ int init_ciphers(flow *f){
|
|
|
|
|
|
key_len = EVP_CIPHER_key_length(c);
|
|
|
iv_len = EVP_CIPHER_iv_length(c); //EVP_GCM_TLS_FIXED_IV_LEN;
|
|
|
- mac_len = EVP_MD_size(EVP_sha384());
|
|
|
+ mac_len = EVP_MD_size(f->message_digest);
|
|
|
int32_t total_len = key_len + iv_len + mac_len;
|
|
|
total_len *= 2;
|
|
|
uint8_t *key_block = calloc(1, total_len);
|
|
|
|
|
|
- PRF(f->master_secret, SSL3_MASTER_SECRET_SIZE,
|
|
|
+ PRF(f, f->master_secret, SSL3_MASTER_SECRET_SIZE,
|
|
|
(uint8_t *) TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
|
|
|
f->server_random, SSL3_RANDOM_SIZE,
|
|
|
f->client_random, SSL3_RANDOM_SIZE,
|