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