-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasn1.h
More file actions
241 lines (222 loc) · 9.14 KB
/
asn1.h
File metadata and controls
241 lines (222 loc) · 9.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#include <stdint.h>
#include <time.h>
// Universal types
#define ASN1_EOC 0
#define ASN1_END_OF_CONTENT 0
#define ASN1_BOOLEAN 1
#define ASN1_INTEGER 2
#define ASN1_BIT_STRING 3
#define ASN1_OCTET_STRING 4
#define ASN1_NULL 5
#define ASN1_OBJECT_IDENTIFIER 6
#define ASN1_OID 6
#define ASN1_OBJECT_DESCRIPTOR 7
#define ASN1_EXTERNAL 8
#define ASN1_REAL 9
#define ASN1_FLOAT 9
#define ASN1_ENUMERATED 10
#define ASN1_EMBEDDED_PDV 11
#define ASN1_UTF8STRING 12
#define ASN1_UTF8_STRING 12
#define ASN1_RELATIVE_OID 13
#define ASN1_TIME 14
#define ASN1_SEQUENCE 16
#define ASN1_SEQUENCE_OF 16
#define ASN1_SET 17
#define ASN1_SET_OF 17
#define ASN1_NUMERICSTRING 18
#define ASN1_NUMERIC_STRING 18
#define ASN1_PRINTABLESTRING 19
#define ASN1_PRINTABLE_STRING 19
#define ASN1_T61STRING 20
#define ASN1_T61_STRING 20
#define ASN1_TELETEXSTRING 20
#define ASN1_TELETEX_STRING 20
#define ASN1_VIDEOTEXSTRING 21
#define ASN1_VIDEOTEX_STRING 21
#define ASN1_IA5STRING 22
#define ASN1_IA5_STRING 22
#define ASN1_ASCII_STRING 22
#define ASN1_UTCTIME 23
#define ASN1_UTC_TIME 23
#define ASN1_GENERALIZEDTIME 24
#define ASN1_GENERALIZED_TIME 24
#define ASN1_GRAPHICSTRING 25
#define ASN1_GRAPHIC_STRING 25
#define ASN1_VISIBLESTRING 26
#define ASN1_VISIBLE_STRING 26
#define ASN1_ISO646_STRING 26
#define ASN1_GENERALSTRING 27
#define ASN1_GENERAL_STRING 27
#define ASN1_UNIVERSALSTRING 28
#define ASN1_UNIVERSAL_STRING 28
#define ASN1_UTF32_STRING 28
#define ASN1_UCS4_STRING 28
#define ASN1_ISO10646_STRING 28
#define ASN1_CHARACTER_STRING 29
#define ASN1_BMPSTRING 30
#define ASN1_BMP_STRING 30
#define ASN1_UTF16_STRING 30
#define ASN1_UCS2_STRING 30
#define ASN1_DATE 31
#define ASN1_TIME_OF_DAY 32
#define ASN1_DATE_TIME 33
#define ASN1_DURATION 34
#define ASN1_OID_IRI 35
#define ASN1_RELATIVE_OID_IRI 36
// ASN.1X universal types
#define ASN1_BCD_STRING 64
#define ASN1_PC_STRING 65
#define ASN1_TRON_STRING 66
#define ASN1_KEY_VALUE_LIST 67
#define ASN1_UTC_TIMESTAMP 68
#define ASN1_SI_TIMESTAMP 69
#define ASN1_UTC_TIME_INTERVAL 70
#define ASN1_SI_TIME_INTERVAL 71
#define ASN1_OUT_OF_BAND 72
#define ASN1_MORSE_STRING 73
#define ASN1_REFERENCE 74
#define ASN1_IDENTIFIED_DATA 75
#define ASN1_RATIONAL 76
#define ASN1_TRANSLATION_LIST 77
#define ASN1_SCIENTIFIC 78
// Classes
#define ASN1_UNIVERSAL 0
#define ASN1_APPLICATION 1
#define ASN1_CONTEXT_SPECIFIC 2
#define ASN1_PRIVATE 3
// Results
#define ASN1_OK 0
#define ASN1_ERROR 1
#define ASN1_IMPROPER_TYPE 2
#define ASN1_IMPROPER_VALUE 3
#define ASN1_TOO_SHORT 4
#define ASN1_TOO_SMALL 4
#define ASN1_IMPROPER_ENCODING 5
#define ASN1_TOO_BIG 6
#define ASN1_OVERFLOW 6
#define ASN1_IMPROPER_MODE 7
#define ASN1_IMPROPER_ARGUMENT 8
#define ASN1_DONE 9
// Flags
#define ASN1_SORT 0x01
#define ASN1_KVSORT 0x02
#define ASN1_INDEFINITE 0x04
#define ASN1_ONCE 0x08
// Others
#define ASN1_AUTO 0 // means use the existing universal or explicit type instead of an implicit type
#define ASN1_TRON_EPOCH 473385600LL
#define ASN1_LOWERCASE 0x61
#define ASN1_UPPERCASE 0x41
typedef struct {
const uint8_t*data;
size_t length;
uint32_t type;
uint8_t class,constructed,own;
} ASN1;
typedef struct {
int16_t zone; // measured in minutes
int16_t year;
uint8_t month,day,hours,minutes,seconds;
uint32_t nano;
} ASN1_DateTime;
typedef struct ASN1_Encoder ASN1_Encoder;
typedef struct {
const uint8_t*data;
size_t length;
} ASN1_Iterator;
typedef ASN1 ASN1_Value;
int asn1_construct(ASN1_Encoder*enc,uint8_t class,uint32_t type,uint8_t mode);
int asn1_copy(const ASN1*in,ASN1*out);
uint64_t asn1_count(const ASN1*x);
ASN1_Encoder*asn1_create_encoder(FILE*file);
FILE*asn1_current_file(ASN1_Encoder*enc);
int asn1_date_to_time(const ASN1_DateTime*in,time_t*out,uint32_t*nano);
int asn1_decode_date(const ASN1*asn,uint32_t type,ASN1_DateTime*out);
int asn1_decode_double(const ASN1*asn,uint32_t type,double*out);
int asn1_decode_float(const ASN1*asn,uint32_t type,float*out);
int asn1_decode_int8(const ASN1*asn,uint32_t type,int8_t*out);
int asn1_decode_int16(const ASN1*asn,uint32_t type,int16_t*out);
int asn1_decode_int32(const ASN1*asn,uint32_t type,int32_t*out);
int asn1_decode_int64(const ASN1*asn,uint32_t type,int64_t*out);
int asn1_decode_real_parts(const ASN1*asn,uint32_t type,uint8_t*significand,size_t length,int8_t*sign,uint8_t*decimal,int64_t*exponent,uint8_t*infinite,uint8_t*exact);
int asn1_decode_time(const ASN1*asn,uint32_t type,int16_t zone,time_t*out,uint32_t*nano);
int asn1_decode_uint8(const ASN1*asn,uint32_t type,uint8_t*out);
int asn1_decode_uint16(const ASN1*asn,uint32_t type,uint16_t*out);
int asn1_decode_uint32(const ASN1*asn,uint32_t type,uint32_t*out);
int asn1_decode_uint64(const ASN1*asn,uint32_t type,uint64_t*out);
int asn1_distinguished_parse(const uint8_t*data,size_t length,ASN1*out,size_t*next);
int asn1_encode(ASN1_Encoder*enc,const ASN1*value);
int asn1_encode_boolean(ASN1_Encoder*enc,int value);
int asn1_encode_c_string(ASN1_Encoder*enc,uint32_t type,const char*text);
int asn1_encode_date(ASN1_Encoder*enc,uint32_t type,const ASN1_DateTime*x);
int asn1_encode_double(ASN1_Encoder*enc,double value);
int asn1_encode_float(ASN1_Encoder*enc,float value);
int asn1_encode_int8(ASN1_Encoder*enc,int8_t value);
int asn1_encode_int16(ASN1_Encoder*enc,int16_t value);
int asn1_encode_int32(ASN1_Encoder*enc,int32_t value);
int asn1_encode_int64(ASN1_Encoder*enc,int64_t value);
int asn1_encode_integer_base(ASN1_Encoder*enc,int base,const uint8_t*digits,size_t length,int8_t sign,char trans);
int asn1_encode_oid(ASN1_Encoder*enc,const char*t);
int asn1_encode_real_parts(ASN1_Encoder*enc,const uint8_t*significand,size_t length,int8_t sign,uint8_t decimal,int64_t exponent,uint8_t infinite);
int asn1_encode_time(ASN1_Encoder*enc,uint32_t type,time_t value,uint32_t nano,int16_t zone);
int asn1_encode_uint16(ASN1_Encoder*enc,uint16_t value);
int asn1_encode_uint32(ASN1_Encoder*enc,uint32_t value);
int asn1_encode_uint64(ASN1_Encoder*enc,uint64_t value);
int asn1_end(ASN1_Encoder*enc);
int asn1_explicit(ASN1_Encoder*enc,uint8_t class,uint32_t type);
int asn1_finish_encoder(ASN1_Encoder*enc);
int asn1_flush(ASN1_Encoder*enc);
void asn1_free(ASN1*obj);
int asn1_from_c_string(uint8_t class,uint32_t type,const char*data,ASN1*out);
int asn1_implicit(ASN1_Encoder*enc,uint8_t class,uint32_t type);
int asn1_make_oid(const char*text,ASN1*out);
int asn1_make_static_oid(const char*text,uint8_t*buf,size_t maxlen,ASN1*out);
int asn1_next(ASN1_Iterator*iter,ASN1*value);
int asn1_parse(const uint8_t*data,size_t length,ASN1*out,size_t*next);
int asn1_primitive(ASN1_Encoder*enc,uint8_t class,uint32_t type,const uint8_t*data,size_t length);
FILE*asn1_primitive_stream(ASN1_Encoder*enc,uint8_t class,uint32_t type);
int asn1_print_decimal_oid(const ASN1*data,uint32_t type,FILE*stream);
int asn1_read(FILE*fp,uint8_t*constructed,uint8_t*class,uint32_t*type,size_t*length,uint64_t*remain);
int asn1_read_item(FILE*fp,ASN1*item,uint64_t*remain);
int asn1_rewind(ASN1_Iterator*iter,const ASN1*value);
int asn1_sorter_mark(ASN1_Encoder*enc);
ASN1_Encoder*asn1_start_encoding_constructed_value(ASN1*out,uint8_t class,uint32_t type,uint8_t mode);
ASN1_Encoder*asn1_start_encoding_value(ASN1*out);
int asn1_time_to_date(time_t in,uint32_t nano,ASN1_DateTime*out);
int asn1_wrap(ASN1_Encoder*enc);
void asn1_write_length(uint64_t length,FILE*stream);
void asn1_write_type(uint8_t constructed,uint8_t class,uint32_t type,FILE*stream);
#define asn1_encode_null(A) asn1_primitive(A,ASN1_UNIVERSAL,ASN1_NULL,0,0)
#define asn1_start_encoding_file asn1_create_encoder
#define asn1__decode_number__(D,E,F) __builtin_choose_expr(__builtin_types_compatible_p(typeof(D),E*),asn1_decode_##F,
#define asn1_decode_number(A,B,C) (( \
asn1__decode_number__(C,int8_t,int8) \
asn1__decode_number__(C,int16_t,int16) \
asn1__decode_number__(C,int32_t,int32) \
asn1__decode_number__(C,int64_t,int64) \
asn1__decode_number__(C,uint8_t,uint8) \
asn1__decode_number__(C,uint16_t,uint16) \
asn1__decode_number__(C,uint32_t,uint32) \
asn1__decode_number__(C,uint64_t,uint64) \
asn1__decode_number__(C,double,double) \
asn1__decode_number__(C,float,float) \
(void)0 )))))))))))(A,B,C) )
#define asn1__encode_number__(D,E,F) __builtin_choose_expr(__builtin_types_compatible_p(typeof(D),E),asn1_encode_##F,
#define asn1_encode_integer(A,C) (( \
asn1__encode_number__(C,int8_t,int8) \
asn1__encode_number__(C,int16_t,int16) \
asn1__encode_number__(C,int32_t,int32) \
asn1__encode_number__(C,int64_t,int64) \
asn1__encode_number__(C,uint8_t,uint16) \
asn1__encode_number__(C,uint16_t,uint16) \
asn1__encode_number__(C,uint32_t,uint32) \
asn1__encode_number__(C,uint64_t,uint64) \
(void)0 )))))))))(A,C) )
#define asn1_foreach(A,B,C,D) for(A=asn1_rewind(B,C)?:asn1_next(B,D);!(A);A=asn1_next(B,D))
#define asn1_foreach2(A,B,C,D,E) for(A=asn1_rewind(B,C)?:asn1_next(B,D)?:asn1_next(B,E);!(A);A=asn1_next(B,D)?:asn1_next(B,E))
#define asn1_first_of(A,B) \
({ ASN1*asn1__A=A; const ASN1*asn1__B=B; asn1__B->length?asn1_parse(asn1__B->data,asn1__B->length,asn1__A,0):ASN1_DONE; })
#define asn1_next_of(A,B) \
({ ASN1*asn1__A=A; const ASN1*asn1__B=B; \
asn1__A->data+asn1__A->length==asn1__B->data+asn1__B->length?ASN1_DONE:asn1_parse(asn1__A->data+asn1__A->length,asn1__B->length-asn1__A->length-(asn1__A->data-asn1__B->data),asn1__A,0); })