1 /*
2     SSL parser
3 
4     This parses SSL packets from the server. It is built in multiple levels:
5 
6     RECORDS - ssl_parse_record()
7       |
8       +---> heartbeat
9       |        |
10       |        +---> banner grab
11       |
12       +---> handshake
13                |
14                +---> server hello
15                |        |
16                |        +---> banner grab
17                |
18                +---> certificate
19                         |
20                         +---> X.509 parser
21                                  |
22                                  +---> subject name (banner)
23                                  |
24                                  +---> certificate (banner)
25 
26 
27     For "heartbeat", we grab the so-called "heartbleed" exploit info.
28     For "server hello", we grab which cipher is used
29     For "certificate", we grab the szubjectName of the server
30 
31 
32     !!!!!!!!!!!!  BIZARRE CODE ALERT !!!!!!!!!!!!!!!
33 
34     This module uses a "streaming state-machine" to parse the SSL protocol.
35     In other words, this does not "reasemble" fragments. Instead, it allows
36     state to cross packet-boundaries. Thus, it supports both fragmentation
37     at the TCP layer and the SSL record layer, but without reassembling
38     things. Only in the output, in the gathered "banners", does reassembly
39     happen -- in other words, reassembly happens after OSI Layer 7 rather
40     than OSI Layer 4.
41 
42     As many are unfamiliar with this technique, they'll find it a little
43     weird.
44 
45     The upshot of doing things this way is that we can support 10 million
46     open TCP connections with minimal memory usage.
47  */
48 #include "proto-ssl.h"
49 #include "proto-interactive.h"
50 #include "unusedparm.h"
51 #include "masscan-app.h"
52 #include "siphash24.h"
53 #include "string_s.h"
54 #include "util-malloc.h"
55 #include <string.h>
56 #include <ctype.h>
57 #include <assert.h>
58 
59 
60 
61 /**
62  * Fugly macro for doing state-machine parsing. I know it's bad, but
63  * it makes stepping through the code in a debugger so much easier.
64  */
65 #define DROPDOWN(i,length,state) (state)++;if (++(i)>=(length)) break
66 
67 
68 /*****************************************************************************
69  *****************************************************************************/
70 static void
BANNER_CIPHER(struct BannerOutput * banout,unsigned cipher_suite)71 BANNER_CIPHER(struct BannerOutput *banout, unsigned cipher_suite)
72 {
73     //const char *notes = "";
74     char foo[64];
75     sprintf_s(foo, sizeof(foo), "cipher:0x%x", cipher_suite);
76     banout_append(banout, PROTO_SSL3, foo, AUTO_LEN);
77 
78     /*switch (cipher_suite) {
79      case 0x0005: notes = "(_/RSA/RC4/SHA)"; break;
80      case 0x0035: notes = "(_/RSA/AES-CBC/SHA)"; break;
81      case 0x002f: notes = "(_/RSA/AES-CBC/SHA)"; break;
82      case 0xc013: notes = "(ECDHE/RSA/AES-CBC/SHA)"; break;
83      }
84      banout_append(banout, PROTO_SSL3, notes, AUTO_LEN);*/
85 
86 }
87 /*****************************************************************************
88  *****************************************************************************/
89 static void
BANNER_VERSION(struct BannerOutput * banout,unsigned version_major,unsigned version_minor)90 BANNER_VERSION(struct BannerOutput *banout, unsigned version_major,
91                unsigned version_minor)
92 {
93     char foo[64];
94 
95     switch (version_major<<8 | version_minor) {
96         case 0x0300:
97             banout_append(banout, PROTO_SSL3, "SSLv3 ", AUTO_LEN);
98             banout_append(  banout, PROTO_VULN, "SSL[v3] ", AUTO_LEN);
99             break;
100         case 0x0301:
101             banout_append(banout, PROTO_SSL3, "TLS/1.0 ", AUTO_LEN);
102             break;
103         case 0x0302:
104             banout_append(banout, PROTO_SSL3, "TLS/1.1 ", AUTO_LEN);
105             break;
106         case 0x0303:
107             banout_append(banout, PROTO_SSL3, "TLS/1.2 ", AUTO_LEN);
108             break;
109         case 0x0304:
110             banout_append(banout, PROTO_SSL3, "TLS/1.3 ", AUTO_LEN);
111             break;
112         default:
113             sprintf_s(foo, sizeof(foo), "SSLver[%u,%u] ",
114                       version_major,
115                       version_minor);
116             banout_append(banout, PROTO_SSL3, foo, strlen(foo));
117     }
118 }
119 
120 
121 /*****************************************************************************
122  * This parses the "Server Hello" packet, the response to our "ClientHello"
123  * that we sent. We are looking for the following bits of information:
124  *  - cipher chosen by the server
125  *  - whether heartbeats are enabled
126  *****************************************************************************/
127 static void
parse_server_hello(const struct Banner1 * banner1,void * banner1_private,struct ProtocolState * pstate,const unsigned char * px,size_t length,struct BannerOutput * banout,struct InteractiveData * more)128 parse_server_hello(
129         const struct Banner1 *banner1,
130         void *banner1_private,
131         struct ProtocolState *pstate,
132         const unsigned char *px, size_t length,
133         struct BannerOutput *banout,
134         struct InteractiveData *more)
135 {
136     struct SSL_SERVER_HELLO *hello = &pstate->sub.ssl.x.server_hello;
137     unsigned state = hello->state;
138     unsigned remaining = hello->remaining;
139     unsigned i;
140     enum {
141         VERSION_MAJOR, VERSION_MINOR,
142         TIME0, TIME1, TIME2, TIME3,
143         RANDOM,
144         SESSION_LENGTH, SESSION_ID,
145         CIPHER0, CIPHER1,
146         COMPRESSION,
147         LENGTH0, LENGTH1,
148         EXT_TAG0, EXT_TAG1,
149         EXT_LEN0, EXT_LEN1,
150         EXT_DATA,
151         EXT_DATA_HEARTBEAT,
152         UNKNOWN,
153     };
154 
155     UNUSEDPARM(banout);
156     UNUSEDPARM(banner1_private);
157     UNUSEDPARM(banner1);
158     UNUSEDPARM(more);
159 
160     /* What this structure looks like in ASN.1 format
161        struct {
162            ProtocolVersion server_version;
163            Random random;
164            SessionID session_id;
165            CipherSuite cipher_suite;
166            CompressionMethod compression_method;
167        } ServerHello;
168     */
169 
170     /* 'for all bytes in the packet...' */
171     for (i=0; i<length; i++)
172     switch (state) {
173     case VERSION_MAJOR:
174         hello->version_major = px[i];
175         DROPDOWN(i,length,state);
176 
177     case VERSION_MINOR:
178         hello->version_minor = px[i];
179         BANNER_VERSION(banout, hello->version_major, hello->version_minor);
180         if (banner1->is_poodle_sslv3) {
181             banout_append(banout, PROTO_VULN, " POODLE ", AUTO_LEN);
182         }
183         if (hello->version_major > 3 || hello->version_minor > 4) {
184             state = UNKNOWN;
185             break;
186         }
187         hello->timestamp = 0;
188         DROPDOWN(i,length,state);
189 
190     case TIME0:
191         hello->timestamp <<= 8;
192         hello->timestamp |= px[i];
193         DROPDOWN(i,length,state);
194     case TIME1:
195         hello->timestamp <<= 8;
196         hello->timestamp |= px[i];
197         DROPDOWN(i,length,state);
198     case TIME2:
199         hello->timestamp <<= 8;
200         hello->timestamp |= px[i];
201         DROPDOWN(i,length,state);
202     case TIME3:
203         hello->timestamp <<= 8;
204         hello->timestamp |= px[i];
205         remaining = 28;
206         DROPDOWN(i,length,state);
207     case RANDOM:
208         {
209             /* do our typical "skip" logic to skip this
210              * 32 byte field */
211             unsigned len = (unsigned)length-i;
212             if (len > remaining)
213                 len = remaining;
214 
215             remaining -= len;
216             i += len-1;
217 
218             if (remaining != 0) {
219                 break;
220             }
221         }
222         DROPDOWN(i,length,state);
223 
224     case SESSION_LENGTH:
225         remaining = px[i];
226 		if (banner1->is_ticketbleed && remaining > 16) {
227 			banout_append(  banout, PROTO_VULN, "SSL[ticketbleed] ", 17);
228 		}
229         DROPDOWN(i,length,state);
230 
231     case SESSION_ID:
232         {
233             unsigned len = (unsigned)length-i;
234             if (len > remaining)
235                 len = remaining;
236 
237             remaining -= len;
238             i += len-1;
239 
240             if (remaining != 0) {
241                 break;
242             }
243         }
244         hello->cipher_suite = 0;
245         DROPDOWN(i,length,state);
246 
247     case CIPHER0:
248         hello->cipher_suite <<= 8;
249         hello->cipher_suite |= px[i];
250         DROPDOWN(i,length,state);
251 
252     case CIPHER1:
253         hello->cipher_suite <<= 8;
254         hello->cipher_suite |= px[i]; /* cipher-suite recorded here */
255         BANNER_CIPHER(banout, hello->cipher_suite);
256         DROPDOWN(i,length,state);
257 
258     case COMPRESSION:
259         hello->compression_method = px[i];
260         DROPDOWN(i,length,state);
261 
262     case LENGTH0:
263         remaining = px[i];
264         DROPDOWN(i,length,state);
265 
266     case LENGTH1:
267         remaining <<= 8;
268         remaining |= px[i];
269         DROPDOWN(i,length,state);
270 
271     case EXT_TAG0:
272     ext_tag:
273         if (remaining < 4) {
274             state = UNKNOWN;
275             continue;
276         }
277         hello->ext_tag = px[i]<<8;
278         remaining--;
279         DROPDOWN(i,length,state);
280 
281     case EXT_TAG1:
282         hello->ext_tag |= px[i];
283         remaining--;
284         DROPDOWN(i,length,state);
285 
286     case EXT_LEN0:
287         hello->ext_remaining = px[i]<<8;
288         remaining--;
289         DROPDOWN(i,length,state);
290     case EXT_LEN1:
291         hello->ext_remaining |= px[i];
292         remaining--;
293         switch (hello->ext_tag) {
294             case 0x000f: /* heartbeat */
295                 state = EXT_DATA_HEARTBEAT;
296                 continue;
297         }
298         DROPDOWN(i,length,state);
299 
300     case EXT_DATA:
301         if (hello->ext_remaining == 0) {
302             state = EXT_TAG0;
303             goto ext_tag;
304         }
305         if (remaining == 0) {
306             state = UNKNOWN;
307             continue;
308         }
309         remaining--;
310         hello->ext_remaining--;
311         continue;
312 
313     case EXT_DATA_HEARTBEAT:
314         if (hello->ext_remaining == 0) {
315             state = EXT_TAG0;
316             goto ext_tag;
317         }
318         if (remaining == 0) {
319             state = UNKNOWN;
320             continue;
321         }
322         remaining--;
323         hello->ext_remaining--;
324         if (px[i]) {
325             banout_append(  banout, PROTO_VULN, "SSL[heartbeat] ", 15);
326         }
327         state = EXT_DATA;
328         continue;
329 
330 
331 
332     case UNKNOWN:
333     default:
334         i = (unsigned)length;
335     }
336 
337     hello->state = state;
338     hello->remaining = remaining;
339 }
340 
341 
342 /*****************************************************************************
343  * This parses the certificates from the server. Thise contains an outer
344  * length field for all certificates, and then uses a length field for
345  * each certificate. The length fields are 3 bytes long.
346  *
347  * +--------+--------+--------+
348  * |  length of all certs     |
349  * +--------+--------+--------+
350  *    +--------+--------+--------+
351  *    |        cert length       |
352  *    +--------+--------+--------+
353  *    .                          .
354  *    . . .    certificate   . . .
355  *    .                          .
356  *    +--------+--------+--------+
357  *    |        cert length       |
358  *    +--------+--------+--------+
359  *    .                          .
360  *    . . .    certificate   . . .
361  *    .                          .
362  *
363  * This parser doesn't parse the certificates themselves, but initializes
364  * and passes fragments to the X.509 parser.
365  *
366  * Called by ssl_parser_record()->parse_handshake()
367  * Calls x509_decode() to parse the certificate
368  * Calls banout_append_base64() to capture the certificate
369  *****************************************************************************/
370 static void
parse_server_cert(const struct Banner1 * banner1,void * banner1_private,struct ProtocolState * pstate,const unsigned char * px,size_t length,struct BannerOutput * banout,struct InteractiveData * more)371 parse_server_cert(
372         const struct Banner1 *banner1,
373         void *banner1_private,
374         struct ProtocolState *pstate,
375         const unsigned char *px, size_t length,
376         struct BannerOutput *banout,
377         struct InteractiveData *more)
378 {
379     struct SSL_SERVER_CERT *data = &pstate->sub.ssl.x.server_cert;
380     unsigned state = data->state;
381     unsigned remaining = data->remaining;
382     unsigned cert_remaining = data->sub.remaining;
383     unsigned i;
384     enum {
385         LEN0, LEN1, LEN2,
386         CLEN0, CLEN1, CLEN2,
387         CERT,
388         UNKNOWN,
389     };
390 
391     UNUSEDPARM(banner1);
392     UNUSEDPARM(banner1_private);
393 
394     for (i=0; i<length; i++)
395     switch (state) {
396     case LEN0:
397         remaining = px[i];
398         DROPDOWN(i,length,state);
399     case LEN1:
400         remaining = remaining * 256 + px[i];
401         DROPDOWN(i,length,state);
402     case LEN2:
403         remaining = remaining * 256 + px[i];
404         DROPDOWN(i,length,state);
405 
406     case CLEN0:
407         if (remaining < 3) {
408             state = UNKNOWN;
409             continue;
410         }
411         cert_remaining = px[i];
412         remaining--;
413         DROPDOWN(i,length,state);
414     case CLEN1:
415         cert_remaining = cert_remaining * 256 + px[i];
416         remaining--;
417         DROPDOWN(i,length,state);
418     case CLEN2:
419         cert_remaining = cert_remaining * 256 + px[i];
420         remaining--;
421         if (banner1->is_capture_cert) {
422             banout_init_base64(&pstate->base64);
423             //banout_append(  banout, PROTO_X509_CERT, "cert:", 5);
424         }
425 
426         {
427             unsigned count = data->x509.count;
428             memset(&data->x509, 0, sizeof(data->x509));
429             x509_decode_init(&data->x509, cert_remaining);
430             data->x509.count = (unsigned char)count + 1;
431         }
432         DROPDOWN(i,length,state);
433 
434     case CERT:
435         {
436             unsigned len = (unsigned)length-i;
437             if (len > remaining)
438                 len = remaining;
439             if (len > cert_remaining)
440                 len = cert_remaining;
441 
442             /* parse the certificate */
443             if (banner1->is_capture_cert) {
444                 banout_append_base64(banout,
445                              PROTO_X509_CERT,
446                              px+i, len,
447                              &pstate->base64);
448             }
449 
450             x509_decode(&data->x509, px+i, len, banout);
451 
452 
453             remaining -= len;
454             cert_remaining -= len;
455             i += len-1;
456 
457             if (cert_remaining == 0) {
458                 /* We've reached the end of the certificate, so make
459                  * a record of it */
460                 if (banner1->is_capture_cert) {
461                     banout_finalize_base64(banout,
462                                            PROTO_X509_CERT,
463                                            &pstate->base64);
464                     banout_end(banout, PROTO_X509_CERT);
465                 }
466                 state = CLEN0;
467                 if (remaining == 0) {
468                     if (!banner1->is_heartbleed)
469                         tcp_close(more);
470                 }
471             }
472         }
473         break;
474 
475 
476     case UNKNOWN:
477     default:
478         i = (unsigned)length;
479     }
480 
481     data->state = state;
482     data->remaining = remaining;
483     data->sub.remaining = cert_remaining;
484 }
485 
486 /*****************************************************************************
487  * Called from the SSL Record parser to parse the contents of
488  * a handshake record. The way SSL handshaking works is that after we
489  * have sent the "hello", the server then sends us a bunch of records,
490  * including its certificate, then is done on their side with the handshake.
491  * Then, the client sends a bunch of stuff, to complete their end of the
492  * handshake (which we won't do). At that point, they then do a "change
493  * cipher spec" to negotiate the encryption keys, which isn't technically
494  * part of the handshaking.
495  *
496  * This is a four byte protocol:
497  * +--------+
498  * |  type  |
499  * +--------+--------+--------+
500  * |          length          |
501  * +--------+--------+--------+
502  * |  content ...
503  * .
504  * .
505  *
506  * Note that the "length" field is 3 bytes, supporting in theory 16-megs
507  * of content, but the outer record that calls this uses only 2-byte length
508  * fields. That's because records support fragmentation. This parser supports
509  * this fragmentation -- the 'state' variable crosses fragment boundaries.
510  *****************************************************************************/
511 static void
parse_handshake(const struct Banner1 * banner1,void * banner1_private,struct ProtocolState * pstate,const unsigned char * px,size_t length,struct BannerOutput * banout,struct InteractiveData * more)512 parse_handshake(
513         const struct Banner1 *banner1,
514         void *banner1_private,
515         struct ProtocolState *pstate,
516         const unsigned char *px, size_t length,
517         struct BannerOutput *banout,
518         struct InteractiveData *more)
519 {
520     struct SSLRECORD *ssl = &pstate->sub.ssl;
521     unsigned state = ssl->handshake.state;
522     unsigned remaining = ssl->handshake.remaining;
523     unsigned i;
524     enum {
525         START,
526         LENGTH0, LENGTH1, LENGTH2,
527         CONTENTS,
528         UNKNOWN,
529     };
530 
531     /*
532      * `for all bytes in the segment`
533      *   `do a state transition for that byte `
534      */
535     for (i=0; i<length; i++)
536     switch (state) {
537 
538     /* There are 20 or so handshaking sub-messages, indicates by it's own
539      * 'type' field, which we parse out here */
540     case START:
541         if (px[i] & 0x80) {
542             state = UNKNOWN;
543             break;
544         }
545         /* remember the 'type' field for use later in the CONTENT state */
546         ssl->handshake.type = px[i];
547 
548         /* initialize the state variable that will be used by the inner
549          * parsers */
550         ssl->x.all.state = 0;
551         DROPDOWN(i,length,state);
552 
553     /* This grabs the 'length' field. Note that unlike other length fields,
554      * this one is 3 bytes long. That's because a single certificate
555      * packet can contain so many certificates in a chain that it exceeds
556      * 64k kilobytes in size. */
557     case LENGTH0:
558         remaining = px[i];
559         DROPDOWN(i,length,state);
560     case LENGTH1:
561         remaining <<= 8;
562         remaining |= px[i];
563         DROPDOWN(i,length,state);
564     case LENGTH2:
565         remaining <<= 8;
566         remaining |= px[i];
567 
568         /* If we get a "server done" response, then it's a good time to
569          * send the heartbleed request. Note that these are usually zero
570          * length, so we can't process this below in the CONTENT state
571          * but have to do it here at the end of the LENGTH2 state */
572         if (ssl->handshake.type == 2 && banner1->is_heartbleed) {
573             static const char heartbleed_request[] =
574                 "\x15\x03\x02\x00\x02\x01\x80"
575                 "\x18\x03\x02\x00\x03\x01" "\x40\x00";
576             tcp_transmit(more, heartbleed_request, sizeof(heartbleed_request)-1, 0);
577         }
578         DROPDOWN(i,length,state);
579 
580     /* This parses the contents of the handshake. This parser just skips
581      * the data, in the same way as explained in the "ssl_parse_record()"
582      * function at its CONTENT state. We may pass the fragment to an inner
583      * parser, but whatever the inner parser does is independent from this
584      * parser, and has no effect on this parser
585      */
586     case CONTENTS:
587         {
588             unsigned len = (unsigned)length-i;
589             if (len > remaining)
590                 len = remaining;
591 
592             switch (ssl->handshake.type) {
593                 case 0: /* hello request*/
594                 case 1: /* client hello */
595                 case 3: /* DTLS hello verify request */
596                 case 4: /* new session ticket */
597                 case 12: /* server key exchange */
598                 case 13: /* certificate request */
599                 case 14: /* server done */
600                 case 15: /* certificate verify */
601                 case 16: /* client key exchange */
602                 case 20: /* finished */
603                 case 22: /* certificate status */
604                 default:
605                     /* don't parse these types, just skip them */
606                     break;
607 
608                 case 2: /* server hello */
609                     parse_server_hello( banner1,
610                                        banner1_private,
611                                        pstate,
612                                        px+i, len,
613                                        banout,
614                                        more);
615                     break;
616                 case 11: /* server certificate */
617                     parse_server_cert(  banner1,
618                                       banner1_private,
619                                       pstate,
620                                       px+i, len,
621                                       banout,
622                                       more);
623                     break;
624             }
625 
626             remaining -= len;
627             i += len-1;
628 
629             if (remaining == 0)
630                 state = START;
631         }
632 
633         break;
634     case UNKNOWN:
635     default:
636         i = (unsigned)length;
637     }
638 
639     ssl->handshake.state = state;
640     ssl->handshake.remaining = remaining;
641 }
642 
643 
644 /*****************************************************************************
645  * Called to parse the "hearbeat" data. This consists of the following
646  * structure:
647  *
648  * +--------+
649  * |  type  | 1=request, 2=response
650  * +--------+--------+
651  * |      length     |
652  * +--------+--------+
653  *
654  * This is followed by the echoed bytes, followed by some padding.
655  *
656  *****************************************************************************/
657 static void
parse_heartbeat(const struct Banner1 * banner1,void * banner1_private,struct ProtocolState * pstate,const unsigned char * px,size_t length,struct BannerOutput * banout,struct InteractiveData * more)658 parse_heartbeat(
659         const struct Banner1 *banner1,
660         void *banner1_private,
661         struct ProtocolState *pstate,
662         const unsigned char *px, size_t length,
663         struct BannerOutput *banout,
664         struct InteractiveData *more)
665 {
666     struct SSLRECORD *ssl = &pstate->sub.ssl;
667     unsigned state = ssl->handshake.state;
668     unsigned remaining = ssl->handshake.remaining;
669     unsigned i;
670     enum {
671         START,
672         LENGTH0, LENGTH1,
673         CONTENTS,
674         UNKNOWN,
675     };
676 
677     UNUSEDPARM(more);
678     UNUSEDPARM(banner1_private);
679 
680     /*
681      * `for all bytes in the segment`
682      *   `do a state transition for that byte `
683      */
684     for (i=0; i<length; i++)
685     switch (state) {
686 
687     /* this is the 'type' field for the hearbeat. There are only two
688      * values, '1' for request and '2' for response. Anything else indicates
689      * that either the data was corrupted, or else it is encrypted.
690      */
691     case START:
692         if (px[i] < 1 || 2 < px[i]) {
693             state = UNKNOWN;
694             break;
695         }
696         ssl->handshake.type = px[i];
697         DROPDOWN(i,length,state);
698 
699     /* Grab the two byte length field */
700     case LENGTH0:
701         remaining = px[i];
702         DROPDOWN(i,length,state);
703     case LENGTH1:
704         remaining <<= 8;
705         remaining |= px[i];
706 
707         /* `if heartbeat response ` */
708         if (ssl->handshake.type == 2) {
709 
710             /* if we have a non-trivial amount of data in the response, then
711              * it means the "bleed" attempt succeeded. */
712             if (remaining >= 16)
713                 banout_append(  banout, PROTO_VULN, "SSL[HEARTBLEED] ", 16);
714 
715             /* if we've been configured to "capture" the heartbleed contents,
716              * then initialize the BASE64 encoder */
717             if (banner1->is_capture_heartbleed) {
718                 banout_init_base64(&pstate->base64);
719                 banout_append(banout, PROTO_HEARTBLEED, "", 0);
720             }
721         }
722         DROPDOWN(i,length,state);
723 
724     /* Here is where we parse the contents of the heartbeat. This is the same
725      * skipping logic as the CONTENTS state within the ssl_parse_record()
726      * function.*/
727     case CONTENTS:
728         {
729             unsigned len = (unsigned)length-i;
730             if (len > remaining)
731                 len = remaining;
732 
733             /* If this is a RESPONSE, and we've been configured to CAPTURE
734              * hearbleed responses, then we write the bleeding bytes in
735              * BASE64 into the banner system. The user will be able to
736              * then do research on those bleeding bytes */
737             if (ssl->handshake.type == 2 && banner1->is_capture_heartbleed) {
738                 banout_append_base64(banout,
739                                      PROTO_HEARTBLEED,
740                                      px+i, len,
741                                      &pstate->base64);
742             }
743 
744             remaining -= len;
745             i += len-1;
746 
747             if (remaining == 0)
748                 state = UNKNOWN; /* padding */
749         }
750 
751         break;
752 
753     /* We reach this state either because the hearbeat data is corrupted or
754      * encrypted, or because we've reached the padding area after the
755      * heartbeat */
756     case UNKNOWN:
757     default:
758         i = (unsigned)length;
759     }
760 
761     /* not the handshake protocol, but we re-use their variables */
762     ssl->handshake.state = state;
763     ssl->handshake.remaining = remaining;
764 }
765 
766 /*****************************************************************************
767  * Called to parse the "hearbeat" data. This consists of the following
768  * structure:
769  *
770  * +--------+
771  * | level  | 1=warning, 2=fatal
772  * +--------+
773  * | descr  |
774  * +--------+
775  *
776  *****************************************************************************/
777 static void
parse_alert(const struct Banner1 * banner1,void * banner1_private,struct ProtocolState * pstate,const unsigned char * px,size_t length,struct BannerOutput * banout,struct InteractiveData * more)778 parse_alert(
779                 const struct Banner1 *banner1,
780                 void *banner1_private,
781                 struct ProtocolState *pstate,
782                 const unsigned char *px, size_t length,
783                 struct BannerOutput *banout,
784                 struct InteractiveData *more)
785 {
786     struct SSLRECORD *ssl = &pstate->sub.ssl;
787     unsigned state = ssl->handshake.state;
788     unsigned remaining = ssl->handshake.remaining;
789     unsigned i;
790     enum {
791         START,
792         DESCRIPTION,
793         UNKNOWN,
794     };
795 
796     UNUSEDPARM(more);
797     UNUSEDPARM(banner1_private);
798 
799     /*
800      * `for all bytes in the segment`
801      *   `do a state transition for that byte `
802      */
803     for (i=0; i<length; i++)
804         switch (state) {
805             case START:
806                 ssl->x.server_alert.level = px[i];
807                 DROPDOWN(i,length,state);
808 
809             case DESCRIPTION:
810                 ssl->x.server_alert.description = px[i];
811                 if (banner1->is_poodle_sslv3 && ssl->x.server_alert.level == 2) {
812                     char foo[64];
813 
814                     /* fatal error */
815                     switch (ssl->x.server_alert.description) {
816                         case 86:
817                             if (!banout_is_contains(banout, PROTO_SAFE, "TLS_FALLBACK_SCSV"))
818                                 banout_append(banout, PROTO_SAFE,
819                                       "poodle[TLS_FALLBACK_SCSV] ", AUTO_LEN);
820                             break;
821                         case 40:
822                             if (!banout_is_contains(banout, PROTO_SAFE, "TLS_FALLBACK_SCSV"))
823                                 banout_append(banout, PROTO_SAFE,
824                                           "poodle[no-SSLv3] ", AUTO_LEN);
825                             break;
826                         default:
827                             banout_append(banout, PROTO_SAFE,
828                                           "poodle[no-SSLv3] ", AUTO_LEN);
829                             sprintf_s(foo, sizeof(foo), " ALERT(0x%02x%02x) ",
830                                       ssl->x.server_alert.level,
831                                       ssl->x.server_alert.description
832                                       );
833 
834                             banout_append(banout, PROTO_SSL3, foo, AUTO_LEN);
835                             break;
836                     }
837                 } else {
838                     char foo[64];
839                     sprintf_s(foo, sizeof(foo), " ALERT(0x%02x%02x) ",
840                               ssl->x.server_alert.level,
841                               ssl->x.server_alert.description
842                               );
843 
844                     banout_append(banout, PROTO_SSL3, foo, AUTO_LEN);
845                 }
846                 DROPDOWN(i,length,state);
847 
848             case UNKNOWN:
849             default:
850                 i = (unsigned)length;
851         }
852 
853     /* not the handshake protocol, but we re-use their variables */
854     ssl->handshake.state = state;
855     ssl->handshake.remaining = remaining;
856 }
857 
858 
859 /*****************************************************************************
860  * This is the main SSL parsing function.
861  *
862  * SSL is a multi-layered protocol, consisting of "Records" as the outer
863  * protocol, with records containing data inside. The inner data is
864  * unencrypted during the session handshake, but then encrypted from then on.
865  *
866  * The SSL Records are a simple 5 byte protocol:
867  *
868  * +--------+
869  * |  type  |
870  * +--------+--------+
871  * |ver-mjr |ver-mnr |
872  * +--------+--------+
873  * |      length     |
874  * +--------+--------+
875  *
876  * This allows simple state-machine parsing. We need only 6 states, one for
877  * each byte, and then a "content" state tracking the contents of the recod
878  * until we've parsed "length" bytes, then back to the initial state.
879  *
880  *****************************************************************************/
881 static void
ssl_parse_record(const struct Banner1 * banner1,void * banner1_private,struct ProtocolState * pstate,const unsigned char * px,size_t length,struct BannerOutput * banout,struct InteractiveData * more)882 ssl_parse_record(
883         const struct Banner1 *banner1,
884         void *banner1_private,
885         struct ProtocolState *pstate,
886         const unsigned char *px, size_t length,
887         struct BannerOutput *banout,
888         struct InteractiveData *more)
889 {
890     unsigned state = pstate->state;
891     unsigned remaining = pstate->remaining;
892     struct SSLRECORD *ssl = &pstate->sub.ssl;
893     unsigned i;
894     enum {
895         START,
896         VERSION_MAJOR,
897         VERSION_MINOR,
898         LENGTH0, LENGTH1,
899         CONTENTS,
900         UNKNOWN,
901     };
902 
903     /*
904      * `for all bytes in the segment`
905      *   `do a state transition for that byte `
906      */
907     for (i=0; i<length; i++)
908     switch (state) {
909 
910     /*
911      * The initial state parses the "type" byte. There are only a few types
912      * defined so far, the values 20-25, but more can be defined in the
913      * future. The standard explicity says that they must be lower than 128,
914      * so if the high-order bit is set, we know that the byte is invalid,
915      * and that something is wrong.
916      */
917     case START:
918         if (px[i] & 0x80) {
919             state = UNKNOWN;
920             break;
921         }
922         if (ssl->type != px[i]) {
923             ssl->type = px[i];
924 
925             /* this is for some minimal fragmentation/reassembly */
926             ssl->handshake.state = 0;
927         }
928         DROPDOWN(i,length,state);
929 
930     /* This is the major version number, which must be the value '3',
931      * which means both SSLv3 and TLSv1. This parser doesn't support
932      * earlier versions of SSL. */
933     case VERSION_MAJOR:
934         if (px[i] != 3) {
935             state = UNKNOWN;
936             break;
937         }
938         ssl->version_major = px[i];
939         DROPDOWN(i,length,state);
940 
941     /* This is the minor version number. It's a little weird:
942      * 0 = SSLv3.0
943      * 1 = TLSv1.0
944      * 2 = TLSv1.1
945      * 3 = TLSv1.2
946      * 4 = TLSv1.3
947      */
948     case VERSION_MINOR:
949         ssl->version_minor = px[i];
950         DROPDOWN(i,length,state);
951 
952     /* This is the length field. In theory, it can be the full 64k bytes
953      * in length, but typical implements limit it to 16k */
954     case LENGTH0:
955         remaining = px[i]<<8;
956         DROPDOWN(i,length,state);
957     case LENGTH1:
958         remaining |= px[i];
959         DROPDOWN(i,length,state);
960         ssl->handshake.state = 0;
961 
962     /*
963      * This state parses the "contents" of a record. What we do here is at
964      * this level of the parser is that we calculate a sub-segment size,
965      * which is bounded by either the number of bytes in this records (when
966      * there are multiple records per packet), or the packet size (when the
967      * record exceeds the size of the packet).
968      * We then pass this sug-segment to the inner content parser. However, the
969      * inner parser has no effect on what happens in this parser. It's wholy
970      * indpedent, doing it's own thing.
971      */
972     case CONTENTS:
973         {
974             unsigned len;
975 
976             /* Size of this segment is either the bytes remaining in the
977              * current packet, or the bytes remaining in the record */
978             len = (unsigned)length - i;
979             if (len > remaining)
980                 len = remaining;
981 
982             /* Do an inner-parse of this segment. Note that the inner-parser
983              * has no effect on this outer record parser */
984             switch (ssl->type) {
985                 case 20: /* change cipher spec */
986                     break;
987                 case 21: /* alert */
988                     /* encrypted, usually, but if we get one here, it won't
989                      * be encrypted */
990                     parse_alert(banner1,
991                                     banner1_private,
992                                     pstate,
993                                     px+i, len,
994                                     banout,
995                                     more);
996                     break;
997                 case 22: /* handshake */
998                     parse_handshake(banner1,
999                                     banner1_private,
1000                                     pstate,
1001                                     px+i, len,
1002                                     banout,
1003                                     more);
1004                     break;
1005                 case 23: /* application data */
1006                     /* encrypted, always*/
1007                     break;
1008                 case 24: /* heartbeat */
1009                     /* enrypted, in theory, but not practice */
1010                     parse_heartbeat(banner1,
1011                                     banner1_private,
1012                                     pstate,
1013                                     px+i, len,
1014                                     banout,
1015                                     more);
1016                     break;
1017             }
1018 
1019             /* Skip ahead the number bytes in this segment. This makes the
1020              * parser very fast, because we aren't actually doing a single
1021              * byte at a time, but skipping forward large number of bytes
1022              * at a time -- except for the 5 byte headers */
1023             remaining -= len;
1024             i += len-1; /* if 'len' is zero, this still works */
1025 
1026             /* Once we've exhausted the contents of record, go back to the
1027              * start parsing the next record */
1028             if (remaining == 0)
1029                 state = START;
1030         }
1031         break;
1032 
1033     /* We reach the state when the protocol has become corrupted, such as in
1034      * those cases where it's not SSL */
1035     case UNKNOWN:
1036     default:
1037         i = (unsigned)length;
1038     }
1039 
1040     pstate->state = state;
1041     pstate->remaining = remaining;
1042 }
1043 
1044 
1045 /*****************************************************************************
1046  * This is called at program startup to initialize any structures we need
1047  * for parsing. The SSL parser doesn't need anything in particular, so
1048  * we just ignore it. We have to implement the callback, however, which
1049  * is why this empty function exists.
1050  *****************************************************************************/
1051 static void *
ssl_init(struct Banner1 * banner1)1052 ssl_init(struct Banner1 *banner1)
1053 {
1054     UNUSEDPARM(banner1);
1055     return 0;
1056 }
1057 
1058 /*****************************************************************************
1059  * This is the template "Client Hello" packet that is sent to the server
1060  * to initiate the SSL connection. Right now, it's statically just transmitted
1061  * on to the wire.
1062  * TODO: we need to make this dynamically generated, so that users can
1063  * select various options.
1064  *****************************************************************************/
1065 static const char
1066 ssl_hello_template[] =
1067 "\x16\x03\x02\x01\x6f"          /* TLSv1.1 record layer */
1068 "\x01" /* type = client-hello */
1069 "\x00\x01\x6b" /* length = 363 */
1070 "\x03\x02"      /* version = 3.02 (TLS 1.1) */
1071 
1072 "\x52\x48\xc5\x1a\x23\xf7\x3a\x4e\xdf\xe2\xb4\x82\x2f\xff\x09\x54" /* random */
1073 "\x9f\xa7\xc4\x79\xb0\x68\xc6\x13\x8c\xa4\x1c\x3d\x22\xe1\x1a\x98" /* TODO: re-randomize for each request, or at least on startup */
1074 
1075 "\x20" /* session-id-length = 32 */
1076 "\x84\xb4\x2c\x85\xaf\x6e\xe3\x59\xbb\x62\x68\x6c\xff\x28\x3d\x27"  /* random */
1077 "\x3a\xa9\x82\xd9\x6f\xc8\xa2\xd7\x93\x98\xb4\xef\x80\xe5\xb9\x90"  /* TODO: re-randomize for each request, or at least on startup */
1078 
1079 "\x00\x28" /* cipher suites length */
1080 "\xc0\x0a\xc0\x14\x00\x39\x00\x6b\x00\x35\x00\x3d\xc0\x07\xc0\x09"
1081 "\xc0\x23\xc0\x11\xc0\x13\xc0\x27\x00\x33\x00\x67\x00\x32\x00\x05"
1082 "\x00\x04\x00\x2f\x00\x3c\x00\x0a"
1083 
1084 "\x01" /* compression-methods-length = 1 */
1085 "\x00"
1086 
1087 "\x00\xfa" /* extensions length */
1088 
1089 /* server name */
1090 "\xef\x00"
1091 "\x00\x1a"
1092 "\x00\x18\x00\x00\x15\x73\x79\x6e\x64\x69\x63\x61\x74\x69\x6f\x6e"
1093 "\x2e\x74\x77\x69\x6d\x67\x2e\x63\x6f\x6d"
1094 
1095 "\xff\x01"
1096 "\x00\x01"
1097 "\x00"
1098 
1099 "\x00\x0a"
1100 "\x00\x08"
1101 "\x00\x06\x00\x17\x00\x18\x00\x19"
1102 
1103 "\x00\x0b"
1104 "\x00\x02"
1105 "\x01\x00"
1106 
1107 "\x00\x23"
1108 "\x00\xb0"
1109 "\x81\x01\x19\x67\x60\x1e\x04\x42\x9a\xf3\xe2\x3c\x86\x58\x4f\x87"
1110 "\x69\x44\xb0\x1d\x8e\x01\xfa\xa5\x87\x3d\x5d\xdc\x16\x4c\xb4\x20"
1111 "\xda\xd3\x42\xb0\x88\xec\x0a\x13\xc3\xc6\x4c\x44\x74\x7d\xf5\x83"
1112 "\x93\xeb\x16\x60\x7e\x47\x07\x15\xae\x68\x3f\x32\xfc\x28\x71\xdd"
1113 "\x8d\x2a\xe0\x9e\x03\xad\x28\xd9\x89\x2f\x0f\x07\xaf\xc1\x27\x8e"
1114 "\xf1\x57\xfb\xc6\xc4\xd4\x56\x3a\xf6\xed\x59\x61\x4a\x17\x14\x0b"
1115 "\xd7\x7c\xae\xfe\x55\xd9\x7a\xa6\xf6\xc6\x57\xb5\x3c\xed\x78\x9d"
1116 "\xee\x39\xd8\x67\x02\x09\x92\xcb\xa5\x66\xa3\x48\x3d\x06\xed\xa5"
1117 "\x02\x2e\x9b\x16\xf6\x2b\xe7\x3f\x79\x65\x1a\xcb\x6c\x5c\xbd\x6b"
1118 "\xad\x11\xde\xbe\xdf\x35\xdb\x0b\xff\x2c\x90\x94\x32\xb5\x94\x57"
1119 "\x3d\x5e\x25\xd2\x1b\xd2\x44\x85\x96\x31\x28\x69\xd7\x4a\x13\x0a"
1120 "\x33\x74\x00\x00\x75\x4f\x00\x00\x00\x05\x00\x05\x01\x00\x00\x00"
1121 "\x00"
1122 ;
1123 
1124 
1125 /*****************************************************************************
1126  *****************************************************************************/
1127 static char *
ssl_add_cipherspec_sslv3(void * templ,unsigned cipher_spec,unsigned is_append)1128 ssl_add_cipherspec_sslv3(void *templ, unsigned cipher_spec, unsigned is_append)
1129 {
1130     unsigned char *px;
1131     size_t len0 = ssl_hello_size(templ);
1132     size_t len1;
1133     size_t len1b;
1134     size_t len2;
1135     size_t offset;
1136     size_t offset2;
1137 
1138     /* Increase space by 2 for additional cipherspec */
1139     px = REALLOC(templ, ssl_hello_size(templ) + 2);
1140 
1141     /* parse the lengths */
1142     len1 = px[3] << 8 | px[4];
1143     len1b = px[6] << 16 | px[7] << 8 | px[8];
1144 
1145 
1146     /* skip session id field */
1147     offset = 43;
1148     offset += px[offset] + 1;
1149 
1150     /* do cipherspecs */
1151     len2 = px[offset] << 8 | px[offset+1];
1152     offset2 = offset+2;
1153     if (is_append) {
1154         /* append to end of list */
1155         memmove(px + offset2 + len2 + 2,
1156                 px + offset2 + len2,
1157                 len0 - (offset2 + len2));
1158         px[offset2 + len2    ] = (unsigned char)(cipher_spec>>8);
1159         px[offset2 + len2 + 1] = (unsigned char)(cipher_spec>>0);
1160     } else {
1161         /* prepend to start of list, making this the prefered cipherspec*/
1162         memmove(px + offset2 + 2,
1163                 px + offset2,
1164                 len0 - offset2);
1165         px[offset2    ] = (unsigned char)(cipher_spec>>8);
1166         px[offset2 + 1] = (unsigned char)(cipher_spec>>0);
1167     }
1168 
1169     /* fix length fields */
1170     len2 += 2;
1171     px[offset    ] = (unsigned char)(len2>>8);
1172     px[offset + 1] = (unsigned char)(len2>>0);
1173     len1b += 2;
1174     px[6] = (unsigned char)(len1b>>16);
1175     px[7] = (unsigned char)(len1b>> 8);
1176     px[8] = (unsigned char)(len1b>> 0);
1177     len1 += 2;
1178     px[3] = (unsigned char)(len1>>8);
1179     px[4] = (unsigned char)(len1>>0);
1180 
1181     return (char*)px;
1182 }
1183 
1184 /*****************************************************************************
1185  *****************************************************************************/
1186 char *
ssl_add_cipherspec(void * templ,unsigned cipher_spec,unsigned is_append)1187 ssl_add_cipherspec(void *templ, unsigned cipher_spec, unsigned is_append)
1188 {
1189     const unsigned char *px = (const unsigned char *)templ;
1190     unsigned version;
1191 
1192     /* ignore things that aren't "Hello" messages */
1193     if (px[0] != 0x16) {
1194         fprintf(stderr, "internal error\n");
1195         return templ;
1196     }
1197 
1198     /* figure out the proper version */
1199     version = px[1] << 8 | px[2];
1200 
1201     /* do different parsing depending on version */
1202     switch (version) {
1203         case 0x300:
1204             return ssl_add_cipherspec_sslv3(templ, cipher_spec, is_append);
1205         default:
1206             /*TODO:*/
1207             fprintf(stderr, "internal error\n");
1208             return templ;
1209     }
1210 }
1211 
1212 /*****************************************************************************
1213  * Figure out the Hello message size by parsing the data
1214  *****************************************************************************/
1215 unsigned
ssl_hello_size(const void * templ)1216 ssl_hello_size(const void *templ)
1217 {
1218     const unsigned char *px = (const unsigned char *)templ;
1219     size_t template_size;
1220 
1221     template_size = (px[3]<<8 | px[4]) + 5;
1222 
1223     return (unsigned)template_size;
1224 }
1225 
1226 /*****************************************************************************
1227  *****************************************************************************/
1228 char *
ssl_hello(const void * templ)1229 ssl_hello(const void *templ)
1230 {
1231     unsigned char *px = (unsigned char *)templ;
1232     unsigned now = (unsigned)time(0);
1233     unsigned i;
1234 
1235     /* parse existing template to figure out size */
1236     size_t template_size = (px[3]<<8 | px[4]) + 5;
1237 
1238     /* allocate memory for that size and copy */
1239     px = MALLOC(template_size);
1240     memcpy(px, templ, template_size);
1241 
1242     /* set the new timestamp and randomize buffer */
1243     px[11] = (unsigned char)(now>>24);
1244     px[12] = (unsigned char)(now>>16);
1245     px[13] = (unsigned char)(now>> 8);
1246     px[14] = (unsigned char)(now>> 0);
1247 
1248     /* create a pattern to make this detectable as specfically masscan */
1249     for (i=4; i<32; i++) {
1250         static const uint64_t key[2] = {0,0};
1251         unsigned val = i+now;
1252         unsigned char c = (unsigned char)siphash24(&val, sizeof(val), key);
1253 
1254         px[11+i] = c;
1255     }
1256 
1257     return (char*)px;
1258 }
1259 
1260 
1261 extern unsigned char ssl_test_case_1[];
1262 extern size_t ssl_test_case_1_size;
1263 extern unsigned char ssl_test_case_3[];
1264 extern size_t ssl_test_case_3_size;
1265 extern unsigned char google_cert[];
1266 extern size_t google_cert_size;
1267 extern unsigned char yahoo_cert[];
1268 extern size_t yahoo_cert_size;
1269 
1270 
1271 /*****************************************************************************
1272  *****************************************************************************/
1273 static int
ssl_selftest(void)1274 ssl_selftest(void)
1275 {
1276     struct Banner1 *banner1;
1277     struct ProtocolState state[1];
1278     unsigned ii;
1279     struct BannerOutput banout1[1];
1280     struct BannerOutput banout2[1];
1281     struct InteractiveData more;
1282     unsigned x;
1283 
1284     /*
1285      * Yahoo cert
1286      */
1287     {
1288         struct CertDecode certstate[1];
1289 
1290         memset(certstate, 0, sizeof(certstate));
1291         x509_decode_init(certstate, yahoo_cert_size);
1292 
1293         banner1 = banner1_create();
1294         banner1->is_capture_cert = 1;
1295         banout_init(banout1);
1296         x509_decode(certstate,
1297                     yahoo_cert,
1298                     yahoo_cert_size,
1299                     banout1);
1300         x = banout_is_contains(banout1, PROTO_SSL3,
1301                             ", fr.yahoo.com, ");
1302         if (!x) {
1303             printf("x.509 parser failure: google.com\n");
1304             return 1;
1305         }
1306 
1307 
1308         banner1_destroy(banner1);
1309         banout_release(banout1);
1310     }
1311 
1312 
1313     /*
1314      * Google cert
1315      */
1316     {
1317         struct CertDecode certstate[1];
1318 
1319         memset(certstate, 0, sizeof(certstate));
1320         x509_decode_init(certstate, google_cert_size);
1321 
1322         banner1 = banner1_create();
1323         banner1->is_capture_cert = 1;
1324         banout_init(banout1);
1325         x509_decode(certstate,
1326                     google_cert,
1327                     google_cert_size,
1328                     banout1);
1329         x = banout_is_equal(banout1, PROTO_SSL3,
1330                             ", www.google.com, www.google.com");
1331         if (!x) {
1332             printf("x.509 parser failure: google.com\n");
1333             return 1;
1334         }
1335         banner1_destroy(banner1);
1336         banout_release(banout1);
1337     }
1338 
1339 
1340     /*
1341      * Do the normal parse
1342      */
1343     banner1 = banner1_create();
1344     banner1->is_capture_cert = 1;
1345     memset(state, 0, sizeof(state));
1346     banout_init(banout1);
1347     {
1348         size_t i;
1349         for (i=0; i<ssl_test_case_3_size; i++)
1350         ssl_parse_record(  banner1,
1351                          0,
1352                          state,
1353                          ssl_test_case_3+i,
1354                          1,
1355                          banout1,
1356                          &more
1357                          );
1358     }
1359     /*if (0) {
1360         const char *foo = (char*)banout_string(banout1, PROTO_X509_CERT);
1361         printf("-----BEGIN CERTIFICATE-----\n");
1362         for (;;) {
1363             if (strlen(foo) > 72) {
1364                 printf("%.*s\n", 72, foo);
1365                 foo += 72;
1366             } else {
1367                 printf("%s\n", foo);
1368                 break;
1369             }
1370 
1371         }
1372         printf("-----END CERTIFICATE-----\n");
1373     }*/
1374     banner1_destroy(banner1);
1375     banout_release(banout1);
1376 
1377     /*
1378      * Do the fragmented parse
1379      */
1380     banner1 = banner1_create();
1381     banner1->is_capture_cert = 1;
1382     memset(state, 0, sizeof(state));
1383     banout_init(banout2);
1384     for (ii=0; ii<ssl_test_case_3_size; ii++)
1385     ssl_parse_record(  banner1,
1386                 0,
1387                 state,
1388                 (const unsigned char *)ssl_test_case_3+ii,
1389                 1,
1390                 banout2,
1391                 &more
1392                 );
1393     banner1_destroy(banner1);
1394     banout_release(banout2);
1395 
1396     /*
1397      * Do checking
1398      */
1399 #if 0
1400     if (memcmp(banner, "cert:MIIGYjCCBUqgAwIBAgIIWQmqMKKz/PYwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE", 65) != 0) {
1401         fprintf(stderr, "FAIL: ssl test\n");
1402         return 1;
1403     }
1404 
1405     if (banner_offset != bannerx_offset
1406         || memcmp(banner, bannerx, banner_offset) != 0)
1407         return 1;
1408 #endif
1409 #if 0
1410     {
1411         unsigned i = 0;
1412 
1413         while (i < banner_offset) {
1414             while (i < banner_offset && isspace(banner[i]))
1415                 i++;
1416             if (memcmp(&banner[i], "cert:", 5) == 0)
1417                 i += 5;
1418 
1419             printf("-----BEGIN CERTIFICATE-----\n");
1420             while (i < banner_offset && !isspace(banner[i])) {
1421                 unsigned j;
1422                 for (j=0; i+j<banner_offset && !isspace(banner[i+j]) && j < 64; j++)
1423                     ;
1424                 printf("%.*s\n", j, banner+i);
1425                 i += j;
1426             }
1427             printf("-----END CERTIFICATE-----\n");
1428         }
1429     }
1430 #endif
1431 
1432     return 0;
1433 }
1434 
1435 /*****************************************************************************
1436  * This is the 'plugin' structure that registers callbacks for this parser in
1437  * the main system.
1438  *****************************************************************************/
1439 struct ProtocolParserStream banner_ssl = {
1440     "ssl", 443, ssl_hello_template, sizeof(ssl_hello_template)-1, 0,
1441     ssl_selftest,
1442     ssl_init,
1443     ssl_parse_record,
1444 };
1445 
1446