Dear all, please find attached a small patch for the sess_id application. It adds an option -keylog. When this option is set, the session id and the corresponding master key are output in NSS keylog format. Such an output can be used e.g. by wireshark to decrypt captured ssl data.
I'd be happy if it was possible to merge this into OpenSSL. Of course, I'd appreciate any comments / feedback. Best regards, Martin
>From 4fa09c73c332f669daf3c199b3edbbfd238b32b0 Mon Sep 17 00:00:00 2001 From: Martin Kaiser <[email protected]> Date: Tue, 11 Mar 2014 11:55:17 +0100 Subject: [PATCH] add -keylog option to sess_id to export session id and master key in NSS keylog format --- CHANGES | 4 ++++ apps/sess_id.c | 12 ++++++++++-- doc/apps/sess_id.pod | 5 +++++ ssl/ssl.h | 1 + ssl/ssl_txt.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index d5142be..8920d70 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Changes between 1.0.2 and 1.1.0 [xx XXX xxxx] + *) New -keylog option in the sess_id command line tool. This allows exporting the + session id and the master key in NSS keylog format. + [Martin Kaiser <[email protected]>] + *) Harmonize version and its documentation. -f flag is used to display compilation flags. [mancha <[email protected]>] diff --git a/apps/sess_id.c b/apps/sess_id.c index b16686c..294aa95 100644 --- a/apps/sess_id.c +++ b/apps/sess_id.c @@ -77,6 +77,7 @@ static const char *sess_id_usage[]={ " -in arg - input file - default stdin\n", " -out arg - output file - default stdout\n", " -text - print ssl session id details\n", +" -keylog - print session session id and master key in NSS keylog format\n", " -cert - output certificate \n", " -noout - no CRL output\n", " -context arg - set the session ID context\n", @@ -95,7 +96,7 @@ int MAIN(int argc, char **argv) BIO *out=NULL; int informat,outformat; char *infile=NULL,*outfile=NULL,*context=NULL; - int cert=0,noout=0,text=0; + int cert=0,noout=0,text=0, keylog=0; const char **pp; apps_startup(); @@ -134,6 +135,8 @@ int MAIN(int argc, char **argv) } else if (strcmp(*argv,"-text") == 0) text= ++num; + else if (strcmp(*argv,"-keylog") == 0) + keylog= ++num; else if (strcmp(*argv,"-cert") == 0) cert= ++num; else if (strcmp(*argv,"-noout") == 0) @@ -198,7 +201,7 @@ bad: } #endif - if (!noout || text) + if (!noout || text || keylog) { out=BIO_new(BIO_s_file()); if (out == NULL) @@ -240,6 +243,11 @@ bad: } } + if (keylog) + { + SSL_SESSION_print_keylog(out,x); + } + if (!noout && !cert) { if (outformat == FORMAT_ASN1) diff --git a/doc/apps/sess_id.pod b/doc/apps/sess_id.pod index 9988d2c..546f472 100644 --- a/doc/apps/sess_id.pod +++ b/doc/apps/sess_id.pod @@ -14,6 +14,7 @@ B<openssl> B<sess_id> [B<-out filename>] [B<-text>] [B<-noout>] +[B<-keylog>] [B<-context ID>] =head1 DESCRIPTION @@ -62,6 +63,10 @@ if the B<-text> option is also present then it will be printed out in text form. this option prevents output of the encoded version of the session. +=item B<-keylog> + +print session session id and master key in NSS keylog format. + =item B<-context ID> this option can set the session id so the output session information uses the diff --git a/ssl/ssl.h b/ssl/ssl.h index 92ffae9..7d0c7bb 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -2235,6 +2235,7 @@ int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses); #endif #ifndef OPENSSL_NO_BIO int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses); +int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x); #endif void SSL_SESSION_free(SSL_SESSION *ses); int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c index 20b95a2..0ffdcb0 100644 --- a/ssl/ssl_txt.c +++ b/ssl/ssl_txt.c @@ -248,3 +248,33 @@ err: return(0); } +/* print session id and master key in NSS keylog format + (RSA Session-ID:<session id> Master-Key:<master key>) */ +int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x) + { + unsigned int i; + + if (x == NULL) goto err; + if (x->session_id_length==0 || x->master_key_length==0) goto err; + + /* the RSA prefix is required by the format's definition although there's + nothing RSA-specifc in the output, therefore, we don't have to check + if the cipher suite is based on RSA */ + if (BIO_puts(bp,"RSA ") <= 0) goto err; + + if (BIO_puts(bp,"Session-ID:") <= 0) goto err; + for (i=0; i<x->session_id_length; i++) + { + if (BIO_printf(bp,"%02X",x->session_id[i]) <= 0) goto err; + } + if (BIO_puts(bp," Master-Key:") <= 0) goto err; + for (i=0; i<(unsigned int)x->master_key_length; i++) + { + if (BIO_printf(bp,"%02X",x->master_key[i]) <= 0) goto err; + } + if (BIO_puts(bp,"\n") <= 0) goto err; + + return(1); +err: + return(0); + } -- 1.7.6.5
