security/nss/lib/ssl/ssltrace.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  * Functions to trace SSL protocol behavior in DEBUG builds.
     3  *
     4  * This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include <stdarg.h>
     8 #include "cert.h"
     9 #include "ssl.h"
    10 #include "sslimpl.h"
    11 #include "sslproto.h"
    12 #include "prprf.h"
    14 #if defined(DEBUG) || defined(TRACE)
    15 static const char *hex = "0123456789abcdef";
    17 static const char printable[257] = {
    18 	"................"	/* 0x */
    19 	"................"	/* 1x */
    20 	" !\"#$%&'()*+,-./"	/* 2x */
    21 	"0123456789:;<=>?"	/* 3x */
    22 	"@ABCDEFGHIJKLMNO"	/* 4x */
    23 	"PQRSTUVWXYZ[\\]^_"	/* 5x */
    24 	"`abcdefghijklmno"	/* 6x */
    25 	"pqrstuvwxyz{|}~."	/* 7x */
    26 	"................"	/* 8x */
    27 	"................"	/* 9x */
    28 	"................"	/* ax */
    29 	"................"	/* bx */
    30 	"................"	/* cx */
    31 	"................"	/* dx */
    32 	"................"	/* ex */
    33 	"................"	/* fx */
    34 };
    36 void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
    37 {
    38     const unsigned char *cp = (const unsigned char *)vp;
    39     char buf[80];
    40     char *bp;
    41     char *ap;
    43     if (ss) {
    44 	SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
    45 		   msg, len));
    46     } else {
    47 	SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
    48     }
    49     memset(buf, ' ', sizeof buf);
    50     bp = buf;
    51     ap = buf + 50;
    52     while (--len >= 0) {
    53 	unsigned char ch = *cp++;
    54 	*bp++ = hex[(ch >> 4) & 0xf];
    55 	*bp++ = hex[ch & 0xf];
    56 	*bp++ = ' ';
    57 	*ap++ = printable[ch];
    58 	if (ap - buf >= 66) {
    59 	    *ap = 0;
    60 	    SSL_TRACE(("   %s", buf));
    61 	    memset(buf, ' ', sizeof buf);
    62 	    bp = buf;
    63 	    ap = buf + 50;
    64 	}
    65     }
    66     if (bp > buf) {
    67 	*ap = 0;
    68 	SSL_TRACE(("   %s", buf));
    69     }
    70 }
    72 #define LEN(cp)		(((cp)[0] << 8) | ((cp)[1]))
    74 static void PrintType(sslSocket *ss, char *msg)
    75 {
    76     if (ss) {
    77 	SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd,
    78 		   msg));
    79     } else {
    80 	SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
    81     }
    82 }
    84 static void PrintInt(sslSocket *ss, char *msg, unsigned v)
    85 {
    86     if (ss) {
    87 	SSL_TRACE(("%d: SSL[%d]:           %s=%u", SSL_GETPID(), ss->fd,
    88 		   msg, v));
    89     } else {
    90 	SSL_TRACE(("%d: SSL:           %s=%u", SSL_GETPID(), msg, v));
    91     }
    92 }
    94 /* PrintBuf is just like ssl_PrintBuf above, except that:
    95  * a) It prefixes each line of the buffer with "XX: SSL[xxx]           "
    96  * b) It dumps only hex, not ASCII.
    97  */
    98 static void PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
    99 {
   100     char buf[80];
   101     char *bp;
   103     if (ss) {
   104 	SSL_TRACE(("%d: SSL[%d]:           %s [Len: %d]", 
   105 		   SSL_GETPID(), ss->fd, msg, len));
   106     } else {
   107 	SSL_TRACE(("%d: SSL:           %s [Len: %d]", 
   108 		   SSL_GETPID(), msg, len));
   109     }
   110     bp = buf;
   111     while (--len >= 0) {
   112 	unsigned char ch = *cp++;
   113 	*bp++ = hex[(ch >> 4) & 0xf];
   114 	*bp++ = hex[ch & 0xf];
   115 	*bp++ = ' ';
   116 	if (bp + 4 > buf + 50) {
   117 	    *bp = 0;
   118 	    if (ss) {
   119 		SSL_TRACE(("%d: SSL[%d]:             %s",
   120 			   SSL_GETPID(), ss->fd, buf));
   121 	    } else {
   122 		SSL_TRACE(("%d: SSL:             %s", SSL_GETPID(), buf));
   123 	    }
   124 	    bp = buf;
   125 	}
   126     }
   127     if (bp > buf) {
   128 	*bp = 0;
   129 	if (ss) {
   130 	    SSL_TRACE(("%d: SSL[%d]:             %s",
   131 		       SSL_GETPID(), ss->fd, buf));
   132 	} else {
   133 	    SSL_TRACE(("%d: SSL:             %s", SSL_GETPID(), buf));
   134 	}
   135     }
   136 }
   138 void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
   139 {
   140     switch (bp[0]) {
   141       case SSL_MT_ERROR:
   142 	PrintType(ss, "Error");
   143 	PrintInt(ss, "error", LEN(bp+1));
   144 	break;
   146       case SSL_MT_CLIENT_HELLO:
   147 	{
   148 	    unsigned lcs = LEN(bp+3);
   149 	    unsigned ls  = LEN(bp+5);
   150 	    unsigned lc  = LEN(bp+7);
   152 	    PrintType(ss, "Client-Hello");
   154 	    PrintInt(ss, "version (Major)",                   bp[1]);
   155 	    PrintInt(ss, "version (minor)",                   bp[2]);
   157 	    PrintBuf(ss, "cipher-specs",         bp+9,        lcs);
   158 	    PrintBuf(ss, "session-id",           bp+9+lcs,    ls);
   159 	    PrintBuf(ss, "challenge",            bp+9+lcs+ls, lc);
   160 	}
   161 	break;
   162       case SSL_MT_CLIENT_MASTER_KEY:
   163 	{
   164 	    unsigned lck = LEN(bp+4);
   165 	    unsigned lek = LEN(bp+6);
   166 	    unsigned lka = LEN(bp+8);
   168 	    PrintType(ss, "Client-Master-Key");
   170 	    PrintInt(ss, "cipher-choice",                       bp[1]);
   171 	    PrintInt(ss, "key-length",                          LEN(bp+2));
   173 	    PrintBuf(ss, "clear-key",            bp+10,         lck);
   174 	    PrintBuf(ss, "encrypted-key",        bp+10+lck,     lek);
   175 	    PrintBuf(ss, "key-arg",              bp+10+lck+lek, lka);
   176 	}
   177 	break;
   178       case SSL_MT_CLIENT_FINISHED:
   179 	PrintType(ss, "Client-Finished");
   180 	PrintBuf(ss, "connection-id",            bp+1,          len-1);
   181 	break;
   182       case SSL_MT_SERVER_HELLO:
   183 	{
   184 	    unsigned lc = LEN(bp+5);
   185 	    unsigned lcs = LEN(bp+7);
   186 	    unsigned lci = LEN(bp+9);
   188 	    PrintType(ss, "Server-Hello");
   190 	    PrintInt(ss, "session-id-hit",                     bp[1]);
   191 	    PrintInt(ss, "certificate-type",                   bp[2]);
   192 	    PrintInt(ss, "version (Major)",                    bp[3]);
   193 	    PrintInt(ss, "version (minor)",                    bp[3]);
   194 	    PrintBuf(ss, "certificate",          bp+11,        lc);
   195 	    PrintBuf(ss, "cipher-specs",         bp+11+lc,     lcs);
   196 	    PrintBuf(ss, "connection-id",        bp+11+lc+lcs, lci);
   197 	}
   198 	break;
   199       case SSL_MT_SERVER_VERIFY:
   200 	PrintType(ss, "Server-Verify");
   201 	PrintBuf(ss, "challenge",                bp+1,         len-1);
   202 	break;
   203       case SSL_MT_SERVER_FINISHED:
   204 	PrintType(ss, "Server-Finished");
   205 	PrintBuf(ss, "session-id",               bp+1,         len-1);
   206 	break;
   207       case SSL_MT_REQUEST_CERTIFICATE:
   208 	PrintType(ss, "Request-Certificate");
   209 	PrintInt(ss, "authentication-type",                    bp[1]);
   210 	PrintBuf(ss, "certificate-challenge",    bp+2,         len-2);
   211 	break;
   212       case SSL_MT_CLIENT_CERTIFICATE:
   213 	{
   214 	    unsigned lc = LEN(bp+2);
   215 	    unsigned lr = LEN(bp+4);
   216 	    PrintType(ss, "Client-Certificate");
   217 	    PrintInt(ss, "certificate-type",                   bp[1]);
   218 	    PrintBuf(ss, "certificate",          bp+6,         lc);
   219 	    PrintBuf(ss, "response",             bp+6+lc,      lr);
   220 	}
   221 	break;
   222       default:
   223 	ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
   224 	return;
   225     }
   226 }
   228 void
   229 ssl_Trace(const char *format, ... )
   230 {
   231     char buf[2000]; 
   232     va_list args;
   234     if (ssl_trace_iob) {
   235 	va_start(args, format);
   236 	PR_vsnprintf(buf, sizeof(buf), format, args);
   237 	va_end(args);
   239 	fputs(buf,  ssl_trace_iob);
   240 	fputs("\n", ssl_trace_iob);
   241     }
   242 }
   243 #endif

mercurial