Bug Summary

File:s/cmd/ssltap/ssltap.c
Warning:line 2372, column 5
Value stored to 'iter' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ssltap.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/ssltap -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/ssltap -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -I ../../../dist/public/seccmd -I ../../../dist/public/dbm -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c ssltap.c
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
39struct _DataBufferList;
40struct _DataBuffer;
41
42typedef 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
52typedef struct _DataBuffer {
53 unsigned char *buffer;
54 int length;
55 int offset; /* offset of first good byte */
56 struct _DataBuffer *next;
57} DataBuffer;
58
59struct sslhandshake {
60 PRUint8 type;
61 PRUint32 length;
62};
63
64typedef struct _SSLRecord {
65 PRUint8 type;
66 PRUint8 ver_maj, ver_min;
67
68 PRUint8 length[2];
69} SSLRecord;
70
71typedef 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
81typedef 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
92typedef 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 */
103void showErr(const char *msg);
104
105#define TAPBUFSIZ16384 16384
106
107#define DEFPORT1924 1924
108#include <ctype.h>
109
110const char *progName;
111int hexparse = 0;
112int sslparse = 0;
113int sslhexparse = 0;
114int looparound = 0;
115int fancy = 0;
116int isV2Session = 0;
117int currentcipher = 0;
118DataBufferList clientstream, serverstream;
119
120#define PR_FPUTS(x)PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), x) PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), x)
121
122#define GET_SHORT(x)((PRUint16)(((PRUint16)((PRUint8 *)x)[0]) << 8) + ((PRUint16
)((PRUint8 *)x)[1]))
((PRUint16)(((PRUint16)((PRUint8 *)x)[0]) << 8) + ((PRUint16)((PRUint8 *)x)[1]))
123#define GET_24(x)((PRUint32)( (((PRUint32)((PRUint8 *)x)[0]) << 16) + ((
(PRUint32)((PRUint8 *)x)[1]) << 8) + (((PRUint32)((PRUint8
*)x)[2]) << 0)))
((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)( (((PRUint32)((PRUint8 *)x)[0]) << 24) + ((
(PRUint32)((PRUint8 *)x)[1]) << 16) + (((PRUint32)((PRUint8
*)x)[2]) << 8) + (((PRUint32)((PRUint8 *)x)[3]) <<
0)))
((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
133void print_hex(int amt, unsigned char *buf);
134void read_stream_bytes(unsigned char *d, DataBufferList *db, int length);
135
136void
137myhalt(int dblsize, int collectedsize)
138{
139
140 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "HALTED\n");
141 PR_ASSERT(dblsize == collectedsize)((dblsize == collectedsize)?((void)0):PR_Assert("dblsize == collectedsize"
,"ssltap.c",141))
;
142 exit(13);
143}
144
145const char *
146get_error_text(int error)
147{
148 switch (error) {
149 case PR_IO_TIMEOUT_ERROR(-5990L):
150 return "Timeout";
151 break;
152 case PR_CONNECT_REFUSED_ERROR(-5981L):
153 return "Connection refused";
154 break;
155 case PR_NETWORK_UNREACHABLE_ERROR(-5980L):
156 return "Network unreachable";
157 break;
158 case PR_BAD_ADDRESS_ERROR(-5983L):
159 return "Bad address";
160 break;
161 case PR_CONNECT_RESET_ERROR(-5961L):
162 return "Connection reset";
163 break;
164 case PR_PIPE_ERROR(-5955L):
165 return "Pipe error";
166 break;
167 }
168
169 return "";
170}
171
172void
173check_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 */
192DataBuffer *
193free_head(DataBufferList *dbl)
194{
195 DataBuffer *db = dbl->first;
196 PR_ASSERT(db->offset >= db->length)((db->offset >= db->length)?((void)0):PR_Assert("db->offset >= db->length"
,"ssltap.c",196))
;
197 if (db->offset >= db->length) {
198 dbl->first = db->next;
199 if (dbl->first == NULL((void*)0)) {
200 dbl->last = NULL((void*)0);
201 }
202 PORT_FreePORT_Free_Util(db->buffer);
203 PORT_FreePORT_Free_Util(db);
204 db = dbl->first;
205 }
206 return db;
207}
208
209void
210read_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_STDERRPR_GetSpecialFD(PR_StandardError), "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)((db->length - db->offset)<(length)?(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
240void
241flush_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_FreePORT_Free_Util(dbl->msgBuf);
253 dbl->msgBuf = NULL((void*)0);
254 }
255 dbl->msgBufOffset = 0;
256 dbl->msgBufSize = 0;
257 dbl->hMACsize = 0;
258}
259
260const char *
261V2CipherString(int cs_int)
262{
263 char *cs_str;
264 cs_str = NULL((void*)0);
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
766const char *
767CompressionMethodString(int cm_int)
768{
769 char *cm_str;
770 cm_str = NULL((void*)0);
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
789const char *
790helloExtensionNameString(int ex_num)
791{
792 const char *ex_name = NULL((void*)0);
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 snprintf(buf, sizeof(buf), "%d", ex_num);
831 ex_name = (const char *)buf;
832 break;
833 }
834
835 return ex_name;
836}
837
838static int
839isNULLmac(int cs_int)
840{
841 return (cs_int == TLS_NULL_WITH_NULL_NULL0x0000);
842}
843
844static int
845isNULLcipher(int cs_int)
846{
847 return ((cs_int == TLS_RSA_WITH_NULL_MD50x0001) ||
848 (cs_int == TLS_RSA_WITH_NULL_SHA0x0002) ||
849 (cs_int == SSL_FORTEZZA_DMS_WITH_NULL_SHA0x001c) ||
850 (cs_int == TLS_ECDH_ECDSA_WITH_NULL_SHA0xC001) ||
851 (cs_int == TLS_ECDHE_ECDSA_WITH_NULL_SHA0xC006) ||
852 (cs_int == TLS_ECDH_RSA_WITH_NULL_SHA0xC00B) ||
853 (cs_int == TLS_ECDHE_RSA_WITH_NULL_SHA0xC010));
854}
855
856void
857partial_packet(int thispacket, int size, int needed)
858{
859 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "(%u bytes", thispacket);
860 if (thispacket < needed) {
861 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), ", making %u", size);
862 }
863 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " of %u", needed);
864 if (size > needed) {
865 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), ", with %u left over", size - needed);
866 }
867 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), ")\n");
868}
869
870char *
871get_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
885void
886print_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_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] Encrypted {...}\n");
899 return;
900 }
901 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [%s]", get_time_string());
902 switch (chv2->type) {
903 case 1:
904 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] ClientHelloV2 {\n");
905 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " version = {0x%02x, 0x%02x}\n",
906 (PRUint32)chv2->version[0], (PRUint32)chv2->version[1]);
907 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher-specs-length = %d (0x%02x)\n",
908 (PRUint32)(GET_SHORT((chv2->cslength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->cslength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->cslength))[1]))
),
909 (PRUint32)(GET_SHORT((chv2->cslength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->cslength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->cslength))[1]))
));
910 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " sid-length = %d (0x%02x)\n",
911 (PRUint32)(GET_SHORT((chv2->sidlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->sidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->sidlength))[1]))
),
912 (PRUint32)(GET_SHORT((chv2->sidlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->sidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->sidlength))[1]))
));
913 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " challenge-length = %d (0x%02x)\n",
914 (PRUint32)(GET_SHORT((chv2->rndlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->rndlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->rndlength))[1]))
),
915 (PRUint32)(GET_SHORT((chv2->rndlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->rndlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->rndlength))[1]))
));
916 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher-suites = { \n");
917 for (p =
918 0;
919 p < (PRUint32)GET_SHORT((chv2->cslength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->cslength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->cslength))[1]))
; p += 3) {
920 PRUint32 cs_int = GET_24((&chv2->csuites[p]))((PRUint32)( (((PRUint32)((PRUint8 *)(&chv2->csuites[p
]))[0]) << 16) + (((PRUint32)((PRUint8 *)(&chv2->
csuites[p]))[1]) << 8) + (((PRUint32)((PRUint8 *)(&
chv2->csuites[p]))[2]) << 0)))
;
921 const char *cs_str =
922 V2CipherString(cs_int);
923
924 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " (0x%06x) %s\n",
925 cs_int, cs_str);
926 }
927 q = p;
928 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
929 if (GET_SHORT((chv2->sidlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->sidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->sidlength))[1]))
) {
930 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " session-id = { ");
931 for (p = 0;
932 p < (PRUint32)GET_SHORT((chv2->sidlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->sidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->sidlength))[1]))
; p += 2) {
933 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "0x%04x ", (PRUint32)(GET_SHORT((&chv2->csuites[p + q]))((PRUint16)(((PRUint16)((PRUint8 *)(&chv2->csuites[p +
q]))[0]) << 8) + ((PRUint16)((PRUint8 *)(&chv2->
csuites[p + q]))[1]))
));
934 }
935 }
936 q += p;
937 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "}\n");
938 if (GET_SHORT((chv2->rndlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->rndlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->rndlength))[1]))
) {
939 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " challenge = { ");
940 for (p = 0;
941 p < (PRUint32)GET_SHORT((chv2->rndlength))((PRUint16)(((PRUint16)((PRUint8 *)(chv2->rndlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(chv2->rndlength))[1]))
; p += 2) {
942 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "0x%04x ", (PRUint32)(GET_SHORT((&chv2->csuites[p + q]))((PRUint16)(((PRUint16)((PRUint8 *)(&chv2->csuites[p +
q]))[0]) << 8) + ((PRUint16)((PRUint8 *)(&chv2->
csuites[p + q]))[1]))
));
943 }
944 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "}\n");
945 }
946 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "}\n");
947 break;
948 /* end of V2 CLientHello Parsing */
949
950 case 2: /* Client Master Key */
951 {
952 const char *cs_str =
953 NULL((void*)0);
954 PRUint32 cs_int =
955 0;
956 ClientMasterKeyV2 *cmkv2;
957 cmkv2 = (ClientMasterKeyV2 *)chv2;
958 isV2Session = 1;
959
960 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] ClientMasterKeyV2 { \n");
961
962 cs_int = GET_24(&cmkv2->cipherkind[0])((PRUint32)( (((PRUint32)((PRUint8 *)&cmkv2->cipherkind
[0])[0]) << 16) + (((PRUint32)((PRUint8 *)&cmkv2->
cipherkind[0])[1]) << 8) + (((PRUint32)((PRUint8 *)&
cmkv2->cipherkind[0])[2]) << 0)))
;
963 cs_str = V2CipherString(cs_int);
964 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher-spec-chosen = (0x%06x) %s\n",
965 cs_int, cs_str);
966
967 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " clear-portion = %d bits\n",
968 8 *
969 (PRUint32)(GET_SHORT((cmkv2->clearkey))((PRUint16)(((PRUint16)((PRUint8 *)(cmkv2->clearkey))[0]) <<
8) + ((PRUint16)((PRUint8 *)(cmkv2->clearkey))[1]))
));
970
971 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
972 clientstream.isEncrypted = 1;
973 serverstream.isEncrypted = 1;
974 } break;
975
976 case 3:
977 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [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_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] ServerHelloV2 {\n");
985 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " sid hit = {0x%02x}\n",
986 (PRUintn)shv2->sidhit);
987 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " version = {0x%02x, 0x%02x}\n",
988 (PRUint32)shv2->version[0], (PRUint32)shv2->version[1]);
989 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher-specs-length = %d (0x%02x)\n",
990 (PRUint32)(GET_SHORT((shv2->cslength))((PRUint16)(((PRUint16)((PRUint8 *)(shv2->cslength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(shv2->cslength))[1]))
),
991 (PRUint32)(GET_SHORT((shv2->cslength))((PRUint16)(((PRUint16)((PRUint8 *)(shv2->cslength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(shv2->cslength))[1]))
));
992 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " sid-length = %d (0x%02x)\n",
993 (PRUint32)(GET_SHORT((shv2->cidlength))((PRUint16)(((PRUint16)((PRUint8 *)(shv2->cidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(shv2->cidlength))[1]))
),
994 (PRUint32)(GET_SHORT((shv2->cidlength))((PRUint16)(((PRUint16)((PRUint8 *)(shv2->cidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(shv2->cidlength))[1]))
));
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)((PRUint16)(((PRUint16)((PRUint8 *)&shv2->certlength)[
0]) << 8) + ((PRUint16)((PRUint8 *)&shv2->certlength
)[1]))
;
1000 if (q > recordLen) {
1001 goto eosh;
1002 }
1003 pos += q; /* skip certificate */
1004
1005 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher-suites = { ");
1006 len = GET_SHORT((shv2->cslength))((PRUint16)(((PRUint16)((PRUint8 *)(shv2->cslength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(shv2->cslength))[1]))
;
1007 for (p = 0; p < len; p += 3) {
1008 PRUint32 cs_int = GET_24((pos + p))((PRUint32)( (((PRUint32)((PRUint8 *)(pos + p))[0]) << 16
) + (((PRUint32)((PRUint8 *)(pos + p))[1]) << 8) + (((PRUint32
)((PRUint8 *)(pos + p))[2]) << 0)))
;
1009 const char *cs_str =
1010 V2CipherString(cs_int);
1011 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n ");
1012 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "(0x%06x) %s", cs_int, cs_str);
1013 }
1014 pos += len;
1015 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n"); /* End of cipher suites */
1016 len = (PRUint32)GET_SHORT((shv2->cidlength))((PRUint16)(((PRUint16)((PRUint8 *)(shv2->cidlength))[0]) <<
8) + ((PRUint16)((PRUint8 *)(shv2->cidlength))[1]))
;
1017 if (len) {
1018 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " connection-id = { ");
1019 for (p =
1020 0;
1021 p < len; p += 2) {
1022 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "0x%04x ", (PRUint32)(GET_SHORT((pos + p))((PRUint16)(((PRUint16)((PRUint8 *)(pos + p))[0]) << 8)
+ ((PRUint16)((PRUint8 *)(pos + p))[1]))
));
1023 }
1024 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n"); /* End of connection id */
1025 }
1026 eosh:
1027 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n }\n"); /* end of ServerHelloV2 */
1028 if (shv2->sidhit) {
1029 clientstream.isEncrypted =
1030 1;
1031 serverstream.isEncrypted =
1032 1;
1033 }
1034 break;
1035
1036 case 5:
1037 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] Server Verify V2 {...}\n");
1038 isV2Session = 1;
1039 break;
1040
1041 case 6:
1042 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] Server Finished V2 {...}\n");
1043 isV2Session = 1;
1044 break;
1045
1046 case 7:
1047 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] Request Certificate V2 {...}\n");
1048 isV2Session = 1;
1049 break;
1050
1051 case 8:
1052 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] Client Certificate V2 {...}\n");
1053 isV2Session = 1;
1054 break;
1055
1056 default:
1057 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [ssl2] UnknownType 0x%02x {...}\n",
1058 (PRUint32)chv2->type);
1059 break;
1060 }
1061}
1062
1063unsigned int
1064print_hello_extension(unsigned char *hsdata,
1065 unsigned int length,
1066 unsigned int pos)
1067{
1068 /* pretty print extensions, if any */
1069 if (pos < length) {
1070 int exListLen = GET_SHORT((hsdata + pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1071 pos += 2;
1072 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1073 " extensions[%d] = {\n", exListLen);
1074 while (exListLen > 0 && pos < length) {
1075 int exLen;
1076 int exType = GET_SHORT((hsdata + pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1077 pos += 2;
1078 exLen = GET_SHORT((hsdata + pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1079 pos += 2;
1080 /* dump the extension */
1081 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1082 " extension type %s, length [%d]",
1083 helloExtensionNameString(exType), exLen);
1084 if (exLen > 0) {
1085 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " = {\n");
1086 print_hex(exLen, hsdata + pos);
1087 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1088 } else {
1089 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n");
1090 }
1091 pos += exLen;
1092 exListLen -= 2 + exLen;
1093 }
1094 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1095 }
1096 return pos;
1097}
1098
1099/*
1100 * Note this must match (exactly) the enumeration ocspResponseStatus.
1101 */
1102static char *responseStatusNames[] = {
1103 "successful (Response has valid confirmations)",
1104 "malformedRequest (Illegal confirmation request)",
1105 "internalError (Internal error in issuer)",
1106 "tryLater (Try again later)",
1107 "unused ((4) is not used)",
1108 "sigRequired (Must sign the request)",
1109 "unauthorized (Request unauthorized)",
1110};
1111
1112static void
1113print_ocsp_cert_id(FILE *out_file, CERTOCSPCertID *cert_id, int level)
1114{
1115 SECU_Indent(out_file, level);
1116 fprintf(out_file, "Cert ID:\n");
1117 level++;
1118 /*
1119 SECU_PrintAlgorithmID (out_file, &(cert_id->hashAlgorithm),
1120 "Hash Algorithm", level);
1121 SECU_PrintAsHex (out_file, &(cert_id->issuerNameHash),
1122 "Issuer Name Hash", level);
1123 SECU_PrintAsHex (out_file, &(cert_id->issuerKeyHash),
1124 "Issuer Key Hash", level);
1125*/
1126 SECU_PrintInteger(out_file, &(cert_id->serialNumber),
1127 "Serial Number", level);
1128 /* XXX lookup the cert; if found, print something nice (nickname?) */
1129}
1130
1131static void
1132print_ocsp_version(FILE *out_file, SECItem *version, int level)
1133{
1134 if (version->len > 0) {
1135 SECU_PrintInteger(out_file, version, "Version", level);
1136 } else {
1137 SECU_Indent(out_file, level);
1138 fprintf(out_file, "Version: DEFAULT\n");
1139 }
1140}
1141
1142static void
1143print_responder_id(FILE *out_file, ocspResponderID *responderID, int level)
1144{
1145 SECU_Indent(out_file, level);
1146 fprintf(out_file, "Responder ID ");
1147
1148 switch (responderID->responderIDType) {
1149 case ocspResponderID_byName:
1150 fprintf(out_file, "(byName):\n");
1151 SECU_PrintName(out_file, &(responderID->responderIDValue.name),
1152 "Name", level + 1);
1153 break;
1154 case ocspResponderID_byKey:
1155 fprintf(out_file, "(byKey):\n");
1156 SECU_PrintAsHex(out_file, &(responderID->responderIDValue.keyHash),
1157 "Key Hash", level + 1);
1158 break;
1159 default:
1160 fprintf(out_file, "Unrecognized Responder ID Type\n");
1161 break;
1162 }
1163}
1164
1165static void
1166print_ocsp_extensions(FILE *out_file, CERTCertExtension **extensions,
1167 char *msg, int level)
1168{
1169 if (extensions) {
1170 SECU_PrintExtensions(out_file, extensions, msg, level);
1171 } else {
1172 SECU_Indent(out_file, level);
1173 fprintf(out_file, "No %s\n", msg);
1174 }
1175}
1176
1177static void
1178print_revoked_info(FILE *out_file, ocspRevokedInfo *revoked_info, int level)
1179{
1180 SECU_PrintGeneralizedTime(out_file, &(revoked_info->revocationTime),
1181 "Revocation Time", level);
1182
1183 if (revoked_info->revocationReason != NULL((void*)0)) {
1184 SECU_PrintAsHex(out_file, revoked_info->revocationReason,
1185 "Revocation Reason", level);
1186 } else {
1187 SECU_Indent(out_file, level);
1188 fprintf(out_file, "No Revocation Reason.\n");
1189 }
1190}
1191
1192static void
1193print_cert_status(FILE *out_file, ocspCertStatus *status, int level)
1194{
1195 SECU_Indent(out_file, level);
1196 fprintf(out_file, "Status: ");
1197
1198 switch (status->certStatusType) {
1199 case ocspCertStatus_good:
1200 fprintf(out_file, "Cert is good.\n");
1201 break;
1202 case ocspCertStatus_revoked:
1203 fprintf(out_file, "Cert has been revoked.\n");
1204 print_revoked_info(out_file, status->certStatusInfo.revokedInfo,
1205 level + 1);
1206 break;
1207 case ocspCertStatus_unknown:
1208 fprintf(out_file, "Cert is unknown to responder.\n");
1209 break;
1210 default:
1211 fprintf(out_file, "Unrecognized status.\n");
1212 break;
1213 }
1214}
1215
1216static void
1217print_single_response(FILE *out_file, CERTOCSPSingleResponse *single,
1218 int level)
1219{
1220 print_ocsp_cert_id(out_file, single->certID, level);
1221
1222 print_cert_status(out_file, single->certStatus, level);
1223
1224 SECU_PrintGeneralizedTime(out_file, &(single->thisUpdate),
1225 "This Update", level);
1226
1227 if (single->nextUpdate != NULL((void*)0)) {
1228 SECU_PrintGeneralizedTime(out_file, single->nextUpdate,
1229 "Next Update", level);
1230 } else {
1231 SECU_Indent(out_file, level);
1232 fprintf(out_file, "No Next Update\n");
1233 }
1234
1235 print_ocsp_extensions(out_file, single->singleExtensions,
1236 "Single Response Extensions", level);
1237}
1238
1239static void
1240print_response_data(FILE *out_file, ocspResponseData *responseData, int level)
1241{
1242 SECU_Indent(out_file, level);
1243 fprintf(out_file, "Response Data:\n");
1244 level++;
1245
1246 print_ocsp_version(out_file, &(responseData->version), level);
1247
1248 print_responder_id(out_file, responseData->responderID, level);
1249
1250 SECU_PrintGeneralizedTime(out_file, &(responseData->producedAt),
1251 "Produced At", level);
1252
1253 if (responseData->responses != NULL((void*)0)) {
1254 int i;
1255
1256 for (i = 0; responseData->responses[i] != NULL((void*)0); i++) {
1257 SECU_Indent(out_file, level);
1258 fprintf(out_file, "Response %d:\n", i);
1259 print_single_response(out_file, responseData->responses[i],
1260 level + 1);
1261 }
1262 } else {
1263 fprintf(out_file, "Response list is empty.\n");
1264 }
1265
1266 print_ocsp_extensions(out_file, responseData->responseExtensions,
1267 "Response Extensions", level);
1268}
1269
1270static void
1271print_basic_response(FILE *out_file, ocspBasicOCSPResponse *basic, int level)
1272{
1273 SECU_Indent(out_file, level);
1274 fprintf(out_file, "Basic OCSP Response:\n");
1275 level++;
1276
1277 print_response_data(out_file, basic->tbsResponseData, level);
1278}
1279
1280static void
1281print_status_response(SECItem *data)
1282{
1283 int level = 2;
1284 CERTOCSPResponse *response;
1285 response = CERT_DecodeOCSPResponse(data);
1286 if (!response) {
1287 SECU_Indent(stdoutstdout, level);
1288 fprintf(stdoutstdout, "unable to decode certificate_status\n");
1289 return;
1290 }
1291
1292 SECU_Indent(stdoutstdout, level);
1293 if (response->statusValue >= ocspResponse_min &&
1294 response->statusValue <= ocspResponse_max) {
1295 fprintf(stdoutstdout, "Response Status: %s\n",
1296 responseStatusNames[response->statusValue]);
1297 } else {
1298 fprintf(stdoutstdout,
1299 "Response Status: other (Status value %d out of defined range)\n",
1300 (int)response->statusValue);
1301 }
1302
1303 if (response->statusValue == ocspResponse_successful) {
1304 ocspResponseBytes *responseBytes = response->responseBytes;
1305 PORT_Assert(responseBytes != NULL)((responseBytes != ((void*)0))?((void)0):PR_Assert("responseBytes != NULL"
,"ssltap.c",1305))
;
1306
1307 level++;
1308 SECU_PrintObjectID(stdoutstdout, &(responseBytes->responseType),
1309 "Response Type", level);
1310 switch (response->responseBytes->responseTypeTag) {
1311 case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
1312 print_basic_response(stdoutstdout,
1313 responseBytes->decodedResponse.basic,
1314 level);
1315 break;
1316 default:
1317 SECU_Indent(stdoutstdout, level);
1318 fprintf(stdoutstdout, "Unknown response syntax\n");
1319 break;
1320 }
1321 } else {
1322 SECU_Indent(stdoutstdout, level);
1323 fprintf(stdoutstdout, "Unsuccessful response, no more information.\n");
1324 }
1325
1326 CERT_DestroyOCSPResponse(response);
1327}
1328
1329/* In the case of renegotiation, handshakes that occur in an already MAC'ed
1330 * channel, by the time of this call, the caller has already removed the MAC
1331 * from input recordLen. The only MAC'ed record that will get here with its
1332 * MAC intact (not removed) is the first Finished message on the connection.
1333 */
1334void
1335print_ssl3_handshake(unsigned char *recordBuf,
1336 unsigned int recordLen,
1337 SSLRecord *sr,
1338 DataBufferList *s)
1339{
1340 struct sslhandshake sslh;
1341 unsigned char *hsdata;
1342 unsigned int offset = 0;
1343
1344 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " handshake {\n");
1345
1346 if (s->msgBufOffset && s->msgBuf) {
1347 /* append recordBuf to msgBuf, then use msgBuf */
1348 if (s->msgBufOffset + recordLen > s->msgBufSize) {
1349 int newSize = s->msgBufOffset + recordLen;
1350 unsigned char *newBuf = PORT_ReallocPORT_Realloc_Util(s->msgBuf, newSize);
1351 if (!newBuf) {
1352 PR_ASSERT(newBuf)((newBuf)?((void)0):PR_Assert("newBuf","ssltap.c",1352));
1353 showErr("Realloc failed");
1354 exit(10);
1355 }
1356 s->msgBuf = newBuf;
1357 s->msgBufSize = newSize;
1358 }
1359 memcpy(s->msgBuf + s->msgBufOffset, recordBuf, recordLen);
1360 s->msgBufOffset += recordLen;
1361 recordLen = s->msgBufOffset;
1362 recordBuf = s->msgBuf;
1363 }
1364 while (offset + 4 <= recordLen) {
1365 sslh.type = recordBuf[offset];
1366 sslh.length = GET_24(recordBuf + offset + 1)((PRUint32)( (((PRUint32)((PRUint8 *)recordBuf + offset + 1)[
0]) << 16) + (((PRUint32)((PRUint8 *)recordBuf + offset
+ 1)[1]) << 8) + (((PRUint32)((PRUint8 *)recordBuf + offset
+ 1)[2]) << 0)))
;
1367 if (offset + 4 + sslh.length > recordLen)
1368 break;
1369 /* finally have a complete message */
1370 if (sslhexparse)
1371 print_hex(4, recordBuf + offset);
1372
1373 hsdata = &recordBuf[offset + 4];
1374
1375 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " type = %d (", sslh.type);
1376 switch (sslh.type) {
1377 case 0:
1378 PR_FPUTS("hello_request)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "hello_request)\n"
)
;
1379 break;
1380 case 1:
1381 PR_FPUTS("client_hello)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "client_hello)\n"
)
;
1382 break;
1383 case 2:
1384 PR_FPUTS("server_hello)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "server_hello)\n"
)
;
1385 break;
1386 case 4:
1387 PR_FPUTS("new_session_ticket)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "new_session_ticket)\n"
)
;
1388 break;
1389 case 11:
1390 PR_FPUTS("certificate)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate)\n"
)
;
1391 break;
1392 case 12:
1393 PR_FPUTS("server_key_exchange)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "server_key_exchange)\n"
)
;
1394 break;
1395 case 13:
1396 PR_FPUTS("certificate_request)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_request)\n"
)
;
1397 break;
1398 case 14:
1399 PR_FPUTS("server_hello_done)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "server_hello_done)\n"
)
;
1400 break;
1401 case 15:
1402 PR_FPUTS("certificate_verify)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_verify)\n"
)
;
1403 break;
1404 case 16:
1405 PR_FPUTS("client_key_exchange)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "client_key_exchange)\n"
)
;
1406 break;
1407 case 20:
1408 PR_FPUTS("finished)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "finished)\n");
1409 break;
1410 case 22:
1411 PR_FPUTS("certificate_status)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_status)\n"
)
;
1412 break;
1413 default:
1414 PR_FPUTS("unknown)\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "unknown)\n");
1415 break;
1416 }
1417
1418 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " length = %d (0x%06x)\n", sslh.length, sslh.length);
1419 switch (sslh.type) {
1420
1421 case 0: /* hello_request */ /* not much to show here. */
1422 break;
1423
1424 case 1: /* client hello */
1425 switch (sr->ver_maj) {
1426 case 3: /* ssl version 3 */
1427 {
1428 unsigned int pos;
1429 int w;
1430
1431 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ClientHelloV3 {\n");
1432 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " client_version = {%d, %d}\n",
1433 (PRUint8)hsdata[0], (PRUint8)hsdata[1]);
1434 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " random = {...}\n");
1435 if (sslhexparse)
1436 print_hex(32, &hsdata[2]);
1437
1438 /* pretty print Session ID */
1439 {
1440 int sidlength =
1441 (int)hsdata[2 + 32];
1442 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " session ID = {\n");
1443 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " length = %d\n", sidlength);
1444 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " contents = {...}\n");
1445 if (sslhexparse)
1446 print_hex(sidlength, &hsdata[2 + 32 + 1]);
1447 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1448 pos =
1449 2 +
1450 32 +
1451 1 +
1452 sidlength;
1453 }
1454
1455 /* pretty print cipher suites */
1456 {
1457 int csuitelength =
1458 GET_SHORT((hsdata + pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1459 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher_suites[%d] = {\n",
1460 csuitelength /
1461 2);
1462 if (csuitelength %
1463 2) {
1464 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1465 "*error in protocol - csuitelength shouldn't be odd*\n");
1466 }
1467 for (w =
1468 0;
1469 w <
1470 csuitelength;
1471 w += 2) {
1472 PRUint32 cs_int =
1473 GET_SHORT((hsdata + pos + 2 + w))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos + 2 + w))[0]
) << 8) + ((PRUint16)((PRUint8 *)(hsdata + pos + 2 + w)
)[1]))
;
1474 const char *cs_str =
1475 V2CipherString(cs_int);
1476 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1477 " (0x%04x) %s\n", cs_int, cs_str);
1478 }
1479 pos +=
1480 2 +
1481 csuitelength;
1482 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1483 }
1484
1485 /* pretty print compression methods */
1486 {
1487 int complength =
1488 hsdata[pos];
1489 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " compression[%d] = {\n",
1490 complength);
1491 for (w =
1492 0;
1493 w <
1494 complength;
1495 w++) {
1496 PRUint32 cm_int =
1497 hsdata[pos + 1 + w];
1498 const char *cm_str =
1499 CompressionMethodString(cm_int);
1500 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1501 " (%02x) %s\n", cm_int, cm_str);
1502 }
1503 pos +=
1504 1 +
1505 complength;
1506 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1507 }
1508
1509 /* pretty print extensions, if any */
1510 pos =
1511 print_hello_extension(hsdata, sslh.length, pos);
1512
1513 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1514 } /* end of ssl version 3 */
1515 break;
1516 default:
1517 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " UNDEFINED VERSION %d.%d {...}\n",
1518 sr->ver_maj, sr->ver_min);
1519 if (sslhexparse)
1520 print_hex(sslh.length, hsdata);
1521 break;
1522 } /* end of switch sr->ver_maj */
1523 break;
1524
1525 case 2: /* server hello */
1526 {
1527 unsigned int sidlength, pos;
1528
1529 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ServerHello {\n");
1530
1531 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " server_version = {%d, %d}\n",
1532 (PRUint8)hsdata[0], (PRUint8)hsdata[1]);
1533 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " random = {...}\n");
1534 if (sslhexparse)
1535 print_hex(32, &hsdata[2]);
1536 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " session ID = {\n");
1537 sidlength = (int)hsdata[2 +
1538 32];
1539 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " length = %d\n", sidlength);
1540 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " contents = {...}\n");
1541 if (sslhexparse)
1542 print_hex(sidlength, &hsdata[2 + 32 + 1]);
1543 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1544 pos = 2 +
1545 32 + 1 +
1546 sidlength;
1547
1548 /* pretty print chosen cipher suite */
1549 {
1550 PRUint32 cs_int = GET_SHORT((hsdata + pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1551 const char *cs_str =
1552 V2CipherString(cs_int);
1553 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " cipher_suite = (0x%04x) %s\n",
1554 cs_int, cs_str);
1555 currentcipher =
1556 cs_int;
1557 pos +=
1558 2;
1559 }
1560 /* pretty print chosen compression method */
1561 {
1562 PRUint32 cm_int = hsdata[pos++];
1563 const char *cm_str =
1564 CompressionMethodString(cm_int);
1565 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " compression method = (%02x) %s\n",
1566 cm_int, cm_str);
1567 }
1568
1569 /* pretty print extensions, if any */
1570 pos = print_hello_extension(hsdata, sslh.length, pos);
1571
1572 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1573 } break;
1574
1575 case 4: /* new session ticket */
1576 {
1577 PRUint32 lifetimehint;
1578 PRUint16 ticketlength;
1579 char lifetime[32];
1580 lifetimehint = GET_32(hsdata)((PRUint32)( (((PRUint32)((PRUint8 *)hsdata)[0]) << 24)
+ (((PRUint32)((PRUint8 *)hsdata)[1]) << 16) + (((PRUint32
)((PRUint8 *)hsdata)[2]) << 8) + (((PRUint32)((PRUint8 *
)hsdata)[3]) << 0)))
;
1581 if (lifetimehint) {
1582 PRExplodedTime et;
1583 PRTime t =
1584 lifetimehint;
1585 t *=
1586 PR_USEC_PER_SEC1000000L;
1587 PR_ExplodeTime(t, PR_GMTParameters, &et);
1588 /* use HTTP Cookie header's date format */
1589 PR_FormatTimeUSEnglish(lifetime, sizeof lifetime,
1590 "%a, %d-%b-%Y %H:%M:%S GMT", &et);
1591 } else {
1592 /* 0 means the lifetime of the ticket is unspecified */
1593 strcpy(lifetime, "unspecified");
1594 }
1595 ticketlength = GET_SHORT((hsdata +((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + 4))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + 4))[1]))
1596 4))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + 4))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + 4))[1]))
;
1597 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " NewSessionTicket {\n");
1598 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ticket_lifetime_hint = %s\n",
1599 lifetime);
1600 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ticket = {\n");
1601 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " length = %d\n", ticketlength);
1602 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " contents = {...}\n");
1603 if (sslhexparse)
1604 print_hex(ticketlength, &hsdata[4 + 2]);
1605 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1606 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1607 } break;
1608
1609 case 11: /* certificate */
1610 {
1611 PRFileDesc *cfd;
1612 int pos;
1613 int certslength;
1614 int certlength;
1615 int certbytesread = 0;
1616 static int certFileNumber;
1617 char certFileName[20];
1618
1619 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " CertificateChain {\n");
1620 certslength = GET_24(hsdata)((PRUint32)( (((PRUint32)((PRUint8 *)hsdata)[0]) << 16)
+ (((PRUint32)((PRUint8 *)hsdata)[1]) << 8) + (((PRUint32
)((PRUint8 *)hsdata)[2]) << 0)))
;
1621 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " chainlength = %d (0x%04x)\n",
1622 certslength, certslength);
1623 pos = 3;
1624 while (certbytesread < certslength) {
1625 certlength =
1626 GET_24((hsdata + pos))((PRUint32)( (((PRUint32)((PRUint8 *)(hsdata + pos))[0]) <<
16) + (((PRUint32)((PRUint8 *)(hsdata + pos))[1]) << 8
) + (((PRUint32)((PRUint8 *)(hsdata + pos))[2]) << 0)))
;
1627 pos +=
1628 3;
1629 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " Certificate {\n");
1630 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " size = %d (0x%04x)\n",
1631 certlength, certlength);
1632 certbytesread +=
1633 certlength + 3;
1634 if (certbytesread <=
1635 certslength) {
1636 PR_snprintf(certFileName, sizeof certFileName, "cert.%03d",
1637 ++certFileNumber);
1638 cfd =
1639 PR_Open(certFileName, PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_TRUNCATE0x20,
1640 0664);
1641 if (!cfd) {
1642 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1643 " data = { couldn't save file '%s' }\n",
1644 certFileName);
1645 } else {
1646 PR_Write(cfd, (hsdata + pos),
1647 certlength);
1648 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1649 " data = { saved in file '%s' }\n",
1650 certFileName);
1651 PR_Close(cfd);
1652 }
1653 }
1654
1655 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1656 pos += certlength;
1657 }
1658 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1659 } break;
1660
1661 case 12: /* server_key_exchange */
1662 if (sslhexparse)
1663 print_hex(sslh.length, hsdata);
1664 break;
1665
1666 case 13: /* certificate request */
1667 {
1668 unsigned int pos = 0;
1669 int w, reqLength;
1670
1671 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " CertificateRequest {\n");
1672
1673 /* pretty print requested certificate types */
1674 reqLength = hsdata[pos];
1675 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " certificate types[%d] = {",
1676 reqLength);
1677 for (w =
1678 0;
1679 w < reqLength; w++) {
1680 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " %02x", hsdata[pos + 1 + w]);
1681 }
1682 pos += 1 + reqLength;
1683 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1684
1685 /* pretty print CA names, if any */
1686 if (pos < sslh.length) {
1687 int exListLen =
1688 GET_SHORT((hsdata + pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1689 pos += 2;
1690 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1691 " certificate_authorities[%d] = {\n",
1692 exListLen);
1693 while (exListLen >
1694 0 &&
1695 pos < sslh.length) {
1696 char *ca_name;
1697 SECItem it;
1698 int dnLen = GET_SHORT((hsdata +((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
1699 pos))((PRUint16)(((PRUint16)((PRUint8 *)(hsdata + pos))[0]) <<
8) + ((PRUint16)((PRUint8 *)(hsdata + pos))[1]))
;
1700 pos += 2;
1701
1702 /* dump the CA name */
1703 it.type =
1704 siBuffer;
1705 it.data =
1706 hsdata + pos;
1707 it.len =
1708 dnLen;
1709 ca_name =
1710 CERT_DerNameToAscii(&it);
1711 if (ca_name) {
1712 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " %s\n", ca_name);
1713 PORT_FreePORT_Free_Util(ca_name);
1714 } else {
1715 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1716 " distinguished name [%d]", dnLen);
1717 if (dnLen >
1718 0 &&
1719 sslhexparse) {
1720 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " = {\n");
1721 print_hex(dnLen, hsdata + pos);
1722 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1723 } else {
1724 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "\n");
1725 }
1726 }
1727 pos +=
1728 dnLen;
1729 exListLen -=
1730 2 + dnLen;
1731 }
1732 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1733 }
1734
1735 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1736 } break;
1737
1738 case 14: /* server_hello_done */ /* not much to show here. */
1739 break;
1740
1741 case 15: /* certificate_verify */
1742 if (sslhexparse)
1743 print_hex(sslh.length, hsdata);
1744 break;
1745
1746 case 16: /* client key exchange */
1747 {
1748 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ClientKeyExchange {\n");
1749 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " message = {...}\n");
1750 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1751 } break;
1752
1753 case 20: /* finished */
1754 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " Finished {\n");
1755 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " verify_data = {...}\n");
1756 if (sslhexparse)
1757 print_hex(sslh.length, hsdata);
1758 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1759
1760 if (!isNULLmac(currentcipher) &&
1761 !s->hMACsize) {
1762 /* To calculate the size of MAC, we subtract the number of known
1763 * bytes of message from the number of remaining bytes in the
1764 * record. This assumes that this is the first record on the
1765 * connection to have a MAC, and that the sender has not put another
1766 * message after the finished message in the handshake record.
1767 * This is only correct for the first transition from unMACed to
1768 * MACed. If the connection switches from one cipher suite to
1769 * another one with a different MAC, this logic will not track that
1770 * change correctly.
1771 */
1772 s->hMACsize =
1773 recordLen - (sslh.length + 4);
1774 sslh.length +=
1775 s->hMACsize; /* skip over the MAC data */
1776 }
1777 break;
1778
1779 case 22: /* certificate_status */
1780 {
1781 SECItem data;
1782 PRFileDesc *ofd;
1783 static int ocspFileNumber;
1784 char ocspFileName[20];
1785
1786 /* skip 4 bytes with handshake numbers, as in ssl3_HandleCertificateStatus */
1787 data.type = siBuffer;
1788 data.data = hsdata + 4;
1789 data.len = sslh.length - 4;
1790 print_status_response(&data);
1791
1792 PR_snprintf(ocspFileName, sizeof ocspFileName, "ocsp.%03d",
1793 ++ocspFileNumber);
1794 ofd = PR_Open(ocspFileName, PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_TRUNCATE0x20,
1795 0664);
1796 if (!ofd) {
1797 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1798 " data = { couldn't save file '%s' }\n",
1799 ocspFileName);
1800 } else {
1801 PR_Write(ofd, data.data, data.len);
1802 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput),
1803 " data = { saved in file '%s' }\n",
1804 ocspFileName);
1805 PR_Close(ofd);
1806 }
1807 } break;
1808
1809 default: {
1810 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " UNKNOWN MESSAGE TYPE %d [%d] {\n",
1811 sslh.type, sslh.length);
1812 if (sslhexparse)
1813 print_hex(sslh.length, hsdata);
1814 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1815 }
1816 } /* end of switch sslh.type */
1817 offset += sslh.length + 4;
1818 } /* while */
1819 if (offset < recordLen) { /* stuff left over */
1820 unsigned int newMsgLen = recordLen - offset;
1821 if (!s->msgBuf) {
1822 s->msgBuf = PORT_AllocPORT_Alloc_Util(newMsgLen);
1823 if (!s->msgBuf) {
1824 PR_ASSERT(s->msgBuf)((s->msgBuf)?((void)0):PR_Assert("s->msgBuf","ssltap.c"
,1824))
;
1825 showErr("Malloc failed");
1826 exit(11);
1827 }
1828 s->msgBufSize = newMsgLen;
1829 memcpy(s->msgBuf, recordBuf + offset, newMsgLen);
1830 } else if (newMsgLen > s->msgBufSize) {
1831 unsigned char *newBuf = PORT_ReallocPORT_Realloc_Util(s->msgBuf, newMsgLen);
1832 if (!newBuf) {
1833 PR_ASSERT(newBuf)((newBuf)?((void)0):PR_Assert("newBuf","ssltap.c",1833));
1834 showErr("Realloc failed");
1835 exit(12);
1836 }
1837 s->msgBuf = newBuf;
1838 s->msgBufSize = newMsgLen;
1839 } else if (offset || s->msgBuf != recordBuf) {
1840 memmove(s->msgBuf, recordBuf + offset, newMsgLen);
1841 }
1842 s->msgBufOffset = newMsgLen;
1843 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " [incomplete handshake message]\n");
1844 } else {
1845 s->msgBufOffset = 0;
1846 }
1847 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " }\n");
1848}
1849
1850void
1851print_ssl(DataBufferList *s, int length, unsigned char *buffer)
1852{
1853 /* -------------------------------------------------------- */
1854 /* first, create a new buffer object for this piece of data. */
1855
1856 DataBuffer *db;
1857
1858 if (s->size == 0 && length > 0 && buffer[0] >= 32 && buffer[0] < 128) {
1859 /* Not an SSL record, treat entire buffer as plaintext */
1860 PR_Write(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), buffer, length);
1861 return;
1862 }
1863
1864 check_integrity(s);
1865
1866 db = PR_NEW(struct _DataBuffer)((struct _DataBuffer *) (PR_Malloc((sizeof(struct _DataBuffer
)))))
;
1867
1868 if (!db) {
1869 return;
1870 }
1871
1872 db->buffer = (unsigned char *)PORT_AllocPORT_Alloc_Util(length);
1873 db->length = length;
1874 db->offset = 0;
1875 memcpy(db->buffer, buffer, length);
1876 db->next = NULL((void*)0);
1877
1878 /* now, add it to the stream */
1879
1880 if (s->last != NULL((void*)0))
1881 s->last->next = db;
1882 s->last = db;
1883 s->size += length;
1884 if (s->first == NULL((void*)0))
1885 s->first = db;
1886
1887 check_integrity(s);
1888
1889 /*------------------------------------------------------- */
1890 /* now we look at the stream to see if we have enough data to
1891 decode */
1892
1893 while (s->size > 0) {
1894 unsigned char *recordBuf = NULL((void*)0);
1895
1896 SSLRecord sr;
1897 unsigned recordLen;
1898 unsigned recordsize;
1899
1900 check_integrity(s);
1901
1902 if (s->first == NULL((void*)0)) {
1903 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "ERROR: s->first is null\n");
1904 exit(9);
1905 }
1906
1907 /* in the case of an SSL 2 client-hello */
1908 /* will have the high-bit set, whereas an SSL 3 client-hello will not */
1909 /* SSL2 can also send records that begin with the high bit clear.
1910 * This code will incorrectly handle them. XXX
1911 */
1912 if (isV2Session || s->first->buffer[s->first->offset] & 0x80) {
1913 /* it's an SSL 2 packet */
1914 unsigned char lenbuf[3];
1915
1916 /* first, we check if there's enough data for it to be an SSL2-type
1917 * record. What a pain.*/
1918 if (s->size < sizeof lenbuf) {
1919 partial_packet(length, s->size, sizeof lenbuf);
1920 return;
1921 }
1922
1923 /* read the first two bytes off the stream. */
1924 read_stream_bytes(lenbuf, s, sizeof(lenbuf));
1925 recordLen = ((unsigned int)(lenbuf[0] & 0x7f) << 8) + lenbuf[1] +
1926 ((lenbuf[0] & 0x80) ? 2 : 3);
1927 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "recordLen = %u bytes\n", recordLen);
1928
1929 /* put 'em back on the head of the stream. */
1930 db = PR_NEW(struct _DataBuffer)((struct _DataBuffer *) (PR_Malloc((sizeof(struct _DataBuffer
)))))
;
1931
1932 db->length = sizeof lenbuf;
1933 db->buffer = (unsigned char *)PORT_AllocPORT_Alloc_Util(db->length);
1934 db->offset = 0;
1935 memcpy(db->buffer, lenbuf, sizeof lenbuf);
1936
1937 db->next = s->first;
1938 s->first = db;
1939 if (s->last == NULL((void*)0))
1940 s->last = db;
1941 s->size += db->length;
1942
1943 /* if there wasn't enough, go back for more. */
1944 if (s->size < recordLen) {
1945 check_integrity(s);
1946 partial_packet(length, s->size, recordLen);
1947 return;
1948 }
1949 partial_packet(length, s->size, recordLen);
1950
1951 /* read in the whole record. */
1952 recordBuf = PORT_AllocPORT_Alloc_Util(recordLen);
1953 read_stream_bytes(recordBuf, s, recordLen);
1954
1955 print_sslv2(s, recordBuf, recordLen);
1956 PR_FREEIF(recordBuf)if (recordBuf) { PR_Free(recordBuf); (recordBuf) = ((void*)0)
; }
;
1957 check_integrity(s);
1958
1959 continue;
1960 }
1961
1962 /***********************************************************/
1963 /* It's SSL v3 */
1964 /***********************************************************/
1965 check_integrity(s);
1966
1967 if (s->size < sizeof sr) {
1968 partial_packet(length, s->size, sizeof(SSLRecord));
1969 return;
1970 }
1971
1972 read_stream_bytes((unsigned char *)&sr, s, sizeof sr);
1973
1974 /* we have read the stream bytes. Look at the length of
1975 the ssl record. If we don't have enough data to satisfy this
1976 request, then put the bytes we just took back at the head
1977 of the queue */
1978 recordsize = GET_SHORT(sr.length)((PRUint16)(((PRUint16)((PRUint8 *)sr.length)[0]) << 8)
+ ((PRUint16)((PRUint8 *)sr.length)[1]))
;
1979
1980 if (recordsize > s->size) {
1981 db = PR_NEW(struct _DataBuffer)((struct _DataBuffer *) (PR_Malloc((sizeof(struct _DataBuffer
)))))
;
1982
1983 db->length = sizeof sr;
1984 db->buffer = (unsigned char *)PORT_AllocPORT_Alloc_Util(db->length);
1985 db->offset = 0;
1986 memcpy(db->buffer, &sr, sizeof sr);
1987 db->next = s->first;
1988
1989 /* now, add it back on to the head of the stream */
1990
1991 s->first = db;
1992 if (s->last == NULL((void*)0))
1993 s->last = db;
1994 s->size += db->length;
1995
1996 check_integrity(s);
1997 partial_packet(length, s->size, recordsize);
1998 return;
1999 }
2000 partial_packet(length, s->size, recordsize);
2001
2002 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "SSLRecord { [%s]\n", get_time_string());
2003 if (sslhexparse) {
2004 print_hex(5, (unsigned char *)&sr);
2005 }
2006
2007 check_integrity(s);
2008
2009 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " type = %d (", sr.type);
2010 switch (sr.type) {
2011 case 20:
2012 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "change_cipher_spec)\n");
2013 break;
2014 case 21:
2015 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "alert)\n");
2016 break;
2017 case 22:
2018 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "handshake)\n");
2019 break;
2020 case 23:
2021 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "application_data)\n");
2022 break;
2023 default:
2024 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "unknown)\n");
2025 break;
2026 }
2027 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " version = { %d,%d }\n",
2028 (PRUint32)sr.ver_maj, (PRUint32)sr.ver_min);
2029 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " length = %d (0x%x)\n",
2030 (PRUint32)GET_SHORT(sr.length)((PRUint16)(((PRUint16)((PRUint8 *)sr.length)[0]) << 8)
+ ((PRUint16)((PRUint8 *)sr.length)[1]))
, (PRUint32)GET_SHORT(sr.length)((PRUint16)(((PRUint16)((PRUint8 *)sr.length)[0]) << 8)
+ ((PRUint16)((PRUint8 *)sr.length)[1]))
);
2031
2032 recordLen = recordsize;
2033 PR_ASSERT(s->size >= recordLen)((s->size >= recordLen)?((void)0):PR_Assert("s->size >= recordLen"
,"ssltap.c",2033))
;
2034 if (s->size >= recordLen) {
2035 recordBuf = (unsigned char *)PORT_AllocPORT_Alloc_Util(recordLen);
2036 read_stream_bytes(recordBuf, s, recordLen);
2037
2038 if (s->isEncrypted) {
2039 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " < encrypted >\n");
2040 } else { /* not encrypted */
2041
2042 switch (sr.type) {
2043 case 20: /* change_cipher_spec */
2044 if (sslhexparse)
2045 print_hex(recordLen - s->hMACsize, recordBuf);
2046 /* mark to say we can only dump hex form now on
2047 * if it is not one on a null cipher */
2048 s->isEncrypted =
2049 isNULLcipher(currentcipher) ? 0 : 1;
2050 break;
2051
2052 case 21: /* alert */
2053 switch (recordBuf[0]) {
2054 case 1:
2055 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " warning: ");
2056 break;
2057 case 2:
2058 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " fatal: ");
2059 break;
2060 default:
2061 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " unknown level %d: ", recordBuf[0]);
2062 break;
2063 }
2064
2065 switch (recordBuf[1]) {
2066 case 0:
2067 PR_FPUTS("close_notify\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "close_notify\n"
)
;
2068 break;
2069 case 10:
2070 PR_FPUTS("unexpected_message\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "unexpected_message\n"
)
;
2071 break;
2072 case 20:
2073 PR_FPUTS("bad_record_mac\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "bad_record_mac\n"
)
;
2074 break;
2075 case 21:
2076 PR_FPUTS("decryption_failed\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "decryption_failed\n"
)
;
2077 break;
2078 case 22:
2079 PR_FPUTS("record_overflow\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "record_overflow\n"
)
;
2080 break;
2081 case 30:
2082 PR_FPUTS("decompression_failure\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "decompression_failure\n"
)
;
2083 break;
2084 case 40:
2085 PR_FPUTS("handshake_failure\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "handshake_failure\n"
)
;
2086 break;
2087 case 41:
2088 PR_FPUTS("no_certificate\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "no_certificate\n"
)
;
2089 break;
2090 case 42:
2091 PR_FPUTS("bad_certificate\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "bad_certificate\n"
)
;
2092 break;
2093 case 43:
2094 PR_FPUTS("unsupported_certificate\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "unsupported_certificate\n"
)
;
2095 break;
2096 case 44:
2097 PR_FPUTS("certificate_revoked\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_revoked\n"
)
;
2098 break;
2099 case 45:
2100 PR_FPUTS("certificate_expired\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_expired\n"
)
;
2101 break;
2102 case 46:
2103 PR_FPUTS("certificate_unknown\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_unknown\n"
)
;
2104 break;
2105 case 47:
2106 PR_FPUTS("illegal_parameter\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "illegal_parameter\n"
)
;
2107 break;
2108 case 48:
2109 PR_FPUTS("unknown_ca\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "unknown_ca\n"
)
;
2110 break;
2111 case 49:
2112 PR_FPUTS("access_denied\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "access_denied\n"
)
;
2113 break;
2114 case 50:
2115 PR_FPUTS("decode_error\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "decode_error\n"
)
;
2116 break;
2117 case 51:
2118 PR_FPUTS("decrypt_error\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "decrypt_error\n"
)
;
2119 break;
2120 case 60:
2121 PR_FPUTS("export_restriction\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "export_restriction\n"
)
;
2122 break;
2123 case 70:
2124 PR_FPUTS("protocol_version\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "protocol_version\n"
)
;
2125 break;
2126 case 71:
2127 PR_FPUTS("insufficient_security\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "insufficient_security\n"
)
;
2128 break;
2129 case 80:
2130 PR_FPUTS("internal_error\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "internal_error\n"
)
;
2131 break;
2132 case 90:
2133 PR_FPUTS("user_canceled\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "user_canceled\n"
)
;
2134 break;
2135 case 100:
2136 PR_FPUTS("no_renegotiation\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "no_renegotiation\n"
)
;
2137 break;
2138 case 110:
2139 PR_FPUTS("unsupported_extension\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "unsupported_extension\n"
)
;
2140 break;
2141 case 111:
2142 PR_FPUTS("certificate_unobtainable\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "certificate_unobtainable\n"
)
;
2143 break;
2144 case 112:
2145 PR_FPUTS("unrecognized_name\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "unrecognized_name\n"
)
;
2146 break;
2147 case 113:
2148 PR_FPUTS("bad_certificate_status_response\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "bad_certificate_status_response\n"
)
;
2149 break;
2150 case 114:
2151 PR_FPUTS("bad_certificate_hash_value\n")PR_fprintf(PR_GetSpecialFD(PR_StandardOutput), "bad_certificate_hash_value\n"
)
;
2152 break;
2153
2154 default:
2155 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "unknown alert %d\n", recordBuf[1]);
2156 break;
2157 }
2158
2159 if (sslhexparse)
2160 print_hex(recordLen - s->hMACsize, recordBuf);
2161 break;
2162
2163 case 22: /* handshake */
2164 print_ssl3_handshake(recordBuf, recordLen - s->hMACsize,
2165 &sr, s);
2166 break;
2167
2168 case 23: /* application data */
2169 print_hex(recordLen -
2170 s->hMACsize,
2171 recordBuf);
2172 break;
2173
2174 default:
2175 print_hex(recordLen -
2176 s->hMACsize,
2177 recordBuf);
2178 break;
2179 }
2180 if (s->hMACsize) {
2181 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " MAC = {...}\n");
2182 if (sslhexparse) {
2183 unsigned char *offset =
2184 recordBuf + (recordLen - s->hMACsize);
2185 print_hex(s->hMACsize, offset);
2186 }
2187 }
2188 } /* not encrypted */
2189 }
2190 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "}\n");
2191 PR_FREEIF(recordBuf)if (recordBuf) { PR_Free(recordBuf); (recordBuf) = ((void*)0)
; }
;
2192 check_integrity(s);
2193 }
2194}
2195
2196void
2197print_hex(int amt, unsigned char *buf)
2198{
2199 int i, j, k;
2200 char t[20];
2201 static char string[5000];
2202
2203 for (i = 0; i < amt; i++) {
2204 t[1] = 0;
2205
2206 if (i % 16 == 0) { /* if we are at the beginning of a line */
2207 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "%4x:", i); /* print the line number */
2208 strcpy(string, "");
2209 }
2210
2211 if (i % 4 == 0) {
2212 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ");
2213 }
2214
2215 j = buf[i];
2216
2217 t[0] = (j >= 0x20 && j < 0x80) ? j : '.';
2218
2219 if (fancy) {
2220 switch (t[0]) {
2221 case '<':
2222 strcpy(t, "&lt;");
2223 break;
2224 case '>':
2225 strcpy(t, "&gt;");
2226 break;
2227 case '&':
2228 strcpy(t, "&amp;");
2229 break;
2230 }
2231 }
2232 strcat(string, t);
2233
2234 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "%02x ", (PRUint8)buf[i]);
2235
2236 /* if we've reached the end of the line - add the string */
2237 if (i % 16 == 15)
2238 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " | %s\n", string);
2239 }
2240 /* we reached the end of the buffer,*/
2241 /* do we have buffer left over? */
2242 j = i % 16;
2243 if (j > 0) {
2244 for (k = 0; k < (16 -
2245 j);
2246 k++) {
2247 /* print additional space after every four bytes */
2248 if ((k + j) % 4 == 0) {
2249 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ");
2250 }
2251 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " ");
2252 }
2253 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), " | %s\n", string);
2254 }
2255}
2256
2257void
2258Usage(void)
2259{
2260 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Usage: ssltap [-vhfsxl] [-p port] hostname:port\n");
2261 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -v [prints version string]\n");
2262 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -h [outputs hex instead of ASCII]\n");
2263 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -f [turn on Fancy HTML coloring]\n");
2264 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -s [turn on SSL decoding]\n");
2265 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -x [turn on extra SSL hex dumps]\n");
2266 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -p port [specify rendezvous port (default 1924)]\n");
2267 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " -l [loop - continue to wait for more connections]\n");
2268}
2269
2270void
2271showErr(const char *msg)
2272{
2273 PRErrorCode err = PR_GetError();
2274 const char *errString;
2275
2276 if (err == PR_UNKNOWN_ERROR(-5994L))
2277 err = PR_CONNECT_RESET_ERROR(-5961L); /* bug in NSPR. */
2278 errString = SECU_Strerror(err)PR_ErrorToString((err), 0);
2279
2280 if (!errString)
2281 errString = "(no text available)";
2282 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s: Error %d: %s: %s", progName, err, errString, msg);
2283}
2284
2285int
2286main(int argc, char *argv[])
2287{
2288 char *hostname = NULL((void*)0);
2289 PRUint16 rendport = DEFPORT1924, port;
2290 PRAddrInfo *ai;
2291 void *iter;
2292 PRStatus r;
2293 PRNetAddr na_client, na_server, na_rend;
2294 PRFileDesc *s_server, *s_client, *s_rend; /*rendezvous */
2295 int c_count = 0;
2296 PLOptState *optstate;
2297 PLOptStatus status;
2298 SECStatus rv;
2299
2300 progName = argv[0];
2301 optstate = PL_CreateOptState(argc, argv, "fxhslp:");
2302 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
2303 switch (optstate->option) {
2304 case 'f':
2305 fancy++;
2306 break;
2307 case 'h':
2308 hexparse++;
2309 break;
2310 case 's':
2311 sslparse++;
2312 break;
2313 case 'x':
2314 sslhexparse++;
2315 break;
2316 case 'l':
2317 looparound++;
2318 break;
2319 case 'p':
2320 rendport =
2321 atoi(optstate->value);
2322 break;
2323 case '\0':
2324 hostname =
2325 PL_strdup(optstate->value);
2326 }
2327 }
2328 if (status == PL_OPT_BAD)
2329 Usage();
2330
2331 if (fancy) {
2332 if (!hexparse && !sslparse) {
2333 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
2334 "Note: use of -f without -s or -h not recommended, \n"
2335 "as the output looks a little strange. It may be useful, however\n");
2336 }
2337 }
2338
2339 if (!hostname)
2340 Usage(), exit(2);
2341
2342 {
2343 char *colon = (char *)strchr(hostname, ':');
2344 if (!colon) {
2345 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
2346 "You must specify the host AND port you wish to connect to\n");
2347 Usage(), exit(3);
2348 }
2349 port = atoi(&colon[1]);
2350 *colon = '\0';
2351
2352 if (port == 0) {
2353 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Port must be a nonzero number.\n");
2354 exit(4);
2355 }
2356 }
2357
2358 /* find the 'server' IP address so we don't have to look it up later */
2359
2360 if (fancy) {
2361 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "<HTML><HEAD><TITLE>SSLTAP output</TITLE></HEAD>\n");
2362 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "<BODY><PRE>\n");
2363 }
2364 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Looking up \"%s\"...\n", hostname);
2365 ai = PR_GetAddrInfoByName(hostname, PR_AF_UNSPEC0, PR_AI_ADDRCONFIG0x20);
2366 if (!ai) {
2367 showErr("Host Name lookup failed\n");
2368 exit(5);
2369 }
2370
2371 iter = NULL((void*)0);
2372 iter = PR_EnumerateAddrInfo(iter, ai, port, &na_server);
Value stored to 'iter' is never read
2373 /* set up the port which the client will connect to */
2374
2375 r = PR_InitializeNetAddr(PR_IpAddrAny, rendport, &na_rend);
2376 if (r == PR_FAILURE) {
2377 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
2378 "PR_InitializeNetAddr(,%d,) failed with error %d\n", PR_GetError());
2379 exit(0);
2380 }
2381
2382 rv = NSS_NoDB_Init("");
2383 if (rv != SECSuccess) {
2384 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
2385 "NSS_NoDB_Init() failed with error %d\n", PR_GetError());
2386 exit(5);
2387 }
2388
2389 s_rend = PR_NewTCPSocket();
2390 if (!s_rend) {
2391 showErr("Couldn't create socket\n");
2392 exit(6);
2393 }
2394
2395 if (PR_Bind(s_rend, &na_rend)) {
2396 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Couldn't bind to port %d (error %d)\n", rendport, PR_GetError());
2397 exit(-1);
2398 }
2399
2400 if (PR_Listen(s_rend, 5)) {
2401 showErr("Couldn't listen\n");
2402 exit(-1);
2403 }
2404
2405 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Proxy socket ready and listening\n");
2406 do { /* accept one connection and process it. */
2407 PRPollDesc pds[2];
2408
2409 s_client = PR_Accept(s_rend, &na_client, PR_SecondsToInterval(3600));
2410 if (s_client == NULL((void*)0)) {
2411 showErr("accept timed out\n");
2412 exit(7);
2413 }
2414
2415 s_server = PR_OpenTCPSocket(na_server.raw.family);
2416 if (s_server == NULL((void*)0)) {
2417 showErr("couldn't open new socket to connect to server \n");
2418 exit(8);
2419 }
2420
2421 r = PR_Connect(s_server, &na_server, PR_SecondsToInterval(5));
2422
2423 if (r == PR_FAILURE) {
2424 showErr("Couldn't connect\n");
2425 return -1;
2426 }
2427
2428 if (looparound) {
2429 if (fancy)
2430 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "<p><HR><H2>");
2431 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Connection #%d [%s]\n", c_count + 1,
2432 get_time_string());
2433 if (fancy)
2434 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "</H2>");
2435 }
2436
2437 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Connected to %s:%d\n", hostname, port);
2438
2439#define PD_C0 0
2440#define PD_S1 1
2441
2442 pds[PD_C0].fd = s_client;
2443 pds[PD_S1].fd = s_server;
2444 pds[PD_C0].in_flags = PR_POLL_READ0x1;
2445 pds[PD_S1].in_flags = PR_POLL_READ0x1;
2446
2447 /* make sure the new connections don't start out encrypted. */
2448 clientstream.isEncrypted = 0;
2449 serverstream.isEncrypted = 0;
2450 isV2Session = 0;
2451
2452 while ((pds[PD_C0].in_flags & PR_POLL_READ0x1) != 0 ||
2453 (pds[PD_S1].in_flags & PR_POLL_READ0x1) != 0) { /* Handle all messages on the connection */
2454 PRInt32 amt;
2455 PRInt32 wrote;
2456 unsigned char buffer[TAPBUFSIZ16384];
2457
2458 amt = PR_Poll(pds, 2, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
2459 if (amt <= 0) {
2460 if (amt)
2461 showErr("PR_Poll failed.\n");
2462 else
2463 showErr("PR_Poll timed out.\n");
2464 break;
2465 }
2466
2467 if (pds[PD_C0].out_flags & PR_POLL_EXCEPT0x4) {
2468 showErr("Exception on client-side socket.\n");
2469 break;
2470 }
2471
2472 if (pds[PD_S1].out_flags & PR_POLL_EXCEPT0x4) {
2473 showErr("Exception on server-side socket.\n");
2474 break;
2475 }
2476
2477 /* read data, copy it to stdout, and write to other socket */
2478
2479 if ((pds[PD_C0].in_flags & PR_POLL_READ0x1) != 0 &&
2480 (pds[PD_C0].out_flags & PR_POLL_READ0x1) != 0) {
2481
2482 amt = PR_Read(s_client, buffer, sizeof(buffer));
2483
2484 if (amt < 0) {
2485 showErr("Client socket read failed.\n");
2486 break;
2487 }
2488
2489 if (amt == 0) {
2490 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Read EOF on Client socket. [%s]\n",
2491 get_time_string());
2492 pds[PD_C0].in_flags &= ~PR_POLL_READ0x1;
2493 PR_Shutdown(s_server, PR_SHUTDOWN_SEND);
2494 continue;
2495 }
2496
2497 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "--> [\n");
2498 if (fancy)
2499 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "<font color=blue>");
2500
2501 if (hexparse)
2502 print_hex(amt, buffer);
2503 if (sslparse)
2504 print_ssl(&clientstream, amt, buffer);
2505 if (!hexparse && !sslparse)
2506 PR_Write(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), buffer, amt);
2507 if (fancy)
2508 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "</font>");
2509 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "]\n");
2510
2511 wrote = PR_Write(s_server, buffer, amt);
2512 if (wrote != amt) {
2513 if (wrote < 0) {
2514 showErr("Write to server socket failed.\n");
2515 break;
2516 } else {
2517 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Short write to server socket!\n");
2518 }
2519 }
2520 } /* end of read from client socket. */
2521
2522 /* read data, copy it to stdout, and write to other socket */
2523 if ((pds[PD_S1].in_flags & PR_POLL_READ0x1) != 0 &&
2524 (pds[PD_S1].out_flags & PR_POLL_READ0x1) != 0) {
2525
2526 amt = PR_Read(s_server, buffer, sizeof(buffer));
2527
2528 if (amt < 0) {
2529 showErr("error on server-side socket.\n");
2530 break;
2531 }
2532
2533 if (amt == 0) {
2534 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "Read EOF on Server socket. [%s]\n",
2535 get_time_string());
2536 pds[PD_S1].in_flags &= ~PR_POLL_READ0x1;
2537 PR_Shutdown(s_client, PR_SHUTDOWN_SEND);
2538 continue;
2539 }
2540
2541 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "<-- [\n");
2542 if (fancy)
2543 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "<font color=red>");
2544 if (hexparse)
2545 print_hex(amt, (unsigned char *)buffer);
2546 if (sslparse)
2547 print_ssl(&serverstream, amt, (unsigned char *)buffer);
2548 if (!hexparse && !sslparse)
2549 PR_Write(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), buffer, amt);
2550 if (fancy)
2551 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "</font>");
2552 PR_fprintf(PR_STDOUTPR_GetSpecialFD(PR_StandardOutput), "]\n");
2553
2554 wrote = PR_Write(s_client, buffer, amt);
2555 if (wrote != amt) {
2556 if (wrote < 0) {
2557 showErr("Write to client socket failed.\n");
2558 break;
2559 } else {
2560 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Short write to client socket!\n");
2561 }
2562 }
2563
2564 } /* end of read from server socket. */
2565
2566 /* Loop, handle next message. */
2567
2568 } /* handle messages during a connection loop */
2569 PR_Close(s_client);
2570 PR_Close(s_server);
2571 flush_stream(&clientstream);
2572 flush_stream(&serverstream);
2573 /* Connection is closed, so reset the current cipher */
2574 currentcipher = 0;
2575 c_count++;
2576 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Connection %d Complete [%s]\n", c_count,
2577 get_time_string());
2578 } while (looparound); /* accept connection and process it. */
2579 PR_Close(s_rend);
2580 if (NSS_Shutdown() != SECSuccess) {
2581 return 1;
2582 }
2583 return 0;
2584}