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