2 * Functions to trace SSL protocol behavior in DEBUG builds.
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 /* $Id: ssltrace.c,v 1.5 2012/04/25 14:50:12 gerv%gerv.net Exp $ */
15 #if defined(DEBUG) || defined(TRACE)
16 static const char *hex
= "0123456789abcdef";
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 */
37 void ssl_PrintBuf(sslSocket
*ss
, const char *msg
, const void *vp
, int len
)
39 const unsigned char *cp
= (const unsigned char *)vp
;
45 SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss
->fd
,
48 SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg
, len
));
50 memset(buf
, ' ', sizeof buf
);
54 unsigned char ch
= *cp
++;
55 *bp
++ = hex
[(ch
>> 4) & 0xf];
56 *bp
++ = hex
[ch
& 0xf];
58 *ap
++ = printable
[ch
];
61 SSL_TRACE((" %s", buf
));
62 memset(buf
, ' ', sizeof buf
);
69 SSL_TRACE((" %s", buf
));
73 #define LEN(cp) (((cp)[0] << 8) | ((cp)[1]))
75 static void PrintType(sslSocket
*ss
, char *msg
)
78 SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss
->fd
,
81 SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg
));
85 static void PrintInt(sslSocket
*ss
, char *msg
, unsigned v
)
88 SSL_TRACE(("%d: SSL[%d]: %s=%u", SSL_GETPID(), ss
->fd
,
91 SSL_TRACE(("%d: SSL: %s=%u", SSL_GETPID(), msg
, v
));
95 /* PrintBuf is just like ssl_PrintBuf above, except that:
96 * a) It prefixes each line of the buffer with "XX: SSL[xxx] "
97 * b) It dumps only hex, not ASCII.
99 static void PrintBuf(sslSocket
*ss
, char *msg
, unsigned char *cp
, int len
)
105 SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]",
106 SSL_GETPID(), ss
->fd
, msg
, len
));
108 SSL_TRACE(("%d: SSL: %s [Len: %d]",
109 SSL_GETPID(), msg
, len
));
113 unsigned char ch
= *cp
++;
114 *bp
++ = hex
[(ch
>> 4) & 0xf];
115 *bp
++ = hex
[ch
& 0xf];
117 if (bp
+ 4 > buf
+ 50) {
120 SSL_TRACE(("%d: SSL[%d]: %s",
121 SSL_GETPID(), ss
->fd
, buf
));
123 SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf
));
131 SSL_TRACE(("%d: SSL[%d]: %s",
132 SSL_GETPID(), ss
->fd
, buf
));
134 SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf
));
139 void ssl_DumpMsg(sslSocket
*ss
, unsigned char *bp
, unsigned len
)
143 PrintType(ss
, "Error");
144 PrintInt(ss
, "error", LEN(bp
+1));
147 case SSL_MT_CLIENT_HELLO
:
149 unsigned lcs
= LEN(bp
+3);
150 unsigned ls
= LEN(bp
+5);
151 unsigned lc
= LEN(bp
+7);
153 PrintType(ss
, "Client-Hello");
155 PrintInt(ss
, "version (Major)", bp
[1]);
156 PrintInt(ss
, "version (minor)", bp
[2]);
158 PrintBuf(ss
, "cipher-specs", bp
+9, lcs
);
159 PrintBuf(ss
, "session-id", bp
+9+lcs
, ls
);
160 PrintBuf(ss
, "challenge", bp
+9+lcs
+ls
, lc
);
163 case SSL_MT_CLIENT_MASTER_KEY
:
165 unsigned lck
= LEN(bp
+4);
166 unsigned lek
= LEN(bp
+6);
167 unsigned lka
= LEN(bp
+8);
169 PrintType(ss
, "Client-Master-Key");
171 PrintInt(ss
, "cipher-choice", bp
[1]);
172 PrintInt(ss
, "key-length", LEN(bp
+2));
174 PrintBuf(ss
, "clear-key", bp
+10, lck
);
175 PrintBuf(ss
, "encrypted-key", bp
+10+lck
, lek
);
176 PrintBuf(ss
, "key-arg", bp
+10+lck
+lek
, lka
);
179 case SSL_MT_CLIENT_FINISHED
:
180 PrintType(ss
, "Client-Finished");
181 PrintBuf(ss
, "connection-id", bp
+1, len
-1);
183 case SSL_MT_SERVER_HELLO
:
185 unsigned lc
= LEN(bp
+5);
186 unsigned lcs
= LEN(bp
+7);
187 unsigned lci
= LEN(bp
+9);
189 PrintType(ss
, "Server-Hello");
191 PrintInt(ss
, "session-id-hit", bp
[1]);
192 PrintInt(ss
, "certificate-type", bp
[2]);
193 PrintInt(ss
, "version (Major)", bp
[3]);
194 PrintInt(ss
, "version (minor)", bp
[3]);
195 PrintBuf(ss
, "certificate", bp
+11, lc
);
196 PrintBuf(ss
, "cipher-specs", bp
+11+lc
, lcs
);
197 PrintBuf(ss
, "connection-id", bp
+11+lc
+lcs
, lci
);
200 case SSL_MT_SERVER_VERIFY
:
201 PrintType(ss
, "Server-Verify");
202 PrintBuf(ss
, "challenge", bp
+1, len
-1);
204 case SSL_MT_SERVER_FINISHED
:
205 PrintType(ss
, "Server-Finished");
206 PrintBuf(ss
, "session-id", bp
+1, len
-1);
208 case SSL_MT_REQUEST_CERTIFICATE
:
209 PrintType(ss
, "Request-Certificate");
210 PrintInt(ss
, "authentication-type", bp
[1]);
211 PrintBuf(ss
, "certificate-challenge", bp
+2, len
-2);
213 case SSL_MT_CLIENT_CERTIFICATE
:
215 unsigned lc
= LEN(bp
+2);
216 unsigned lr
= LEN(bp
+4);
217 PrintType(ss
, "Client-Certificate");
218 PrintInt(ss
, "certificate-type", bp
[1]);
219 PrintBuf(ss
, "certificate", bp
+6, lc
);
220 PrintBuf(ss
, "response", bp
+6+lc
, lr
);
224 ssl_PrintBuf(ss
, "sending *unknown* message type", bp
, len
);
230 ssl_Trace(const char *format
, ... )
236 va_start(args
, format
);
237 PR_vsnprintf(buf
, sizeof(buf
), format
, args
);
240 fputs(buf
, ssl_trace_iob
);
241 fputs("\n", ssl_trace_iob
);