|
@@ -100,7 +100,7 @@ int update_flow(flow *f) {
|
|
|
int i;
|
|
|
for(i=0; (i<current->data_len) && (i+data_len < record_len); i++){
|
|
|
|
|
|
- record[data_len] = p[i];
|
|
|
+ record[data_len+i] = p[i];
|
|
|
}
|
|
|
//printf("Filled %d\n", i);
|
|
|
data_len += current->data_len;
|
|
@@ -121,28 +121,31 @@ int update_flow(flow *f) {
|
|
|
handshake_hdr = (struct handshake_header*) p;
|
|
|
f->state = handshake_hdr->type;
|
|
|
|
|
|
+ printf("record length: %d, hanshake length: %d\n", record_len, HANDSHAKE_MESSAGE_LEN(handshake_hdr));
|
|
|
+
|
|
|
/* Now see if there's anything extra to do */
|
|
|
switch(f->state){
|
|
|
/* Checks to see if this is a possibly tagged hello msg */
|
|
|
case TLS_CLNT_HELLO:
|
|
|
/* Expecting server hello msg */
|
|
|
printf("Received client hello!\n");
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
break;
|
|
|
case TLS_SERV_HELLO:
|
|
|
extract_server_random(f, p);
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received server hello!\n");
|
|
|
break;
|
|
|
case TLS_NEW_SESS:
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received new session ticket!\n");
|
|
|
break;
|
|
|
case TLS_CERT:
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received certificate!\n");
|
|
|
break;
|
|
|
case TLS_SRVR_KEYEX:
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received server key exchange!\n");
|
|
|
/* Need to extract server params */
|
|
|
if(extract_parameters(f, p)){
|
|
@@ -153,22 +156,24 @@ int update_flow(flow *f) {
|
|
|
}
|
|
|
break;
|
|
|
case TLS_CERT_REQ:
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received certificate request!\n");
|
|
|
break;
|
|
|
case TLS_SRVR_HELLO_DONE:
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received server hello done!\n");
|
|
|
break;
|
|
|
case TLS_CERT_VERIFY:
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received certificate verify!\n");
|
|
|
break;
|
|
|
case TLS_CLNT_KEYEX:
|
|
|
- //update_finish_hash(f, p);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received client key exchange!\n");
|
|
|
break;
|
|
|
case TLS_FINISHED:
|
|
|
+ verify_finish_hash(f,p, incoming);
|
|
|
+ update_finish_hash(f, p);
|
|
|
printf("Received finished message!\n");
|
|
|
break;
|
|
|
default:
|
|
@@ -356,16 +361,13 @@ int add_packet(flow *f, uint8_t *p){
|
|
|
/** UTILITY **/
|
|
|
|
|
|
int update_finish_hash(flow *f, uint8_t *hs){
|
|
|
- EVP_MD_CTX *ctx = f->finish_md_ctx;
|
|
|
//find handshake length
|
|
|
const struct handshake_header *hs_hdr;
|
|
|
uint8_t *p = hs;
|
|
|
hs_hdr = (struct handshake_header*) p;
|
|
|
uint32_t hs_len = HANDSHAKE_MESSAGE_LEN(hs_hdr);
|
|
|
|
|
|
- /* Now compute SHA384(secret, A+seed)
|
|
|
- * can't sign update, don't have master secret yet*/
|
|
|
- EVP_DigestUpdate(&ctx, hs, hs_len);
|
|
|
+ EVP_DigestUpdate(f->finish_md_ctx, hs, hs_len+4);
|
|
|
|
|
|
return 1;
|
|
|
|
|
@@ -463,41 +465,48 @@ int decrypt_fin(flow *f, uint8_t *hs, int32_t len, int32_t incoming){
|
|
|
13, buf);
|
|
|
printf("pad: %d\n", pad);
|
|
|
|
|
|
- printf("Decrypting (%d bytes):\n", len);
|
|
|
- for(int i=0; i<len; i++){
|
|
|
- printf("%02x ", p[i]);
|
|
|
- }
|
|
|
- printf("\n");
|
|
|
|
|
|
int32_t n = EVP_Cipher(ds, p, p, len); //decrypt in place
|
|
|
|
|
|
p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
|
len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
|
|
//print out decrypted record
|
|
|
- printf("Record (decrypted %d/%d bytes): \n", n, len);
|
|
|
- for(int i=0; i<n; i++){
|
|
|
- printf("%02x ", p[i]);
|
|
|
- }
|
|
|
- printf("\n");
|
|
|
|
|
|
- /*get context
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int verify_finish_hash(flow *f, uint8_t *p, int32_t incoming){
|
|
|
+ EVP_MD_CTX ctx;
|
|
|
+ uint8_t hash[EVP_MAX_MD_SIZE];
|
|
|
+ int32_t hash_len;
|
|
|
+
|
|
|
+ EVP_MD_CTX_init(&ctx);
|
|
|
|
|
|
//get header length
|
|
|
+ struct handshake_header *hs_hdr;
|
|
|
hs_hdr = (struct handshake_header*) p;
|
|
|
uint32_t fin_length = HANDSHAKE_MESSAGE_LEN(hs_hdr);
|
|
|
p += HANDSHAKE_HEADER_LEN;
|
|
|
|
|
|
//finalize hash of handshake msgs
|
|
|
EVP_MD_CTX_copy_ex(&ctx, f->finish_md_ctx);
|
|
|
- EVP_DigestFinal(&ctx, hash, &hash_len);
|
|
|
+ EVP_DigestFinal_ex(&ctx, hash, &hash_len);
|
|
|
|
|
|
//now use pseudorandom function
|
|
|
uint8_t *output = calloc(1, fin_length);
|
|
|
- PRF(f->master_secret, SSL3_MASTER_SECRET_SIZE, finished_label, finished_label_len, hash, hash_len, NULL, 0, NULL, 0, output, fin_length);
|
|
|
+ if(incoming){
|
|
|
+ PRF(f->master_secret, SSL3_MASTER_SECRET_SIZE, 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, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE , hash, hash_len, NULL, 0, NULL, 0, output, fin_length);
|
|
|
+ }
|
|
|
|
|
|
//now compare
|
|
|
-
|
|
|
-*/
|
|
|
+ if(CRYPTO_memcmp(p, output, fin_length) != 0){
|
|
|
+ printf("VERIFY FAILED\n");
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ printf("VERIFY PASSED\n");
|
|
|
+ }
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
@@ -708,7 +717,7 @@ int init_ciphers(flow *f){
|
|
|
EVP_CIPHER_CTX_init(r_ctx);
|
|
|
EVP_CIPHER_CTX_init(w_ctx);
|
|
|
|
|
|
-//#ifdef KSSL_DEBUG
|
|
|
+/*#ifdef KSSL_DEBUG
|
|
|
{
|
|
|
int i;
|
|
|
fprintf(stderr, "EVP_CipherInit_ex(r_ctx,c,key=,iv=,which)\n");
|
|
@@ -721,7 +730,7 @@ int init_ciphers(flow *f){
|
|
|
fprintf(stderr, "%02x", read_iv[i]);
|
|
|
fprintf(stderr, "\n");
|
|
|
}
|
|
|
-//#endif /* KSSL_DEBUG_*/
|
|
|
+//#endif KSSL_DEBUG_
|
|
|
{
|
|
|
int i;
|
|
|
fprintf(stderr, "EVP_CipherInit_ex(w_ctx,c,key=,iv=,which)\n");
|
|
@@ -734,21 +743,14 @@ int init_ciphers(flow *f){
|
|
|
fprintf(stderr, "%02x", write_iv[i]);
|
|
|
fprintf(stderr, "\n");
|
|
|
}
|
|
|
-//#endif /* KSSL_DEBUG */
|
|
|
+//#endif KSSL_DEBUG */
|
|
|
|
|
|
|
|
|
EVP_CipherInit_ex(r_ctx, c, NULL, read_key, NULL, 0);
|
|
|
EVP_CipherInit_ex(w_ctx, c, NULL, write_key, NULL, 0);
|
|
|
EVP_CIPHER_CTX_ctrl(r_ctx, EVP_CTRL_GCM_SET_IV_FIXED, EVP_GCM_TLS_FIXED_IV_LEN, read_iv);
|
|
|
EVP_CIPHER_CTX_ctrl(w_ctx, EVP_CTRL_GCM_SET_IV_FIXED, EVP_GCM_TLS_FIXED_IV_LEN, write_iv);
|
|
|
- fprintf(stderr, "\t\tIV: ");
|
|
|
- for (int i = 0; i < r_ctx->cipher->iv_len; i++)
|
|
|
- fprintf(stderr, "%02X", r_ctx->iv[i]);
|
|
|
- fprintf(stderr, "\n");
|
|
|
- fprintf(stderr, "\t\tIV: ");
|
|
|
- for (int i = 0; i < w_ctx->cipher->iv_len; i++)
|
|
|
- fprintf(stderr, "%02X", w_ctx->iv[i]);
|
|
|
- fprintf(stderr, "\n");
|
|
|
+
|
|
|
f->read_ctx = r_ctx;
|
|
|
f->write_ctx = w_ctx;
|
|
|
}
|