Index: configure.in =================================================================== RCS file: /cvsroot/ssldump/ssldump/configure.in,v retrieving revision 1.3 diff -u -p -r1.3 configure.in --- configure.in 29 Mar 2005 17:53:04 -0000 1.3 +++ configure.in 5 Jun 2010 17:47:40 -0000 @@ -59,164 +59,14 @@ esac RECORD_MOD="dummy" -dnl Look for PCAP -dnl We absolutely need pcap -ac_pcap_inc_dir="/usr/include /usr/include/pcap /usr/local/include" -ac_pcap_lib_dir="/usr/lib /usr/local/lib" - -AC_ARG_WITH(pcap,[--with-pcap root location for pcap library], - if test "$withval" = "no"; then - AC_MSG_ERROR(PCAP required for ssldump) - else - ac_pcap_inc_dir=$withval/include - ac_pcap_lib_dir=$withval/lib - fi -) - -AC_ARG_WITH(pcap-inc,[--with-pcap-inc PCAP include files], - ac_pcap_inc_dir=$withval -) -AC_ARG_WITH(pcap-lib,[--with-pcap-lib PCAP library files], - ac_pcap_lib_dir=$withval -) - -dnl Now look for it -AC_MSG_CHECKING(for PCAP include files) -ac_found_pcap_inc_dir="no" -for dir in $ac_pcap_inc_dir; do - if test -f $dir/pcap.h; then - if test "$dir" != "/usr/include"; then - INCLUDES="-I$dir $INCLUDES" - fi - ac_found_pcap_inc_dir=$dir - echo "found in $dir" - break; - fi -done - -if test "$ac_found_pcap_inc_dir" = "no"; then - echo - AC_MSG_ERROR(Couldn't find PCAP includes: needed for ssldump) -fi - -AC_MSG_CHECKING(for PCAP library) -ac_found_pcap_lib_dir="no" -for dir in $ac_pcap_lib_dir; do - if test -f $dir/libpcap.a; then - dnl Ok, we think we've found them, but check that they - dnl actually ontain the right functions - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - LIBS="-lpcap $LIBS" - if test "$dir" != "/usr/lib"; then - LDFLAGS="-L$dir $LDFLAGS" - fi - AC_TRY_LINK_FUNC(pcap_open_live,ac_linked_libpcap="true", - ac_linked_libpcap="false"); - if test "$ac_linked_libpcap" != "false"; then - ac_found_pcap_lib_dir=$dir - break - fi - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - fi -done - -if test "$ac_found_pcap_lib_dir" = "no"; then - echo - AC_MSG_ERROR(Couldn't find PCAP library: needed for ssldump) -else - echo "found in $ac_found_pcap_lib_dir" -fi - -dnl See if we can find OpenSSL dnl We can compile without OpenSSL if we have to -ac_use_openssl="true" -ac_openssl_lib_dir="/usr/lib /usr/local /usr/local/ssl /usr/local/ssl/lib /usr/pkg" -ac_openssl_inc_dir="/usr/include /usr/local /usr/local/ssl /usr/pkg /usr/local/ssl/include" - -AC_ARG_WITH(openssl,[--with-openssl root location for OpenSSL], - if test "$withval" = "no"; then - ac_use_openssl="false" - else - ac_openssl_lib_dir="$withval/lib $withval" - ac_openssl_inc_dir=$withval/include - fi -) - -AC_ARG_WITH(openssl-inc,[--with-openssl-inc OpenSSL include files], - ac_openssl_inc_dir=$withval -) -AC_ARG_WITH(openssl-lib,[--with-openssl-lib OpenSSL library files], - ac_openssl_lib_dir=$withval -) - -dnl Now look for OpenSSL -if test "$ac_use_openssl" != "false"; then - ac_found_openssl_inc_dir="no" - AC_MSG_CHECKING(for OpenSSL include files) - for dir in $ac_openssl_inc_dir; do - if test -f $dir/openssl/ssl.h; then - ac_found_openssl_inc_dir=$dir - break - fi - done - if test "$ac_found_openssl_inc_dir" != "no"; then - echo "found in $ac_found_openssl_inc_dir" - else - echo "not found." - ac_use_openssl="false" - fi -fi - -if test "$ac_use_openssl" != "false"; then - ac_found_openssl_lib_dir="no" - AC_MSG_CHECKING(for OpenSSL libraries) - for dir in $ac_openssl_lib_dir; do - found_ssl="false" - if test -f $dir/libssl.a -a -f $dir/libcrypto.a; then - found_ssl="true" - fi - if test -f $dir/libssl.so -a -f $dir/libcrypto.so; then - found_ssl="true" - fi - if test -f $dir/libssl.dylib -a -f $dir/libcrypto.dylib; then - found_ssl="true" - fi - if $found_ssl != "false"; then - dnl Ok, we think we've found them, but check that they - dnl actually ontain the right functions - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - LIBS="-lssl -lcrypto $LIBS" - LDFLAGS="-L$dir $LDFLAGS" - AC_TRY_LINK_FUNC(SSL_load_error_strings,ac_linked_libssl="true", - ac_linked_libssl="false"); - AC_TRY_LINK_FUNC(RC4_set_key,ac_linked_libcrypto="true", - ac_linked_libcrypto="false"); - if test "$ac_linked_libssl" != "false" -a \ - "$ac_linked_libcrypto" != "false"; then - ac_found_openssl_lib_dir=$dir - break - fi - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - fi - done - if test "$ac_found_openssl_lib_dir" != "no"; then - echo "found in $ac_found_openssl_lib_dir" - INCLUDES="-I$ac_found_openssl_inc_dir $INCLUDES" +AC_ARG_WITH(openssl,[--with-openssl Compile with OpenSSL for decryption], + if test "$withval" != "no"; then + LIBS="`pkg-config --libs openssl` $LIBS" + INCLUDES="`pkg-config --cflags openssl` $INCLUDES" DEFINES="-DOPENSSL $DEFINES" - else - echo "not found." - ac_use_openssl="false" fi -fi - -if test "$ac_use_openssl" = "false"; then - AC_MSG_WARN(compiling without OpenSSL) -fi - +) AC_ARG_WITH(record,[--with-record Compile with record module (EKR Use Only)], DEFINES="-DENABLE_RECORD $DEFINES" RECORD_MOD="record" @@ -225,9 +75,12 @@ AC_ARG_WITH(record,[--with-record Compil AC_CHECK_HEADER(netinet/ip6.h, DEFINES="-DSSLDUMP_USE_INET6 $DEFINES",,) AC_CHECK_HEADER(stdint.h, DEFINES="-DHAVE_STDINT_H $DEFINES",,) +AC_CHECK_HEADER(net/bpf.h, DEFINES="-DHAVE_NET_BPF_H $DEFINES",,) +AC_CHECK_HEADER(pcap-bpf.h, DEFINES="-DHAVE_PCAP_BPF_H $DEFINES",,) dnl Replace `main' with a function in -lpcap: -AC_CHECK_LIB(pcap, pcap_open) +dnl AC_CHECK_LIB(pcap, pcap_open) +LIBS="-lpcap $LIBS" dnl Checks for header files. Index: ssldump.1 =================================================================== RCS file: /cvsroot/ssldump/ssldump/ssldump.1,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 ssldump.1 --- ssldump.1 14 Dec 2002 02:07:16 -0000 1.1.1.1 +++ ssldump.1 5 Jun 2010 17:47:40 -0000 @@ -81,6 +81,10 @@ ssldump \- dump SSL traffic on a network .I password ] [ +.B \-s +.I session_cache +] +[ .I expression ] .br @@ -148,14 +152,14 @@ dumps. See also -X. .B \-e Print absolute timestamps instead of relative timestamps .TP -.B \-r +.BI "\-r " file Read data from \fIfile\fP instead of from the network. The old -f option still works but is deprecated and will probably be removed with the next version. .B \-H Print the full SSL packet header. .TP -.B \-k +.BI "\-k " keyfile Use \fIkeyfile\fP as the location of the SSL keyfile (OpenSSL format) Previous versions of ssldump automatically looked in ./server.pem. Now you must specify your keyfile every time. @@ -167,9 +171,14 @@ Don't try to resolve host names from IP Attempt to parse ASN.1 when it appears, such as in certificates and DNs. .TP -.B \-p +.BI "\-p " password Use \fIpassword\fP as the SSL keyfile password. .TP +.BI "\-s " session_cache +Use the \fIsession_cache\fP directory as a session cache, allowing decoding +of resumed sessions provided the start of the session was priorly decoded +by ssldump +.TP .B \-P Don't put the interface into promiscuous mode. .TP @@ -509,8 +518,3 @@ Support is provided for only for Etherne because that's all that I have. If you have another kind of network you will need to modify pcap_cb in base/pcap-snoop.c. If you have direct experience with ssldump on other networks, please send me patches. -.LP -ssldump doesn't implement session caching and therefore can't decrypt -resumed sessions. - - Index: base/network.c =================================================================== RCS file: /cvsroot/ssldump/ssldump/base/network.c,v retrieving revision 1.2 diff -u -p -r1.2 network.c --- base/network.c 2 Jan 2003 18:44:38 -0000 1.2 +++ base/network.c 5 Jun 2010 17:47:40 -0000 @@ -105,8 +105,8 @@ int network_handler_destroy(handlerp) int network_process_packet(handler,timestamp,data,length) n_handler *handler; - struct timeval *timestamp; - UCHAR *data; + const struct timeval *timestamp; + const UCHAR *data; int length; { int r; @@ -117,7 +117,7 @@ int network_process_packet(handler,times /*We can pretty much ignore all the options*/ memcpy(&p.ts,timestamp,sizeof(struct timeval)); - p.base=data; + p.base=(UCHAR *)data; p._len=length; p.data=data; p.len=length; Index: base/network.h =================================================================== RCS file: /cvsroot/ssldump/ssldump/base/network.h,v retrieving revision 1.2 diff -u -p -r1.2 network.h --- base/network.h 2 Jan 2003 18:44:41 -0000 1.2 +++ base/network.h 5 Jun 2010 17:47:40 -0000 @@ -87,7 +87,7 @@ int network_handler_create PROTO_LIST((p n_handler **handlerp)); int network_handler_destroy PROTO_LIST((n_handler **handlerp)); int network_process_packet PROTO_LIST((n_handler *handler, - struct timeval *timestamp,UCHAR *data,int length)); + const struct timeval *timestamp,const UCHAR *data,int length)); int packet_copy PROTO_LIST((packet *in,packet **out)); int packet_destroy PROTO_LIST((packet *p)); int timestamp_diff PROTO_LIST(( struct timeval *t1,struct timeval *t0, @@ -99,7 +99,7 @@ struct packet_ { struct timeval ts; UCHAR *base; /*The base of the packet*/ int _len; - UCHAR *data; /*The data ptr appropriate to this layer*/ + const UCHAR *data; /*The data ptr appropriate to this layer*/ int len; /*The length of the data segment*/ /*These just save us the effort of doing casts to the data Index: base/pcap-snoop.c =================================================================== RCS file: /cvsroot/ssldump/ssldump/base/pcap-snoop.c,v retrieving revision 1.3 diff -u -p -r1.3 pcap-snoop.c --- base/pcap-snoop.c 29 Mar 2005 17:53:05 -0000 1.3 +++ base/pcap-snoop.c 5 Jun 2010 17:47:40 -0000 @@ -52,7 +52,11 @@ static char *RCSSTRING="$Id: pcap-snoop. #ifdef HAVE_STDINT_H #include #endif +#ifdef HAVE_PCAP_BPF_H +#include +#else #include +#endif #ifndef _WIN32 #include #endif @@ -76,6 +80,9 @@ static char *RCSSTRING="$Id: pcap-snoop. #ifdef ENABLE_RECORD #include "record_analyze.h" #endif +#ifdef DLT_LINUX_SLL +#include "pcap/sll.h" +#endif #ifndef ETHERTYPE_8021Q # define ETHERTYPE_8021Q 0x8100 @@ -90,8 +97,8 @@ static int pcap_if_type=DLT_NULL; int err_exit PROTO_LIST((char *str,int num)); int usage PROTO_LIST((void)); int print_version PROTO_LIST((void)); -RETSIGTYPE sig_handler PROTO_LIST((void)); -void pcap_cb PROTO_LIST((u_char *ptr,struct pcap_pkthdr *hdr,u_char *data)); +RETSIGTYPE sig_handler PROTO_LIST((int)); +void pcap_cb PROTO_LIST((u_char *ptr,const struct pcap_pkthdr *hdr,const u_char *data)); int main PROTO_LIST((int argc,char **argv)); int err_exit(str,num) @@ -105,7 +112,7 @@ int err_exit(str,num) int usage() { fprintf(stderr,"Usage: ssldump [-r dumpfile] [-i interface] \n"); - fprintf(stderr," [-k keyfile] [-p password] [-vtaTnsAxVNde]\n"); + fprintf(stderr," [-k keyfile] [-p password] [-s session_cache] [-vtaTnsAxVNde]\n"); fprintf(stderr," [filter]\n"); exit(0); } @@ -121,7 +128,8 @@ int print_version() exit(0); } -RETSIGTYPE sig_handler() +RETSIGTYPE sig_handler(sig) + int sig; { fflush(stdout); exit(0); @@ -129,8 +137,8 @@ RETSIGTYPE sig_handler() void pcap_cb(ptr,hdr,data) u_char *ptr; - struct pcap_pkthdr *hdr; - u_char *data; + const struct pcap_pkthdr *hdr; + const u_char *data; { n_handler *n; int len; @@ -146,6 +154,7 @@ void pcap_cb(ptr,hdr,data) case DLT_NULL: data+=4; len-=4; + type=ETHERTYPE_IP; break; case DLT_EN10MB: type=ntohs(e_hdr->ether_type); @@ -153,23 +162,33 @@ void pcap_cb(ptr,hdr,data) data+=sizeof(struct ether_header); len-=sizeof(struct ether_header); - /* if vlans, push past VLAN header (4 bytes) */ - if(type==ETHERTYPE_8021Q) { - type=ntohs(*(uint16_t *)(data + 2)); + break; +#ifdef DLT_LINUX_SLL + case DLT_LINUX_SLL: + { + struct sll_header *sll = (struct sll_header *)data; + type = ntohs(sll->sll_protocol); + data+=SLL_HDR_LEN; + len-=SLL_HDR_LEN; + } + break; +#endif + } + /* if vlans, push past VLAN header (4 bytes) */ + if(type==ETHERTYPE_8021Q) { + type=ntohs(*(uint16_t *)(data + 2)); - data+=4; - len+=4; - } + data+=4; + len+=4; + } #ifndef SSLDUMP_USE_INET6 - if(type!=ETHERTYPE_IP) + if(type!=ETHERTYPE_IP) #else - if((type!=ETHERTYPE_IP) && (type!=ETHERTYPE_IPV6)) + if((type!=ETHERTYPE_IP) && (type!=ETHERTYPE_IPV6)) #endif - return; + return; - break; - } network_process_packet(n,&hdr->ts,data,len); } @@ -217,7 +236,7 @@ int main(argc,argv) signal(SIGINT,sig_handler); - while((c=getopt(argc,argv,"vr:f:S:Ttai:k:p:nsAxXhHVNdqem:P"))!=EOF){ + while((c=getopt(argc,argv,"vr:f:S:Ttai:k:p:ns:AxXhHVNdqem:P"))!=EOF){ switch(c){ case 'v': print_version(); @@ -250,6 +269,9 @@ int main(argc,argv) case 'p': SSL_password=strdup(optarg); break; + case 's': + SSL_session_cache = strdup(optarg); + break; case 'P': ++no_promiscuous; break; @@ -297,7 +319,7 @@ int main(argc,argv) err_exit("Aborting",-1); } } - if(!(p=pcap_open_live(interface_name,5000,!no_promiscuous,1000,errbuf))){ + if(!(p=pcap_open_live(interface_name,65000,!no_promiscuous,1000,errbuf))){ fprintf(stderr,"PCAP: %s\n",errbuf); err_exit("Aborting",-1); } Index: common/lib/r_assoc.c =================================================================== RCS file: /cvsroot/ssldump/ssldump/common/lib/r_assoc.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 r_assoc.c --- common/lib/r_assoc.c 14 Dec 2002 02:08:09 -0000 1.1.1.1 +++ common/lib/r_assoc.c 5 Jun 2010 17:47:40 -0000 @@ -56,6 +56,7 @@ static char *RCSSTRING="$Id: r_assoc.c,v 1.1.1.1 2002/12/14 02:08:09 rescorla Exp $"; +#include #include #include "r_assoc.h" Index: common/lib/r_bitfield.c =================================================================== RCS file: /cvsroot/ssldump/ssldump/common/lib/r_bitfield.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 r_bitfield.c --- common/lib/r_bitfield.c 14 Dec 2002 02:08:10 -0000 1.1.1.1 +++ common/lib/r_bitfield.c 5 Jun 2010 17:47:40 -0000 @@ -10,6 +10,7 @@ static char *RCSSTRING="$Id: r_bitfield.c,v 1.1.1.1 2002/12/14 02:08:10 rescorla Exp $"; +#include #include #include "r_bitfield.h" Index: common/lib/r_data.c =================================================================== RCS file: /cvsroot/ssldump/ssldump/common/lib/r_data.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 r_data.c --- common/lib/r_data.c 14 Dec 2002 02:08:09 -0000 1.1.1.1 +++ common/lib/r_data.c 5 Jun 2010 17:47:40 -0000 @@ -46,6 +46,7 @@ static char *RCSSTRING="$Id: r_data.c,v 1.1.1.1 2002/12/14 02:08:09 rescorla Exp $"; +#include #include #include Index: ssl/ssl_analyze.h =================================================================== RCS file: /cvsroot/ssldump/ssldump/ssl/ssl_analyze.h,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 ssl_analyze.h --- ssl/ssl_analyze.h 14 Dec 2002 02:07:56 -0000 1.1.1.1 +++ ssl/ssl_analyze.h 5 Jun 2010 17:47:40 -0000 @@ -82,6 +82,7 @@ extern proto_mod ssl_mod; extern UINT4 SSL_print_flags; extern char *SSL_keyfile; extern char *SSL_password; +extern char *SSL_session_cache; #endif Index: ssl/ssldecode.c =================================================================== RCS file: /cvsroot/ssldump/ssldump/ssl/ssldecode.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 ssldecode.c --- ssl/ssldecode.c 14 Dec 2002 02:08:00 -0000 1.1.1.1 +++ ssl/ssldecode.c 5 Jun 2010 17:47:40 -0000 @@ -49,6 +49,7 @@ #include "ssl.enums.h" #ifdef OPENSSL #include +#include #include #include #include @@ -56,6 +57,8 @@ #include "ssldecode.h" #include "ssl_rec.h" #include "r_assoc.h" +#include + static char *RCSSTRING="$Id: ssldecode.c,v 1.1.1.1 2002/12/14 02:08:00 rescorla Exp $"; #define PRF(ssl,secret,usage,rnd1,rnd2,out) (ssl->version==SSLV3_VERSION)? \ @@ -65,6 +68,8 @@ static char *RCSSTRING="$Id: ssldecode.c static char *ssl_password; +char *SSL_session_cache = NULL; + extern UINT4 SSL_print_flags; struct ssl_decode_ctx_ { @@ -131,7 +136,8 @@ int ssl_decode_ctx_create(dp,keyfile,pas ssl_decode_ctx *d=0; int r,_status; - SSLeay_add_all_algorithms(); + SSL_load_error_strings(); + SSL_library_init(); if(!(d=(ssl_decode_ctx *)malloc(sizeof(ssl_decode_ctx)))) ABORT(R_NO_MEMORY); if(!(d->ssl_ctx=SSL_CTX_new(SSLv23_server_method()))) @@ -404,6 +410,35 @@ static int ssl_create_session_lookup_key return(_status); } +static int ssl_create_session_lookup_key_ascii(ssl,id,idlen,keyp) + ssl_obj *ssl; + UCHAR *id; + UINT4 idlen; + UCHAR **keyp; + { + UCHAR *key=0; + UINT4 l; + int r,_status; + + l=strlen(SSL_session_cache) + 1 + strlen(ssl->server_name)+1+5+1+idlen*2+1; /* HOST + PORT + id */ + + if(!(key=(UCHAR *)malloc(l))) + ABORT(R_NO_MEMORY); + *keyp=key; + + sprintf(key,"%s/%s:%d:",SSL_session_cache, ssl->server_name,ssl->server_port); + key+=strlen(key); + + for (r = 0; r < idlen; r++) { + sprintf(key, "%02X", id[r]); + key+=2; + } + + _status=0; + abort: + return(_status); + } + /* Look up the session id in the session cache and generate the appropriate keying material */ int ssl_restore_session(ssl,d) @@ -412,17 +447,44 @@ int ssl_restore_session(ssl,d) { UCHAR *lookup_key=0; void *msv; - Data *msd; + Data *msd = 0; int lookup_key_len; - int r,_status; + int r, r2,_status; + FILE *in = 0; + char *buf = 0; + int len; #ifdef OPENSSL if(r=ssl_create_session_lookup_key(ssl, d->session_id->data,d->session_id->len,&lookup_key, &lookup_key_len)) ABORT(r); if(r=r_assoc_fetch(d->ctx->session_cache,lookup_key,lookup_key_len, - &msv)) - ABORT(r); + &msv)) { + if (!SSL_session_cache) + ABORT(r); + FREE(lookup_key); + if(r2=ssl_create_session_lookup_key_ascii(ssl,d->session_id->data, + d->session_id->len,&lookup_key)) + ABORT(r2); + in = fopen(lookup_key, "rb"); + if (!in) + ABORT(r); + buf = malloc(8192); + if (!buf) + ABORT(R_NO_MEMORY); + len = fread(buf, 1, 8192, in); + if (len <= 0) + ABORT(r); + if(r=r_data_create(&msd,buf,len)) + ABORT(r); + if(r=r_assoc_insert(d->ctx->session_cache,lookup_key,lookup_key_len, + (void *)msd,0,(int (*)(void *))r_data_zfree, + R_ASSOC_NEW | R_ASSOC_REPLACE)) + ABORT(r); + if(r=r_assoc_fetch(d->ctx->session_cache,lookup_key,lookup_key_len, + &msv)) + ABORT(r); + } msd=(Data *)msv; if(r=r_data_create(&d->MS,msd->data,msd->len)) ABORT(r); @@ -444,6 +506,9 @@ int ssl_restore_session(ssl,d) _status=0; abort: FREE(lookup_key); + FREE(buf); + if (in) + fclose(in); return(_status); #else return(0); @@ -462,6 +527,7 @@ int ssl_save_session(ssl,d) Data *msd=0; int lookup_key_len; int r,_status; + FILE *out; if(r=ssl_create_session_lookup_key(ssl,d->session_id->data, d->session_id->len,&lookup_key, @@ -473,7 +539,15 @@ int ssl_save_session(ssl,d) (void *)msd,0,(int (*)(void *))r_data_zfree, R_ASSOC_NEW | R_ASSOC_REPLACE)) ABORT(r); - + if (SSL_session_cache) { + FREE(lookup_key); + if(r=ssl_create_session_lookup_key_ascii(ssl,d->session_id->data, + d->session_id->len,&lookup_key)) + ABORT(r); + out = fopen(lookup_key, "wb"); + fwrite(msd->data, msd->len, 1, out); + fclose(out); + } _status=0; abort: if(_status){ Index: ssl/ssldecode.h =================================================================== RCS file: /cvsroot/ssldump/ssldump/ssl/ssldecode.h,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 ssldecode.h --- ssl/ssldecode.h 14 Dec 2002 02:08:00 -0000 1.1.1.1 +++ ssl/ssldecode.h 5 Jun 2010 17:47:40 -0000 @@ -70,6 +70,7 @@ int ssl_process_change_cipher_spec PROTO int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction, int ct,int version,Data *d)); +extern char *SSL_session_cache; #endif