mirror of
https://github.com/adulau/ssldump.git
synced 2024-11-22 09:27:04 +00:00
commit
c36c411547
6 changed files with 426 additions and 46 deletions
234
ssl/ssl.enums.c
234
ssl/ssl.enums.c
|
@ -6,6 +6,8 @@
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#endif
|
#endif
|
||||||
#include "ssl.enums.h"
|
#include "ssl.enums.h"
|
||||||
|
static int decode_extension(ssl,dir,seg,data);
|
||||||
|
static int decode_server_name(ssl,dir,seg,data);
|
||||||
static int decode_ContentType_ChangeCipherSpec(ssl,dir,seg,data)
|
static int decode_ContentType_ChangeCipherSpec(ssl,dir,seg,data)
|
||||||
ssl_obj *ssl;
|
ssl_obj *ssl;
|
||||||
int dir;
|
int dir;
|
||||||
|
@ -174,14 +176,16 @@ static int decode_HandshakeType_ClientHello(ssl,dir,seg,data)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
UINT4 vj,vn,cs,cslen,complen,comp,odd;
|
UINT4 vj,vn,cs,cslen,complen,comp,odd,exlen,ex;
|
||||||
Data session_id,random;
|
Data session_id,random;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
extern decoder cipher_suite_decoder[];
|
extern decoder cipher_suite_decoder[];
|
||||||
extern decoder compression_method_decoder[];
|
extern decoder compression_method_decoder[];
|
||||||
|
extern decoder extension_decoder[];
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
SSL_DECODE_UINT8(ssl,0,0,data,&vj);
|
SSL_DECODE_UINT8(ssl,0,0,data,&vj);
|
||||||
SSL_DECODE_UINT8(ssl,0,0,data,&vn);
|
SSL_DECODE_UINT8(ssl,0,0,data,&vn);
|
||||||
|
|
||||||
|
@ -226,6 +230,22 @@ static int decode_HandshakeType_ClientHello(ssl,dir,seg,data)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSL_DECODE_UINT16(ssl,"extensions len",0,data,&exlen);
|
||||||
|
if (exlen) {
|
||||||
|
explain(ssl , "extensions\n");
|
||||||
|
while(data->len) {
|
||||||
|
SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex);
|
||||||
|
if (ssl_decode_switch(ssl,extension_decoder,ex,dir,seg,data) == R_NOT_FOUND) {
|
||||||
|
decode_extension(ssl,dir,seg,data);
|
||||||
|
P_(P_RH){
|
||||||
|
explain(ssl, "Extension type: %s not yet implemented in ssldump", ex);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -236,11 +256,14 @@ static int decode_HandshakeType_ServerHello(ssl,dir,seg,data)
|
||||||
Data *data;
|
Data *data;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
Data rnd,session_id;
|
Data rnd,session_id;
|
||||||
UINT4 vj,vn;
|
UINT4 vj,vn,exlen,ex;
|
||||||
|
|
||||||
|
extern decoder extension_decoder[];
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
SSL_DECODE_UINT8(ssl,0,0,data,&vj);
|
SSL_DECODE_UINT8(ssl,0,0,data,&vj);
|
||||||
SSL_DECODE_UINT8(ssl,0,0,data,&vn);
|
SSL_DECODE_UINT8(ssl,0,0,data,&vn);
|
||||||
|
|
||||||
|
@ -267,6 +290,23 @@ static int decode_HandshakeType_ServerHello(ssl,dir,seg,data)
|
||||||
P_(P_HL) printf("\n");
|
P_(P_HL) printf("\n");
|
||||||
SSL_DECODE_ENUM(ssl,"compressionMethod",1,compression_method_decoder,P_HL,data,0);
|
SSL_DECODE_ENUM(ssl,"compressionMethod",1,compression_method_decoder,P_HL,data,0);
|
||||||
P_(P_HL) printf("\n");
|
P_(P_HL) printf("\n");
|
||||||
|
|
||||||
|
SSL_DECODE_UINT16(ssl,"extensions len",0,data,&exlen);
|
||||||
|
if (exlen) {
|
||||||
|
explain(ssl , "extensions\n");
|
||||||
|
while(data->len) {
|
||||||
|
SSL_DECODE_UINT16(ssl, "extension type", 0, data, &ex);
|
||||||
|
if (ssl_decode_switch(ssl,extension_decoder,ex,dir,seg,data) == R_NOT_FOUND) {
|
||||||
|
decode_extension(ssl,dir,seg,data);
|
||||||
|
P_(P_RH){
|
||||||
|
explain(ssl, "Extension type: %s not yet implemented in ssldump", ex);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -283,6 +323,7 @@ static int decode_HandshakeType_Certificate(ssl,dir,seg,data)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
SSL_DECODE_UINT24(ssl,"certificates len",0,data,&len);
|
SSL_DECODE_UINT24(ssl,"certificates len",0,data,&len);
|
||||||
|
|
||||||
while(len){
|
while(len){
|
||||||
|
@ -306,7 +347,7 @@ static int decode_HandshakeType_ServerKeyExchange(ssl,dir,seg,data)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
if(ssl->cs){
|
if(ssl->cs){
|
||||||
P_(P_ND){
|
P_(P_ND){
|
||||||
explain(ssl,"params\n");
|
explain(ssl,"params\n");
|
||||||
|
@ -344,6 +385,7 @@ static int decode_HandshakeType_CertificateRequest(ssl,dir,seg,data)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
SSL_DECODE_UINT8(ssl,"certificate_types len",0,data,&len);
|
SSL_DECODE_UINT8(ssl,"certificate_types len",0,data,&len);
|
||||||
for(;len;len--){
|
for(;len;len--){
|
||||||
SSL_DECODE_ENUM(ssl,"certificate_types",1,
|
SSL_DECODE_ENUM(ssl,"certificate_types",1,
|
||||||
|
@ -375,6 +417,7 @@ static int decode_HandshakeType_ServerHelloDone(ssl,dir,seg,data)
|
||||||
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -388,6 +431,7 @@ static int decode_HandshakeType_CertificateVerify(ssl,dir,seg,data)
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
SSL_DECODE_OPAQUE_ARRAY(ssl,"Signature",-(1<<15-1),P_HL,data,0);
|
SSL_DECODE_OPAQUE_ARRAY(ssl,"Signature",-(1<<15-1),P_HL,data,0);
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
@ -404,6 +448,7 @@ static int decode_HandshakeType_ClientKeyExchange(ssl,dir,seg,data)
|
||||||
Data pms;
|
Data pms;
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
ssl_update_handshake_messages(ssl,data);
|
||||||
if(ssl->cs){
|
if(ssl->cs){
|
||||||
switch(ssl->cs->kex){
|
switch(ssl->cs->kex){
|
||||||
|
|
||||||
|
@ -2403,3 +2448,184 @@ decoder client_certificate_type_decoder[]={
|
||||||
{-1}
|
{-1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int decode_extension_server_name(ssl,dir,seg,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
int dir;
|
||||||
|
segment *seg;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
UINT4 t;
|
||||||
|
int l,r,p;
|
||||||
|
|
||||||
|
extern decoder server_name_type_decoder[];
|
||||||
|
|
||||||
|
SSL_DECODE_UINT16(ssl,"extension length",0,data,&l);
|
||||||
|
|
||||||
|
if(dir==DIR_I2R){
|
||||||
|
SSL_DECODE_UINT16(ssl,"server name list length",0,data,&l);
|
||||||
|
printf("\n");
|
||||||
|
while(l) {
|
||||||
|
p=data->len;
|
||||||
|
SSL_DECODE_UINT8(ssl, "server name type", 0, data, &t);
|
||||||
|
|
||||||
|
if (ssl_decode_switch(ssl,server_name_type_decoder,t,dir,seg,data) == R_NOT_FOUND) {
|
||||||
|
decode_server_name(ssl,dir,seg,data);
|
||||||
|
P_(P_RH){
|
||||||
|
explain(ssl, "Server Name type: %s not yet implemented in ssldump", t);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
l-=(p-data->len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
data->len-=l;
|
||||||
|
data->data+=l;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
static int decode_extension_encrypt_then_mac(ssl,dir,seg,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
int dir;
|
||||||
|
segment *seg;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
int l,r,*etm;
|
||||||
|
|
||||||
|
etm=&ssl->extensions->encrypt_then_mac;
|
||||||
|
|
||||||
|
SSL_DECODE_UINT16(ssl,"extension length",0,data,&l);
|
||||||
|
data->len-=l;
|
||||||
|
data->data+=l;
|
||||||
|
|
||||||
|
*etm=dir==DIR_I2R?1:*etm==1;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
static int decode_extension_extended_master_secret(ssl,dir,seg,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
int dir;
|
||||||
|
segment *seg;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
int l,r,*ems;
|
||||||
|
|
||||||
|
ems=&ssl->extensions->extended_master_secret;
|
||||||
|
|
||||||
|
SSL_DECODE_UINT16(ssl,"extension length",0,data,&l);
|
||||||
|
data->len-=l;
|
||||||
|
data->data+=l;
|
||||||
|
|
||||||
|
*ems=dir==DIR_I2R?1:*ems==1;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
static int decode_extension(ssl,dir,seg,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
int dir;
|
||||||
|
segment *seg;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
int l,r;
|
||||||
|
SSL_DECODE_UINT16(ssl,"extension length",0,data,&l);
|
||||||
|
data->len-=l;
|
||||||
|
data->data+=l;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
decoder extension_decoder[] = {
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
"server_name",
|
||||||
|
decode_extension_server_name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
"max_fragment_length",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
2,
|
||||||
|
"client_certificate_url",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
3,
|
||||||
|
"trusted_ca_keys",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
4,
|
||||||
|
"truncated_hmac",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
5,
|
||||||
|
"status_request",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
13,
|
||||||
|
"signature_algorithms",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
16,
|
||||||
|
"application_layer_protocol_negotiation",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
{
|
||||||
|
22,
|
||||||
|
"encrypt_then_mac",
|
||||||
|
decode_extension_encrypt_then_mac
|
||||||
|
},
|
||||||
|
{
|
||||||
|
23,
|
||||||
|
"extended_master_secret",
|
||||||
|
decode_extension_extended_master_secret
|
||||||
|
},
|
||||||
|
{
|
||||||
|
13172,
|
||||||
|
"next_protocol_negotiation",
|
||||||
|
decode_extension
|
||||||
|
},
|
||||||
|
|
||||||
|
{-1}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int decode_server_name_type_host_name(ssl,dir,seg,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
int dir;
|
||||||
|
segment *seg;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
int l,r;
|
||||||
|
SSL_DECODE_UINT16(ssl,"server name length",0,data,&l);
|
||||||
|
printf(": %.*s",l,data->data);
|
||||||
|
|
||||||
|
/* Possibly use data->data to set/modify ssl->server_name */
|
||||||
|
|
||||||
|
data->len-=l;
|
||||||
|
data->data+=l;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
static int decode_server_name(ssl,dir,seg,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
int dir;
|
||||||
|
segment *seg;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
int l,r;
|
||||||
|
SSL_DECODE_UINT16(ssl,"server name length",0,data,&l);
|
||||||
|
data->len-=l;
|
||||||
|
data->data+=l;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder server_name_type_decoder[]={
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
"host_name",
|
||||||
|
decode_server_name_type_host_name
|
||||||
|
},
|
||||||
|
{-1}
|
||||||
|
};
|
||||||
|
|
|
@ -266,6 +266,9 @@ static int create_ssl_analyzer(handle,ctx,conn,objp,i_addr,i_port,r_addr,r_port,
|
||||||
if(r=ssl_decoder_create(&obj->decoder,obj->ssl_ctx))
|
if(r=ssl_decoder_create(&obj->decoder,obj->ssl_ctx))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
|
if (!(obj->extensions=malloc(sizeof(ssl_extensions))))
|
||||||
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
*objp=(proto_obj *)obj;
|
*objp=(proto_obj *)obj;
|
||||||
|
|
||||||
_status=0;
|
_status=0;
|
||||||
|
@ -292,6 +295,7 @@ static int destroy_ssl_analyzer(objp)
|
||||||
ssl_decoder_destroy(&obj->decoder);
|
ssl_decoder_destroy(&obj->decoder);
|
||||||
free(obj->client_name);
|
free(obj->client_name);
|
||||||
free(obj->server_name);
|
free(obj->server_name);
|
||||||
|
free(obj->extensions);
|
||||||
free(*objp);
|
free(*objp);
|
||||||
*objp=0;
|
*objp=0;
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,11 @@ typedef struct d_queue_ {
|
||||||
int offset; /*How far into the first segment this record starts*/
|
int offset; /*How far into the first segment this record starts*/
|
||||||
} r_queue;
|
} r_queue;
|
||||||
|
|
||||||
|
typedef struct ssl_extensions_ {
|
||||||
|
int encrypt_then_mac;
|
||||||
|
int extended_master_secret;
|
||||||
|
} ssl_extensions;
|
||||||
|
|
||||||
typedef struct ssl_obj_ {
|
typedef struct ssl_obj_ {
|
||||||
tcp_conn *conn;
|
tcp_conn *conn;
|
||||||
int r_state;
|
int r_state;
|
||||||
|
@ -86,6 +91,7 @@ typedef struct ssl_obj_ {
|
||||||
struct timeval time_last;
|
struct timeval time_last;
|
||||||
ssl_decode_ctx *ssl_ctx;
|
ssl_decode_ctx *ssl_ctx;
|
||||||
ssl_decoder *decoder;
|
ssl_decoder *decoder;
|
||||||
|
ssl_extensions *extensions;
|
||||||
|
|
||||||
int process_ciphertext;
|
int process_ciphertext;
|
||||||
|
|
||||||
|
|
110
ssl/ssl_rec.c
110
ssl/ssl_rec.c
|
@ -94,7 +94,7 @@ char *ciphers[]={
|
||||||
|
|
||||||
|
|
||||||
static int tls_check_mac PROTO_LIST((ssl_rec_decoder *d,int ct,
|
static int tls_check_mac PROTO_LIST((ssl_rec_decoder *d,int ct,
|
||||||
int ver,UCHAR *data,UINT4 datalen,UCHAR *mac));
|
int ver,UCHAR *data,UINT4 datalen,UCHAR *iv,UINT4 ivlen,UCHAR *mac));
|
||||||
static int fmt_seq PROTO_LIST((UINT4 num,UCHAR *buf));
|
static int fmt_seq PROTO_LIST((UINT4 num,UCHAR *buf));
|
||||||
|
|
||||||
int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
|
int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
|
||||||
|
@ -162,6 +162,7 @@ int ssl_destroy_rec_decoder(dp)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
|
int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
|
||||||
ssl_obj *ssl;
|
ssl_obj *ssl;
|
||||||
ssl_rec_decoder *d;
|
ssl_rec_decoder *d;
|
||||||
|
@ -174,50 +175,91 @@ int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
int pad;
|
int pad;
|
||||||
int r;
|
int r,encpadl;
|
||||||
UCHAR *mac;
|
UCHAR *mac,*iv;
|
||||||
|
|
||||||
CRDUMP("Ciphertext",in,inl);
|
CRDUMP("Ciphertext",in,inl);
|
||||||
/* First decrypt*/
|
|
||||||
EVP_Cipher(d->evp,out,in,inl);
|
|
||||||
|
|
||||||
CRDUMP("Plaintext",out,inl);
|
if(ssl->extensions->encrypt_then_mac){
|
||||||
*outl=inl;
|
*outl=inl;
|
||||||
|
|
||||||
/* Now strip off the padding*/
|
/* First strip off the MAC */
|
||||||
if(d->cs->block>1){
|
*outl-=d->cs->dig_len;
|
||||||
pad=out[inl-1];
|
mac=in+(*outl);
|
||||||
*outl-=(pad+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And the MAC */
|
encpadl=*outl;
|
||||||
*outl-=d->cs->dig_len;
|
/* Now decrypt */
|
||||||
mac=out+(*outl);
|
EVP_Cipher(d->evp,out,in,*outl);
|
||||||
CRDUMP("Record data",out,*outl);
|
CRDUMP("Plaintext",out,*outl);
|
||||||
|
|
||||||
/* Now check the MAC */
|
/* And then strip off the padding*/
|
||||||
if(ssl->version==0x300){
|
if(d->cs->block>1){
|
||||||
if(r=ssl3_check_mac(d,ct,version,out,*outl,mac))
|
pad=out[*outl-1];
|
||||||
ERETURN(r);
|
*outl-=(pad+1);
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||||
* non-stream ciphers. */
|
* non-stream ciphers. */
|
||||||
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
||||||
UINT4 blk = ssl->cs->block;
|
UINT4 blk = ssl->cs->block;
|
||||||
if (blk <= *outl) {
|
if (blk <= *outl) {
|
||||||
*outl-=blk;
|
*outl-=blk;
|
||||||
memmove(out, out+blk, *outl);
|
memmove(out, out+blk, *outl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG((0,"Block size greater than Plaintext!"));
|
DBG((0,"Block size greater than Plaintext!"));
|
||||||
ERETURN(SSL_BAD_MAC);
|
ERETURN(SSL_BAD_MAC);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(r=tls_check_mac(d,ct,version,out,*outl,mac))
|
|
||||||
ERETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(r=tls_check_mac(d,ct,version,in+blk,encpadl,in,blk,mac))
|
||||||
|
ERETURN(r);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(r=tls_check_mac(d,ct,version,in,encpadl,NULL,0,mac))
|
||||||
|
ERETURN(r);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* First decrypt*/
|
||||||
|
EVP_Cipher(d->evp,out,in,inl);
|
||||||
|
|
||||||
|
CRDUMP("Plaintext",out,inl);
|
||||||
|
*outl=inl;
|
||||||
|
|
||||||
|
/* Now strip off the padding*/
|
||||||
|
if(d->cs->block>1){
|
||||||
|
pad=out[inl-1];
|
||||||
|
*outl-=(pad+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And the MAC */
|
||||||
|
*outl-=d->cs->dig_len;
|
||||||
|
mac=out+(*outl);
|
||||||
|
CRDUMP("Record data",out,*outl);
|
||||||
|
|
||||||
|
/* Now check the MAC */
|
||||||
|
if(ssl->version==0x300){
|
||||||
|
if(r=ssl3_check_mac(d,ct,version,out,*outl,mac))
|
||||||
|
ERETURN(r);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||||
|
* non-stream ciphers. */
|
||||||
|
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
||||||
|
UINT4 blk = ssl->cs->block;
|
||||||
|
if (blk <= *outl) {
|
||||||
|
*outl-=blk;
|
||||||
|
memmove(out, out+blk, *outl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG((0,"Block size greater than Plaintext!"));
|
||||||
|
ERETURN(SSL_BAD_MAC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(r=tls_check_mac(d,ct,version,out,*outl,NULL,0,mac))
|
||||||
|
ERETURN(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
@ -242,12 +284,14 @@ static int fmt_seq(num,buf)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_check_mac(d,ct,ver,data,datalen,mac)
|
static int tls_check_mac(d,ct,ver,data,datalen,iv,ivlen,mac)
|
||||||
ssl_rec_decoder *d;
|
ssl_rec_decoder *d;
|
||||||
int ct;
|
int ct;
|
||||||
int ver;
|
int ver;
|
||||||
UCHAR *data;
|
UCHAR *data;
|
||||||
UINT4 datalen;
|
UINT4 datalen;
|
||||||
|
UCHAR *iv;
|
||||||
|
UINT4 ivlen;
|
||||||
UCHAR *mac;
|
UCHAR *mac;
|
||||||
{
|
{
|
||||||
HMAC_CTX hm;
|
HMAC_CTX hm;
|
||||||
|
@ -272,7 +316,13 @@ static int tls_check_mac(d,ct,ver,data,datalen,mac)
|
||||||
buf[1]=LSB(datalen);
|
buf[1]=LSB(datalen);
|
||||||
HMAC_Update(&hm,buf,2);
|
HMAC_Update(&hm,buf,2);
|
||||||
|
|
||||||
HMAC_Update(&hm,data,datalen);
|
/* for encrypt-then-mac with an explicit IV */
|
||||||
|
if(ivlen && iv){
|
||||||
|
HMAC_Update(&hm,iv,ivlen);
|
||||||
|
HMAC_Update(&hm,data,datalen-ivlen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HMAC_Update(&hm,data,datalen);
|
||||||
|
|
||||||
HMAC_Final(&hm,buf,&l);
|
HMAC_Final(&hm,buf,&l);
|
||||||
if(memcmp(mac,buf,l))
|
if(memcmp(mac,buf,l))
|
||||||
|
|
101
ssl/ssldecode.c
101
ssl/ssldecode.c
|
@ -91,6 +91,8 @@ struct ssl_decoder_ {
|
||||||
int ephemeral_rsa;
|
int ephemeral_rsa;
|
||||||
Data *PMS;
|
Data *PMS;
|
||||||
Data *MS;
|
Data *MS;
|
||||||
|
Data *handshake_messages;
|
||||||
|
Data *session_hash;
|
||||||
ssl_rec_decoder *c_to_s;
|
ssl_rec_decoder *c_to_s;
|
||||||
ssl_rec_decoder *s_to_c;
|
ssl_rec_decoder *s_to_c;
|
||||||
ssl_rec_decoder *c_to_s_n;
|
ssl_rec_decoder *c_to_s_n;
|
||||||
|
@ -111,6 +113,8 @@ static int ssl3_generate_export_iv PROTO_LIST((ssl_obj *ssl,
|
||||||
Data *rnd1,Data *rnd2,Data *out));
|
Data *rnd1,Data *rnd2,Data *out));
|
||||||
static int ssl_generate_keying_material PROTO_LIST((ssl_obj *ssl,
|
static int ssl_generate_keying_material PROTO_LIST((ssl_obj *ssl,
|
||||||
ssl_decoder *d));
|
ssl_decoder *d));
|
||||||
|
static int ssl_generate_session_hash PROTO_LIST((ssl_obj *ssl,
|
||||||
|
ssl_decoder *d));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ssl_create_session_lookup_key PROTO_LIST((ssl_obj *ssl,
|
static int ssl_create_session_lookup_key PROTO_LIST((ssl_obj *ssl,
|
||||||
|
@ -214,6 +218,8 @@ int ssl_decoder_destroy(dp)
|
||||||
r_data_destroy(&d->session_id);
|
r_data_destroy(&d->session_id);
|
||||||
r_data_destroy(&d->PMS);
|
r_data_destroy(&d->PMS);
|
||||||
r_data_destroy(&d->MS);
|
r_data_destroy(&d->MS);
|
||||||
|
r_data_destroy(&d->handshake_messages);
|
||||||
|
r_data_destroy(&d->session_hash);
|
||||||
ssl_destroy_rec_decoder(&d->c_to_s);
|
ssl_destroy_rec_decoder(&d->c_to_s);
|
||||||
ssl_destroy_rec_decoder(&d->c_to_s_n);
|
ssl_destroy_rec_decoder(&d->c_to_s_n);
|
||||||
ssl_destroy_rec_decoder(&d->s_to_c);
|
ssl_destroy_rec_decoder(&d->s_to_c);
|
||||||
|
@ -382,6 +388,35 @@ int ssl_decode_record(ssl,dec,direction,ct,version,d)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ssl_update_handshake_messages(ssl,data)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
Data *data;
|
||||||
|
{
|
||||||
|
#ifdef OPENSSL
|
||||||
|
Data *hms;
|
||||||
|
UCHAR *d;
|
||||||
|
int l,r;
|
||||||
|
|
||||||
|
hms = ssl->decoder->handshake_messages;
|
||||||
|
d = data->data-4;
|
||||||
|
l = data->len+4;
|
||||||
|
|
||||||
|
if(hms){
|
||||||
|
if(!(hms->data = realloc(hms->data,l+hms->len)))
|
||||||
|
ERETURN(R_NO_MEMORY);
|
||||||
|
|
||||||
|
memcpy(hms->data+hms->len,d,l);
|
||||||
|
hms->len+=l;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(r=r_data_create(&hms,d,l))
|
||||||
|
ERETURN(r);
|
||||||
|
ssl->decoder->handshake_messages=hms;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int ssl_create_session_lookup_key(ssl,id,idlen,keyp,keyl)
|
static int ssl_create_session_lookup_key(ssl,id,idlen,keyp,keyl)
|
||||||
ssl_obj *ssl;
|
ssl_obj *ssl;
|
||||||
|
@ -564,6 +599,7 @@ int ssl_process_client_key_exchange(ssl,d,msg,len)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
static int tls_P_hash(ssl,secret,seed,md,out)
|
static int tls_P_hash(ssl,secret,seed,md,out)
|
||||||
ssl_obj *ssl;
|
ssl_obj *ssl;
|
||||||
|
@ -810,7 +846,7 @@ static int ssl_generate_keying_material(ssl,d)
|
||||||
ssl_obj *ssl;
|
ssl_obj *ssl;
|
||||||
ssl_decoder *d;
|
ssl_decoder *d;
|
||||||
{
|
{
|
||||||
Data *key_block=0;
|
Data *key_block=0,temp;
|
||||||
UCHAR _iv_c[8],_iv_s[8];
|
UCHAR _iv_c[8],_iv_s[8];
|
||||||
UCHAR _key_c[16],_key_s[16];
|
UCHAR _key_c[16],_key_s[16];
|
||||||
int needed;
|
int needed;
|
||||||
|
@ -821,9 +857,19 @@ static int ssl_generate_keying_material(ssl,d)
|
||||||
if(r=r_data_alloc(&d->MS,48))
|
if(r=r_data_alloc(&d->MS,48))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
if(r=PRF(ssl,d->PMS,"master secret",d->client_random,d->server_random,
|
if (ssl->extensions->extended_master_secret) {
|
||||||
d->MS))
|
if(r=ssl_generate_session_hash(ssl,d))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
|
temp.len=0;
|
||||||
|
if(r=PRF(ssl,d->PMS,"extended master secret",d->session_hash,&temp,
|
||||||
|
d->MS))
|
||||||
|
ABORT(r);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(r=PRF(ssl,d->PMS,"master secret",d->client_random,d->server_random,
|
||||||
|
d->MS))
|
||||||
|
ABORT(r);
|
||||||
|
|
||||||
CRDUMPD("MS",d->MS);
|
CRDUMPD("MS",d->MS);
|
||||||
}
|
}
|
||||||
|
@ -958,4 +1004,51 @@ static int ssl_generate_keying_material(ssl,d)
|
||||||
return(_status);
|
return(_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ssl_generate_session_hash(ssl,d)
|
||||||
|
ssl_obj *ssl;
|
||||||
|
ssl_decoder *d;
|
||||||
|
{
|
||||||
|
int r,_status,dgi;
|
||||||
|
unsigned int len;
|
||||||
|
const EVP_MD *md;
|
||||||
|
EVP_MD_CTX dgictx;
|
||||||
|
|
||||||
|
if(r=r_data_alloc(&d->session_hash,EVP_MAX_MD_SIZE))
|
||||||
|
ABORT(r);
|
||||||
|
|
||||||
|
switch(ssl->version){
|
||||||
|
case TLSV12_VERSION:
|
||||||
|
dgi = MAX(DIG_SHA256,ssl->cs->dig)-0x40;
|
||||||
|
if ((md=EVP_get_digestbyname(digests[dgi])) == NULL) {
|
||||||
|
DBG((0,"Cannot get EVP for digest %s, openssl library current?",
|
||||||
|
digests[dgi]));
|
||||||
|
ERETURN(SSL_BAD_MAC);
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_DigestInit(&dgictx,md);
|
||||||
|
EVP_DigestUpdate(&dgictx,d->handshake_messages->data,d->handshake_messages->len);
|
||||||
|
EVP_DigestFinal(&dgictx,d->session_hash->data,&d->session_hash->len);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSLV3_VERSION:
|
||||||
|
case TLSV1_VERSION:
|
||||||
|
case TLSV11_VERSION:
|
||||||
|
EVP_DigestInit(&dgictx,EVP_get_digestbyname("MD5"));
|
||||||
|
EVP_DigestUpdate(&dgictx,d->handshake_messages->data,d->handshake_messages->len);
|
||||||
|
EVP_DigestFinal_ex(&dgictx,d->session_hash->data,&d->session_hash->len);
|
||||||
|
|
||||||
|
EVP_DigestInit(&dgictx,EVP_get_digestbyname("SHA1"));
|
||||||
|
EVP_DigestUpdate(&dgictx,d->handshake_messages->data,d->handshake_messages->len);
|
||||||
|
EVP_DigestFinal(&dgictx,d->session_hash->data+d->session_hash->len,&len);
|
||||||
|
|
||||||
|
d->session_hash->len+=len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ABORT(SSL_CANT_DO_CIPHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
_status=0;
|
||||||
|
abort:
|
||||||
|
return(_status);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,7 +66,8 @@ int ssl_process_client_key_exchange PROTO_LIST((struct ssl_obj_ *,
|
||||||
ssl_decoder *d,UCHAR *msg,int len));
|
ssl_decoder *d,UCHAR *msg,int len));
|
||||||
int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj *ssl,
|
int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj *ssl,
|
||||||
ssl_decoder *d,int direction));
|
ssl_decoder *d,int direction));
|
||||||
|
int ssl_update_handshake_messages PROTO_LIST((ssl_obj *ssl,
|
||||||
|
Data *data));
|
||||||
int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction,
|
int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction,
|
||||||
int ct,int version,Data *d));
|
int ct,int version,Data *d));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue