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 "pk11func.h"
10 #include "ssl.h"
11 #include "sslimpl.h"
12 #include "sslproto.h"
13 #include "prprf.h"
14 
15 #if defined(DEBUG) || defined(TRACE)
16 static const char *hex = "0123456789abcdef";
17 
18 static const char printable[257] = {
19     "................"  /* 0x */
20     "................"  /* 1x */
21     " !\"#$%&'()*+,-./" /* 2x */
22     "0123456789:;<=>?"  /* 3x */
23     "@ABCDEFGHIJKLMNO"  /* 4x */
24     "PQRSTUVWXYZ[\\]^_" /* 5x */
25     "`abcdefghijklmno"  /* 6x */
26     "pqrstuvwxyz{|}~."  /* 7x */
27     "................"  /* 8x */
28     "................"  /* 9x */
29     "................"  /* ax */
30     "................"  /* bx */
31     "................"  /* cx */
32     "................"  /* dx */
33     "................"  /* ex */
34     "................"  /* fx */
35 };
36 
37 void
ssl_PrintBuf(const sslSocket * ss,const char * msg,const void * vp,int len)38 ssl_PrintBuf(const sslSocket *ss, const char *msg, const void *vp, int len)
39 {
40     const unsigned char *cp = (const unsigned char *)vp;
41     char buf[80];
42     char *bp;
43     char *ap;
44 
45     if (ss) {
46         SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
47                    msg, len));
48     } else {
49         SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
50     }
51 
52     if (!cp) {
53         SSL_TRACE(("   <NULL>"));
54         return;
55     }
56 
57     memset(buf, ' ', sizeof buf);
58     bp = buf;
59     ap = buf + 50;
60     while (--len >= 0) {
61         unsigned char ch = *cp++;
62         *bp++ = hex[(ch >> 4) & 0xf];
63         *bp++ = hex[ch & 0xf];
64         *bp++ = ' ';
65         *ap++ = printable[ch];
66         if (ap - buf >= 66) {
67             *ap = 0;
68             SSL_TRACE(("   %s", buf));
69             memset(buf, ' ', sizeof buf);
70             bp = buf;
71             ap = buf + 50;
72         }
73     }
74     if (bp > buf) {
75         *ap = 0;
76         SSL_TRACE(("   %s", buf));
77     }
78 }
79 
80 void
ssl_Trace(const char * format,...)81 ssl_Trace(const char *format, ...)
82 {
83     char buf[2000];
84     va_list args;
85 
86     if (ssl_trace_iob) {
87         va_start(args, format);
88         PR_vsnprintf(buf, sizeof(buf), format, args);
89         va_end(args);
90 
91         fputs(buf, ssl_trace_iob);
92         fputs("\n", ssl_trace_iob);
93     }
94 }
95 
96 void
ssl_PrintKey(const sslSocket * ss,const char * msg,PK11SymKey * key)97 ssl_PrintKey(const sslSocket *ss, const char *msg, PK11SymKey *key)
98 {
99     SECStatus rv;
100     SECItem *rawkey;
101 
102     rv = PK11_ExtractKeyValue(key);
103     if (rv != SECSuccess) {
104         ssl_Trace("Could not extract key for %s", msg);
105         return;
106     }
107     rawkey = PK11_GetKeyData(key);
108     if (!rawkey) {
109         ssl_Trace("Could not extract key for %s", msg);
110         return;
111     }
112     ssl_PrintBuf(ss, msg, rawkey->data, rawkey->len);
113 }
114 #endif
115