1 #ifndef PROTO_X509_H
2 #define PROTO_X509_H
3 #include <time.h>
4 #include <stdint.h>
5 struct BannerOutput;
6 
7 /****************************************************************************
8  * This stores the "state" of the X.509 certificate parser
9  ****************************************************************************/
10 struct CertDecode {
11     /** This is the master 'state' variable in the massive switch statement */
12     unsigned state;
13 
14     /** ASN.1 nests fields within fields. Therefore, as we parse down into
15      * the structure, we push the parent length/state info on the stack,
16      * and then when we exit a field, we pop it back off the stack.
17      * NOTE: since space is at a premium, we have separate arrays
18      * for the length/state, instead of a an array of objects containing
19      * both. */
20     struct {
21         unsigned short remainings[9];
22         unsigned char states[9];
23         unsigned char depth;
24     } stack;
25 
26     /** We catch some DER non-canonical encoding errors, but not all. Someday
27      * we'll improve the parser to catch all of them */
28     unsigned is_der_failure:1;
29     unsigned is_capture_subject:1;
30     unsigned is_capture_issuer:1;
31 
32 
33 
34     /** Number of certificates we've processed */
35     unsigned char count;
36 
37     /** ??? */
38     time_t prev;
39 
40     /** This parser was originally written just to grab the "subect name"
41      * of a certificate, i.e. "*.google.com" for Google's certificates.
42      * However, there are many different types of subject names. Each
43      * subnect name comes in two parts, the first part being an OID
44      * saying the type of subject, then the subject itself. We need to stash
45      * the result of parsing the OID somewhere before parsing the subject
46      */
47     struct {
48         unsigned type;
49     } subject;
50 
51     unsigned child_state;
52     unsigned brother_state;
53 
54     /**
55      * This union contains the intermediate/partial values as we are decoding
56      * them. Since a packet may end with a field only partially decoded,
57      * we have to stash that value someplace before the next bytes arive
58      * that complete the decoding
59      */
60     union {
61         struct {
62             unsigned short remaining;
63             unsigned char length_of_length;
64         } tag;
65         uint64_t num;
66         unsigned next_state;
67         struct {
68             uint64_t num;
69             unsigned short state;
70             unsigned char last_id;
71         } oid;
72         struct {
73             unsigned state;
74             unsigned year:7;
75             unsigned month:4;
76             unsigned day:5;
77             unsigned hour:5;
78             unsigned minute:6;
79             unsigned second:6;
80         } timestamp;
81     } u;
82 };
83 
84 /**
85  * Called before parsing the first fragment of an X.509 certificate
86  */
87 void
88 x509_decode_init(struct CertDecode *x, size_t length);
89 
90 /**
91  * Called to decode the next fragment of an X.509 certificate.
92  * Must call x509_decode_init() first.
93  */
94 void
95 x509_decode(struct CertDecode *x,
96             const unsigned char *px, size_t length,
97             struct BannerOutput *banout);
98 
99 /**
100  * Called at program startup to initialize internal parsing structures
101  * for certificates. Once called, it creates static read-only thread-safe
102  * structures
103  */
104 void
105 x509_init(void);
106 
107 #endif
108 
109