1 /*
2 !!!!! BIZZARE CODE ALERT !!!!
3
4 This module decodes X.509 public-key certificates using a
5 "state-machine parser". If you are unfamiliar with such parsers,
6 this will look very strange to you.
7
8 The reason for such parsers is scalability. Certificates are so big
9 that they typically cross packet boundaries. This requires some sort
10 of "reassembly", which in term requires "memory allocation". This
11 is done on a per-connection basis, resulting in running out of memory
12 when dealing with millions of connections.
13
14 With a state-machine parser, we don't need to reassemble certificates, or
15 allocate memory. Instead, we maintain "state" between fragments. There
16 is about 60 bytes of state that we must keep.
17
18 If you are a code reviewer, you may care about looking into these common
19 ASN.1 parsing errors. I've marked them with a [NAME] here, you can search
20 these strings in the code to see how they are handled.
21
22 [ASN1-CHILD-OVERFLOW]
23 when the child length field causes it to exceed the length of
24 its parent
25 [ASN1-CHILD-UNDERFLOW]
26 when there is padding after all the child fields within a larger
27 parent field
28 [ASN1-DER-LENGTH]
29 when there are more bits used to encode a length field than necessary,
30 such as using 0x82 0x00 0x12 instead of simply 0x12 as a length
31 [ASN1-DER-NUMBER]
32 When there are more bits than necessary to encode an integer, such
33 as 0x00 0x00 0x00 0x20 rather than just 0x20.
34 Since we don't deal with numbers, we don't check this.
35 [ASN1-DER-SIGNED]
36 issues with signed vs. unsigned numbers, where unsined 4 byte integers
37 need an extra leading zero byte if their high-order bit is set
38 Since we don't deal with numbers, we don't check this.
39 [ASN1-DER-OID]
40 Issues with inserting zeroes into OIDs.
41 We explicitly deal with the opposite issue, allowing zeroes to be
42 inserted. We should probably chainge that, and detect it as a DER
43 error.
44
45 CERTIFICATE FORMAT
46
47 Certificate ::= SEQUENCE {
48 tbsCertificate TBSCertificate,
49 signatureAlgorithm AlgorithmIdentifier,
50 signatureValue BIT STRING }
51 TBSCertificate ::= SEQUENCE {
52 version [0] EXPLICIT Version DEFAULT v1,
53 serialNumber CertificateSerialNumber,
54 signature AlgorithmIdentifier,
55 issuer Name,
56 validity Validity,
57 subject Name,
58 subjectPublicKeyInfo SubjectPublicKeyInfo,
59 issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
60 -- If present, version MUST be v2 or v3
61 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
62 -- If present, version MUST be v2 or v3
63 extensions [3] EXPLICIT Extensions OPTIONAL
64 -- If present, version MUST be v3
65 }
66 Version ::= INTEGER { v1(0), v2(1), v3(2) }
67 CertificateSerialNumber ::= INTEGER
68 Validity ::= SEQUENCE {
69 notBefore Time,
70 notAfter Time }
71 Time ::= CHOICE {
72 utcTime UTCTime,
73 generalTime GeneralizedTime }
74 UniqueIdentifier ::= BIT STRING
75 SubjectPublicKeyInfo ::= SEQUENCE {
76 algorithm AlgorithmIdentifier,
77 subjectPublicKey BIT STRING }
78 Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
79 Extension ::= SEQUENCE {
80 extnID OBJECT IDENTIFIER,
81 critical BOOLEAN DEFAULT FALSE,
82 extnValue OCTET STRING
83 -- contains the DER encoding of an ASN.1 value
84 -- corresponding to the extension type identified
85 -- by extnID
86 }
87 */
88 #include "proto-x509.h"
89 #include "proto-spnego.h"
90 #include "proto-banout.h"
91 #include "masscan-app.h"
92 #include "smack.h"
93 #include "logger.h"
94 #include <assert.h>
95 #include <ctype.h>
96 #include <string.h>
97 #include <stdlib.h>
98 #include <stddef.h>
99 #include <stdint.h>
100 #include <time.h>
101
102 /****************************************************************************
103 * The X.509 certificates mark certain extensible fields with ASN.1
104 * object-identifiers. Instead of copying these out of the certificate,
105 * we match them using an Aho-Corasick DFA parser. These object-ids are
106 * below. At program startup, the main() function must call x509_init()
107 * to build the Aho-Corasick state-machine, which the main state-machine
108 * will use to parse these object-ids.
109 ****************************************************************************/
110 static struct SMACK *global_mib;
111
112
113 /****************************************************************************
114 * Currently, the only field we extract is the "Common Name".
115 ****************************************************************************/
116 enum {
117 Subject_Unknown,
118 Subject_Common,
119 };
120
121 /****************************************************************************
122 * See "global_mib" above.
123 ****************************************************************************/
124 static struct ObjectIdentifer {
125 const char *oid;
126 const char *name;
127 int id;
128 } mib[] = {
129 {"43.1006.51.341332", "selftest"}, /* for regression test */
130 {"43", "iso.org"},
131 {"43.6", "dod"},
132 {"43.6.1", "inet"},
133 {"43.6.1.2", "mgmt"},
134 {"43.6.1.2.1", "mib2"},
135 {"43.6.1.2.1.", "sys"},
136 {"43.6.1.2.1.1.1", "sysDescr"},
137 {"43.6.1.2.1.1.2", "sysObjectID"},
138 {"43.6.1.2.1.1.3", "sysUpTime"},
139 {"43.6.1.2.1.1.4", "sysContact"},
140 {"43.6.1.2.1.1.5", "sysName"},
141 {"43.6.1.2.1.1.6", "sysLocation"},
142 {"43.6.1.2.1.1.7", "sysServices"},
143 {"43.6.1.4", "priv"},
144 {"43.6.1.4.1", "enterprise"},
145 {"43.6.1.4.1.2001", "okidata"},
146 {"42", "1.2"},
147 {"42.840", "1.2.840"},
148 {"42.840.52", "0"},
149 {"42.840.113549", "1.2.840.113549"},
150 {"42.840.113549.1", "1.2.840.113549.1"},
151 {"42.840.113549.1.1", "1.2.840.113549.1.1"},
152 {"42.840.113549.1.1.4", "md5WithRSAEncryption"},
153 {"42.840.113549.1.1.5", "shaWithRSAEncryption"},
154 {"42.840.113549.1.1.11", "sha256WithRSAEncryption"},
155 {"42.840.113549.1.9", "1.2.840.113549.1.9"},
156 {"42.840.113549.1.9.1", "email"},
157 {"85", "2.5"},
158 {"85.4", "2.5.4"},
159 {"85.4.3", "common", Subject_Common},
160 {"85.4.5", "serial"},
161 {"85.4.6", "country"},
162 {"85.4.7", "locality"},
163 {"85.4.8", "state"},
164 {"85.4.10", "organization"},
165 {"85.4.11", "unit"},
166 {"85.4.13", "description"},
167 {"85.29", "2.5.29"},
168 {"85.29.17", "altname", Subject_Common},
169 {0,0},
170 };
171
172
173
174 /****************************************************************************
175 * Used in converting text object-ids into their binary form.
176 * @see convert_oid()
177 ****************************************************************************/
178 static unsigned
id_prefix_count(unsigned id)179 id_prefix_count(unsigned id)
180 {
181 #define TWO_BYTE ((unsigned long long)(~0)<<7)
182 #define THREE_BYTE ((unsigned long long)(~0)<<14)
183 #define FOUR_BYTE ((unsigned long long)(~0)<<21)
184 #define FIVE_BYTE ((unsigned long long)(~0)<<28)
185
186 if (id & FIVE_BYTE)
187 return 4;
188 if (id & FOUR_BYTE)
189 return 3;
190 if (id & THREE_BYTE)
191 return 2;
192 if (id & TWO_BYTE)
193 return 1;
194 return 0;
195 }
196
197
198 /****************************************************************************
199 * Convert text OID to binary. This is used when building a Aho-Corasick
200 * table for matching object-identifiers: we type the object-ids in the
201 * source-code in human-readable format, but must compile them to binary
202 * pattenrs to match within the X.509 certificates.
203 * @see x509_init()
204 ****************************************************************************/
205 static unsigned
convert_oid(unsigned char * dst,size_t sizeof_dst,const char * src)206 convert_oid(unsigned char *dst, size_t sizeof_dst, const char *src)
207 {
208 size_t offset = 0;
209
210 /* 'for all text characters' */
211 while (*src) {
212 const char *next_src;
213 unsigned id;
214 unsigned count;
215 unsigned i;
216
217 /* skip to next number */
218 while (*src == '.')
219 src++;
220
221 /* parse integer */
222 id = (unsigned)strtoul(src, (char**)&next_src, 0);
223 if (src == next_src)
224 break; /* invalid integer, programming error */
225 else
226 src = next_src;
227
228 /* find length of the integer */
229 count = id_prefix_count(id);
230
231 /* add binary integer to pattern */
232 for (i=count; i>0; i--) {
233 if (offset < sizeof_dst)
234 dst[offset++] = ((id>>(7*i)) & 0x7F) | 0x80;
235 }
236 if (offset < sizeof_dst)
237 dst[offset++] = (id & 0x7F);
238 }
239
240 return (unsigned)offset;
241 }
242
243
244 /****************************************************************************
245 * We need to initialize the OID/MIB parser
246 * This should be called on program startup.
247 * This is so that we can show short names, like "sysName", rather than
248 * the entire OID.
249 ****************************************************************************/
250 void
x509_init(void)251 x509_init(void)
252 {
253 unsigned i;
254
255 /* We use an Aho-Corasick pattern matcher for this. Not necessarily
256 * the most efficient, but also not bad */
257 global_mib = smack_create("ssl-oids", 0);
258
259 /* We just go through the table of OIDs and add them all one by
260 * one */
261 for (i=0; mib[i].name; i++) {
262 unsigned char pattern[256];
263 unsigned len;
264
265 len = convert_oid(pattern, sizeof(pattern), mib[i].oid);
266
267 smack_add_pattern( global_mib,
268 pattern,
269 len,
270 i,
271 SMACK_ANCHOR_BEGIN | SMACK_SNMP_HACK
272 );
273 }
274
275 /* Now that we've added all the OIDs, we need to compile this into
276 * an efficientdata structure. Later, when we get packets, we'll
277 * use this for searching */
278 smack_compile(global_mib);
279
280 }
281
282
283
284 /****************************************************************************
285 * Since ASN.1 contains nested structures, each with their own length field,
286 * we must maintain a small stack as we parse down the structure. Every time
287 * we enter a field, this function "pushes" the ASN.1 "length" field onto
288 * the stack. When we are done parsing the current field, we'll pop the
289 * length back off the stack, and subtract from it the number of bytes
290 * we've parsed.
291 *
292 * @param x
293 * The X.509 certificate parsing structure.
294 * @param next_state
295 * Tells the parser the next field we'll be parsing after this field
296 * at the same level of the nested ASN.1 structure, or nothing if
297 * there are no more fields.
298 * @param remaining
299 * The 'length' field. We call it 'remaining' instead of 'length'
300 * because as more bytes arrive, we decrement the length field until
301 * it reaches zero. Thus, at any point of time, it doesn't represent
302 * the length of the current ASN.1 field, but the remaining-length.
303 ****************************************************************************/
304 static void
ASN1_push(struct CertDecode * x,unsigned next_state,uint64_t remaining)305 ASN1_push(struct CertDecode *x, unsigned next_state, uint64_t remaining)
306 {
307 static const size_t STACK_DEPTH
308 = sizeof(x->stack.remainings)
309 / sizeof(x->stack.remainings[0]);
310
311 /* X.509 certificates can't be more than 64k in size. Therefore, to
312 * conserve space (as we must store the state for millions of TCP
313 * connections), we use the smallest number possible for the length,
314 * meaning a 16-bit 'unsigned short'. If the certificate has a larger
315 * length field, we need to reject it. */
316 if ((remaining >> 16) != 0) {
317 fprintf(stderr, "ASN.1 length field too big\n");
318 x->state = 0xFFFFFFFF;
319 return;
320 }
321
322 /* Make sure we don't recurse too deep, past the end of the stack. Note
323 * that this condition checks a PRGRAMMING error not an INPUT error,
324 * because we skip over fields we don't care about, and don't recurse
325 * into them even if they have many levels deep */
326 if (x->stack.depth >= STACK_DEPTH) {
327 fprintf(stderr, "ASN.1 recursion too deep\n");
328 x->state = 0xFFFFFFFF;
329 return;
330 }
331
332 /* Subtract this length from it's parent.
333 *
334 *[ASN1-CHILD-OVERFLOW]
335 * It is here that we deal with the classic ASN.1 parsing problem in
336 * which the child object claims a bigger length than its parent
337 * object. We could shrink the length field to fit, then continue
338 * parsing, but instead we choose to instead cease parsing the certificate.
339 * Note that this property is recursive: I don't need to redo the check
340 * all the way up the stack, because I know my parent's length does
341 * not exceed my grandparent's length.
342 * I know certificates exist that trigger this error -- I need to track
343 * them down and figure out why.
344 */
345 if (x->stack.depth) {
346 if (remaining > x->stack.remainings[0]) {
347 LOG(1, "ASN.1 inner object bigger than container [%u, %u]\n",
348 next_state, x->stack.states[0]);
349 x->state = 0xFFFFFFFF;
350 return;
351 }
352 x->stack.remainings[0] = (unsigned short)
353 (x->stack.remainings[0] - remaining);
354 }
355
356 /* Since 'remainings[0]' always represents the top of the stack, we
357 * move all the bytes down one during the push operation. I suppose this
358 * is more expensive than doing it the other way, where something
359 * like "raminings[stack.depth]" reprents the top of the stack,
360 * meaning no moves are necessary, but I prefer the cleanliness of the
361 * code using [0] index instead */
362 memmove( &x->stack.remainings[1],
363 &x->stack.remainings[0],
364 x->stack.depth * sizeof(x->stack.remainings[0]));
365 x->stack.remainings[0] = (unsigned short)remaining;
366
367 memmove( &x->stack.states[1],
368 &x->stack.states[0],
369 x->stack.depth * sizeof(x->stack.states[0]));
370 x->stack.states[0] = (unsigned char)next_state;
371
372 /* increment the count by one and exit */
373 x->stack.depth++;
374 }
375
376
377 /****************************************************************************
378 * This is the corresponding 'pop' operation to the ASN1_push() operation.
379 * See that function for more details.
380 * @see ASN1_push()
381 ****************************************************************************/
382 static unsigned
ASN1_pop(struct CertDecode * x)383 ASN1_pop(struct CertDecode *x)
384 {
385 unsigned next_state;
386 next_state = x->stack.states[0];
387 x->stack.depth--;
388 memmove( &x->stack.remainings[0],
389 &x->stack.remainings[1],
390 x->stack.depth * sizeof(x->stack.remainings[0]));
391 memmove( &x->stack.states[0],
392 &x->stack.states[1],
393 x->stack.depth * sizeof(x->stack.states[0]));
394 return next_state;
395 }
396
397
398 /****************************************************************************
399 * Called to skip the remainder of the ASN.1 field
400 * @return
401 * 1 if we've reached the end of the field
402 * 0 otherwise
403 ****************************************************************************/
404 static unsigned
ASN1_skip(struct CertDecode * x,unsigned * i,size_t length)405 ASN1_skip(struct CertDecode *x, unsigned *i, size_t length)
406 {
407 unsigned len;
408
409 if (x->stack.remainings[0] == 0)
410 return 1;
411
412 /* bytes remaining in packet */
413 len = (unsigned)(length - (*i) - 1);
414
415 /* bytes remaining in field */
416 if (len > x->stack.remainings[0])
417 len = x->stack.remainings[0];
418
419 /* increment 'offset' by this length */
420 (*i) += len;
421
422 /* decrement 'remaining' by this length */
423 x->stack.remainings[0] = (unsigned short)(x->stack.remainings[0] - len);
424
425 return x->stack.remainings[0] == 0;
426
427 }
428
429
430 /****************************************************************************
431 * The X.509 ASN.1 parser is done with a state-machine, where each byte of
432 * the certificate has a corresponding state value. This massive enum
433 * is for all those states.
434 * DANGER NOTE NOTE NOTE NOTE DANGER NOTE DANGER NOTE
435 * These states are in a specific order. We'll just do 'state++' sometimes
436 * to go the next state. Therefore, you can't chane the order wihtout
437 * changing the code.
438 ****************************************************************************/
439 enum X509state {
440 TAG0, TAG0_LEN, TAG0_LENLEN,
441 TAG1, TAG1_LEN, TAG1_LENLEN,
442 VERSION0_TAG, VERSION0_LEN, VERSION0_LENLEN,
443 VERSION1_TAG, VERSION1_LEN, VERSION1_LENLEN, VERSION_CONTENTS,
444 SERIAL_TAG, SERIAL_LEN, SERIAL_LENLEN, SERIAL_CONTENTS,
445 SIG0_TAG, SIG0_LEN, SIG0_LENLEN,
446 SIG1_TAG, SIG1_LEN, SIG1_LENLEN, SIG1_CONTENTS0,SIG1_CONTENTS1,
447 ISSUER0_TAG, ISSUER0_LEN, ISSUER0_LENLEN,
448 ISSUER1_TAG, ISSUER1_LEN, ISSUER1_LENLEN,
449 ISSUER2_TAG, ISSUER2_LEN, ISSUER2_LENLEN,
450 ISSUERID_TAG, ISSUERID_LEN, ISSUERID_LENLEN, ISSUERID_CONTENTS0, ISSUERID_CONTENTS1,
451 ISSUERNAME_TAG, ISSUERNAME_LEN, ISSUERNAME_LENLEN, ISSUERNAME_CONTENTS,
452 VALIDITY_TAG, VALIDITY_LEN, VALIDITY_LENLEN,
453 VNBEFORE_TAG, VNBEFORE_LEN, VNBEFORE_LENLEN, VNBEFORE_CONTENTS,
454 VNAFTER_TAG, VNAFTER_LEN, VNAFTER_LENLEN, VNAFTER_CONTENTS,
455 SUBJECT0_TAG, SUBJECT0_LEN, SUBJECT0_LENLEN,
456 SUBJECT1_TAG, SUBJECT1_LEN, SUBJECT1_LENLEN,
457 SUBJECT2_TAG, SUBJECT2_LEN, SUBJECT2_LENLEN,
458 SUBJECTID_TAG, SUBJECTID_LEN, SUBJECTID_LENLEN, SUBJECTID_CONTENTS0, SUBJECTID_CONTENTS1,
459 SUBJECTNAME_TAG,SUBJECTNAME_LEN,SUBJECTNAME_LENLEN, SUBJECTNAME_CONTENTS,
460 PUBKEY0_TAG, PUBKEY0_LEN, PUBKEY0_LENLEN, PUBKEY0_CONTENTS,
461 EXTENSIONS_A_TAG, EXTENSIONS_A_LEN, EXTENSIONS_A_LENLEN,
462 EXTENSIONS_S_TAG, EXTENSIONS_S_LEN, EXTENSIONS_S_LENLEN,
463 EXTENSION_TAG, EXTENSION_LEN, EXTENSION_LENLEN,
464 EXTENSION_ID_TAG, EXTENSION_ID_LEN, EXTENSION_ID_LENLEN, EXTENSION_ID_CONTENTS0, EXTENSION_ID_CONTENTS1,
465 EXTVALUE_TAG, EXTVALUE_LEN, EXTVALUE_LENLEN,
466 EXTVALUE2_TAG, EXTVALUE2_LEN, EXTVALUE2_LENLEN,
467 EXTVALUE3_TAG, EXTVALUE3_LEN, EXTVALUE3_LENLEN,
468 EXT_DNSNAME_TAG, EXT_DNSNAME_LEN, EXT_DNSNAME_LENLEN, EXT_DNSNAME_CONTENTS,
469 ALGOID0_TAG, ALGOID0_LEN, ALGOID0_LENLEN,
470 ALGOID1_TAG, ALGOID1_LEN, ALGOID1_LENLEN, ALGOID1_CONTENTS0, ALGOID1_CONTENTS1,
471 ENC_TAG, ENC_LEN, ENC_LENLEN, ENC_CONTENTS,
472
473
474 PADDING=254,
475 ERROR=0xFFFFFFFF,
476 };
477
478 /****************************************************************************
479 * My parser was kludged together in a couple of hours, and has this bug
480 * where I really don't know the next state like I should. Therefore, this
481 * function patches it, converting the next state I think I want to the
482 * next state that I really do want.
483 * TODO: fix the parser so that this function is no longer necessary.
484 ****************************************************************************/
485 static unsigned
kludge_next(unsigned state)486 kludge_next(unsigned state)
487 {
488 switch (state) {
489 case TAG1_LEN:
490 return ALGOID0_TAG;
491 case ALGOID0_LEN:
492 return ENC_TAG;
493 case SERIAL_LEN:
494 return SIG0_TAG;
495 case VERSION0_LEN:
496 return SERIAL_TAG;
497 case SIG0_LEN:
498 return ISSUER0_TAG;
499 case ISSUER0_LEN:
500 return VALIDITY_TAG;
501 case SUBJECT0_LEN:
502 return PUBKEY0_TAG;
503 case ISSUER1_LEN:
504 return ISSUER1_TAG;
505 case SUBJECT1_LEN:
506 return SUBJECT1_TAG;
507 case ISSUERID_LEN:
508 return ISSUERNAME_TAG;
509 case EXTENSION_LEN:
510 return EXTENSION_TAG;
511 case EXTENSION_ID_LEN:
512 return EXTVALUE_TAG;
513 case EXT_DNSNAME_LEN:
514 return EXTVALUE3_TAG;
515 case SUBJECTID_LEN:
516 return SUBJECTNAME_TAG;
517 case VALIDITY_LEN:
518 return SUBJECT0_TAG;
519 case VNBEFORE_LEN:
520 return VNAFTER_TAG;
521 case PUBKEY0_LEN:
522 return EXTENSIONS_A_TAG;
523 default:
524 return PADDING;
525 }
526 }
527
528
529
530
531 /****************************************************************************
532 * This is a parser for X.509 certificates. It uses "state-machine"
533 * technology, so that it accepts an in-order sequence of fragments. The
534 * entire x.509 certificate does not need to be in memory -- you can start
535 * calling this function when you have only the first fragment.
536 *
537 * It works by enumerating every possible state. In other words, every
538 * byte of an X.509 certificate has an enumerated 'state' variable. As
539 * each byte arrives from the stream, we parse it, and change to the next
540 * state. When we run out of input, we exit the function, saving the
541 * current state-variable. When the next fragment arrives, we resume
542 * at the same state where we left off.
543 ****************************************************************************/
544 void
x509_decode(struct CertDecode * x,const unsigned char * px,size_t length,struct BannerOutput * banout)545 x509_decode(struct CertDecode *x,
546 const unsigned char *px, size_t length,
547 struct BannerOutput *banout)
548 {
549 unsigned i;
550 enum X509state state = x->state;
551
552
553 #define GOTO_ERROR(state, i, length) (state)=0xFFFFFFFF;(i)=(length);continue
554
555 /* 'for all bytes in the current fragment ...'
556 * 'process that byte, causing a state-transition '
557 */
558 for (i=0; i<length; i++) {
559
560
561 /*
562 * If we've reached the end of the current field, then we need to
563 * pop up the stack and resume parsing the parent field. Since we
564 * reach the end of several levels simultaneously, we may need to
565 * pop several levels at once
566 */
567 while (x->stack.remainings[0] == 0) {
568 if (x->stack.depth == 0)
569 return;
570 state = ASN1_pop(x);
571 }
572
573 /*
574 * Decrement the current 'remaining' length field.
575 */
576 x->stack.remainings[0]--;
577
578 /*
579 * Jump to the current current state
580 */
581 switch (state) {
582 case ENC_TAG:
583 if (px[i] != 0x03) {
584 state = ERROR;
585 continue;
586 }
587 state++;
588 break;
589 case ISSUERNAME_TAG:
590 if (px[i] != 0x13 && px[i] != 0x0c) {
591 state++;
592 continue;
593 }
594 if (x->is_capture_issuer) {
595 banout_append(banout, PROTO_SSL3, " issuer[", AUTO_LEN);
596 }
597 state++;
598 break;
599 case SUBJECTNAME_TAG:
600 if (px[i] != 0x13 && px[i] != 0x0c) {
601 state++;
602 continue;
603 }
604 if (x->is_capture_subject) {
605 banout_append(banout, PROTO_SSL3, " subject[", AUTO_LEN);
606 }
607 state++;
608 break;
609 case ISSUER1_TAG:
610 case SUBJECT1_TAG:
611 x->subject.type = 0;
612 if (px[i] != 0x31) {
613 state++;
614 continue;
615 }
616 state++;
617 break;
618 case VNBEFORE_TAG:
619 case VNAFTER_TAG:
620 if (px[i] != 0x17) {
621 state++;
622 continue;
623 }
624 state++;
625 break;
626 case VERSION0_TAG:
627 if (px[i] != 0xa0) {
628 state = ERROR;
629 continue;
630 }
631 state++;
632 break;
633 case SIG1_TAG:
634 case ISSUERID_TAG:
635 case SUBJECTID_TAG:
636 case EXTENSION_ID_TAG:
637 case ALGOID1_TAG:
638 if (px[i] != 0x06) {
639 state = ERROR;
640 continue;
641 }
642 state++;
643 break;
644 case VERSION1_TAG:
645 case SERIAL_TAG:
646 if (px[i] != 0x02) {
647 state = ERROR;
648 continue;
649 }
650 x->u.num = 0;
651 state++;
652 break;
653 case ISSUERNAME_CONTENTS:
654 if (x->is_capture_issuer) {
655 banout_append(banout, PROTO_SSL3, px+i, 1);
656 if (x->stack.remainings[0] == 0)
657 banout_append(banout, PROTO_SSL3, "]", 1);
658 }
659 break;
660 case SUBJECTNAME_CONTENTS:
661 case EXT_DNSNAME_CONTENTS:
662 if (x->is_capture_subject) {
663 banout_append(banout, PROTO_SSL3, px+i, 1);
664 if (x->stack.remainings[0] == 0)
665 banout_append(banout, PROTO_SSL3, "]", 1);
666 } else if (x->subject.type == Subject_Common)
667 banout_append(banout, PROTO_SSL3, px+i, 1);
668 break;
669 case VERSION_CONTENTS:
670 x->u.num <<= 8;
671 x->u.num |= px[i];
672 if (x->stack.remainings[0] == 0)
673 state = PADDING;
674 break;
675 case ISSUERID_CONTENTS0:
676 case SUBJECTID_CONTENTS0:
677 case EXTENSION_ID_CONTENTS0:
678 case ALGOID1_CONTENTS0:
679 case SIG1_CONTENTS0:
680 memset(&x->u.oid, 0, sizeof(x->u.oid));
681 state++;
682 case ISSUERID_CONTENTS1:
683 case SUBJECTID_CONTENTS1:
684 case EXTENSION_ID_CONTENTS1:
685 case ALGOID1_CONTENTS1:
686 case SIG1_CONTENTS1:
687 {
688 size_t id;
689 unsigned offset = i;
690 unsigned oid_state = x->u.oid.state;
691
692
693 /* First, look it up */
694 id = smack_search_next( global_mib,
695 &oid_state,
696 px,
697 &offset,
698 offset + 1);
699 x->u.oid.state = (unsigned short)oid_state;
700
701 /* Do the multibyte numbers */
702 x->u.oid.num <<= 7;
703 x->u.oid.num |= px[i] & 0x7F;
704
705 if (px[i] & 0x80) {
706 /* This is a multibyte number, don't do anything at
707 * this stage */
708 ;
709 } else {
710 if (id == SMACK_NOT_FOUND) {
711 if (x->u.oid.last_id) {
712 //printf("%s", mib[x->u.oid.last_id].name);
713 x->u.oid.last_id = 0;
714 }
715 //printf(".%u", (unsigned)x->u.oid.num);
716 } else {
717 //printf("%s [%u]\n", mib[x->u.oid.last_id].name, mib[x->u.oid.last_id].id);
718 x->subject.type = mib[id].id;
719 if (x->subject.type == Subject_Common
720 && state == SUBJECTID_CONTENTS1) {
721 if (x->count <= 1) {
722 /* only handle first certificate in the chain */
723 banout_append(banout, PROTO_SSL3, ", ", 2);
724 } else {
725 x->subject.type = 0;
726 }
727
728
729 }
730 //if (x->subject.type == Subject_Common
731 // && state == EXTENSION_ID_CONTENTS1)
732 // ; //banout_append(banout, PROTO_SSL3, ", ", 2);
733 x->u.oid.last_id = (unsigned char)id;
734 }
735 x->u.oid.num = 0;
736 }
737 if (x->stack.remainings[0] == 0) {
738 if (x->u.oid.last_id) {
739 //printf("%s", mib[x->u.oid.last_id].name);
740 x->u.oid.last_id = 0;
741 }
742 state = PADDING;
743 //printf("\n");
744 }
745 }
746 break;
747 case SERIAL_CONTENTS:
748 x->stack.states[0] = (unsigned char)(state+1);
749 x->u.num <<= 8;
750 x->u.num |= px[i];
751 if (x->stack.remainings[0] == 0)
752 state = PADDING;
753 break;
754
755 case TAG0:
756 case TAG1:
757 case SIG0_TAG:
758 case ISSUER0_TAG:
759 case ISSUER2_TAG:
760 case SUBJECT0_TAG:
761 case SUBJECT2_TAG:
762 case VALIDITY_TAG:
763 case PUBKEY0_TAG:
764 case EXTENSIONS_S_TAG:
765 case EXTENSION_TAG:
766 case EXTVALUE2_TAG:
767 case ALGOID0_TAG:
768 if (px[i] != 0x30) {
769 state = ERROR;
770 continue;
771 }
772 state++;
773 break;
774 case EXTENSIONS_A_TAG:
775 if (px[i] != 0xa3) {
776 state = ERROR;
777 continue;
778 }
779 state++;
780 break;
781
782 /*
783 GeneralName ::= CHOICE {
784 otherName [0] OtherName,
785 rfc822Name [1] IA5String,
786 dNSName [2] IA5String,
787 x400Address [3] ORAddress,
788 directoryName [4] Name,
789 ediPartyName [5] EDIPartyName,
790 uniformResourceIdentifier [6] IA5String,
791 iPAddress [7] OCTET STRING,
792 registeredID [8] OBJECT IDENTIFIER }
793 */
794
795 case EXTVALUE3_TAG:
796 if (x->subject.type == Subject_Common) {
797 switch (px[i]) {
798 case 0x82: /* dNSName */
799 banout_append(banout, PROTO_SSL3, ", ", 2);
800 state = EXT_DNSNAME_LEN;
801 break;
802 default:
803 state = PADDING;
804 break;
805 }
806 } else {
807 state = PADDING;
808 }
809 break;
810
811 case EXTVALUE_TAG:
812 /* can be anything */
813 switch (px[i]) {
814 default:
815 case 2:
816 state = PADDING;
817 break;
818 case 4:
819 state++;
820 break;
821 }
822 break;
823
824
825 case TAG0_LEN:
826 case TAG1_LEN:
827 case VERSION0_LEN:
828 case VERSION1_LEN:
829 case SERIAL_LEN:
830 case SIG0_LEN:
831 case SIG1_LEN:
832 case ISSUER0_LEN:
833 case ISSUER1_LEN:
834 case ISSUER2_LEN:
835 case ISSUERID_LEN:
836 case ISSUERNAME_LEN:
837 case VALIDITY_LEN:
838 case VNBEFORE_LEN:
839 case VNAFTER_LEN:
840 case SUBJECT0_LEN:
841 case SUBJECT1_LEN:
842 case SUBJECT2_LEN:
843 case SUBJECTID_LEN:
844 case SUBJECTNAME_LEN:
845 case EXTENSIONS_A_LEN:
846 case EXTENSIONS_S_LEN:
847 case EXTENSION_LEN:
848 case EXTENSION_ID_LEN:
849 case EXTVALUE_LEN:
850 case EXTVALUE2_LEN:
851 case EXTVALUE3_LEN:
852 case EXT_DNSNAME_LEN:
853 case PUBKEY0_LEN:
854 case ALGOID0_LEN:
855 case ALGOID1_LEN:
856 case ENC_LEN:
857 /* We do the same processing for all the various length fields.
858 * There are three possible length fields:
859 * 0x7F - for lengths 127 and below
860 * 0x81 XX - for lengths 127 to 255
861 * 0x82 XX XX - for length 256 to 65535
862 * This state processes the first byte, and if it's an extended
863 * field, switches to the correspondign xxx_LENLEN state
864 */
865 if (px[i] & 0x80) {
866 x->u.tag.length_of_length = px[i]&0x7F;
867 x->u.tag.remaining = 0;
868 state++;
869 break;
870 } else {
871 x->u.tag.remaining = px[i];
872 ASN1_push(x, kludge_next(state), x->u.tag.remaining);
873 state += 2;
874 memset(&x->u, 0, sizeof(x->u));
875 break;
876 }
877
878 case TAG0_LENLEN:
879 case TAG1_LENLEN:
880 case VERSION0_LENLEN:
881 case VERSION1_LENLEN:
882 case SERIAL_LENLEN:
883 case SIG0_LENLEN:
884 case SIG1_LENLEN:
885 case ISSUER0_LENLEN:
886 case ISSUER1_LENLEN:
887 case ISSUER2_LENLEN:
888 case ISSUERID_LENLEN:
889 case ISSUERNAME_LENLEN:
890 case VALIDITY_LENLEN:
891 case VNBEFORE_LENLEN:
892 case VNAFTER_LENLEN:
893 case SUBJECT0_LENLEN:
894 case SUBJECT1_LENLEN:
895 case SUBJECT2_LENLEN:
896 case SUBJECTID_LENLEN:
897 case SUBJECTNAME_LENLEN:
898 case PUBKEY0_LENLEN:
899 case EXTENSIONS_A_LENLEN:
900 case EXTENSIONS_S_LENLEN:
901 case EXTENSION_LENLEN:
902 case EXTENSION_ID_LENLEN:
903 case EXTVALUE_LENLEN:
904 case EXTVALUE2_LENLEN:
905 case EXTVALUE3_LENLEN:
906 case EXT_DNSNAME_LENLEN:
907 case ALGOID0_LENLEN:
908 case ALGOID1_LENLEN:
909 case ENC_LENLEN:
910 /* We process all multibyte lengths the same way in this
911 * state.
912 */
913
914 /* [ASN1-DER-LENGTH]
915 * Check for strict DER compliance, which says that there should
916 * be no leading zero bytes */
917 if (x->u.tag.remaining == 0 && px[i] == 0)
918 x->is_der_failure = 1;
919
920 /* parse this byte */
921 x->u.tag.remaining = (x->u.tag.remaining)<<8 | px[i];
922 x->u.tag.length_of_length--;
923
924 /* If we aren't finished yet, loop around and grab the next */
925 if (x->u.tag.length_of_length)
926 continue;
927
928 /* [ASN1-DER-LENGTH]
929 * Check for strict DER compliance, which says that for lengths
930 * 127 and below, we need only 1 byte to encode it, not many */
931 if (x->u.tag.remaining < 128)
932 x->is_der_failure = 1;
933
934 /*
935 * We have finished parsing the tag-length fields, and are now
936 * ready to parse the 'value'. Push the current state on the
937 * stack, then decend into the child field.
938 */
939 ASN1_push(x, kludge_next(state-1), x->u.tag.remaining);
940 state++;
941 memset(&x->u, 0, sizeof(x->u));
942 break;
943
944 case VNBEFORE_CONTENTS:
945 case VNAFTER_CONTENTS:
946 switch (x->u.timestamp.state) {
947 case 0:
948 x->u.timestamp.year = (px[i] - '0') * 10;
949 x->u.timestamp.state++;
950 break;
951 case 1:
952 x->u.timestamp.year += (px[i] - '0');
953 x->u.timestamp.state++;
954 break;
955 case 2:
956 x->u.timestamp.month = (px[i] - '0') * 10;
957 x->u.timestamp.state++;
958 break;
959 case 3:
960 x->u.timestamp.month += (px[i] - '0');
961 x->u.timestamp.state++;
962 break;
963 case 4:
964 x->u.timestamp.day = (px[i] - '0') * 10;
965 x->u.timestamp.state++;
966 break;
967 case 5:
968 x->u.timestamp.day += (px[i] - '0');
969 x->u.timestamp.state++;
970 break;
971 case 6:
972 x->u.timestamp.hour = (px[i] - '0') * 10;
973 x->u.timestamp.state++;
974 break;
975 case 7:
976 x->u.timestamp.hour += (px[i] - '0');
977 x->u.timestamp.state++;
978 break;
979 case 8:
980 x->u.timestamp.minute = (px[i] - '0') * 10;
981 x->u.timestamp.state++;
982 break;
983 case 9:
984 x->u.timestamp.minute += (px[i] - '0');
985 x->u.timestamp.state++;
986 break;
987 case 10:
988 x->u.timestamp.second = (px[i] - '0') * 10;
989 x->u.timestamp.state++;
990 break;
991 case 11:
992 x->u.timestamp.second += (px[i] - '0');
993 x->u.timestamp.state++;
994 {
995 struct tm tm;
996 time_t now;
997
998 tm.tm_hour = x->u.timestamp.hour;
999 tm.tm_isdst = 0;
1000 tm.tm_mday = x->u.timestamp.day;
1001 tm.tm_min = x->u.timestamp.minute;
1002 tm.tm_mon = x->u.timestamp.month - 1;
1003 tm.tm_sec = x->u.timestamp.second;
1004 tm.tm_wday = 0;
1005 tm.tm_yday = 0;
1006 tm.tm_year = 100 + x->u.timestamp.year;
1007
1008
1009 now = mktime(&tm);
1010
1011 //tm = *localtime(&now);
1012 if (state == VNBEFORE_CONTENTS)
1013 x->prev = now;
1014 else {
1015 ;//printf("validity:%u-days\n", (now-x->prev)/(24*60*60));
1016 }
1017 }
1018 break;
1019 case 12:
1020 break;
1021 }
1022 break;
1023
1024 case PADDING:
1025 /* [ASN1-CHILD-UNDERFLOW]
1026 * This state is reached when we've parsed everything inside an
1027 * ASN.1 field, yet there are still bytes left to parse. There
1028 * are TWO reasons why we reach this state.
1029 * #1 there is a strict DER encoding problem, and we ought
1030 * to flag the error
1031 * #2 are parser is incomplete; we simply haven't added code
1032 * for all fields yet, and therefore treat them as padding
1033 * We should flag the DER failure, but we can't, because the
1034 * existence of unparsed fields mean we'll falsely trigger DER
1035 * errors all the time.
1036 *
1037 * Note that due to the state-machine style parsing, we don't do
1038 * anything in this field. This problem naturally takes care of
1039 * itself.
1040 */
1041 break;
1042
1043 case PUBKEY0_CONTENTS:
1044 case ENC_CONTENTS:
1045 ASN1_skip(x, &i, length);
1046 break;
1047
1048 case ERROR:
1049 default:
1050 ASN1_skip(x, &i, length);
1051 break;
1052 }
1053 }
1054
1055 /*
1056 * Save the state variable and exit
1057 */
1058 if (x->state != 0xFFFFFFFF)
1059 x->state = state;
1060 }
1061 void
spnego_decode(struct SpnegoDecode * spnego,const unsigned char * px,size_t length,struct BannerOutput * banout)1062 spnego_decode(struct SpnegoDecode *spnego,
1063 const unsigned char *px, size_t length,
1064 struct BannerOutput *banout)
1065 {
1066 struct CertDecode *x = spnego->x509;
1067 unsigned i;
1068 unsigned state = x->state;
1069
1070 enum {
1071 /*NegotiationToken ::= CHOICE {
1072 negTokenInit [0] NegTokenInit,
1073 negTokenResp [1] NegTokenResp
1074 }*/
1075 NegotiationToken_tag, len, lenlen,
1076
1077 NegTokenInit_tag,
1078 NegTokenInit_choice,
1079 NegTokenResp_tag,
1080 NegTokenResp_choice,
1081 mechType_tag,
1082
1083 negState_tag,
1084 supportedMech_tag,
1085 responseToken_tag,
1086 mechListMIC_tag,
1087
1088 mechTypes_tag,
1089 reqFlags_tag,
1090 mechToken_tag,
1091
1092 mechToken_content,
1093 responseToken_content,
1094 mechToken_content2,
1095 responseToken_content2,
1096
1097 UnknownContents,
1098
1099
1100 };
1101
1102 #define GOTO_ERROR(state, i, length) (state)=0xFFFFFFFF;(i)=(length);continue
1103
1104 /* 'for all bytes in the current fragment ...'
1105 * 'process that byte, causing a state-transition '
1106 */
1107 for (i=0; i<length; i++) {
1108
1109
1110 /*
1111 * If we've reached the end of the current field, then we need to
1112 * pop up the stack and resume parsing the parent field. Since we
1113 * reach the end of several levels simultaneously, we may need to
1114 * pop several levels at once
1115 */
1116 while (x->stack.remainings[0] == 0) {
1117 if (x->stack.depth == 0)
1118 return;
1119 state = ASN1_pop(x);
1120 }
1121
1122 /*
1123 * Decrement the current 'remaining' length field.
1124 */
1125 x->stack.remainings[0]--;
1126
1127 /*
1128 * Jump to the current current state
1129 */
1130 switch (state) {
1131 case NegotiationToken_tag:
1132 x->brother_state = UnknownContents;
1133 switch (px[i]) {
1134 case 0xa0:
1135 x->child_state = NegTokenInit_tag;
1136 break;
1137 case 0xa1:
1138 x->child_state = NegTokenResp_tag;
1139 break;
1140 case 0x60:
1141 x->child_state = mechType_tag;
1142 break;
1143 default:
1144 x->child_state = UnknownContents;
1145 break;
1146 }
1147 state = len;
1148 break;
1149
1150 case NegTokenResp_choice:
1151 /*
1152 NegTokenResp ::= SEQUENCE {
1153 negState [0] ENUMERATED {
1154 accept-completed (0),
1155 accept-incomplete (1),
1156 reject (2),
1157 request-mic (3)
1158 } OPTIONAL,
1159 -- REQUIRED in the first reply from the target
1160 supportedMech [1] MechType OPTIONAL,
1161 -- present only in the first reply from the target
1162 responseToken [2] OCTET STRING OPTIONAL,
1163 mechListMIC [3] OCTET STRING OPTIONAL,
1164 ...
1165 }*/
1166 x->brother_state = NegTokenResp_choice;
1167 switch (px[i]) {
1168 case 0xa0:
1169 x->child_state = negState_tag;
1170 break;
1171 case 0xa1:
1172 x->child_state = supportedMech_tag;
1173 break;
1174 case 0xa2:
1175 x->child_state = responseToken_tag;
1176 break;
1177 case 0xa3:
1178 x->child_state = mechListMIC_tag;
1179 break;
1180 default:
1181 x->child_state = UnknownContents;
1182 break;
1183 }
1184 state = len;
1185 break;
1186
1187 case NegTokenResp_tag:
1188 if (px[i] != 0x30) {
1189 x->brother_state = UnknownContents;
1190 x->child_state = UnknownContents;
1191 } else {
1192 x->brother_state = UnknownContents;
1193 x->child_state = NegTokenResp_choice;
1194 }
1195 state = len;
1196 break;
1197
1198 case NegTokenInit_choice:
1199 /*
1200 NegTokenInit ::= SEQUENCE {
1201 mechTypes [0] MechTypeList,
1202 reqFlags [1] ContextFlags OPTIONAL,
1203 -- inherited from RFC 2478 for backward compatibility,
1204 -- RECOMMENDED to be left out
1205 mechToken [2] OCTET STRING OPTIONAL,
1206 mechListMIC [3] OCTET STRING OPTIONAL,
1207 ...
1208 }
1209 }*/
1210 x->brother_state = NegTokenInit_choice;
1211 switch (px[i]) {
1212 case 0xa0:
1213 x->child_state = mechTypes_tag;
1214 break;
1215 case 0xa1:
1216 x->child_state = reqFlags_tag;
1217 break;
1218 case 0xa2:
1219 x->child_state = mechToken_tag;
1220 break;
1221 case 0xa3:
1222 x->child_state = mechListMIC_tag;
1223 break;
1224 default:
1225 x->child_state = UnknownContents;
1226 break;
1227 }
1228 state = len;
1229 break;
1230
1231 case NegTokenInit_tag:
1232 if (px[i] != 0x30) {
1233 x->brother_state = UnknownContents;
1234 x->child_state = UnknownContents;
1235 } else {
1236 x->brother_state = UnknownContents;
1237 x->child_state = NegTokenInit_choice;
1238 }
1239 state = len;
1240 break;
1241
1242 case mechType_tag:
1243 if (px[i] == 0x06) {
1244 x->brother_state = NegotiationToken_tag;
1245 x->child_state = UnknownContents;
1246 } else {
1247 x->brother_state = NegotiationToken_tag;
1248 x->child_state = UnknownContents;
1249 }
1250 state = len;
1251 break;
1252
1253 case negState_tag:
1254 case supportedMech_tag:
1255 case mechListMIC_tag:
1256 case mechTypes_tag:
1257 case reqFlags_tag:
1258 x->brother_state = UnknownContents;
1259 x->child_state = UnknownContents;
1260 state = len;
1261 break;
1262
1263 case responseToken_tag:
1264 x->brother_state = UnknownContents;
1265 x->child_state = responseToken_content;
1266 state = len;
1267 break;
1268
1269 case mechToken_tag:
1270 x->brother_state = UnknownContents;
1271 x->child_state = mechToken_content;
1272 state = len;
1273 break;
1274
1275 case mechToken_content:
1276 case mechToken_content2:
1277 break;
1278
1279 /************************************************************************
1280 ************************************************************************
1281 ************************************************************************
1282 ************************************************************************
1283 ************************************************************************
1284 ************************************************************************
1285 ************************************************************************
1286 */
1287 case responseToken_content:
1288 ntlmssp_decode_init(&spnego->ntlmssp, x->stack.remainings[0] + 1);
1289 state = responseToken_content2;
1290 /* fall through */
1291 case responseToken_content2:
1292 {
1293 size_t new_max = length - i;
1294
1295 if (new_max > x->stack.remainings[0] + 1U)
1296 new_max = x->stack.remainings[0] + 1;
1297
1298 ntlmssp_decode(&spnego->ntlmssp, px+i, new_max, banout);
1299
1300 x->stack.remainings[0] -= (unsigned short)(new_max - 1);
1301 if (x->stack.remainings[0] == 0) {
1302 if (spnego->ntlmssp.buf)
1303 free(spnego->ntlmssp.buf);
1304 }
1305 }
1306 break;
1307
1308 case len:
1309 /* We do the same processing for all the various length fields.
1310 * There are three possible length fields:
1311 * 0x7F - for lengths 127 and below
1312 * 0x81 XX - for lengths 127 to 255
1313 * 0x82 XX XX - for length 256 to 65535
1314 * This state processes the first byte, and if it's an extended
1315 * field, switches to the correspondign xxx_LENLEN state
1316 */
1317 if (px[i] & 0x80) {
1318 x->u.tag.length_of_length = px[i]&0x7F;
1319 x->u.tag.remaining = 0;
1320 state = lenlen;
1321 break;
1322 } else {
1323 x->u.tag.remaining = px[i];
1324 ASN1_push(x, x->brother_state, x->u.tag.remaining);
1325 state = x->child_state;
1326 memset(&x->u, 0, sizeof(x->u));
1327 break;
1328 }
1329 break;
1330 case lenlen:
1331 /* We process all multibyte lengths the same way in this
1332 * state.
1333 */
1334
1335 /* [ASN1-DER-LENGTH]
1336 * Check for strict DER compliance, which says that there should
1337 * be no leading zero bytes */
1338 if (x->u.tag.remaining == 0 && px[i] == 0)
1339 x->is_der_failure = 1;
1340
1341 /* parse this byte */
1342 x->u.tag.remaining = (x->u.tag.remaining)<<8 | px[i];
1343 x->u.tag.length_of_length--;
1344
1345 /* If we aren't finished yet, loop around and grab the next */
1346 if (x->u.tag.length_of_length)
1347 continue;
1348
1349 /* [ASN1-DER-LENGTH]
1350 * Check for strict DER compliance, which says that for lengths
1351 * 127 and below, we need only 1 byte to encode it, not many */
1352 if (x->u.tag.remaining < 128)
1353 x->is_der_failure = 1;
1354
1355 /*
1356 * We have finished parsing the tag-length fields, and are now
1357 * ready to parse the 'value'. Push the current state on the
1358 * stack, then decend into the child field.
1359 */
1360 ASN1_push(x, x->brother_state, x->u.tag.remaining);
1361 state = x->child_state;
1362 memset(&x->u, 0, sizeof(x->u));
1363 break;
1364 default:
1365 ;
1366 }
1367 }
1368 }
1369
1370
1371 /****************************************************************************
1372 * This function must be called to set the initial state.
1373 * @param length
1374 * The size of the certificate. This is parsed from the SSL/TLS field.
1375 * We know that if we exceed this number of bytes, then an overflow has
1376 * occured.
1377 ****************************************************************************/
1378 void
x509_decode_init(struct CertDecode * x,size_t length)1379 x509_decode_init(struct CertDecode *x, size_t length)
1380 {
1381 memset(x, 0, sizeof(*x));
1382 ASN1_push(x, 0xFFFFFFFF, length);
1383 }
1384 void
spnego_decode_init(struct SpnegoDecode * x,size_t length)1385 spnego_decode_init(struct SpnegoDecode *x, size_t length)
1386 {
1387 memset(x, 0, sizeof(*x));
1388
1389 ASN1_push(x->x509, 0xFFFFFFFF, length);
1390 }
1391
1392
1393