1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ssl/ssltrace.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,243 @@ 1.4 +/* 1.5 + * Functions to trace SSL protocol behavior in DEBUG builds. 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 +#include <stdarg.h> 1.11 +#include "cert.h" 1.12 +#include "ssl.h" 1.13 +#include "sslimpl.h" 1.14 +#include "sslproto.h" 1.15 +#include "prprf.h" 1.16 + 1.17 +#if defined(DEBUG) || defined(TRACE) 1.18 +static const char *hex = "0123456789abcdef"; 1.19 + 1.20 +static const char printable[257] = { 1.21 + "................" /* 0x */ 1.22 + "................" /* 1x */ 1.23 + " !\"#$%&'()*+,-./" /* 2x */ 1.24 + "0123456789:;<=>?" /* 3x */ 1.25 + "@ABCDEFGHIJKLMNO" /* 4x */ 1.26 + "PQRSTUVWXYZ[\\]^_" /* 5x */ 1.27 + "`abcdefghijklmno" /* 6x */ 1.28 + "pqrstuvwxyz{|}~." /* 7x */ 1.29 + "................" /* 8x */ 1.30 + "................" /* 9x */ 1.31 + "................" /* ax */ 1.32 + "................" /* bx */ 1.33 + "................" /* cx */ 1.34 + "................" /* dx */ 1.35 + "................" /* ex */ 1.36 + "................" /* fx */ 1.37 +}; 1.38 + 1.39 +void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len) 1.40 +{ 1.41 + const unsigned char *cp = (const unsigned char *)vp; 1.42 + char buf[80]; 1.43 + char *bp; 1.44 + char *ap; 1.45 + 1.46 + if (ss) { 1.47 + SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd, 1.48 + msg, len)); 1.49 + } else { 1.50 + SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len)); 1.51 + } 1.52 + memset(buf, ' ', sizeof buf); 1.53 + bp = buf; 1.54 + ap = buf + 50; 1.55 + while (--len >= 0) { 1.56 + unsigned char ch = *cp++; 1.57 + *bp++ = hex[(ch >> 4) & 0xf]; 1.58 + *bp++ = hex[ch & 0xf]; 1.59 + *bp++ = ' '; 1.60 + *ap++ = printable[ch]; 1.61 + if (ap - buf >= 66) { 1.62 + *ap = 0; 1.63 + SSL_TRACE((" %s", buf)); 1.64 + memset(buf, ' ', sizeof buf); 1.65 + bp = buf; 1.66 + ap = buf + 50; 1.67 + } 1.68 + } 1.69 + if (bp > buf) { 1.70 + *ap = 0; 1.71 + SSL_TRACE((" %s", buf)); 1.72 + } 1.73 +} 1.74 + 1.75 +#define LEN(cp) (((cp)[0] << 8) | ((cp)[1])) 1.76 + 1.77 +static void PrintType(sslSocket *ss, char *msg) 1.78 +{ 1.79 + if (ss) { 1.80 + SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd, 1.81 + msg)); 1.82 + } else { 1.83 + SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg)); 1.84 + } 1.85 +} 1.86 + 1.87 +static void PrintInt(sslSocket *ss, char *msg, unsigned v) 1.88 +{ 1.89 + if (ss) { 1.90 + SSL_TRACE(("%d: SSL[%d]: %s=%u", SSL_GETPID(), ss->fd, 1.91 + msg, v)); 1.92 + } else { 1.93 + SSL_TRACE(("%d: SSL: %s=%u", SSL_GETPID(), msg, v)); 1.94 + } 1.95 +} 1.96 + 1.97 +/* PrintBuf is just like ssl_PrintBuf above, except that: 1.98 + * a) It prefixes each line of the buffer with "XX: SSL[xxx] " 1.99 + * b) It dumps only hex, not ASCII. 1.100 + */ 1.101 +static void PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len) 1.102 +{ 1.103 + char buf[80]; 1.104 + char *bp; 1.105 + 1.106 + if (ss) { 1.107 + SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", 1.108 + SSL_GETPID(), ss->fd, msg, len)); 1.109 + } else { 1.110 + SSL_TRACE(("%d: SSL: %s [Len: %d]", 1.111 + SSL_GETPID(), msg, len)); 1.112 + } 1.113 + bp = buf; 1.114 + while (--len >= 0) { 1.115 + unsigned char ch = *cp++; 1.116 + *bp++ = hex[(ch >> 4) & 0xf]; 1.117 + *bp++ = hex[ch & 0xf]; 1.118 + *bp++ = ' '; 1.119 + if (bp + 4 > buf + 50) { 1.120 + *bp = 0; 1.121 + if (ss) { 1.122 + SSL_TRACE(("%d: SSL[%d]: %s", 1.123 + SSL_GETPID(), ss->fd, buf)); 1.124 + } else { 1.125 + SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf)); 1.126 + } 1.127 + bp = buf; 1.128 + } 1.129 + } 1.130 + if (bp > buf) { 1.131 + *bp = 0; 1.132 + if (ss) { 1.133 + SSL_TRACE(("%d: SSL[%d]: %s", 1.134 + SSL_GETPID(), ss->fd, buf)); 1.135 + } else { 1.136 + SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf)); 1.137 + } 1.138 + } 1.139 +} 1.140 + 1.141 +void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len) 1.142 +{ 1.143 + switch (bp[0]) { 1.144 + case SSL_MT_ERROR: 1.145 + PrintType(ss, "Error"); 1.146 + PrintInt(ss, "error", LEN(bp+1)); 1.147 + break; 1.148 + 1.149 + case SSL_MT_CLIENT_HELLO: 1.150 + { 1.151 + unsigned lcs = LEN(bp+3); 1.152 + unsigned ls = LEN(bp+5); 1.153 + unsigned lc = LEN(bp+7); 1.154 + 1.155 + PrintType(ss, "Client-Hello"); 1.156 + 1.157 + PrintInt(ss, "version (Major)", bp[1]); 1.158 + PrintInt(ss, "version (minor)", bp[2]); 1.159 + 1.160 + PrintBuf(ss, "cipher-specs", bp+9, lcs); 1.161 + PrintBuf(ss, "session-id", bp+9+lcs, ls); 1.162 + PrintBuf(ss, "challenge", bp+9+lcs+ls, lc); 1.163 + } 1.164 + break; 1.165 + case SSL_MT_CLIENT_MASTER_KEY: 1.166 + { 1.167 + unsigned lck = LEN(bp+4); 1.168 + unsigned lek = LEN(bp+6); 1.169 + unsigned lka = LEN(bp+8); 1.170 + 1.171 + PrintType(ss, "Client-Master-Key"); 1.172 + 1.173 + PrintInt(ss, "cipher-choice", bp[1]); 1.174 + PrintInt(ss, "key-length", LEN(bp+2)); 1.175 + 1.176 + PrintBuf(ss, "clear-key", bp+10, lck); 1.177 + PrintBuf(ss, "encrypted-key", bp+10+lck, lek); 1.178 + PrintBuf(ss, "key-arg", bp+10+lck+lek, lka); 1.179 + } 1.180 + break; 1.181 + case SSL_MT_CLIENT_FINISHED: 1.182 + PrintType(ss, "Client-Finished"); 1.183 + PrintBuf(ss, "connection-id", bp+1, len-1); 1.184 + break; 1.185 + case SSL_MT_SERVER_HELLO: 1.186 + { 1.187 + unsigned lc = LEN(bp+5); 1.188 + unsigned lcs = LEN(bp+7); 1.189 + unsigned lci = LEN(bp+9); 1.190 + 1.191 + PrintType(ss, "Server-Hello"); 1.192 + 1.193 + PrintInt(ss, "session-id-hit", bp[1]); 1.194 + PrintInt(ss, "certificate-type", bp[2]); 1.195 + PrintInt(ss, "version (Major)", bp[3]); 1.196 + PrintInt(ss, "version (minor)", bp[3]); 1.197 + PrintBuf(ss, "certificate", bp+11, lc); 1.198 + PrintBuf(ss, "cipher-specs", bp+11+lc, lcs); 1.199 + PrintBuf(ss, "connection-id", bp+11+lc+lcs, lci); 1.200 + } 1.201 + break; 1.202 + case SSL_MT_SERVER_VERIFY: 1.203 + PrintType(ss, "Server-Verify"); 1.204 + PrintBuf(ss, "challenge", bp+1, len-1); 1.205 + break; 1.206 + case SSL_MT_SERVER_FINISHED: 1.207 + PrintType(ss, "Server-Finished"); 1.208 + PrintBuf(ss, "session-id", bp+1, len-1); 1.209 + break; 1.210 + case SSL_MT_REQUEST_CERTIFICATE: 1.211 + PrintType(ss, "Request-Certificate"); 1.212 + PrintInt(ss, "authentication-type", bp[1]); 1.213 + PrintBuf(ss, "certificate-challenge", bp+2, len-2); 1.214 + break; 1.215 + case SSL_MT_CLIENT_CERTIFICATE: 1.216 + { 1.217 + unsigned lc = LEN(bp+2); 1.218 + unsigned lr = LEN(bp+4); 1.219 + PrintType(ss, "Client-Certificate"); 1.220 + PrintInt(ss, "certificate-type", bp[1]); 1.221 + PrintBuf(ss, "certificate", bp+6, lc); 1.222 + PrintBuf(ss, "response", bp+6+lc, lr); 1.223 + } 1.224 + break; 1.225 + default: 1.226 + ssl_PrintBuf(ss, "sending *unknown* message type", bp, len); 1.227 + return; 1.228 + } 1.229 +} 1.230 + 1.231 +void 1.232 +ssl_Trace(const char *format, ... ) 1.233 +{ 1.234 + char buf[2000]; 1.235 + va_list args; 1.236 + 1.237 + if (ssl_trace_iob) { 1.238 + va_start(args, format); 1.239 + PR_vsnprintf(buf, sizeof(buf), format, args); 1.240 + va_end(args); 1.241 + 1.242 + fputs(buf, ssl_trace_iob); 1.243 + fputs("\n", ssl_trace_iob); 1.244 + } 1.245 +} 1.246 +#endif