Hi Matt,

> With regards to the patch itself, it is the idiom of many of the OpenSSL
> command line apps to take a "-outform" argument. I think it would be more in
> keeping with the intention of that argument if the patch were modified to use
> "-outform NSS" instead of "-keylog". Could you make the appropriate amendments
> and resubmit?

here's an updated version of the patch that uses -outform NSS.

Best regards,

   Martin

>From 6abefeefd9ef3cc03d485614c975888e1bb93d38 Mon Sep 17 00:00:00 2001
From: Martin Kaiser <[email protected]>
Date: Tue, 11 Mar 2014 11:55:17 +0100
Subject: [PATCH 2/2] add an NSS output format to sess_id to export to export
 the session id and the master key in NSS keylog format

---
 CHANGES              |    4 ++++
 apps/apps.c          |    2 ++
 apps/apps.h          |    1 +
 apps/sess_id.c       |    4 +++-
 doc/apps/sess_id.pod |    9 +++++----
 ssl/ssl.h            |    1 +
 ssl/ssl_txt.c        |   30 ++++++++++++++++++++++++++++++
 7 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/CHANGES b/CHANGES
index d5142be..a55bdc9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 1.0.2 and 1.1.0  [xx XXX xxxx]
 
+  *) New output format NSS 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/apps.c b/apps/apps.c
index b82882a..9468848 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -263,6 +263,8 @@ int str2fmt(char *s)
 		return(FORMAT_ASN1);
 	else if ((*s == 'T') || (*s == 't'))
 		return(FORMAT_TEXT);
+	else if ((strcmp(s,"NSS") == 0) || (strcmp(s,"nss") == 0))
+		return(FORMAT_NSS);
   	else if ((*s == 'N') || (*s == 'n'))
   		return(FORMAT_NETSCAPE);
   	else if ((*s == 'S') || (*s == 's'))
diff --git a/apps/apps.h b/apps/apps.h
index 5f083d4..b4a9b49 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -363,6 +363,7 @@ void store_setup_crl_download(X509_STORE *st);
 #define FORMAT_MSBLOB	11	/* MS Key blob format */
 #define FORMAT_PVK	12	/* MS PVK file format */
 #define FORMAT_HTTP	13	/* Download using HTTP */
+#define FORMAT_NSS	14	/* NSS keylog format */
 
 #define EXT_COPY_NONE	0
 #define EXT_COPY_ADD	1
diff --git a/apps/sess_id.c b/apps/sess_id.c
index c5823a5..a31d227 100644
--- a/apps/sess_id.c
+++ b/apps/sess_id.c
@@ -73,7 +73,7 @@ static const char *sess_id_usage[]={
 "usage: sess_id args\n",
 "\n",
 " -inform arg     - input format - default PEM (DER or PEM)\n",
-" -outform arg    - output format - default PEM\n",
+" -outform arg    - output format - default PEM (PEM, DER or NSS)\n",
 " -in arg         - input file - default stdin\n",
 " -out arg        - output file - default stdout\n",
 " -text           - print ssl session id details\n",
@@ -246,6 +246,8 @@ bad:
 			i=i2d_SSL_SESSION_bio(out,x);
 		else if (outformat == FORMAT_PEM)
 			i=PEM_write_bio_SSL_SESSION(out,x);
+		else if (outformat == FORMAT_NSS)
+			i=SSL_SESSION_print_keylog(out,x);
 		else	{
 			BIO_printf(bio_err,"bad output format specified for outfile\n");
 			goto end;
diff --git a/doc/apps/sess_id.pod b/doc/apps/sess_id.pod
index 9988d2c..fb5ce12 100644
--- a/doc/apps/sess_id.pod
+++ b/doc/apps/sess_id.pod
@@ -9,7 +9,7 @@ sess_id - SSL/TLS session handling utility
 
 B<openssl> B<sess_id>
 [B<-inform PEM|DER>]
-[B<-outform PEM|DER>]
+[B<-outform PEM|DER|NSS>]
 [B<-in filename>]
 [B<-out filename>]
 [B<-text>]
@@ -33,10 +33,11 @@ format containing session details. The precise format can vary from one version
 to the next.  The B<PEM> form is the default format: it consists of the B<DER>
 format base64 encoded with additional header and footer lines.
 
-=item B<-outform DER|PEM>
+=item B<-outform DER|PEM|NSS>
 
-This specifies the output format, the options have the same meaning as the 
-B<-inform> option.
+This specifies the output format. The B<PEM> and B<DER> options have the same meaning
+as the B<-inform> option. The B<NSS> option outputs the session id and the master key
+in NSS keylog format.
 
 =item B<-in filename>
 
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

Reply via email to