1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 /*
6  * ssltap.c
7  *
8  * Version 1.0 : Frederick Roeber : 11 June 1997
9  * Version 2.0 : Steve Parkinson  : 13 November 1997
10  * Version 3.0 : Nelson Bolyard   : 22 July 1998
11  * Version 3.1 : Nelson Bolyard   : 24 May  1999
12  *
13  * changes in version 2.0:
14  *  Uses NSPR20
15  *  Shows structure of SSL negotiation, if enabled.
16  *
17  * This "proxies" a socket connection (like a socks tunnel), but displays the
18  * data is it flies by.
19  *
20  * In the code, the 'client' socket is the one on the client side of the
21  * proxy, and the server socket is on the server side.
22  *
23  */
24 
25 #include "nspr.h"
26 #include "plstr.h"
27 #include "secutil.h"
28 #include <memory.h> /* for memcpy, etc. */
29 #include <string.h>
30 #include <time.h>
31 
32 #include "plgetopt.h"
33 #include "nss.h"
34 #include "cert.h"
35 #include "sslproto.h"
36 #include "ocsp.h"
37 #include "ocspti.h" /* internals for pretty-printing routines *only* */
38 
39 struct _DataBufferList;
40 struct _DataBuffer;
41 
42 typedef struct _DataBufferList {
43     struct _DataBuffer *first, *last;
44     unsigned int size;
45     int isEncrypted;
46     unsigned char *msgBuf;
47     unsigned int msgBufOffset;
48     unsigned int msgBufSize;
49     unsigned int hMACsize;
50 } DataBufferList;
51 
52 typedef struct _DataBuffer {
53     unsigned char *buffer;
54     int length;
55     int offset; /* offset of first good byte */
56     struct _DataBuffer *next;
57 } DataBuffer;
58 
59 struct sslhandshake {
60     PRUint8 type;
61     PRUint32 length;
62 };
63 
64 typedef struct _SSLRecord {
65     PRUint8 type;
66     PRUint8 ver_maj, ver_min;
67 
68     PRUint8 length[2];
69 } SSLRecord;
70 
71 typedef struct _ClientHelloV2 {
72     PRUint8 length[2];
73     PRUint8 type;
74     PRUint8 version[2];
75     PRUint8 cslength[2];
76     PRUint8 sidlength[2];
77     PRUint8 rndlength[2];
78     PRUint8 csuites[1];
79 } ClientHelloV2;
80 
81 typedef struct _ServerHelloV2 {
82     PRUint8 length[2];
83     PRUint8 type;
84     PRUint8 sidhit;
85     PRUint8 certtype;
86     PRUint8 version[2];
87     PRUint8 certlength[2];
88     PRUint8 cslength[2];
89     PRUint8 cidlength[2];
90 } ServerHelloV2;
91 
92 typedef struct _ClientMasterKeyV2 {
93     PRUint8 length[2];
94     PRUint8 type;
95 
96     PRUint8 cipherkind[3];
97     PRUint8 clearkey[2];
98     PRUint8 secretkey[2];
99 
100 } ClientMasterKeyV2;
101 
102 /* forward declaration */
103 void showErr(const char *msg);
104 
105 #define TAPBUFSIZ 16384
106 
107 #define DEFPORT 1924
108 #include <ctype.h>
109 
110 const char *progName;
111 int hexparse = 0;
112 int sslparse = 0;
113 int sslhexparse = 0;
114 int looparound = 0;
115 int fancy = 0;
116 int isV2Session = 0;
117 int currentcipher = 0;
118 DataBufferList clientstream, serverstream;
119 
120 #define PR_FPUTS(x) PR_fprintf(PR_STDOUT, x)
121 
122 #define GET_SHORT(x) ((PRUint16)(((PRUint16)((PRUint8 *)x)[0]) << 8) + ((PRUint16)((PRUint8 *)x)[1]))
123 #define GET_24(x) ((PRUint32)(              \
124     (((PRUint32)((PRUint8 *)x)[0]) << 16) + \
125     (((PRUint32)((PRUint8 *)x)[1]) << 8) +  \
126     (((PRUint32)((PRUint8 *)x)[2]) << 0)))
127 #define GET_32(x) ((PRUint32)(              \
128     (((PRUint32)((PRUint8 *)x)[0]) << 24) + \
129     (((PRUint32)((PRUint8 *)x)[1]) << 16) + \
130     (((PRUint32)((PRUint8 *)x)[2]) << 8) +  \
131     (((PRUint32)((PRUint8 *)x)[3]) << 0)))
132 
133 void print_hex(int amt, unsigned char *buf);
134 void read_stream_bytes(unsigned char *d, DataBufferList *db, int length);
135 
136 void
myhalt(int dblsize,int collectedsize)137 myhalt(int dblsize, int collectedsize)
138 {
139 
140     PR_fprintf(PR_STDERR, "HALTED\n");
141     PR_ASSERT(dblsize == collectedsize);
142     exit(13);
143 }
144 
145 const char *
get_error_text(int error)146 get_error_text(int error)
147 {
148     switch (error) {
149         case PR_IO_TIMEOUT_ERROR:
150             return "Timeout";
151             break;
152         case PR_CONNECT_REFUSED_ERROR:
153             return "Connection refused";
154             break;
155         case PR_NETWORK_UNREACHABLE_ERROR:
156             return "Network unreachable";
157             break;
158         case PR_BAD_ADDRESS_ERROR:
159             return "Bad address";
160             break;
161         case PR_CONNECT_RESET_ERROR:
162             return "Connection reset";
163             break;
164         case PR_PIPE_ERROR:
165             return "Pipe error";
166             break;
167     }
168 
169     return "";
170 }
171 
172 void
check_integrity(DataBufferList * dbl)173 check_integrity(DataBufferList *dbl)
174 {
175     DataBuffer *db;
176     int i;
177 
178     db = dbl->first;
179     i = 0;
180     while (db) {
181         i += db->length - db->offset;
182         db = db->next;
183     }
184     if (i != dbl->size) {
185         myhalt(dbl->size, i);
186     }
187 }
188 
189 /* Free's the DataBuffer at the head of the list and returns the pointer
190  * to the new head of the list.
191  */
192 DataBuffer *
free_head(DataBufferList * dbl)193 free_head(DataBufferList *dbl)
194 {
195     DataBuffer *db = dbl->first;
196     PR_ASSERT(db->offset >= db->length);
197     if (db->offset >= db->length) {
198         dbl->first = db->next;
199         if (dbl->first == NULL) {
200             dbl->last = NULL;
201         }
202         PORT_Free(db->buffer);
203         PORT_Free(db);
204         db = dbl->first;
205     }
206     return db;
207 }
208 
209 void
read_stream_bytes(unsigned char * d,DataBufferList * dbl,int length)210 read_stream_bytes(unsigned char *d, DataBufferList *dbl, int length)
211 {
212     int copied = 0;
213     DataBuffer *db = dbl->first;
214 
215     if (!db) {
216         PR_fprintf(PR_STDERR, "assert failed - dbl->first is null\n");
217         exit(8);
218     }
219     while (length) {
220         int toCopy;
221         /* find the number of bytes to copy from the head buffer */
222         /* if there's too many in this buffer, then only copy 'length' */
223         toCopy = PR_MIN(db->length - db->offset, length);
224 
225         memcpy(d + copied, db->buffer + db->offset, toCopy);
226         copied += toCopy;
227         db->offset += toCopy;
228         length -= toCopy;
229         dbl->size -= toCopy;
230 
231         /* if we emptied the head buffer */
232         if (db->offset >= db->length) {
233             db = free_head(dbl);
234         }
235     }
236 
237     check_integrity(dbl);
238 }
239 
240 void
flush_stream(DataBufferList * dbl)241 flush_stream(DataBufferList *dbl)
242 {
243     DataBuffer *db = dbl->first;
244     check_integrity(dbl);
245     while (db) {
246         db->offset = db->length;
247         db = free_head(dbl);
248     }
249     dbl->size = 0;
250     check_integrity(dbl);
251     if (dbl->msgBuf) {
252         PORT_Free(dbl->msgBuf);
253         dbl->msgBuf = NULL;
254     }
255     dbl->msgBufOffset = 0;
256     dbl->msgBufSize = 0;
257     dbl->hMACsize = 0;
258 }
259 
260 const char *
V2CipherString(int cs_int)261 V2CipherString(int cs_int)
262 {
263     char *cs_str;
264     cs_str = NULL;
265     switch (cs_int) {
266 
267         case 0x010080:
268             cs_str = "SSL2/RSA/RC4-128/MD5";
269             break;
270         case 0x020080:
271             cs_str = "SSL2/RSA/RC4-40/MD5";
272             break;
273         case 0x030080:
274             cs_str = "SSL2/RSA/RC2CBC128/MD5";
275             break;
276         case 0x040080:
277             cs_str = "SSL2/RSA/RC2CBC40/MD5";
278             break;
279         case 0x050080:
280             cs_str = "SSL2/RSA/IDEA128CBC/MD5";
281             break;
282         case 0x060040:
283             cs_str = "SSL2/RSA/DES56-CBC/MD5";
284             break;
285         case 0x0700C0:
286             cs_str = "SSL2/RSA/3DES192EDE-CBC/MD5";
287             break;
288 
289         case 0x000001:
290             cs_str = "SSL3/RSA/NULL/MD5";
291             break;
292         case 0x000002:
293             cs_str = "SSL3/RSA/NULL/SHA";
294             break;
295         case 0x000003:
296             cs_str = "SSL3/RSA/RC4-40/MD5";
297             break;
298         case 0x000004:
299             cs_str = "SSL3/RSA/RC4-128/MD5";
300             break;
301         case 0x000005:
302             cs_str = "SSL3/RSA/RC4-128/SHA";
303             break;
304         case 0x000006:
305             cs_str = "SSL3/RSA/RC2CBC40/MD5";
306             break;
307         case 0x000007:
308             cs_str = "SSL3/RSA/IDEA128CBC/SHA";
309             break;
310         case 0x000008:
311             cs_str = "SSL3/RSA/DES40-CBC/SHA";
312             break;
313         case 0x000009:
314             cs_str = "SSL3/RSA/DES56-CBC/SHA";
315             break;
316         case 0x00000A:
317             cs_str = "SSL3/RSA/3DES192EDE-CBC/SHA";
318             break;
319 
320         case 0x00000B:
321             cs_str = "SSL3/DH-DSS/DES40-CBC/SHA";
322             break;
323         case 0x00000C:
324             cs_str = "SSL3/DH-DSS/DES56-CBC/SHA";
325             break;
326         case 0x00000D:
327             cs_str = "SSL3/DH-DSS/DES192EDE3CBC/SHA";
328             break;
329         case 0x00000E:
330             cs_str = "SSL3/DH-RSA/DES40-CBC/SHA";
331             break;
332         case 0x00000F:
333             cs_str = "SSL3/DH-RSA/DES56-CBC/SHA";
334             break;
335         case 0x000010:
336             cs_str = "SSL3/DH-RSA/3DES192EDE-CBC/SHA";
337             break;
338 
339         case 0x000011:
340             cs_str = "SSL3/DHE-DSS/DES40-CBC/SHA";
341             break;
342         case 0x000012:
343             cs_str = "SSL3/DHE-DSS/DES56-CBC/SHA";
344             break;
345         case 0x000013:
346             cs_str = "SSL3/DHE-DSS/DES192EDE3CBC/SHA";
347             break;
348         case 0x000014:
349             cs_str = "SSL3/DHE-RSA/DES40-CBC/SHA";
350             break;
351         case 0x000015:
352             cs_str = "SSL3/DHE-RSA/DES56-CBC/SHA";
353             break;
354         case 0x000016:
355             cs_str = "SSL3/DHE-RSA/3DES192EDE-CBC/SHA";
356             break;
357 
358         case 0x000017:
359             cs_str = "SSL3/DH-anon/RC4-40/MD5";
360             break;
361         case 0x000018:
362             cs_str = "SSL3/DH-anon/RC4-128/MD5";
363             break;
364         case 0x000019:
365             cs_str = "SSL3/DH-anon/DES40-CBC/SHA";
366             break;
367         case 0x00001A:
368             cs_str = "SSL3/DH-anon/DES56-CBC/SHA";
369             break;
370         case 0x00001B:
371             cs_str = "SSL3/DH-anon/3DES192EDE-CBC/SHA";
372             break;
373 
374         case 0x00001C:
375             cs_str = "SSL3/FORTEZZA-DMS/NULL/SHA";
376             break;
377         case 0x00001D:
378             cs_str = "SSL3/FORTEZZA-DMS/FORTEZZA-CBC/SHA";
379             break;
380         case 0x00001E:
381             cs_str = "SSL3/FORTEZZA-DMS/RC4-128/SHA";
382             break;
383 
384         case 0x00002F:
385             cs_str = "TLS/RSA/AES128-CBC/SHA";
386             break;
387         case 0x000030:
388             cs_str = "TLS/DH-DSS/AES128-CBC/SHA";
389             break;
390         case 0x000031:
391             cs_str = "TLS/DH-RSA/AES128-CBC/SHA";
392             break;
393         case 0x000032:
394             cs_str = "TLS/DHE-DSS/AES128-CBC/SHA";
395             break;
396         case 0x000033:
397             cs_str = "TLS/DHE-RSA/AES128-CBC/SHA";
398             break;
399         case 0x000034:
400             cs_str = "TLS/DH-ANON/AES128-CBC/SHA";
401             break;
402 
403         case 0x000035:
404             cs_str = "TLS/RSA/AES256-CBC/SHA";
405             break;
406         case 0x000036:
407             cs_str = "TLS/DH-DSS/AES256-CBC/SHA";
408             break;
409         case 0x000037:
410             cs_str = "TLS/DH-RSA/AES256-CBC/SHA";
411             break;
412         case 0x000038:
413             cs_str = "TLS/DHE-DSS/AES256-CBC/SHA";
414             break;
415         case 0x000039:
416             cs_str = "TLS/DHE-RSA/AES256-CBC/SHA";
417             break;
418         case 0x00003A:
419             cs_str = "TLS/DH-ANON/AES256-CBC/SHA";
420             break;
421 
422         case 0x00003B:
423             cs_str = "TLS/RSA/NULL/SHA256";
424             break;
425         case 0x00003C:
426             cs_str = "TLS/RSA/AES128-CBC/SHA256";
427             break;
428         case 0x00003D:
429             cs_str = "TLS/RSA/AES256-CBC/SHA256";
430             break;
431         case 0x00003E:
432             cs_str = "TLS/DH-DSS/AES128-CBC/SHA256";
433             break;
434         case 0x00003F:
435             cs_str = "TLS/DH-RSA/AES128-CBC/SHA256";
436             break;
437         case 0x000040:
438             cs_str = "TLS/DHE-DSS/AES128-CBC/SHA256";
439             break;
440 
441         case 0x000041:
442             cs_str = "TLS/RSA/CAMELLIA128-CBC/SHA";
443             break;
444         case 0x000042:
445             cs_str = "TLS/DH-DSS/CAMELLIA128-CBC/SHA";
446             break;
447         case 0x000043:
448             cs_str = "TLS/DH-RSA/CAMELLIA128-CBC/SHA";
449             break;
450         case 0x000044:
451             cs_str = "TLS/DHE-DSS/CAMELLIA128-CBC/SHA";
452             break;
453         case 0x000045:
454             cs_str = "TLS/DHE-RSA/CAMELLIA128-CBC/SHA";
455             break;
456         case 0x000046:
457             cs_str = "TLS/DH-ANON/CAMELLIA128-CBC/SHA";
458             break;
459 
460         case 0x000060:
461             cs_str = "TLS/RSA-EXPORT1024/RC4-56/MD5";
462             break;
463         case 0x000061:
464             cs_str = "TLS/RSA-EXPORT1024/RC2CBC56/MD5";
465             break;
466         case 0x000062:
467             cs_str = "TLS/RSA-EXPORT1024/DES56-CBC/SHA";
468             break;
469         case 0x000064:
470             cs_str = "TLS/RSA-EXPORT1024/RC4-56/SHA";
471             break;
472         case 0x000063:
473             cs_str = "TLS/DHE-DSS_EXPORT1024/DES56-CBC/SHA";
474             break;
475         case 0x000065:
476             cs_str = "TLS/DHE-DSS_EXPORT1024/RC4-56/SHA";
477             break;
478         case 0x000066:
479             cs_str = "TLS/DHE-DSS/RC4-128/SHA";
480             break;
481 
482         case 0x000067:
483             cs_str = "TLS/DHE-RSA/AES128-CBC/SHA256";
484             break;
485         case 0x000068:
486             cs_str = "TLS/DH-DSS/AES256-CBC/SHA256";
487             break;
488         case 0x000069:
489             cs_str = "TLS/DH-RSA/AES256-CBC/SHA256";
490             break;
491         case 0x00006A:
492             cs_str = "TLS/DHE-DSS/AES256-CBC/SHA256";
493             break;
494         case 0x00006B:
495             cs_str = "TLS/DHE-RSA/AES256-CBC/SHA256";
496             break;
497 
498         case 0x000072:
499             cs_str = "TLS/DHE-DSS/3DESEDE-CBC/RMD160";
500             break;
501         case 0x000073:
502             cs_str = "TLS/DHE-DSS/AES128-CBC/RMD160";
503             break;
504         case 0x000074:
505             cs_str = "TLS/DHE-DSS/AES256-CBC/RMD160";
506             break;
507 
508         case 0x000079:
509             cs_str = "TLS/DHE-RSA/AES256-CBC/RMD160";
510             break;
511 
512         case 0x00007C:
513             cs_str = "TLS/RSA/3DESEDE-CBC/RMD160";
514             break;
515         case 0x00007D:
516             cs_str = "TLS/RSA/AES128-CBC/RMD160";
517             break;
518         case 0x00007E:
519             cs_str = "TLS/RSA/AES256-CBC/RMD160";
520             break;
521 
522         case 0x000080:
523             cs_str = "TLS/GOST341094/GOST28147-OFB/GOST28147";
524             break;
525         case 0x000081:
526             cs_str = "TLS/GOST34102001/GOST28147-OFB/GOST28147";
527             break;
528         case 0x000082:
529             cs_str = "TLS/GOST341094/NULL/GOSTR3411";
530             break;
531         case 0x000083:
532             cs_str = "TLS/GOST34102001/NULL/GOSTR3411";
533             break;
534 
535         case 0x000084:
536             cs_str = "TLS/RSA/CAMELLIA256-CBC/SHA";
537             break;
538         case 0x000085:
539             cs_str = "TLS/DH-DSS/CAMELLIA256-CBC/SHA";
540             break;
541         case 0x000086:
542             cs_str = "TLS/DH-RSA/CAMELLIA256-CBC/SHA";
543             break;
544         case 0x000087:
545             cs_str = "TLS/DHE-DSS/CAMELLIA256-CBC/SHA";
546             break;
547         case 0x000088:
548             cs_str = "TLS/DHE-RSA/CAMELLIA256-CBC/SHA";
549             break;
550         case 0x000089:
551             cs_str = "TLS/DH-ANON/CAMELLIA256-CBC/SHA";
552             break;
553         case 0x00008A:
554             cs_str = "TLS/PSK/RC4-128/SHA";
555             break;
556         case 0x00008B:
557             cs_str = "TLS/PSK/3DES-EDE-CBC/SHA";
558             break;
559         case 0x00008C:
560             cs_str = "TLS/PSK/AES128-CBC/SHA";
561             break;
562         case 0x00008D:
563             cs_str = "TLS/PSK/AES256-CBC/SHA";
564             break;
565         case 0x00008E:
566             cs_str = "TLS/DHE-PSK/RC4-128/SHA";
567             break;
568         case 0x00008F:
569             cs_str = "TLS/DHE-PSK/3DES-EDE-CBC/SHA";
570             break;
571         case 0x000090:
572             cs_str = "TLS/DHE-PSK/AES128-CBC/SHA";
573             break;
574         case 0x000091:
575             cs_str = "TLS/DHE-PSK/AES256-CBC/SHA";
576             break;
577         case 0x000092:
578             cs_str = "TLS/RSA-PSK/RC4-128/SHA";
579             break;
580         case 0x000093:
581             cs_str = "TLS/RSA-PSK/3DES-EDE-CBC/SHA";
582             break;
583         case 0x000094:
584             cs_str = "TLS/RSA-PSK/AES128-CBC/SHA";
585             break;
586         case 0x000095:
587             cs_str = "TLS/RSA-PSK/AES256-CBC/SHA";
588             break;
589         case 0x000096:
590             cs_str = "TLS/RSA/SEED-CBC/SHA";
591             break;
592         case 0x000097:
593             cs_str = "TLS/DH-DSS/SEED-CBC/SHA";
594             break;
595         case 0x000098:
596             cs_str = "TLS/DH-RSA/SEED-CBC/SHA";
597             break;
598         case 0x000099:
599             cs_str = "TLS/DHE-DSS/SEED-CBC/SHA";
600             break;
601         case 0x00009A:
602             cs_str = "TLS/DHE-RSA/SEED-CBC/SHA";
603             break;
604         case 0x00009B:
605             cs_str = "TLS/DH-ANON/SEED-CBC/SHA";
606             break;
607         case 0x00009C:
608             cs_str = "TLS/RSA/AES128-GCM/SHA256";
609             break;
610         case 0x00009E:
611             cs_str = "TLS/DHE-RSA/AES128-GCM/SHA256";
612             break;
613 
614         case 0x0000FF:
615             cs_str = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
616             break;
617         case 0x005600:
618             cs_str = "TLS_FALLBACK_SCSV";
619             break;
620 
621         case 0x00C001:
622             cs_str = "TLS/ECDH-ECDSA/NULL/SHA";
623             break;
624         case 0x00C002:
625             cs_str = "TLS/ECDH-ECDSA/RC4-128/SHA";
626             break;
627         case 0x00C003:
628             cs_str = "TLS/ECDH-ECDSA/3DES-EDE-CBC/SHA";
629             break;
630         case 0x00C004:
631             cs_str = "TLS/ECDH-ECDSA/AES128-CBC/SHA";
632             break;
633         case 0x00C005:
634             cs_str = "TLS/ECDH-ECDSA/AES256-CBC/SHA";
635             break;
636         case 0x00C006:
637             cs_str = "TLS/ECDHE-ECDSA/NULL/SHA";
638             break;
639         case 0x00C007:
640             cs_str = "TLS/ECDHE-ECDSA/RC4-128/SHA";
641             break;
642         case 0x00C008:
643             cs_str = "TLS/ECDHE-ECDSA/3DES-EDE-CBC/SHA";
644             break;
645         case 0x00C009:
646             cs_str = "TLS/ECDHE-ECDSA/AES128-CBC/SHA";
647             break;
648         case 0x00C00A:
649             cs_str = "TLS/ECDHE-ECDSA/AES256-CBC/SHA";
650             break;
651         case 0x00C00B:
652             cs_str = "TLS/ECDH-RSA/NULL/SHA";
653             break;
654         case 0x00C00C:
655             cs_str = "TLS/ECDH-RSA/RC4-128/SHA";
656             break;
657         case 0x00C00D:
658             cs_str = "TLS/ECDH-RSA/3DES-EDE-CBC/SHA";
659             break;
660         case 0x00C00E:
661             cs_str = "TLS/ECDH-RSA/AES128-CBC/SHA";
662             break;
663         case 0x00C00F:
664             cs_str = "TLS/ECDH-RSA/AES256-CBC/SHA";
665             break;
666         case 0x00C010:
667             cs_str = "TLS/ECDHE-RSA/NULL/SHA";
668             break;
669         case 0x00C011:
670             cs_str = "TLS/ECDHE-RSA/RC4-128/SHA";
671             break;
672         case 0x00C012:
673             cs_str = "TLS/ECDHE-RSA/3DES-EDE-CBC/SHA";
674             break;
675         case 0x00C013:
676             cs_str = "TLS/ECDHE-RSA/AES128-CBC/SHA";
677             break;
678         case 0x00C014:
679             cs_str = "TLS/ECDHE-RSA/AES256-CBC/SHA";
680             break;
681         case 0x00C015:
682             cs_str = "TLS/ECDH-anon/NULL/SHA";
683             break;
684         case 0x00C016:
685             cs_str = "TLS/ECDH-anon/RC4-128/SHA";
686             break;
687         case 0x00C017:
688             cs_str = "TLS/ECDH-anon/3DES-EDE-CBC/SHA";
689             break;
690         case 0x00C018:
691             cs_str = "TLS/ECDH-anon/AES128-CBC/SHA";
692             break;
693         case 0x00C019:
694             cs_str = "TLS/ECDH-anon/AES256-CBC/SHA";
695             break;
696 
697         case 0x00C023:
698             cs_str = "TLS/ECDHE-ECDSA/AES128-CBC/SHA256";
699             break;
700         case 0x00C024:
701             cs_str = "TLS/ECDHE-ECDSA/AES256-CBC/SHA384";
702             break;
703         case 0x00C025:
704             cs_str = "TLS/ECDH-ECDSA/AES128-CBC/SHA256";
705             break;
706         case 0x00C026:
707             cs_str = "TLS/ECDH-ECDSA/AES256-CBC/SHA384";
708             break;
709         case 0x00C027:
710             cs_str = "TLS/ECDHE-RSA/AES128-CBC/SHA256";
711             break;
712         case 0x00C028:
713             cs_str = "TLS/ECDHE-RSA/AES256-CBC/SHA384";
714             break;
715         case 0x00C029:
716             cs_str = "TLS/ECDH-RSA/AES128-CBC/SHA256";
717             break;
718         case 0x00C02A:
719             cs_str = "TLS/ECDH-RSA/AES256-CBC/SHA384";
720             break;
721         case 0x00C02B:
722             cs_str = "TLS/ECDHE-ECDSA/AES128-GCM/SHA256";
723             break;
724         case 0x00C02C:
725             cs_str = "TLS/ECDHE-ECDSA/AES256-GCM/SHA384";
726             break;
727         case 0x00C02F:
728             cs_str = "TLS/ECDHE-RSA/AES128-GCM/SHA256";
729             break;
730 
731         case 0x00CCA8:
732             cs_str = "TLS/ECDHE-RSA/CHACHA20-POLY1305/SHA256";
733             break;
734         case 0x00CCA9:
735             cs_str = "TLS/ECDHE-ECDSA/CHACHA20-POLY1305/SHA256";
736             break;
737         case 0x00CCAA:
738             cs_str = "TLS/DHE-RSA/CHACHA20-POLY1305/SHA256";
739             break;
740 
741         case 0x00FEFF:
742             cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA";
743             break;
744         case 0x00FEFE:
745             cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA";
746             break;
747         case 0x00FFE1:
748             cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA";
749             break;
750         case 0x00FFE0:
751             cs_str = "SSL3/RSA-FIPS/3DES192EDE-CBC/SHA";
752             break;
753 
754         /* the string literal is broken up to avoid trigraphs */
755         default:
756             cs_str = "????"
757                      "/????????"
758                      "/?????????"
759                      "/???";
760             break;
761     }
762 
763     return cs_str;
764 }
765 
766 const char *
CompressionMethodString(int cm_int)767 CompressionMethodString(int cm_int)
768 {
769     char *cm_str;
770     cm_str = NULL;
771     switch (cm_int) {
772         case 0:
773             cm_str = "NULL";
774             break;
775         case 1:
776             cm_str = "DEFLATE";
777             break; /* RFC 3749 */
778         case 64:
779             cm_str = "LZS";
780             break; /* RFC 3943 */
781         default:
782             cm_str = "???";
783             break;
784     }
785 
786     return cm_str;
787 }
788 
789 const char *
helloExtensionNameString(int ex_num)790 helloExtensionNameString(int ex_num)
791 {
792     const char *ex_name = NULL;
793     static char buf[10];
794 
795     switch (ex_num) {
796         case 0:
797             ex_name = "server_name";
798             break;
799         case 1:
800             ex_name = "max_fragment_length";
801             break;
802         case 2:
803             ex_name = "client_certificate_url";
804             break;
805         case 3:
806             ex_name = "trusted_ca_keys";
807             break;
808         case 4:
809             ex_name = "truncated_hmac";
810             break;
811         case 5:
812             ex_name = "status_request";
813             break;
814         case 10:
815             ex_name = "elliptic_curves";
816             break;
817         case 11:
818             ex_name = "ec_point_formats";
819             break;
820         case 13:
821             ex_name = "signature_algorithms";
822             break;
823         case 35:
824             ex_name = "session_ticket";
825             break;
826         case 0xff01:
827             ex_name = "renegotiation_info";
828             break;
829         default:
830             sprintf(buf, "%d", ex_num);
831             ex_name = (const char *)buf;
832             break;
833     }
834 
835     return ex_name;
836 }
837 
838 static int
isNULLmac(int cs_int)839 isNULLmac(int cs_int)
840 {
841     return (cs_int == TLS_NULL_WITH_NULL_NULL);
842 }
843 
844 static int
isNULLcipher(int cs_int)845 isNULLcipher(int cs_int)
846 {
847     return ((cs_int == TLS_RSA_WITH_NULL_MD5) ||
848             (cs_int == TLS_RSA_WITH_NULL_SHA) ||
849             (cs_int == SSL_FORTEZZA_DMS_WITH_NULL_SHA) ||
850             (cs_int == TLS_ECDH_ECDSA_WITH_NULL_SHA) ||
851             (cs_int == TLS_ECDHE_ECDSA_WITH_NULL_SHA) ||
852             (cs_int == TLS_ECDH_RSA_WITH_NULL_SHA) ||
853             (cs_int == TLS_ECDHE_RSA_WITH_NULL_SHA));
854 }
855 
856 void
partial_packet(int thispacket,int size,int needed)857 partial_packet(int thispacket, int size, int needed)
858 {
859     PR_fprintf(PR_STDOUT, "(%u bytes", thispacket);
860     if (thispacket < needed) {
861         PR_fprintf(PR_STDOUT, ", making %u", size);
862     }
863     PR_fprintf(PR_STDOUT, " of %u", needed);
864     if (size > needed) {
865         PR_fprintf(PR_STDOUT, ", with %u left over", size - needed);
866     }
867     PR_fprintf(PR_STDOUT, ")\n");
868 }
869 
870 char *
get_time_string(void)871 get_time_string(void)
872 {
873     char *cp;
874     char *eol;
875     time_t tt;
876 
877     time(&tt);
878     cp = ctime(&tt);
879     eol = strchr(cp, '\n');
880     if (eol)
881         *eol = 0;
882     return cp;
883 }
884 
885 void
print_sslv2(DataBufferList * s,unsigned char * recordBuf,unsigned int recordLen)886 print_sslv2(DataBufferList *s, unsigned char *recordBuf, unsigned int recordLen)
887 {
888     ClientHelloV2 *chv2;
889     ServerHelloV2 *shv2;
890     unsigned char *pos;
891     unsigned int p;
892     unsigned int q;
893     PRUint32 len;
894 
895     chv2 = (ClientHelloV2 *)recordBuf;
896     shv2 = (ServerHelloV2 *)recordBuf;
897     if (s->isEncrypted) {
898         PR_fprintf(PR_STDOUT, " [ssl2]  Encrypted {...}\n");
899         return;
900     }
901     PR_fprintf(PR_STDOUT, " [%s]", get_time_string());
902     switch (chv2->type) {
903         case 1:
904             PR_fprintf(PR_STDOUT, " [ssl2]  ClientHelloV2 {\n");
905             PR_fprintf(PR_STDOUT, "           version = {0x%02x, 0x%02x}\n",
906                        (PRUint32)chv2->version[0], (PRUint32)chv2->version[1]);
907             PR_fprintf(PR_STDOUT, "           cipher-specs-length = %d (0x%02x)\n",
908                        (PRUint32)(GET_SHORT((chv2->cslength))),
909                        (PRUint32)(GET_SHORT((chv2->cslength))));
910             PR_fprintf(PR_STDOUT, "           sid-length = %d (0x%02x)\n",
911                        (PRUint32)(GET_SHORT((chv2->sidlength))),
912                        (PRUint32)(GET_SHORT((chv2->sidlength))));
913             PR_fprintf(PR_STDOUT, "           challenge-length = %d (0x%02x)\n",
914                        (PRUint32)(GET_SHORT((chv2->rndlength))),
915                        (PRUint32)(GET_SHORT((chv2->rndlength))));
916             PR_fprintf(PR_STDOUT, "           cipher-suites = { \n");
917             for (p =
918                      0;
919                  p < (PRUint32)GET_SHORT((chv2->cslength)); p += 3) {
920                 PRUint32 cs_int = GET_24((&chv2->csuites[p]));
921                 const char *cs_str =
922                     V2CipherString(cs_int);
923 
924                 PR_fprintf(PR_STDOUT, "                (0x%06x) %s\n",
925                            cs_int, cs_str);
926             }
927             q = p;
928             PR_fprintf(PR_STDOUT, "                }\n");
929             if (GET_SHORT((chv2->sidlength))) {
930                 PR_fprintf(PR_STDOUT, "           session-id = { ");
931                 for (p = 0;
932                      p < (PRUint32)GET_SHORT((chv2->sidlength)); p += 2) {
933                     PR_fprintf(PR_STDOUT, "0x%04x ", (PRUint32)(GET_SHORT((&chv2->csuites[p + q]))));
934                 }
935             }
936             q += p;
937             PR_fprintf(PR_STDOUT, "}\n");
938             if (GET_SHORT((chv2->rndlength))) {
939                 PR_fprintf(PR_STDOUT, "           challenge = { ");
940                 for (p = 0;
941                      p < (PRUint32)GET_SHORT((chv2->rndlength)); p += 2) {
942                     PR_fprintf(PR_STDOUT, "0x%04x ", (PRUint32)(GET_SHORT((&chv2->csuites[p + q]))));
943                 }
944                 PR_fprintf(PR_STDOUT, "}\n");
945             }
946             PR_fprintf(PR_STDOUT, "}\n");
947             break;
948         /* end of V2 CLientHello Parsing */
949 
950         case 2: /* Client Master Key  */
951         {
952             const char *cs_str =
953                 NULL;
954             PRUint32 cs_int =
955                 0;
956             ClientMasterKeyV2 *cmkv2;
957             cmkv2 = (ClientMasterKeyV2 *)chv2;
958             isV2Session = 1;
959 
960             PR_fprintf(PR_STDOUT, " [ssl2]  ClientMasterKeyV2 { \n");
961 
962             cs_int = GET_24(&cmkv2->cipherkind[0]);
963             cs_str = V2CipherString(cs_int);
964             PR_fprintf(PR_STDOUT, "         cipher-spec-chosen = (0x%06x) %s\n",
965                        cs_int, cs_str);
966 
967             PR_fprintf(PR_STDOUT, "         clear-portion = %d bits\n",
968                        8 *
969                            (PRUint32)(GET_SHORT((cmkv2->clearkey))));
970 
971             PR_fprintf(PR_STDOUT, "      }\n");
972             clientstream.isEncrypted = 1;
973             serverstream.isEncrypted = 1;
974         } break;
975 
976         case 3:
977             PR_fprintf(PR_STDOUT, " [ssl2]  Client Finished V2 {...}\n");
978             isV2Session = 1;
979             break;
980 
981         case 4: /* V2 Server Hello */
982             isV2Session = 1;
983 
984             PR_fprintf(PR_STDOUT, " [ssl2]  ServerHelloV2 {\n");
985             PR_fprintf(PR_STDOUT, "           sid hit = {0x%02x}\n",
986                        (PRUintn)shv2->sidhit);
987             PR_fprintf(PR_STDOUT, "           version = {0x%02x, 0x%02x}\n",
988                        (PRUint32)shv2->version[0], (PRUint32)shv2->version[1]);
989             PR_fprintf(PR_STDOUT, "           cipher-specs-length = %d (0x%02x)\n",
990                        (PRUint32)(GET_SHORT((shv2->cslength))),
991                        (PRUint32)(GET_SHORT((shv2->cslength))));
992             PR_fprintf(PR_STDOUT, "           sid-length = %d (0x%02x)\n",
993                        (PRUint32)(GET_SHORT((shv2->cidlength))),
994                        (PRUint32)(GET_SHORT((shv2->cidlength))));
995 
996             pos = (unsigned char *)shv2;
997             pos += 2;  /* skip length header */
998             pos += 11; /* position pointer to Certificate data area */
999             q = GET_SHORT(&shv2->certlength);
1000             if (q > recordLen) {
1001                 goto eosh;
1002             }
1003             pos += q; /* skip certificate */
1004 
1005             PR_fprintf(PR_STDOUT, "           cipher-suites = { ");
1006             len = GET_SHORT((shv2->cslength));
1007             for (p = 0; p < len; p += 3) {
1008                 PRUint32 cs_int = GET_24((pos + p));
1009                 const char *cs_str =
1010                     V2CipherString(cs_int);
1011                 PR_fprintf(PR_STDOUT, "\n              ");
1012                 PR_fprintf(PR_STDOUT, "(0x%06x) %s", cs_int, cs_str);
1013             }
1014             pos += len;
1015             PR_fprintf(PR_STDOUT, "   }\n"); /* End of cipher suites */
1016             len = (PRUint32)GET_SHORT((shv2->cidlength));
1017             if (len) {
1018                 PR_fprintf(PR_STDOUT, "           connection-id = { ");
1019                 for (p =
1020                          0;
1021                      p < len; p += 2) {
1022                     PR_fprintf(PR_STDOUT, "0x%04x ", (PRUint32)(GET_SHORT((pos +
1023                                                                            p))));
1024                 }
1025                 PR_fprintf(PR_STDOUT, "   }\n"); /* End of connection id */
1026             }
1027         eosh:
1028             PR_fprintf(PR_STDOUT, "\n              }\n"); /* end of ServerHelloV2 */
1029             if (shv2->sidhit) {
1030                 clientstream.isEncrypted =
1031                     1;
1032                 serverstream.isEncrypted =
1033                     1;
1034             }
1035             break;
1036 
1037         case 5:
1038             PR_fprintf(PR_STDOUT, " [ssl2]  Server Verify V2 {...}\n");
1039             isV2Session = 1;
1040             break;
1041 
1042         case 6:
1043             PR_fprintf(PR_STDOUT, " [ssl2]  Server Finished V2 {...}\n");
1044             isV2Session = 1;
1045             break;
1046 
1047         case 7:
1048             PR_fprintf(PR_STDOUT, " [ssl2]  Request Certificate V2 {...}\n");
1049             isV2Session = 1;
1050             break;
1051 
1052         case 8:
1053             PR_fprintf(PR_STDOUT, " [ssl2]  Client Certificate V2 {...}\n");
1054             isV2Session = 1;
1055             break;
1056 
1057         default:
1058             PR_fprintf(PR_STDOUT, " [ssl2]  UnknownType 0x%02x {...}\n",
1059                        (PRUint32)chv2->type);
1060             break;
1061     }
1062 }
1063 
1064 unsigned int
print_hello_extension(unsigned char * hsdata,unsigned int length,unsigned int pos)1065 print_hello_extension(unsigned char *hsdata,
1066                       unsigned int length,
1067                       unsigned int pos)
1068 {
1069     /* pretty print extensions, if any */
1070     if (pos < length) {
1071         int exListLen = GET_SHORT((hsdata + pos));
1072         pos += 2;
1073         PR_fprintf(PR_STDOUT,
1074                    "            extensions[%d] = {\n", exListLen);
1075         while (exListLen > 0 && pos < length) {
1076             int exLen;
1077             int exType = GET_SHORT((hsdata + pos));
1078             pos += 2;
1079             exLen = GET_SHORT((hsdata + pos));
1080             pos += 2;
1081             /* dump the extension */
1082             PR_fprintf(PR_STDOUT,
1083                        "              extension type %s, length [%d]",
1084                        helloExtensionNameString(exType), exLen);
1085             if (exLen > 0) {
1086                 PR_fprintf(PR_STDOUT, " = {\n");
1087                 print_hex(exLen, hsdata + pos);
1088                 PR_fprintf(PR_STDOUT, "              }\n");
1089             } else {
1090                 PR_fprintf(PR_STDOUT, "\n");
1091             }
1092             pos += exLen;
1093             exListLen -= 2 + exLen;
1094         }
1095         PR_fprintf(PR_STDOUT, "            }\n");
1096     }
1097     return pos;
1098 }
1099 
1100 /*
1101  * Note this must match (exactly) the enumeration ocspResponseStatus.
1102  */
1103 static char *responseStatusNames[] = {
1104     "successful (Response has valid confirmations)",
1105     "malformedRequest (Illegal confirmation request)",
1106     "internalError (Internal error in issuer)",
1107     "tryLater (Try again later)",
1108     "unused ((4) is not used)",
1109     "sigRequired (Must sign the request)",
1110     "unauthorized (Request unauthorized)",
1111 };
1112 
1113 static void
print_ocsp_cert_id(FILE * out_file,CERTOCSPCertID * cert_id,int level)1114 print_ocsp_cert_id(FILE *out_file, CERTOCSPCertID *cert_id, int level)
1115 {
1116     SECU_Indent(out_file, level);
1117     fprintf(out_file, "Cert ID:\n");
1118     level++;
1119     /*
1120     SECU_PrintAlgorithmID (out_file, &(cert_id->hashAlgorithm),
1121                            "Hash Algorithm", level);
1122     SECU_PrintAsHex (out_file, &(cert_id->issuerNameHash),
1123                      "Issuer Name Hash", level);
1124     SECU_PrintAsHex (out_file, &(cert_id->issuerKeyHash),
1125                      "Issuer Key Hash", level);
1126 */
1127     SECU_PrintInteger(out_file, &(cert_id->serialNumber),
1128                       "Serial Number", level);
1129     /* XXX lookup the cert; if found, print something nice (nickname?) */
1130 }
1131 
1132 static void
print_ocsp_version(FILE * out_file,SECItem * version,int level)1133 print_ocsp_version(FILE *out_file, SECItem *version, int level)
1134 {
1135     if (version->len > 0) {
1136         SECU_PrintInteger(out_file, version, "Version", level);
1137     } else {
1138         SECU_Indent(out_file, level);
1139         fprintf(out_file, "Version: DEFAULT\n");
1140     }
1141 }
1142 
1143 static void
print_responder_id(FILE * out_file,ocspResponderID * responderID,int level)1144 print_responder_id(FILE *out_file, ocspResponderID *responderID, int level)
1145 {
1146     SECU_Indent(out_file, level);
1147     fprintf(out_file, "Responder ID ");
1148 
1149     switch (responderID->responderIDType) {
1150         case ocspResponderID_byName:
1151             fprintf(out_file, "(byName):\n");
1152             SECU_PrintName(out_file, &(responderID->responderIDValue.name),
1153                            "Name", level + 1);
1154             break;
1155         case ocspResponderID_byKey:
1156             fprintf(out_file, "(byKey):\n");
1157             SECU_PrintAsHex(out_file, &(responderID->responderIDValue.keyHash),
1158                             "Key Hash", level + 1);
1159             break;
1160         default:
1161             fprintf(out_file, "Unrecognized Responder ID Type\n");
1162             break;
1163     }
1164 }
1165 
1166 static void
print_ocsp_extensions(FILE * out_file,CERTCertExtension ** extensions,char * msg,int level)1167 print_ocsp_extensions(FILE *out_file, CERTCertExtension **extensions,
1168                       char *msg, int level)
1169 {
1170     if (extensions) {
1171         SECU_PrintExtensions(out_file, extensions, msg, level);
1172     } else {
1173         SECU_Indent(out_file, level);
1174         fprintf(out_file, "No %s\n", msg);
1175     }
1176 }
1177 
1178 static void
print_revoked_info(FILE * out_file,ocspRevokedInfo * revoked_info,int level)1179 print_revoked_info(FILE *out_file, ocspRevokedInfo *revoked_info, int level)
1180 {
1181     SECU_PrintGeneralizedTime(out_file, &(revoked_info->revocationTime),
1182                               "Revocation Time", level);
1183 
1184     if (revoked_info->revocationReason != NULL) {
1185         SECU_PrintAsHex(out_file, revoked_info->revocationReason,
1186                         "Revocation Reason", level);
1187     } else {
1188         SECU_Indent(out_file, level);
1189         fprintf(out_file, "No Revocation Reason.\n");
1190     }
1191 }
1192 
1193 static void
print_cert_status(FILE * out_file,ocspCertStatus * status,int level)1194 print_cert_status(FILE *out_file, ocspCertStatus *status, int level)
1195 {
1196     SECU_Indent(out_file, level);
1197     fprintf(out_file, "Status: ");
1198 
1199     switch (status->certStatusType) {
1200         case ocspCertStatus_good:
1201             fprintf(out_file, "Cert is good.\n");
1202             break;
1203         case ocspCertStatus_revoked:
1204             fprintf(out_file, "Cert has been revoked.\n");
1205             print_revoked_info(out_file, status->certStatusInfo.revokedInfo,
1206                                level + 1);
1207             break;
1208         case ocspCertStatus_unknown:
1209             fprintf(out_file, "Cert is unknown to responder.\n");
1210             break;
1211         default:
1212             fprintf(out_file, "Unrecognized status.\n");
1213             break;
1214     }
1215 }
1216 
1217 static void
print_single_response(FILE * out_file,CERTOCSPSingleResponse * single,int level)1218 print_single_response(FILE *out_file, CERTOCSPSingleResponse *single,
1219                       int level)
1220 {
1221     print_ocsp_cert_id(out_file, single->certID, level);
1222 
1223     print_cert_status(out_file, single->certStatus, level);
1224 
1225     SECU_PrintGeneralizedTime(out_file, &(single->thisUpdate),
1226                               "This Update", level);
1227 
1228     if (single->nextUpdate != NULL) {
1229         SECU_PrintGeneralizedTime(out_file, single->nextUpdate,
1230                                   "Next Update", level);
1231     } else {
1232         SECU_Indent(out_file, level);
1233         fprintf(out_file, "No Next Update\n");
1234     }
1235 
1236     print_ocsp_extensions(out_file, single->singleExtensions,
1237                           "Single Response Extensions", level);
1238 }
1239 
1240 static void
print_response_data(FILE * out_file,ocspResponseData * responseData,int level)1241 print_response_data(FILE *out_file, ocspResponseData *responseData, int level)
1242 {
1243     SECU_Indent(out_file, level);
1244     fprintf(out_file, "Response Data:\n");
1245     level++;
1246 
1247     print_ocsp_version(out_file, &(responseData->version), level);
1248 
1249     print_responder_id(out_file, responseData->responderID, level);
1250 
1251     SECU_PrintGeneralizedTime(out_file, &(responseData->producedAt),
1252                               "Produced At", level);
1253 
1254     if (responseData->responses != NULL) {
1255         int i;
1256 
1257         for (i = 0; responseData->responses[i] != NULL; i++) {
1258             SECU_Indent(out_file, level);
1259             fprintf(out_file, "Response %d:\n", i);
1260             print_single_response(out_file, responseData->responses[i],
1261                                   level + 1);
1262         }
1263     } else {
1264         fprintf(out_file, "Response list is empty.\n");
1265     }
1266 
1267     print_ocsp_extensions(out_file, responseData->responseExtensions,
1268                           "Response Extensions", level);
1269 }
1270 
1271 static void
print_basic_response(FILE * out_file,ocspBasicOCSPResponse * basic,int level)1272 print_basic_response(FILE *out_file, ocspBasicOCSPResponse *basic, int level)
1273 {
1274     SECU_Indent(out_file, level);
1275     fprintf(out_file, "Basic OCSP Response:\n");
1276     level++;
1277 
1278     print_response_data(out_file, basic->tbsResponseData, level);
1279 }
1280 
1281 static void
print_status_response(SECItem * data)1282 print_status_response(SECItem *data)
1283 {
1284     int level = 2;
1285     CERTOCSPResponse *response;
1286     response = CERT_DecodeOCSPResponse(data);
1287     if (!response) {
1288         SECU_Indent(stdout, level);
1289         fprintf(stdout, "unable to decode certificate_status\n");
1290         return;
1291     }
1292 
1293     SECU_Indent(stdout, level);
1294     if (response->statusValue >= ocspResponse_min &&
1295         response->statusValue <= ocspResponse_max) {
1296         fprintf(stdout, "Response Status: %s\n",
1297                 responseStatusNames[response->statusValue]);
1298     } else {
1299         fprintf(stdout,
1300                 "Response Status: other (Status value %d out of defined range)\n",
1301                 (int)response->statusValue);
1302     }
1303 
1304     if (response->statusValue == ocspResponse_successful) {
1305         ocspResponseBytes *responseBytes = response->responseBytes;
1306         PORT_Assert(responseBytes != NULL);
1307 
1308         level++;
1309         SECU_PrintObjectID(stdout, &(responseBytes->responseType),
1310                            "Response Type", level);
1311         switch (response->responseBytes->responseTypeTag) {
1312             case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
1313                 print_basic_response(stdout,
1314                                      responseBytes->decodedResponse.basic,
1315                                      level);
1316                 break;
1317             default:
1318                 SECU_Indent(stdout, level);
1319                 fprintf(stdout, "Unknown response syntax\n");
1320                 break;
1321         }
1322     } else {
1323         SECU_Indent(stdout, level);
1324         fprintf(stdout, "Unsuccessful response, no more information.\n");
1325     }
1326 
1327     CERT_DestroyOCSPResponse(response);
1328 }
1329 
1330 /* In the case of renegotiation, handshakes that occur in an already MAC'ed
1331  * channel, by the time of this call, the caller has already removed the MAC
1332  * from input recordLen. The only MAC'ed record that will get here with its
1333  * MAC intact (not removed) is the first Finished message on the connection.
1334  */
1335 void
print_ssl3_handshake(unsigned char * recordBuf,unsigned int recordLen,SSLRecord * sr,DataBufferList * s)1336 print_ssl3_handshake(unsigned char *recordBuf,
1337                      unsigned int recordLen,
1338                      SSLRecord *sr,
1339                      DataBufferList *s)
1340 {
1341     struct sslhandshake sslh;
1342     unsigned char *hsdata;
1343     unsigned int offset = 0;
1344 
1345     PR_fprintf(PR_STDOUT, "   handshake {\n");
1346 
1347     if (s->msgBufOffset && s->msgBuf) {
1348         /* append recordBuf to msgBuf, then use msgBuf */
1349         if (s->msgBufOffset + recordLen > s->msgBufSize) {
1350             int newSize = s->msgBufOffset + recordLen;
1351             unsigned char *newBuf = PORT_Realloc(s->msgBuf, newSize);
1352             if (!newBuf) {
1353                 PR_ASSERT(newBuf);
1354                 showErr("Realloc failed");
1355                 exit(10);
1356             }
1357             s->msgBuf = newBuf;
1358             s->msgBufSize = newSize;
1359         }
1360         memcpy(s->msgBuf + s->msgBufOffset, recordBuf, recordLen);
1361         s->msgBufOffset += recordLen;
1362         recordLen = s->msgBufOffset;
1363         recordBuf = s->msgBuf;
1364     }
1365     while (offset + 4 <= recordLen) {
1366         sslh.type = recordBuf[offset];
1367         sslh.length = GET_24(recordBuf + offset + 1);
1368         if (offset + 4 + sslh.length > recordLen)
1369             break;
1370         /* finally have a complete message */
1371         if (sslhexparse)
1372             print_hex(4, recordBuf + offset);
1373 
1374         hsdata = &recordBuf[offset + 4];
1375 
1376         PR_fprintf(PR_STDOUT, "      type = %d (", sslh.type);
1377         switch (sslh.type) {
1378             case 0:
1379                 PR_FPUTS("hello_request)\n");
1380                 break;
1381             case 1:
1382                 PR_FPUTS("client_hello)\n");
1383                 break;
1384             case 2:
1385                 PR_FPUTS("server_hello)\n");
1386                 break;
1387             case 4:
1388                 PR_FPUTS("new_session_ticket)\n");
1389                 break;
1390             case 11:
1391                 PR_FPUTS("certificate)\n");
1392                 break;
1393             case 12:
1394                 PR_FPUTS("server_key_exchange)\n");
1395                 break;
1396             case 13:
1397                 PR_FPUTS("certificate_request)\n");
1398                 break;
1399             case 14:
1400                 PR_FPUTS("server_hello_done)\n");
1401                 break;
1402             case 15:
1403                 PR_FPUTS("certificate_verify)\n");
1404                 break;
1405             case 16:
1406                 PR_FPUTS("client_key_exchange)\n");
1407                 break;
1408             case 20:
1409                 PR_FPUTS("finished)\n");
1410                 break;
1411             case 22:
1412                 PR_FPUTS("certificate_status)\n");
1413                 break;
1414             default:
1415                 PR_FPUTS("unknown)\n");
1416                 break;
1417         }
1418 
1419         PR_fprintf(PR_STDOUT, "      length = %d (0x%06x)\n", sslh.length, sslh.length);
1420         switch (sslh.type) {
1421 
1422             case 0: /* hello_request */ /* not much to show here. */
1423                 break;
1424 
1425             case 1: /* client hello */
1426                 switch (sr->ver_maj) {
1427                     case 3: /* ssl version 3 */
1428                     {
1429                         unsigned int pos;
1430                         int w;
1431 
1432                         PR_fprintf(PR_STDOUT, "         ClientHelloV3 {\n");
1433                         PR_fprintf(PR_STDOUT, "            client_version = {%d, %d}\n",
1434                                    (PRUint8)hsdata[0], (PRUint8)hsdata[1]);
1435                         PR_fprintf(PR_STDOUT, "            random = {...}\n");
1436                         if (sslhexparse)
1437                             print_hex(32, &hsdata[2]);
1438 
1439                         /* pretty print Session ID */
1440                         {
1441                             int sidlength =
1442                                 (int)hsdata[2 + 32];
1443                             PR_fprintf(PR_STDOUT, "            session ID = {\n");
1444                             PR_fprintf(PR_STDOUT, "                length = %d\n", sidlength);
1445                             PR_fprintf(PR_STDOUT, "                contents = {...}\n");
1446                             if (sslhexparse)
1447                                 print_hex(sidlength, &hsdata[2 + 32 + 1]);
1448                             PR_fprintf(PR_STDOUT, "            }\n");
1449                             pos =
1450                                 2 +
1451                                 32 +
1452                                 1 +
1453                                 sidlength;
1454                         }
1455 
1456                         /* pretty print cipher suites */
1457                         {
1458                             int csuitelength =
1459                                 GET_SHORT((hsdata + pos));
1460                             PR_fprintf(PR_STDOUT, "            cipher_suites[%d] = {\n",
1461                                        csuitelength /
1462                                            2);
1463                             if (csuitelength %
1464                                 2) {
1465                                 PR_fprintf(PR_STDOUT,
1466                                            "*error in protocol - csuitelength shouldn't be odd*\n");
1467                             }
1468                             for (w =
1469                                      0;
1470                                  w <
1471                                  csuitelength;
1472                                  w += 2) {
1473                                 PRUint32 cs_int =
1474                                     GET_SHORT((hsdata + pos + 2 + w));
1475                                 const char *cs_str =
1476                                     V2CipherString(cs_int);
1477                                 PR_fprintf(PR_STDOUT,
1478                                            "                (0x%04x) %s\n", cs_int, cs_str);
1479                             }
1480                             pos +=
1481                                 2 +
1482                                 csuitelength;
1483                             PR_fprintf(PR_STDOUT, "            }\n");
1484                         }
1485 
1486                         /* pretty print compression methods */
1487                         {
1488                             int complength =
1489                                 hsdata[pos];
1490                             PR_fprintf(PR_STDOUT, "            compression[%d] = {\n",
1491                                        complength);
1492                             for (w =
1493                                      0;
1494                                  w <
1495                                  complength;
1496                                  w++) {
1497                                 PRUint32 cm_int =
1498                                     hsdata[pos + 1 + w];
1499                                 const char *cm_str =
1500                                     CompressionMethodString(cm_int);
1501                                 PR_fprintf(PR_STDOUT,
1502                                            "                (%02x) %s\n", cm_int, cm_str);
1503                             }
1504                             pos +=
1505                                 1 +
1506                                 complength;
1507                             PR_fprintf(PR_STDOUT, "            }\n");
1508                         }
1509 
1510                         /* pretty print extensions, if any */
1511                         pos =
1512                             print_hello_extension(hsdata, sslh.length, pos);
1513 
1514                         PR_fprintf(PR_STDOUT, "         }\n");
1515                     } /* end of ssl version 3 */
1516                     break;
1517                     default:
1518                         PR_fprintf(PR_STDOUT, "         UNDEFINED VERSION %d.%d {...}\n",
1519                                    sr->ver_maj, sr->ver_min);
1520                         if (sslhexparse)
1521                             print_hex(sslh.length, hsdata);
1522                         break;
1523                 } /* end of switch sr->ver_maj */
1524                 break;
1525 
1526             case 2: /* server hello */
1527             {
1528                 unsigned int sidlength, pos;
1529 
1530                 PR_fprintf(PR_STDOUT, "         ServerHello {\n");
1531 
1532                 PR_fprintf(PR_STDOUT, "            server_version = {%d, %d}\n",
1533                            (PRUint8)hsdata[0], (PRUint8)hsdata[1]);
1534                 PR_fprintf(PR_STDOUT, "            random = {...}\n");
1535                 if (sslhexparse)
1536                     print_hex(32, &hsdata[2]);
1537                 PR_fprintf(PR_STDOUT, "            session ID = {\n");
1538                 sidlength = (int)hsdata[2 +
1539                                         32];
1540                 PR_fprintf(PR_STDOUT, "                length = %d\n", sidlength);
1541                 PR_fprintf(PR_STDOUT, "                contents = {...}\n");
1542                 if (sslhexparse)
1543                     print_hex(sidlength, &hsdata[2 + 32 + 1]);
1544                 PR_fprintf(PR_STDOUT, "            }\n");
1545                 pos = 2 +
1546                       32 + 1 +
1547                       sidlength;
1548 
1549                 /* pretty print chosen cipher suite */
1550                 {
1551                     PRUint32 cs_int = GET_SHORT((hsdata + pos));
1552                     const char *cs_str =
1553                         V2CipherString(cs_int);
1554                     PR_fprintf(PR_STDOUT, "            cipher_suite = (0x%04x) %s\n",
1555                                cs_int, cs_str);
1556                     currentcipher =
1557                         cs_int;
1558                     pos +=
1559                         2;
1560                 }
1561                 /* pretty print chosen compression method */
1562                 {
1563                     PRUint32 cm_int = hsdata[pos++];
1564                     const char *cm_str =
1565                         CompressionMethodString(cm_int);
1566                     PR_fprintf(PR_STDOUT, "            compression method = (%02x) %s\n",
1567                                cm_int, cm_str);
1568                 }
1569 
1570                 /* pretty print extensions, if any */
1571                 pos = print_hello_extension(hsdata, sslh.length, pos);
1572 
1573                 PR_fprintf(PR_STDOUT, "         }\n");
1574             } break;
1575 
1576             case 4: /* new session ticket */
1577             {
1578                 PRUint32 lifetimehint;
1579                 PRUint16 ticketlength;
1580                 char lifetime[32];
1581                 lifetimehint = GET_32(hsdata);
1582                 if (lifetimehint) {
1583                     PRExplodedTime et;
1584                     PRTime t =
1585                         lifetimehint;
1586                     t *=
1587                         PR_USEC_PER_SEC;
1588                     PR_ExplodeTime(t, PR_GMTParameters, &et);
1589                     /* use HTTP Cookie header's date format */
1590                     PR_FormatTimeUSEnglish(lifetime, sizeof lifetime,
1591                                            "%a, %d-%b-%Y %H:%M:%S GMT", &et);
1592                 } else {
1593                     /* 0 means the lifetime of the ticket is unspecified */
1594                     strcpy(lifetime, "unspecified");
1595                 }
1596                 ticketlength = GET_SHORT((hsdata +
1597                                           4));
1598                 PR_fprintf(PR_STDOUT, "         NewSessionTicket {\n");
1599                 PR_fprintf(PR_STDOUT, "            ticket_lifetime_hint = %s\n",
1600                            lifetime);
1601                 PR_fprintf(PR_STDOUT, "            ticket = {\n");
1602                 PR_fprintf(PR_STDOUT, "                length = %d\n", ticketlength);
1603                 PR_fprintf(PR_STDOUT, "                contents = {...}\n");
1604                 if (sslhexparse)
1605                     print_hex(ticketlength, &hsdata[4 + 2]);
1606                 PR_fprintf(PR_STDOUT, "            }\n");
1607                 PR_fprintf(PR_STDOUT, "         }\n");
1608             } break;
1609 
1610             case 11: /* certificate */
1611             {
1612                 PRFileDesc *cfd;
1613                 int pos;
1614                 int certslength;
1615                 int certlength;
1616                 int certbytesread = 0;
1617                 static int certFileNumber;
1618                 char certFileName[20];
1619 
1620                 PR_fprintf(PR_STDOUT, "         CertificateChain {\n");
1621                 certslength = GET_24(hsdata);
1622                 PR_fprintf(PR_STDOUT, "            chainlength = %d (0x%04x)\n",
1623                            certslength, certslength);
1624                 pos = 3;
1625                 while (certbytesread < certslength) {
1626                     certlength =
1627                         GET_24((hsdata + pos));
1628                     pos +=
1629                         3;
1630                     PR_fprintf(PR_STDOUT, "            Certificate {\n");
1631                     PR_fprintf(PR_STDOUT, "               size = %d (0x%04x)\n",
1632                                certlength, certlength);
1633                     certbytesread +=
1634                         certlength + 3;
1635                     if (certbytesread <=
1636                         certslength) {
1637                         PR_snprintf(certFileName, sizeof certFileName, "cert.%03d",
1638                                     ++certFileNumber);
1639                         cfd =
1640                             PR_Open(certFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
1641                                     0664);
1642                         if (!cfd) {
1643                             PR_fprintf(PR_STDOUT,
1644                                        "               data = { couldn't save file '%s' }\n",
1645                                        certFileName);
1646                         } else {
1647                             PR_Write(cfd, (hsdata +
1648                                            pos),
1649                                      certlength);
1650                             PR_fprintf(PR_STDOUT,
1651                                        "               data = { saved in file '%s' }\n",
1652                                        certFileName);
1653                             PR_Close(cfd);
1654                         }
1655                     }
1656 
1657                     PR_fprintf(PR_STDOUT, "            }\n");
1658                     pos += certlength;
1659                 }
1660                 PR_fprintf(PR_STDOUT, "         }\n");
1661             } break;
1662 
1663             case 12: /* server_key_exchange */
1664                 if (sslhexparse)
1665                     print_hex(sslh.length, hsdata);
1666                 break;
1667 
1668             case 13: /* certificate request */
1669             {
1670                 unsigned int pos = 0;
1671                 int w, reqLength;
1672 
1673                 PR_fprintf(PR_STDOUT, "         CertificateRequest {\n");
1674 
1675                 /* pretty print requested certificate types */
1676                 reqLength = hsdata[pos];
1677                 PR_fprintf(PR_STDOUT, "            certificate types[%d] = {",
1678                            reqLength);
1679                 for (w =
1680                          0;
1681                      w < reqLength; w++) {
1682                     PR_fprintf(PR_STDOUT, " %02x", hsdata[pos +
1683                                                           1 + w]);
1684                 }
1685                 pos += 1 + reqLength;
1686                 PR_fprintf(PR_STDOUT, " }\n");
1687 
1688                 /* pretty print CA names, if any */
1689                 if (pos < sslh.length) {
1690                     int exListLen =
1691                         GET_SHORT((hsdata + pos));
1692                     pos += 2;
1693                     PR_fprintf(PR_STDOUT,
1694                                "            certificate_authorities[%d] = {\n",
1695                                exListLen);
1696                     while (exListLen >
1697                                0 &&
1698                            pos < sslh.length) {
1699                         char *ca_name;
1700                         SECItem it;
1701                         int dnLen = GET_SHORT((hsdata +
1702                                                pos));
1703                         pos += 2;
1704 
1705                         /* dump the CA name */
1706                         it.type =
1707                             siBuffer;
1708                         it.data =
1709                             hsdata + pos;
1710                         it.len =
1711                             dnLen;
1712                         ca_name =
1713                             CERT_DerNameToAscii(&it);
1714                         if (ca_name) {
1715                             PR_fprintf(PR_STDOUT, "   %s\n", ca_name);
1716                             PORT_Free(ca_name);
1717                         } else {
1718                             PR_fprintf(PR_STDOUT,
1719                                        "              distinguished name [%d]", dnLen);
1720                             if (dnLen >
1721                                     0 &&
1722                                 sslhexparse) {
1723                                 PR_fprintf(PR_STDOUT, " = {\n");
1724                                 print_hex(dnLen, hsdata + pos);
1725                                 PR_fprintf(PR_STDOUT, "              }\n");
1726                             } else {
1727                                 PR_fprintf(PR_STDOUT, "\n");
1728                             }
1729                         }
1730                         pos +=
1731                             dnLen;
1732                         exListLen -=
1733                             2 + dnLen;
1734                     }
1735                     PR_fprintf(PR_STDOUT, "            }\n");
1736                 }
1737 
1738                 PR_fprintf(PR_STDOUT, "         }\n");
1739             } break;
1740 
1741             case 14: /* server_hello_done */ /* not much to show here. */
1742                 break;
1743 
1744             case 15: /* certificate_verify */
1745                 if (sslhexparse)
1746                     print_hex(sslh.length, hsdata);
1747                 break;
1748 
1749             case 16: /* client key exchange */
1750             {
1751                 PR_fprintf(PR_STDOUT, "         ClientKeyExchange {\n");
1752                 PR_fprintf(PR_STDOUT, "            message = {...}\n");
1753                 PR_fprintf(PR_STDOUT, "         }\n");
1754             } break;
1755 
1756             case 20: /* finished */
1757                 PR_fprintf(PR_STDOUT, "         Finished {\n");
1758                 PR_fprintf(PR_STDOUT, "            verify_data = {...}\n");
1759                 if (sslhexparse)
1760                     print_hex(sslh.length, hsdata);
1761                 PR_fprintf(PR_STDOUT, "         }\n");
1762 
1763                 if (!isNULLmac(currentcipher) &&
1764                     !s->hMACsize) {
1765                     /* To calculate the size of MAC, we subtract the number of known
1766                      * bytes of message from the number of remaining bytes in the
1767                      * record. This assumes that this is the first record on the
1768                      * connection to have a MAC, and that the sender has not put another
1769                      * message after the finished message in the handshake record.
1770                      * This is only correct for the first transition from unMACed to
1771                      * MACed. If the connection switches from one cipher suite to
1772                      * another one with a different MAC, this logic will not track that
1773                      * change correctly.
1774                      */
1775                     s->hMACsize =
1776                         recordLen - (sslh.length + 4);
1777                     sslh.length +=
1778                         s->hMACsize; /* skip over the MAC data */
1779                 }
1780                 break;
1781 
1782             case 22: /* certificate_status */
1783             {
1784                 SECItem data;
1785                 PRFileDesc *ofd;
1786                 static int ocspFileNumber;
1787                 char ocspFileName[20];
1788 
1789                 /* skip 4 bytes with handshake numbers, as in ssl3_HandleCertificateStatus */
1790                 data.type = siBuffer;
1791                 data.data = hsdata + 4;
1792                 data.len = sslh.length - 4;
1793                 print_status_response(&data);
1794 
1795                 PR_snprintf(ocspFileName, sizeof ocspFileName, "ocsp.%03d",
1796                             ++ocspFileNumber);
1797                 ofd = PR_Open(ocspFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
1798                               0664);
1799                 if (!ofd) {
1800                     PR_fprintf(PR_STDOUT,
1801                                "               data = { couldn't save file '%s' }\n",
1802                                ocspFileName);
1803                 } else {
1804                     PR_Write(ofd, data.data, data.len);
1805                     PR_fprintf(PR_STDOUT,
1806                                "               data = { saved in file '%s' }\n",
1807                                ocspFileName);
1808                     PR_Close(ofd);
1809                 }
1810             } break;
1811 
1812             default: {
1813                 PR_fprintf(PR_STDOUT, "         UNKNOWN MESSAGE TYPE %d [%d] {\n",
1814                            sslh.type, sslh.length);
1815                 if (sslhexparse)
1816                     print_hex(sslh.length, hsdata);
1817                 PR_fprintf(PR_STDOUT, "         }\n");
1818             }
1819         } /* end of switch sslh.type */
1820         offset += sslh.length + 4;
1821     }                         /* while */
1822     if (offset < recordLen) { /* stuff left over */
1823         unsigned int newMsgLen = recordLen - offset;
1824         if (!s->msgBuf) {
1825             s->msgBuf = PORT_Alloc(newMsgLen);
1826             if (!s->msgBuf) {
1827                 PR_ASSERT(s->msgBuf);
1828                 showErr("Malloc failed");
1829                 exit(11);
1830             }
1831             s->msgBufSize = newMsgLen;
1832             memcpy(s->msgBuf, recordBuf + offset, newMsgLen);
1833         } else if (newMsgLen > s->msgBufSize) {
1834             unsigned char *newBuf = PORT_Realloc(s->msgBuf, newMsgLen);
1835             if (!newBuf) {
1836                 PR_ASSERT(newBuf);
1837                 showErr("Realloc failed");
1838                 exit(12);
1839             }
1840             s->msgBuf = newBuf;
1841             s->msgBufSize = newMsgLen;
1842         } else if (offset || s->msgBuf != recordBuf) {
1843             memmove(s->msgBuf, recordBuf + offset, newMsgLen);
1844         }
1845         s->msgBufOffset = newMsgLen;
1846         PR_fprintf(PR_STDOUT, "     [incomplete handshake message]\n");
1847     } else {
1848         s->msgBufOffset = 0;
1849     }
1850     PR_fprintf(PR_STDOUT, "   }\n");
1851 }
1852 
1853 void
print_ssl(DataBufferList * s,int length,unsigned char * buffer)1854 print_ssl(DataBufferList *s, int length, unsigned char *buffer)
1855 {
1856     /* --------------------------------------------------------  */
1857     /* first, create a new buffer object for this piece of data. */
1858 
1859     DataBuffer *db;
1860 
1861     if (s->size == 0 && length > 0 && buffer[0] >= 32 && buffer[0] < 128) {
1862         /* Not an SSL record, treat entire buffer as plaintext */
1863         PR_Write(PR_STDOUT, buffer, length);
1864         return;
1865     }
1866 
1867     check_integrity(s);
1868 
1869     db = PR_NEW(struct _DataBuffer);
1870 
1871     if (!db) {
1872         return;
1873     }
1874 
1875     db->buffer = (unsigned char *)PORT_Alloc(length);
1876     db->length = length;
1877     db->offset = 0;
1878     memcpy(db->buffer, buffer, length);
1879     db->next = NULL;
1880 
1881     /* now, add it to the stream */
1882 
1883     if (s->last != NULL)
1884         s->last->next = db;
1885     s->last = db;
1886     s->size += length;
1887     if (s->first == NULL)
1888         s->first = db;
1889 
1890     check_integrity(s);
1891 
1892     /*------------------------------------------------------- */
1893     /* now we look at the stream to see if we have enough data to
1894      decode  */
1895 
1896     while (s->size > 0) {
1897         unsigned char *recordBuf = NULL;
1898 
1899         SSLRecord sr;
1900         unsigned recordLen;
1901         unsigned recordsize;
1902 
1903         check_integrity(s);
1904 
1905         if (s->first == NULL) {
1906             PR_fprintf(PR_STDOUT, "ERROR: s->first is null\n");
1907             exit(9);
1908         }
1909 
1910         /* in the case of an SSL 2 client-hello  */
1911         /* will have the high-bit set, whereas an SSL 3 client-hello will not  */
1912         /* SSL2 can also send records that begin with the high bit clear.
1913          * This code will incorrectly handle them. XXX
1914          */
1915         if (isV2Session || s->first->buffer[s->first->offset] & 0x80) {
1916             /* it's an SSL 2 packet */
1917             unsigned char lenbuf[3];
1918 
1919             /* first, we check if there's enough data for it to be an SSL2-type
1920              * record.  What a pain.*/
1921             if (s->size < sizeof lenbuf) {
1922                 partial_packet(length, s->size, sizeof lenbuf);
1923                 return;
1924             }
1925 
1926             /* read the first two bytes off the stream. */
1927             read_stream_bytes(lenbuf, s, sizeof(lenbuf));
1928             recordLen = ((unsigned int)(lenbuf[0] & 0x7f) << 8) + lenbuf[1] +
1929                         ((lenbuf[0] & 0x80) ? 2 : 3);
1930             PR_fprintf(PR_STDOUT, "recordLen = %u bytes\n", recordLen);
1931 
1932             /* put 'em back on the head of the stream. */
1933             db = PR_NEW(struct _DataBuffer);
1934 
1935             db->length = sizeof lenbuf;
1936             db->buffer = (unsigned char *)PORT_Alloc(db->length);
1937             db->offset = 0;
1938             memcpy(db->buffer, lenbuf, sizeof lenbuf);
1939 
1940             db->next = s->first;
1941             s->first = db;
1942             if (s->last == NULL)
1943                 s->last = db;
1944             s->size += db->length;
1945 
1946             /* if there wasn't enough, go back for more. */
1947             if (s->size < recordLen) {
1948                 check_integrity(s);
1949                 partial_packet(length, s->size, recordLen);
1950                 return;
1951             }
1952             partial_packet(length, s->size, recordLen);
1953 
1954             /* read in the whole record. */
1955             recordBuf = PORT_Alloc(recordLen);
1956             read_stream_bytes(recordBuf, s, recordLen);
1957 
1958             print_sslv2(s, recordBuf, recordLen);
1959             PR_FREEIF(recordBuf);
1960             check_integrity(s);
1961 
1962             continue;
1963         }
1964 
1965         /***********************************************************/
1966         /* It's SSL v3 */
1967         /***********************************************************/
1968         check_integrity(s);
1969 
1970         if (s->size < sizeof sr) {
1971             partial_packet(length, s->size, sizeof(SSLRecord));
1972             return;
1973         }
1974 
1975         read_stream_bytes((unsigned char *)&sr, s, sizeof sr);
1976 
1977         /* we have read the stream bytes. Look at the length of
1978        the ssl record. If we don't have enough data to satisfy this
1979        request, then put the bytes we just took back at the head
1980        of the queue */
1981         recordsize = GET_SHORT(sr.length);
1982 
1983         if (recordsize > s->size) {
1984             db = PR_NEW(struct _DataBuffer);
1985 
1986             db->length = sizeof sr;
1987             db->buffer = (unsigned char *)PORT_Alloc(db->length);
1988             db->offset = 0;
1989             memcpy(db->buffer, &sr, sizeof sr);
1990             db->next = s->first;
1991 
1992             /* now, add it back on to the head of the stream */
1993 
1994             s->first = db;
1995             if (s->last == NULL)
1996                 s->last = db;
1997             s->size += db->length;
1998 
1999             check_integrity(s);
2000             partial_packet(length, s->size, recordsize);
2001             return;
2002         }
2003         partial_packet(length, s->size, recordsize);
2004 
2005         PR_fprintf(PR_STDOUT, "SSLRecord { [%s]\n", get_time_string());
2006         if (sslhexparse) {
2007             print_hex(5, (unsigned char *)&sr);
2008         }
2009 
2010         check_integrity(s);
2011 
2012         PR_fprintf(PR_STDOUT, "   type    = %d (", sr.type);
2013         switch (sr.type) {
2014             case 20:
2015                 PR_fprintf(PR_STDOUT, "change_cipher_spec)\n");
2016                 break;
2017             case 21:
2018                 PR_fprintf(PR_STDOUT, "alert)\n");
2019                 break;
2020             case 22:
2021                 PR_fprintf(PR_STDOUT, "handshake)\n");
2022                 break;
2023             case 23:
2024                 PR_fprintf(PR_STDOUT, "application_data)\n");
2025                 break;
2026             default:
2027                 PR_fprintf(PR_STDOUT, "unknown)\n");
2028                 break;
2029         }
2030         PR_fprintf(PR_STDOUT, "   version = { %d,%d }\n",
2031                    (PRUint32)sr.ver_maj, (PRUint32)sr.ver_min);
2032         PR_fprintf(PR_STDOUT, "   length  = %d (0x%x)\n",
2033                    (PRUint32)GET_SHORT(sr.length), (PRUint32)GET_SHORT(sr.length));
2034 
2035         recordLen = recordsize;
2036         PR_ASSERT(s->size >= recordLen);
2037         if (s->size >= recordLen) {
2038             recordBuf = (unsigned char *)PORT_Alloc(recordLen);
2039             read_stream_bytes(recordBuf, s, recordLen);
2040 
2041             if (s->isEncrypted) {
2042                 PR_fprintf(PR_STDOUT, "            < encrypted >\n");
2043             } else { /* not encrypted */
2044 
2045                 switch (sr.type) {
2046                     case 20: /* change_cipher_spec */
2047                         if (sslhexparse)
2048                             print_hex(recordLen - s->hMACsize, recordBuf);
2049                         /* mark to say we can only dump hex form now on
2050                          * if it is not one on a null cipher */
2051                         s->isEncrypted =
2052                             isNULLcipher(currentcipher) ? 0 : 1;
2053                         break;
2054 
2055                     case 21: /* alert */
2056                         switch (recordBuf[0]) {
2057                             case 1:
2058                                 PR_fprintf(PR_STDOUT, "   warning: ");
2059                                 break;
2060                             case 2:
2061                                 PR_fprintf(PR_STDOUT, "   fatal: ");
2062                                 break;
2063                             default:
2064                                 PR_fprintf(PR_STDOUT, "   unknown level %d: ", recordBuf[0]);
2065                                 break;
2066                         }
2067 
2068                         switch (recordBuf[1]) {
2069                             case 0:
2070                                 PR_FPUTS("close_notify\n");
2071                                 break;
2072                             case 10:
2073                                 PR_FPUTS("unexpected_message\n");
2074                                 break;
2075                             case 20:
2076                                 PR_FPUTS("bad_record_mac\n");
2077                                 break;
2078                             case 21:
2079                                 PR_FPUTS("decryption_failed\n");
2080                                 break;
2081                             case 22:
2082                                 PR_FPUTS("record_overflow\n");
2083                                 break;
2084                             case 30:
2085                                 PR_FPUTS("decompression_failure\n");
2086                                 break;
2087                             case 40:
2088                                 PR_FPUTS("handshake_failure\n");
2089                                 break;
2090                             case 41:
2091                                 PR_FPUTS("no_certificate\n");
2092                                 break;
2093                             case 42:
2094                                 PR_FPUTS("bad_certificate\n");
2095                                 break;
2096                             case 43:
2097                                 PR_FPUTS("unsupported_certificate\n");
2098                                 break;
2099                             case 44:
2100                                 PR_FPUTS("certificate_revoked\n");
2101                                 break;
2102                             case 45:
2103                                 PR_FPUTS("certificate_expired\n");
2104                                 break;
2105                             case 46:
2106                                 PR_FPUTS("certificate_unknown\n");
2107                                 break;
2108                             case 47:
2109                                 PR_FPUTS("illegal_parameter\n");
2110                                 break;
2111                             case 48:
2112                                 PR_FPUTS("unknown_ca\n");
2113                                 break;
2114                             case 49:
2115                                 PR_FPUTS("access_denied\n");
2116                                 break;
2117                             case 50:
2118                                 PR_FPUTS("decode_error\n");
2119                                 break;
2120                             case 51:
2121                                 PR_FPUTS("decrypt_error\n");
2122                                 break;
2123                             case 60:
2124                                 PR_FPUTS("export_restriction\n");
2125                                 break;
2126                             case 70:
2127                                 PR_FPUTS("protocol_version\n");
2128                                 break;
2129                             case 71:
2130                                 PR_FPUTS("insufficient_security\n");
2131                                 break;
2132                             case 80:
2133                                 PR_FPUTS("internal_error\n");
2134                                 break;
2135                             case 90:
2136                                 PR_FPUTS("user_canceled\n");
2137                                 break;
2138                             case 100:
2139                                 PR_FPUTS("no_renegotiation\n");
2140                                 break;
2141                             case 110:
2142                                 PR_FPUTS("unsupported_extension\n");
2143                                 break;
2144                             case 111:
2145                                 PR_FPUTS("certificate_unobtainable\n");
2146                                 break;
2147                             case 112:
2148                                 PR_FPUTS("unrecognized_name\n");
2149                                 break;
2150                             case 113:
2151                                 PR_FPUTS("bad_certificate_status_response\n");
2152                                 break;
2153                             case 114:
2154                                 PR_FPUTS("bad_certificate_hash_value\n");
2155                                 break;
2156 
2157                             default:
2158                                 PR_fprintf(PR_STDOUT, "unknown alert %d\n", recordBuf[1]);
2159                                 break;
2160                         }
2161 
2162                         if (sslhexparse)
2163                             print_hex(recordLen - s->hMACsize, recordBuf);
2164                         break;
2165 
2166                     case 22: /* handshake */
2167                         print_ssl3_handshake(recordBuf, recordLen - s->hMACsize,
2168                                              &sr, s);
2169                         break;
2170 
2171                     case 23: /* application data */
2172                         print_hex(recordLen -
2173                                       s->hMACsize,
2174                                   recordBuf);
2175                         break;
2176 
2177                     default:
2178                         print_hex(recordLen -
2179                                       s->hMACsize,
2180                                   recordBuf);
2181                         break;
2182                 }
2183                 if (s->hMACsize) {
2184                     PR_fprintf(PR_STDOUT, "      MAC = {...}\n");
2185                     if (sslhexparse) {
2186                         unsigned char *offset =
2187                             recordBuf + (recordLen - s->hMACsize);
2188                         print_hex(s->hMACsize, offset);
2189                     }
2190                 }
2191             } /* not encrypted */
2192         }
2193         PR_fprintf(PR_STDOUT, "}\n");
2194         PR_FREEIF(recordBuf);
2195         check_integrity(s);
2196     }
2197 }
2198 
2199 void
print_hex(int amt,unsigned char * buf)2200 print_hex(int amt, unsigned char *buf)
2201 {
2202     int i, j, k;
2203     char t[20];
2204     static char string[5000];
2205 
2206     for (i = 0; i < amt; i++) {
2207         t[1] = 0;
2208 
2209         if (i % 16 == 0) {                    /* if we are at the beginning of a line */
2210             PR_fprintf(PR_STDOUT, "%4x:", i); /* print the line number  */
2211             strcpy(string, "");
2212         }
2213 
2214         if (i % 4 == 0) {
2215             PR_fprintf(PR_STDOUT, " ");
2216         }
2217 
2218         j = buf[i];
2219 
2220         t[0] = (j >= 0x20 && j < 0x80) ? j : '.';
2221 
2222         if (fancy) {
2223             switch (t[0]) {
2224                 case '<':
2225                     strcpy(t, "&lt;");
2226                     break;
2227                 case '>':
2228                     strcpy(t, "&gt;");
2229                     break;
2230                 case '&':
2231                     strcpy(t, "&amp;");
2232                     break;
2233             }
2234         }
2235         strcat(string, t);
2236 
2237         PR_fprintf(PR_STDOUT, "%02x ", (PRUint8)buf[i]);
2238 
2239         /* if we've reached the end of the line - add the string */
2240         if (i % 16 == 15)
2241             PR_fprintf(PR_STDOUT, " | %s\n", string);
2242     }
2243     /* we reached the end of the buffer,*/
2244     /* do we have buffer left over? */
2245     j = i % 16;
2246     if (j > 0) {
2247         for (k = 0; k < (16 -
2248                          j);
2249              k++) {
2250             /* print additional space after every four bytes */
2251             if ((k + j) % 4 == 0) {
2252                 PR_fprintf(PR_STDOUT, " ");
2253             }
2254             PR_fprintf(PR_STDOUT, "   ");
2255         }
2256         PR_fprintf(PR_STDOUT, " | %s\n", string);
2257     }
2258 }
2259 
2260 void
Usage(void)2261 Usage(void)
2262 {
2263     PR_fprintf(PR_STDERR, "Usage: ssltap [-vhfsxl] [-p port] hostname:port\n");
2264     PR_fprintf(PR_STDERR, "   -v      [prints version string]\n");
2265     PR_fprintf(PR_STDERR, "   -h      [outputs hex instead of ASCII]\n");
2266     PR_fprintf(PR_STDERR, "   -f      [turn on Fancy HTML coloring]\n");
2267     PR_fprintf(PR_STDERR, "   -s      [turn on SSL decoding]\n");
2268     PR_fprintf(PR_STDERR, "   -x      [turn on extra SSL hex dumps]\n");
2269     PR_fprintf(PR_STDERR, "   -p port [specify rendezvous port (default 1924)]\n");
2270     PR_fprintf(PR_STDERR, "   -l      [loop - continue to wait for more connections]\n");
2271 }
2272 
2273 void
showErr(const char * msg)2274 showErr(const char *msg)
2275 {
2276     PRErrorCode err = PR_GetError();
2277     const char *errString;
2278 
2279     if (err == PR_UNKNOWN_ERROR)
2280         err = PR_CONNECT_RESET_ERROR; /* bug in NSPR. */
2281     errString = SECU_Strerror(err);
2282 
2283     if (!errString)
2284         errString = "(no text available)";
2285     PR_fprintf(PR_STDERR, "%s: Error %d: %s: %s", progName, err, errString, msg);
2286 }
2287 
2288 int
main(int argc,char * argv[])2289 main(int argc, char *argv[])
2290 {
2291     char *hostname = NULL;
2292     PRUint16 rendport = DEFPORT, port;
2293     PRAddrInfo *ai;
2294     void *iter;
2295     PRStatus r;
2296     PRNetAddr na_client, na_server, na_rend;
2297     PRFileDesc *s_server, *s_client, *s_rend; /*rendezvous */
2298     int c_count = 0;
2299     PLOptState *optstate;
2300     PLOptStatus status;
2301     SECStatus rv;
2302 
2303     progName = argv[0];
2304     optstate = PL_CreateOptState(argc, argv, "fxhslp:");
2305     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
2306         switch (optstate->option) {
2307             case 'f':
2308                 fancy++;
2309                 break;
2310             case 'h':
2311                 hexparse++;
2312                 break;
2313             case 's':
2314                 sslparse++;
2315                 break;
2316             case 'x':
2317                 sslhexparse++;
2318                 break;
2319             case 'l':
2320                 looparound++;
2321                 break;
2322             case 'p':
2323                 rendport =
2324                     atoi(optstate->value);
2325                 break;
2326             case '\0':
2327                 hostname =
2328                     PL_strdup(optstate->value);
2329         }
2330     }
2331     if (status == PL_OPT_BAD)
2332         Usage();
2333 
2334     if (fancy) {
2335         if (!hexparse && !sslparse) {
2336             PR_fprintf(PR_STDERR,
2337                        "Note: use of -f without -s or -h not recommended, \n"
2338                        "as the output looks a little strange. It may be useful, however\n");
2339         }
2340     }
2341 
2342     if (!hostname)
2343         Usage(), exit(2);
2344 
2345     {
2346         char *colon = (char *)strchr(hostname, ':');
2347         if (!colon) {
2348             PR_fprintf(PR_STDERR,
2349                        "You must specify the host AND port you wish to connect to\n");
2350             Usage(), exit(3);
2351         }
2352         port = atoi(&colon[1]);
2353         *colon = '\0';
2354 
2355         if (port == 0) {
2356             PR_fprintf(PR_STDERR, "Port must be a nonzero number.\n");
2357             exit(4);
2358         }
2359     }
2360 
2361     /* find the 'server' IP address so we don't have to look it up later */
2362 
2363     if (fancy) {
2364         PR_fprintf(PR_STDOUT, "<HTML><HEAD><TITLE>SSLTAP output</TITLE></HEAD>\n");
2365         PR_fprintf(PR_STDOUT, "<BODY><PRE>\n");
2366     }
2367     PR_fprintf(PR_STDERR, "Looking up \"%s\"...\n", hostname);
2368     ai = PR_GetAddrInfoByName(hostname, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
2369     if (!ai) {
2370         showErr("Host Name lookup failed\n");
2371         exit(5);
2372     }
2373 
2374     iter = NULL;
2375     iter = PR_EnumerateAddrInfo(iter, ai, port, &na_server);
2376     /* set up the port which the client will connect to */
2377 
2378     r = PR_InitializeNetAddr(PR_IpAddrAny, rendport, &na_rend);
2379     if (r == PR_FAILURE) {
2380         PR_fprintf(PR_STDERR,
2381                    "PR_InitializeNetAddr(,%d,) failed with error %d\n", PR_GetError());
2382         exit(0);
2383     }
2384 
2385     rv = NSS_NoDB_Init("");
2386     if (rv != SECSuccess) {
2387         PR_fprintf(PR_STDERR,
2388                    "NSS_NoDB_Init() failed with error %d\n", PR_GetError());
2389         exit(5);
2390     }
2391 
2392     s_rend = PR_NewTCPSocket();
2393     if (!s_rend) {
2394         showErr("Couldn't create socket\n");
2395         exit(6);
2396     }
2397 
2398     if (PR_Bind(s_rend, &na_rend)) {
2399         PR_fprintf(PR_STDERR, "Couldn't bind to port %d (error %d)\n", rendport, PR_GetError());
2400         exit(-1);
2401     }
2402 
2403     if (PR_Listen(s_rend, 5)) {
2404         showErr("Couldn't listen\n");
2405         exit(-1);
2406     }
2407 
2408     PR_fprintf(PR_STDERR, "Proxy socket ready and listening\n");
2409     do { /* accept one connection and process it. */
2410         PRPollDesc pds[2];
2411 
2412         s_client = PR_Accept(s_rend, &na_client, PR_SecondsToInterval(3600));
2413         if (s_client == NULL) {
2414             showErr("accept timed out\n");
2415             exit(7);
2416         }
2417 
2418         s_server = PR_OpenTCPSocket(na_server.raw.family);
2419         if (s_server == NULL) {
2420             showErr("couldn't open new socket to connect to server \n");
2421             exit(8);
2422         }
2423 
2424         r = PR_Connect(s_server, &na_server, PR_SecondsToInterval(5));
2425 
2426         if (r == PR_FAILURE) {
2427             showErr("Couldn't connect\n");
2428             return -1;
2429         }
2430 
2431         if (looparound) {
2432             if (fancy)
2433                 PR_fprintf(PR_STDOUT, "<p><HR><H2>");
2434             PR_fprintf(PR_STDOUT, "Connection #%d [%s]\n", c_count + 1,
2435                        get_time_string());
2436             if (fancy)
2437                 PR_fprintf(PR_STDOUT, "</H2>");
2438         }
2439 
2440         PR_fprintf(PR_STDOUT, "Connected to %s:%d\n", hostname, port);
2441 
2442 #define PD_C 0
2443 #define PD_S 1
2444 
2445         pds[PD_C].fd = s_client;
2446         pds[PD_S].fd = s_server;
2447         pds[PD_C].in_flags = PR_POLL_READ;
2448         pds[PD_S].in_flags = PR_POLL_READ;
2449 
2450         /* make sure the new connections don't start out encrypted. */
2451         clientstream.isEncrypted = 0;
2452         serverstream.isEncrypted = 0;
2453         isV2Session = 0;
2454 
2455         while ((pds[PD_C].in_flags & PR_POLL_READ) != 0 ||
2456                (pds[PD_S].in_flags & PR_POLL_READ) != 0) { /* Handle all messages on the connection */
2457             PRInt32 amt;
2458             PRInt32 wrote;
2459             unsigned char buffer[TAPBUFSIZ];
2460 
2461             amt = PR_Poll(pds, 2, PR_INTERVAL_NO_TIMEOUT);
2462             if (amt <= 0) {
2463                 if (amt)
2464                     showErr("PR_Poll failed.\n");
2465                 else
2466                     showErr("PR_Poll timed out.\n");
2467                 break;
2468             }
2469 
2470             if (pds[PD_C].out_flags & PR_POLL_EXCEPT) {
2471                 showErr("Exception on client-side socket.\n");
2472                 break;
2473             }
2474 
2475             if (pds[PD_S].out_flags & PR_POLL_EXCEPT) {
2476                 showErr("Exception on server-side socket.\n");
2477                 break;
2478             }
2479 
2480             /* read data, copy it to stdout, and write to other socket */
2481 
2482             if ((pds[PD_C].in_flags & PR_POLL_READ) != 0 &&
2483                 (pds[PD_C].out_flags & PR_POLL_READ) != 0) {
2484 
2485                 amt = PR_Read(s_client, buffer, sizeof(buffer));
2486 
2487                 if (amt < 0) {
2488                     showErr("Client socket read failed.\n");
2489                     break;
2490                 }
2491 
2492                 if (amt == 0) {
2493                     PR_fprintf(PR_STDOUT, "Read EOF on Client socket. [%s]\n",
2494                                get_time_string());
2495                     pds[PD_C].in_flags &= ~PR_POLL_READ;
2496                     PR_Shutdown(s_server, PR_SHUTDOWN_SEND);
2497                     continue;
2498                 }
2499 
2500                 PR_fprintf(PR_STDOUT, "--> [\n");
2501                 if (fancy)
2502                     PR_fprintf(PR_STDOUT, "<font color=blue>");
2503 
2504                 if (hexparse)
2505                     print_hex(amt, buffer);
2506                 if (sslparse)
2507                     print_ssl(&clientstream, amt, buffer);
2508                 if (!hexparse && !sslparse)
2509                     PR_Write(PR_STDOUT, buffer, amt);
2510                 if (fancy)
2511                     PR_fprintf(PR_STDOUT, "</font>");
2512                 PR_fprintf(PR_STDOUT, "]\n");
2513 
2514                 wrote = PR_Write(s_server, buffer, amt);
2515                 if (wrote != amt) {
2516                     if (wrote < 0) {
2517                         showErr("Write to server socket failed.\n");
2518                         break;
2519                     } else {
2520                         PR_fprintf(PR_STDERR, "Short write to server socket!\n");
2521                     }
2522                 }
2523             } /* end of read from client socket. */
2524 
2525             /* read data, copy it to stdout, and write to other socket */
2526             if ((pds[PD_S].in_flags & PR_POLL_READ) != 0 &&
2527                 (pds[PD_S].out_flags & PR_POLL_READ) != 0) {
2528 
2529                 amt = PR_Read(s_server, buffer, sizeof(buffer));
2530 
2531                 if (amt < 0) {
2532                     showErr("error on server-side socket.\n");
2533                     break;
2534                 }
2535 
2536                 if (amt == 0) {
2537                     PR_fprintf(PR_STDOUT, "Read EOF on Server socket. [%s]\n",
2538                                get_time_string());
2539                     pds[PD_S].in_flags &= ~PR_POLL_READ;
2540                     PR_Shutdown(s_client, PR_SHUTDOWN_SEND);
2541                     continue;
2542                 }
2543 
2544                 PR_fprintf(PR_STDOUT, "<-- [\n");
2545                 if (fancy)
2546                     PR_fprintf(PR_STDOUT, "<font color=red>");
2547                 if (hexparse)
2548                     print_hex(amt, (unsigned char *)buffer);
2549                 if (sslparse)
2550                     print_ssl(&serverstream, amt, (unsigned char *)buffer);
2551                 if (!hexparse && !sslparse)
2552                     PR_Write(PR_STDOUT, buffer, amt);
2553                 if (fancy)
2554                     PR_fprintf(PR_STDOUT, "</font>");
2555                 PR_fprintf(PR_STDOUT, "]\n");
2556 
2557                 wrote = PR_Write(s_client, buffer, amt);
2558                 if (wrote != amt) {
2559                     if (wrote < 0) {
2560                         showErr("Write to client socket failed.\n");
2561                         break;
2562                     } else {
2563                         PR_fprintf(PR_STDERR, "Short write to client socket!\n");
2564                     }
2565                 }
2566 
2567             } /* end of read from server socket. */
2568 
2569             /* Loop, handle next message. */
2570 
2571         } /* handle messages during a connection loop */
2572         PR_Close(s_client);
2573         PR_Close(s_server);
2574         flush_stream(&clientstream);
2575         flush_stream(&serverstream);
2576         /* Connection is closed, so reset the current cipher */
2577         currentcipher = 0;
2578         c_count++;
2579         PR_fprintf(PR_STDERR, "Connection %d Complete [%s]\n", c_count,
2580                    get_time_string());
2581     } while (looparound); /* accept connection and process it. */
2582     PR_Close(s_rend);
2583     NSS_Shutdown();
2584     return 0;
2585 }
2586