1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11 // https://www.obj-sys.com/asn1tutorial/node128.html
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <assert.h>
17 #include <limits.h>
18 #include <time.h>
19 #include <ctype.h>
20 #include <gmssl/oid.h>
21 #include <gmssl/asn1.h>
22 #include <gmssl/error.h>
23 #include <gmssl/endian.h>
24
25
26 /*
27
28 ## 返回值
29
30 解析函数返回错误:
31
32 1. 输入数据长度为0,如待解析的对象具有OPTIONAL属性,那么不意味错误。
33 应显式告知调用方对象编码为空,由调用方判断是否为错误。
34 2. 输入数据和目标对象类型不符,如待解析的对象具有OPTIONAL属性,那么意味目标对象为空。
35 3. 长度和负载数据解析出错,这意味绝对的错误。
36 4. 数据类型具有IMPLICIT属性时,意味着该对象的Tag被修改了,那么解析时调用方必须提供新的Tag。
37
38 DEFAULT值在接口上不提供这个功能,这个可以在数据的初始化时完成。
39
40 内部接口不支持参数默认值或者多态的接口,例如不允许输入参数为空。
41 接口具有单一的逻辑可以通过严格的检查避免隐藏错误,提高健壮性。
42
43 */
44
45
46 static char *asn1_tag_index[] = {
47 "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]", "[8]", "[9]",
48 "[10]", "[11]", "[12]", "[13]", "[14]", "[15]", "[16]", "[17]", "[18]", "[19]",
49 "[20]", "[21]", "[22]", "[23]", "[24]", "[25]", "[26]", "[27]", "[28]", "[29]",
50 "[30]", "[31]",
51 };
52
asn1_tag_name(int tag)53 const char *asn1_tag_name(int tag)
54 {
55 if (tag < 0 || tag > 0xff) {
56 error_print();
57 return NULL;
58 }
59
60 switch (tag & 0xc0) {
61 case ASN1_TAG_CONTENT_SPECIFIC: return asn1_tag_index[tag & 0xe0];
62 case ASN1_TAG_APPLICATION: return "Application";
63 case ASN1_TAG_PRIVATE: return "Private";
64 }
65
66 switch (tag) {
67 case ASN1_TAG_BOOLEAN: return "BOOLEAN";
68 case ASN1_TAG_INTEGER: return "INTEGER";
69 case ASN1_TAG_BIT_STRING: return "BIT STRING";
70 case ASN1_TAG_OCTET_STRING: return "OCTET STRING";
71 case ASN1_TAG_NULL: return "NULL";
72 case ASN1_TAG_OBJECT_IDENTIFIER: return "OBJECT IDENTIFIER";
73 case ASN1_TAG_ObjectDescriptor: return "ObjectDescriptor";
74 case ASN1_TAG_EXTERNAL: return "EXTERNAL";
75 case ASN1_TAG_REAL: return "REAL";
76 case ASN1_TAG_ENUMERATED: return "ENUMERATED";
77 case ASN1_TAG_EMBEDDED: return "EMBEDDED";
78 case ASN1_TAG_UTF8String: return "UTF8String";
79 case ASN1_TAG_RELATIVE_OID: return "RELATIVE_OID";
80 case ASN1_TAG_NumericString: return "NumericString";
81 case ASN1_TAG_PrintableString: return "PrintableString";
82 case ASN1_TAG_TeletexString: return "TeletexString";
83 case ASN1_TAG_VideotexString: return "VideotexString";
84 case ASN1_TAG_IA5String: return "IA5String";
85 case ASN1_TAG_UTCTime: return "UTCTime";
86 case ASN1_TAG_GeneralizedTime: return "GeneralizedTime";
87 case ASN1_TAG_GraphicString: return "GraphicString";
88 case ASN1_TAG_VisibleString: return "VisibleString";
89 case ASN1_TAG_GeneralString: return "GeneralString";
90 case ASN1_TAG_UniversalString: return "UniversalString";
91 case ASN1_TAG_CHARACTER_STRING: return "CHARACTER STRING";
92 case ASN1_TAG_BMPString: return "BMPString";
93 case ASN1_TAG_SEQUENCE: return "SEQUENCE";
94 case ASN1_TAG_SET: return "SET";
95 case ASN1_TAG_EXPLICIT: return "EXPLICIT";
96 }
97
98 error_print();
99 return NULL;
100 }
101
asn1_tag_is_cstring(int tag)102 int asn1_tag_is_cstring(int tag)
103 {
104 switch (tag) {
105 case ASN1_TAG_UTF8String:
106 case ASN1_TAG_NumericString:
107 case ASN1_TAG_PrintableString:
108 case ASN1_TAG_TeletexString:
109 case ASN1_TAG_IA5String:
110 case ASN1_TAG_GeneralString:
111 return 1;
112 }
113 return 0;
114 }
115
asn1_utf8_string_check(const char * a,size_t alen)116 int asn1_utf8_string_check(const char *a, size_t alen)
117 {
118 return 1;
119 }
120
asn1_printable_string_check(const char * a,size_t alen)121 int asn1_printable_string_check(const char *a, size_t alen)
122 {
123 return 1;
124 }
125
asn1_ia5_string_check(const char * a,size_t alen)126 int asn1_ia5_string_check(const char *a, size_t alen)
127 {
128 return 1;
129 }
130
131 /////////////////////////////////////////////////////////////////////////////////////////////
132 // DER encoding
133 /////////////////////////////////////////////////////////////////////////////////////////////
134 // 这组函数不对输入进行检查
135 // 还是检查报错比较方便,这样调用的函数更容易实现
136 // asn.1编解码不考虑效率的问题
137
asn1_tag_to_der(int tag,uint8_t ** out,size_t * outlen)138 int asn1_tag_to_der(int tag, uint8_t **out, size_t *outlen)
139 {
140 if (out && *out) {
141 *(*out)++ = (uint8_t)tag;
142 }
143 (*outlen)++;
144 return 1;
145 }
146
asn1_length_to_der(size_t len,uint8_t ** out,size_t * outlen)147 int asn1_length_to_der(size_t len, uint8_t **out, size_t *outlen)
148 {
149 if (len < 128) {
150 if (out && *out) {
151 *(*out)++ = (uint8_t)len;
152 }
153 (*outlen)++;
154
155 } else {
156 uint8_t buf[4];
157 int i;
158
159 PUTU32(buf, (uint32_t)len);
160 if (len < 256) i = 1;
161 else if (len < 65536) i = 2;
162 else if (len < (1 << 24)) i = 3;
163 else i = 4;
164
165 if (out && *out) {
166 *(*out)++ = 0x80 + i;
167 memcpy(*out, buf + 4 - i, i);
168 (*out) += i;
169 }
170 (*outlen) += 1 + i;
171 }
172 return 1;
173 }
174
175 // 提供返回值是为了和其他to_der函数一致
asn1_data_to_der(const uint8_t * data,size_t datalen,uint8_t ** out,size_t * outlen)176 int asn1_data_to_der(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen)
177 {
178 if (out && *out) {
179 memcpy(*out, data, datalen);
180 *out += datalen;
181 }
182 *outlen += datalen;
183 return 1;
184 }
185
asn1_tag_from_der(int tag,const uint8_t ** in,size_t * inlen)186 int asn1_tag_from_der(int tag, const uint8_t **in, size_t *inlen)
187 {
188 if (*inlen == 0) {
189 return 0;
190 }
191 if (**in != tag) {
192 return 0;
193 }
194 (*in)++;
195 (*inlen)--;
196 return 1;
197 }
198
asn1_tag_get(int * tag,const uint8_t ** in,size_t * inlen)199 int asn1_tag_get(int *tag, const uint8_t **in, size_t *inlen)
200 {
201 if (*inlen == 0) {
202 return 0;
203 }
204 *tag = **in;
205 return 1;
206 }
207
asn1_length_from_der(size_t * plen,const uint8_t ** pin,size_t * pinlen)208 int asn1_length_from_der(size_t *plen, const uint8_t **pin, size_t *pinlen)
209 {
210 const uint8_t *in = *pin;
211 size_t inlen = *pinlen;
212 size_t len;
213
214 if (inlen <= 0) {
215 return -1;
216 }
217
218
219 if (*in < 128) {
220 len = *in++;
221 inlen--;
222 } else {
223 uint8_t buf[4] = {0};
224 int nbytes = *in++ & 0x7f;
225 //error_print_msg("nbytes = %d\n", nbytes);
226
227 if (nbytes < 1 || nbytes > 4) {
228 error_print();
229 return -1;
230 }
231 inlen--;
232 if (inlen < nbytes) {
233 error_print();
234 return -1;
235 }
236 memcpy(buf + sizeof(buf) - nbytes, in, nbytes);
237 len = (size_t)GETU32(buf);
238 in += nbytes;
239 inlen -= nbytes;
240 }
241
242 *plen = len;
243 *pin = in;
244 *pinlen = inlen;
245
246 if (inlen < len) {
247 error_print_msg("inlen = %zu\n", *pinlen);
248 error_print_msg("length = %zu, left = %zu\n", len, inlen);
249 return -2; // 特殊错误值用于 test_asn1_length() 的测试
250 }
251 return 1;
252 }
253
asn1_data_from_der(const uint8_t ** data,size_t datalen,const uint8_t ** in,size_t * inlen)254 int asn1_data_from_der(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen)
255 {
256 if (*inlen < datalen) {
257 error_print();
258 return -1;
259 }
260 *data = *in;
261 *in += datalen;
262 *inlen -= datalen;
263 return 1;
264 }
265
asn1_header_to_der(int tag,size_t len,uint8_t ** out,size_t * outlen)266 int asn1_header_to_der(int tag, size_t len, uint8_t **out, size_t *outlen)
267 {
268 if (!outlen) {
269 error_print();
270 return -1;
271 }
272 asn1_tag_to_der(tag, out, outlen);
273 asn1_length_to_der(len, out, outlen);
274 return 1;
275 }
276
277
278 // If data == NULL, out should not be NULL
279 // 这个实现是不支持OPTIONAL的
asn1_type_to_der(int tag,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)280 int asn1_type_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
281 {
282 if (!d) {
283 if (dlen) {
284 error_print();
285 return -1;
286 }
287 return 0;
288 }
289 if (asn1_tag_to_der(tag, out, outlen) != 1
290 || asn1_length_to_der(dlen, out, outlen) != 1
291 || asn1_data_to_der(d, dlen, out, outlen) != 1) {
292 error_print();
293 return -1;
294 }
295 return 1;
296 }
297
asn1_type_from_der(int tag,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)298 int asn1_type_from_der(int tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
299 {
300 int ret;
301 if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) {
302 if (ret < 0) error_print();
303 else {
304 *d = NULL;
305 *dlen = 0;
306 }
307 return ret;
308 }
309 if (asn1_length_from_der(dlen, in, inlen) != 1
310 || asn1_data_from_der(d, *dlen, in, inlen) != 1) {
311 error_print();
312 return -1;
313 }
314 return 1;
315 }
316
asn1_any_tag_from_der(int * tag,const uint8_t ** in,size_t * inlen)317 int asn1_any_tag_from_der(int *tag, const uint8_t **in, size_t *inlen)
318 {
319 if (*inlen == 0) {
320 return 0;
321 }
322 *tag = *(*in)++;
323 (*inlen)--;
324 return 1;
325 }
326
327
328
asn1_any_type_from_der(int * tag,const uint8_t ** data,size_t * datalen,const uint8_t ** in,size_t * inlen)329 int asn1_any_type_from_der(int *tag, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen)
330 {
331 int ret;
332 if ((ret = asn1_any_tag_from_der(tag, in, inlen)) != 1) {
333 return ret;
334 }
335 if (asn1_length_from_der(datalen, in, inlen) != 1) {
336 error_print();
337 return -1;
338 }
339 *data = *in;
340 *in += *datalen;
341 *inlen -= *datalen;
342 return 1;
343 }
344
asn1_any_to_der(const uint8_t * tlv,size_t tlvlen,uint8_t ** out,size_t * outlen)345 int asn1_any_to_der(const uint8_t *tlv, size_t tlvlen, uint8_t **out, size_t *outlen)
346 {
347 return asn1_data_to_der(tlv, tlvlen, out, outlen);
348 }
349
asn1_any_from_der(const uint8_t ** tlv,size_t * tlvlen,const uint8_t ** in,size_t * inlen)350 int asn1_any_from_der(const uint8_t **tlv, size_t *tlvlen, const uint8_t **in, size_t *inlen)
351 {
352 int ret;
353 int tag;
354 const uint8_t *data;
355 size_t datalen;
356
357 *tlv = *in;
358 *tlvlen = *inlen;
359 if ((ret = asn1_any_type_from_der(&tag, &data, &datalen, in, inlen)) != 1) {
360 error_print();
361 return ret;
362 }
363 *tlvlen -= *inlen;
364 return 1;
365 }
366
367 //////////////////////////////////////////////////////////////////////////////////////////////////////////
368
369 #define ASN1_TRUE 0xff
370 #define ASN1_FALSE 0x00
371
asn1_boolean_name(int val)372 const char *asn1_boolean_name(int val)
373 {
374 switch (val) {
375 case 1: return "true";
376 case 0: return "false";
377 }
378 return NULL;
379 }
380
asn1_boolean_from_name(int * val,const char * name)381 int asn1_boolean_from_name(int *val, const char *name)
382 {
383 if (strcmp(name, "true") == 0) {
384 *val = 1;
385 return 1;
386 } else if (strcmp(name, "false") == 0) {
387 *val = 0;
388 return 1;
389 }
390 *val = -1;
391 return -1;
392 }
393
asn1_boolean_to_der_ex(int tag,int val,uint8_t ** out,size_t * outlen)394 int asn1_boolean_to_der_ex(int tag, int val, uint8_t **out, size_t *outlen)
395 {
396 if (!outlen) {
397 error_print();
398 return -1;
399 }
400
401 if (val < 0) {
402 return 0;
403 }
404
405 if (out && *out) {
406 *(*out)++ = tag;
407 *(*out)++ = 0x01;
408 *(*out)++ = val ? 0xff : 0x00;
409 }
410 (*outlen) += 3;
411 return 1;
412 }
413
asn1_integer_to_der_ex(int tag,const uint8_t * a,size_t alen,uint8_t ** out,size_t * outlen)414 int asn1_integer_to_der_ex(int tag, const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen)
415 {
416 if (!outlen) {
417 error_print();
418 return -1;
419 }
420
421 if (!a) {
422 return 0;
423 }
424 if (alen <= 0 || alen > INT_MAX) {
425 error_print();
426 return -1;
427 }
428
429 if (out && *out)
430 *(*out)++ = tag;
431 (*outlen)++;
432
433 while (*a == 0 && alen > 1) {
434 a++;
435 alen--;
436 }
437
438 if (a[0] & 0x80) {
439 asn1_length_to_der(alen + 1, out, outlen);
440 if (out && *out) {
441 *(*out)++ = 0x00;
442 memcpy(*out, a, alen);
443 (*out) += alen;
444 }
445 (*outlen) += 1 + alen;
446 } else {
447 asn1_length_to_der(alen, out ,outlen);
448 if (out && *out) {
449 memcpy(*out, a, alen);
450 (*out) += alen;
451 }
452 (*outlen) += alen;
453 }
454
455 return 1;
456 }
457
asn1_int_to_der_ex(int tag,int a,uint8_t ** out,size_t * outlen)458 int asn1_int_to_der_ex(int tag, int a, uint8_t **out, size_t *outlen)
459 {
460 int i;
461 uint8_t buf[4] = {0};
462 size_t len = 0;
463
464 if (a == -1) {
465 return 0;
466 }
467
468 while (a > 0) {
469 buf[3 - len] = a & 0xff;
470 a >>= 8;
471 len++;
472 }
473 if (!len) {
474 len = 1;
475 }
476
477 return asn1_integer_to_der_ex(tag, buf + 4 - len, len, out, outlen);
478 }
479
asn1_bit_string_to_der_ex(int tag,const uint8_t * bits,size_t nbits,uint8_t ** out,size_t * outlen)480 int asn1_bit_string_to_der_ex(int tag, const uint8_t *bits, size_t nbits, uint8_t **out, size_t *outlen)
481 {
482 uint8_t unused = (8 - nbits % 8) % 8;
483 size_t nbytes = (nbits + 7) / 8;
484
485 if (!bits) {
486 return 0;
487 }
488 if (asn1_tag_to_der(tag, out, outlen) != 1
489 || asn1_length_to_der(nbytes + 1, out, outlen) != 1
490 || asn1_data_to_der(&unused, 1, out, outlen) != 1
491 || asn1_data_to_der(bits, nbytes, out, outlen) != 1) {
492 error_print();
493 return -1;
494 }
495 return 1;
496 }
497
asn1_bit_octets_to_der_ex(int tag,const uint8_t * octs,size_t nocts,uint8_t ** out,size_t * outlen)498 int asn1_bit_octets_to_der_ex(int tag, const uint8_t *octs, size_t nocts, uint8_t **out, size_t *outlen)
499 {
500 return asn1_bit_string_to_der_ex(tag, octs, nocts << 3, out, outlen);
501 }
502
asn1_bits_to_der_ex(int tag,int bits,uint8_t ** out,size_t * outlen)503 int asn1_bits_to_der_ex(int tag, int bits, uint8_t **out, size_t *outlen)
504 {
505 size_t nbits = 0;
506 uint8_t buf[4] = {0};
507 int i = 0;
508 uint8_t mask = 0x80;
509
510 if (bits < 0) {
511 return 0;
512 }
513 while (bits > 0) {
514 if (bits & 1)
515 buf[i] |= mask;
516 mask >>= 1;
517 bits >>= 1;
518 nbits++;
519 if (nbits % 8 == 0) {
520 i++;
521 mask = 0x80;
522 }
523 }
524 if (!nbits) {
525 nbits = 1;
526 }
527 return asn1_bit_string_to_der_ex(tag, buf, nbits, out, outlen);
528 }
529
asn1_null_name(void)530 const char *asn1_null_name(void)
531 {
532 return "null";
533 }
534
asn1_null_to_der(uint8_t ** out,size_t * outlen)535 int asn1_null_to_der(uint8_t **out, size_t *outlen)
536 {
537 if (!outlen) {
538 error_print();
539 return -1;
540 }
541 if (out && *out) {
542 *(*out)++ = ASN1_TAG_NULL;
543 *(*out)++ = 0x00;
544 }
545 *outlen += 2;
546 return 1;
547 }
548
asn1_oid_node_to_base128(uint32_t a,uint8_t ** out,size_t * outlen)549 static void asn1_oid_node_to_base128(uint32_t a, uint8_t **out, size_t *outlen)
550 {
551 uint8_t buf[5];
552 int n = 0;
553
554 buf[n++] = a & 0x7f;
555 a >>= 7;
556
557 while (a) {
558 buf[n++] = 0x80 | (a & 0x7f);
559 a >>= 7;
560 }
561
562 while (n--) {
563 if (out && *out)
564 *(*out)++ = buf[n];
565 (*outlen)++;
566 }
567 }
568
569 // 实际上我们在解析的时候是不知道具体在哪里结束的
570 // 解析是有可能出错的,如果没有发现最后一个0开头的字节就出错了
571 // 还有值太大也会出错,我们最多读取5个字节
572 // { 0x81, 0x82 }
573 // { 0x81, 0x82, 0x83, 0x84, 0x85, 0x06 }
asn1_oid_node_from_base128(uint32_t * a,const uint8_t ** in,size_t * inlen)574 static int asn1_oid_node_from_base128(uint32_t *a, const uint8_t **in, size_t *inlen)
575 {
576 uint8_t buf[5];
577 int n = 0;
578 int i;
579
580 for (;;) {
581 if ((*inlen)-- < 1 || n >= 5) {
582 return -1;
583 }
584 buf[n] = *(*in)++;
585 if ((buf[n++] & 0x80) == 0) {
586 break;
587 }
588 }
589
590 // 32 - 7*4 = 4, so the first byte should be like 1000bbbb
591 if (n == 5 && (buf[0] & 0x70)) {
592 return -1;
593 }
594
595 *a = 0;
596 for (i = 0; i < n; i++) {
597 *a = ((*a) << 7) | (buf[i] & 0x7f);
598 }
599
600 return 1;
601 }
602
asn1_object_identifier_to_octets(const uint32_t * nodes,size_t nodes_cnt,uint8_t * out,size_t * outlen)603 int asn1_object_identifier_to_octets(const uint32_t *nodes, size_t nodes_cnt, uint8_t *out, size_t *outlen)
604 {
605 if (!outlen) {
606 error_print();
607 return -1;
608 }
609 if (nodes_cnt < 2 || nodes_cnt > 32) {
610 return -1;
611 }
612 if (out)
613 *out++ = (uint8_t)(nodes[0] * 40 + nodes[1]);
614 (*outlen) = 1;
615 nodes += 2;
616 nodes_cnt -= 2;
617
618 while (nodes_cnt--) {
619 asn1_oid_node_to_base128(*nodes++, &out, outlen);
620 }
621 return 1;
622 }
623
624 // 因为这个函数总是被asn1函数调用的,因此给的输入数据长度是已知的
asn1_object_identifier_from_octets(uint32_t * nodes,size_t * nodes_cnt,const uint8_t * in,size_t inlen)625 int asn1_object_identifier_from_octets(uint32_t *nodes, size_t *nodes_cnt, const uint8_t *in, size_t inlen)
626 {
627 size_t count = 0;
628 const uint8_t *p = in;
629 size_t len = inlen;
630
631 if (!nodes || !nodes_cnt || !in || inlen <= 0) {
632 error_print();
633 return -1;
634 }
635
636 if (inlen < 1) {
637 error_print();
638 return -1;
639 }
640
641 // FIXME: 需要支持 nodes = NULL 吗?
642 if (nodes) {
643 *nodes++ = (*in) / 40;
644 *nodes++ = (*in) % 40;
645 }
646 in++;
647 inlen--;
648 count += 2;
649
650 while (inlen) {
651 uint32_t val;
652 if (count > 32) {
653 error_print();
654 return -1;
655 }
656 if (asn1_oid_node_from_base128(&val, &in, &inlen) < 0) {
657 error_print();
658 return -1;
659 }
660 if (nodes) {
661 *nodes++ = val;
662 }
663 count++;
664 }
665
666 *nodes_cnt = count;
667 return 1;
668 }
669
asn1_object_identifier_to_der_ex(int tag,const uint32_t * nodes,size_t nodes_cnt,uint8_t ** out,size_t * outlen)670 int asn1_object_identifier_to_der_ex(int tag, const uint32_t *nodes, size_t nodes_cnt, uint8_t **out, size_t *outlen)
671 {
672 uint8_t octets[32];
673 size_t octetslen = 0;
674
675 if (!outlen) {
676 error_print();
677 return -1;
678 }
679
680 if (out && *out)
681 *(*out)++ = tag;
682 (*outlen)++;
683
684 asn1_object_identifier_to_octets(nodes, nodes_cnt, octets, &octetslen);
685
686 asn1_length_to_der(octetslen, out, outlen);
687
688 if (out && *out) {
689 // 注意:If out == NULL, *out ==> Segment Fault
690 memcpy(*out, octets, octetslen);
691 *out += octetslen;
692 }
693 *outlen += octetslen;
694 return 1;
695 }
696
asn1_oid_info_from_name(const ASN1_OID_INFO * infos,size_t count,const char * name)697 const ASN1_OID_INFO *asn1_oid_info_from_name(const ASN1_OID_INFO *infos, size_t count, const char *name)
698 {
699 size_t i;
700 for (i = 0; i < count; i++) {
701 if (strcmp(infos[i].name, name) == 0) {
702 return &infos[i];
703 }
704 }
705 return NULL;
706 }
707
asn1_oid_info_from_oid(const ASN1_OID_INFO * infos,size_t count,int oid)708 const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t count, int oid)
709 {
710 size_t i;
711 for (i = 0; i < count; i++) {
712 if (infos[i].oid == oid) {
713 return &infos[i];
714 }
715 }
716 return NULL;
717 }
718
719 // 如果一个正确解析的OID并不在infos列表中,那么仍然返回1,但是调用方必须检查返回的info是否为空
asn1_oid_info_from_der_ex(const ASN1_OID_INFO ** info,uint32_t * nodes,size_t * nodes_cnt,const ASN1_OID_INFO * infos,size_t count,const uint8_t ** in,size_t * inlen)720 int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt,
721 const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen)
722 {
723 int ret;
724 size_t i;
725
726 if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) {
727 if (ret < 0) error_print();
728 return ret;
729 }
730 *info = NULL;
731 for (i = 0; i < count; i++) {
732 if (*nodes_cnt == infos[i].nodes_cnt
733 && memcmp(nodes, infos[i].nodes, (*nodes_cnt) * sizeof(int)) == 0) {
734 *info = &infos[i];
735 goto end;
736 }
737 }
738 end:
739 return 1;
740 }
741
742 // 和ex版本不同的是,如果在infos列表中未找到OID,返回错误
asn1_oid_info_from_der(const ASN1_OID_INFO ** info,const ASN1_OID_INFO * infos,size_t count,const uint8_t ** in,size_t * inlen)743 int asn1_oid_info_from_der(const ASN1_OID_INFO **info, const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen)
744 {
745 int ret;
746 uint32_t nodes[32];
747 size_t nodes_cnt;
748
749 if ((ret = asn1_oid_info_from_der_ex(info, nodes, &nodes_cnt, infos, count, in, inlen)) != 1) {
750 if (ret < 0) error_print();
751 return ret;
752 }
753 if (*info == NULL) {
754 asn1_object_identifier_print(stderr, 0, 0, "Unknown OID", NULL, nodes, nodes_cnt);
755 error_print();
756 return -1;
757 }
758 return 1;
759 }
760
761
762 // asn1_oid_from_octets 不返回错误值,只返回 OID_undef
763 // 但是数据编码仍可能是非法的
764 // 如果返回 OID_undef,需要通过 asn1_object_identifier_from_octets 判断格式是否正确
765
766 // 显然这个函数并不合适,因为在整个gmssl中,我们不提供完整的ASN.1数据库,无法从一个OID中给出解析
767
768
769
770
771
772
773
774
asn1_utf8_string_to_der_ex(int tag,const char * d,size_t dlen,uint8_t ** out,size_t * outlen)775 int asn1_utf8_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen)
776 {
777 return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen);
778 }
779
asn1_printable_string_to_der_ex(int tag,const char * d,size_t dlen,uint8_t ** out,size_t * outlen)780 int asn1_printable_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen)
781 {
782 return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen);
783 }
784
asn1_ia5_string_to_der_ex(int tag,const char * d,size_t dlen,uint8_t ** out,size_t * outlen)785 int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out, size_t *outlen)
786 {
787 return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen);
788 }
789
asn1_utc_time_to_der_ex(int tag,time_t a,uint8_t ** out,size_t * outlen)790 int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen)
791 {
792 struct tm tm_val;
793 char buf[ASN1_UTC_TIME_LEN + 1];
794
795 if (!outlen) {
796 error_print();
797 return -1;
798 }
799
800 gmtime_r(&a, &tm_val);
801 strftime(buf, sizeof(buf), "%y%m%d%H%M%SZ", &tm_val);
802
803 if (out && *out)
804 *(*out)++ = tag;
805 (*outlen)++;
806 asn1_length_to_der(sizeof(buf)-1, out, outlen);
807 if (out && *out) {
808 memcpy(*out, buf, sizeof(buf)-1);
809 (*out) += sizeof(buf)-1;
810 }
811 *outlen += sizeof(buf)-1;
812
813 return 1;
814 }
815
816
asn1_generalized_time_to_der_ex(int tag,time_t a,uint8_t ** out,size_t * outlen)817 int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen)
818 {
819 struct tm tm_val;
820 char buf[ASN1_GENERALIZED_TIME_LEN + 1];
821
822 if (!outlen) {
823 error_print();
824 return -1;
825 }
826
827 gmtime_r(&a, &tm_val);
828 strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &tm_val);
829 //printf("%s %d: generalized time : %s\n", __FILE__, __LINE__, buf);
830
831 if (out && *out)
832 *(*out)++ = tag;
833 (*outlen)++;
834 asn1_length_to_der(ASN1_GENERALIZED_TIME_LEN, out, outlen);
835 if (out && *out) {
836 memcpy(*out, buf, ASN1_GENERALIZED_TIME_LEN);
837 (*out) += ASN1_GENERALIZED_TIME_LEN;
838 }
839 *outlen += ASN1_GENERALIZED_TIME_LEN;
840
841 return 1;
842 }
843
844
845 /////////////////////////////////////////////////////////////////////////////////////////////
846 // DER decoding
847 /////////////////////////////////////////////////////////////////////////////////////////////
848
849
850 /*
851 解码函数的返回值:
852
853 ret == 0
854 当前剩余的数据数据长度为0
855 或者下一个对象与期待不符,即输入对象的标签不等于输入的tag
856 当对象为OPTIONAL时,调用方可以通过判断返回值是否为0进行处理
857 ret < 0
858 标签正确但是长度或数据解析出错
859 ret == 1
860 解析正确
861
862
863 解码函数的输入:
864
865 *in != NULL
866 例如一个SEQUENCE中的属性均为OPTIONAL,解析后指针仍不为空
867 因此不允许输入空的输入数据指针
868
869
870 处理规则
871
872 当返回值 ret <= 0 时,*tag, *in, *inlen 的值保持不变
873
874 如果一个类型有 DEFAULT 属性,调用方可以将返回数据预先设置为默认值,
875 如果该对象未被编码,即返回值为0,那么解码函数不会修改已经设置的默认值
876
877 */
878
asn1_boolean_from_der_ex(int tag,int * val,const uint8_t ** in,size_t * inlen)879 int asn1_boolean_from_der_ex(int tag, int *val, const uint8_t **in, size_t *inlen)
880 {
881 if (!val || !in || !(*in) || !inlen) {
882 return -1;
883 }
884
885 if (*inlen <= 0 || **in != tag) {
886 *val = -1;
887 return 0;
888 }
889 if (*inlen < 3
890 || *(*in + 1) != 0x01
891 || (*(*in + 2) != 0 && *(*in + 2) != 0xff)) {
892 return -1;
893 }
894 *val = *(*in + 2) ? 1 : 0;
895 *in += 3;
896 *inlen -= 3;
897 return 1;
898 }
899
asn1_integer_from_der_ex(int tag,const uint8_t ** a,size_t * alen,const uint8_t ** pin,size_t * pinlen)900 int asn1_integer_from_der_ex(int tag, const uint8_t **a, size_t *alen, const uint8_t **pin, size_t *pinlen)
901 {
902 const uint8_t *in = *pin;
903 size_t inlen = *pinlen;
904 size_t len;
905
906 if (!a || !alen || !pin || !(*pin) || !pinlen) {
907 error_print();
908 return -1;
909 }
910
911 if (inlen-- <= 0 || *in++ != tag) {
912 return 0;
913 }
914 if (asn1_length_from_der(&len, &in, &inlen) != 1
915 || len <= 0) {
916 error_print();
917 return -1;
918 }
919
920 // 判断 ASN1_INTEGER 是否为负数,我们不支持负整数,返回特性不支持错误
921 if (*in & 0x80) {
922 error_print();
923 return -255;
924 }
925
926 if (*in == 0 && len > 1) {
927 inlen--;
928 in++;
929 len--;
930 }
931 if (*in == 0 && len > 1) {
932 error_print();
933 return -1;
934 }
935 *a = in;
936 *alen = len;
937 *pin = in + len;
938 *pinlen = inlen - len;
939 return 1;
940 }
941
asn1_int_from_der_ex(int tag,int * a,const uint8_t ** in,size_t * inlen)942 int asn1_int_from_der_ex(int tag, int *a, const uint8_t **in, size_t *inlen)
943 {
944 int ret;
945 const uint8_t *p;
946 size_t len, i;
947 unsigned int val = 0;
948
949 if (!a || !in || !(*in) || !inlen) {
950 error_print();
951 return -1;
952 }
953 if ((ret = asn1_integer_from_der_ex(tag, &p, &len, in, inlen)) != 1) {
954 if (ret < 0) error_print();
955 else *a = -1;
956 return ret;
957 }
958 if (len > 8) {
959 error_print();
960 return -1;
961 }
962
963 for (i = 0; i < len; i++) {
964 val = (val << 8) | p[i];
965 }
966 *a = val;
967 return 1;
968 }
969
asn1_bit_string_from_der_ex(int tag,const uint8_t ** bits,size_t * nbits,const uint8_t ** in,size_t * inlen)970 int asn1_bit_string_from_der_ex(int tag, const uint8_t **bits, size_t *nbits, const uint8_t **in, size_t *inlen)
971 {
972 int ret;
973 size_t len;
974 int unused_bits;
975
976 if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) {
977 if (ret < 0) error_print();
978 else {
979 *bits = NULL;
980 *nbits = 0;
981 }
982 return ret;
983 }
984 if (asn1_length_from_der(&len, in, inlen) != 1
985 || asn1_data_from_der(bits, len, in, inlen) != 1) {
986 error_print();
987 return -1;
988 }
989 if (len < 2) {
990 error_print();
991 return -1;
992 }
993
994
995 unused_bits = **bits;
996
997 if (len < 1) {
998 error_print();
999 return -1;
1000 }
1001 if (unused_bits > 8 || (len == 1 && unused_bits > 0)) {
1002 error_print();
1003 return -1;
1004 }
1005
1006 (*bits)++;
1007 *nbits = (len - 1) << 3;
1008
1009 return 1;
1010 }
1011
asn1_bit_octets_from_der_ex(int tag,const uint8_t ** octs,size_t * nocts,const uint8_t ** in,size_t * inlen)1012 int asn1_bit_octets_from_der_ex(int tag, const uint8_t **octs, size_t *nocts, const uint8_t **in, size_t *inlen)
1013 {
1014 int ret;
1015 size_t nbits;
1016
1017 if ((ret = asn1_bit_string_from_der_ex(tag, octs, &nbits, in, inlen)) != 1) {
1018 if (ret < 0) error_print();
1019 return ret;
1020 }
1021 if (nbits % 8) {
1022 error_print();
1023 return -1;
1024 }
1025 *nocts = nbits >> 3;
1026 return 1;
1027 }
1028
asn1_bits_from_der_ex(int tag,int * bits,const uint8_t ** in,size_t * inlen)1029 int asn1_bits_from_der_ex(int tag, int *bits, const uint8_t **in, size_t *inlen)
1030 {
1031 int ret;
1032 const uint8_t *p;
1033 size_t nbits, i;
1034 uint8_t c;
1035
1036 if ((ret = asn1_bit_string_from_der_ex(tag, &p, &nbits, in, inlen)) != 1) {
1037 if (ret < 0) error_print();
1038 return ret;
1039 }
1040 if (nbits > 31) {
1041 error_print();
1042 return -1;
1043 }
1044
1045 *bits = 0;
1046 for (i = 0; i < nbits; i++) {
1047 if (i % 8 == 0) {
1048 c = *p++;
1049 }
1050 *bits |= ((c & 0x80) >> 7) << i;
1051 c <<= 1;
1052 }
1053 return 1;
1054 }
1055
asn1_null_from_der(const uint8_t ** in,size_t * inlen)1056 int asn1_null_from_der(const uint8_t **in, size_t *inlen)
1057 {
1058 if (!in || !(*in) || !inlen) {
1059 return -1;
1060 }
1061 if (*inlen <= 0 || **in != ASN1_TAG_NULL) {
1062 return 0;
1063 }
1064 if (*inlen < 2
1065 || (*in)[1] != 0x00) {
1066 return -1;
1067 }
1068 *in += 2;
1069 *inlen -= 2;
1070 return 1;
1071 }
1072
asn1_object_identifier_from_der_ex(int tag,uint32_t * nodes,size_t * nodes_cnt,const uint8_t ** in,size_t * inlen)1073 int asn1_object_identifier_from_der_ex(int tag, uint32_t *nodes, size_t *nodes_cnt,
1074 const uint8_t **in, size_t *inlen)
1075 {
1076 int ret;
1077 size_t len;
1078 const uint8_t *p;
1079
1080 if ((ret = asn1_tag_from_der(tag, in, inlen)) != 1) {
1081 if (ret < 0) error_print();
1082 return ret;
1083 }
1084 if (asn1_length_from_der(&len, in, inlen) != 1
1085 || asn1_data_from_der(&p, len, in, inlen) != 1
1086 || asn1_object_identifier_from_octets(nodes, nodes_cnt, p, len) != 1) {
1087 error_print();
1088 return -1;
1089 }
1090 return 1;
1091 }
1092
asn1_string_from_der(int tag,const char ** a,size_t * alen,const uint8_t ** pin,size_t * pinlen)1093 int asn1_string_from_der(int tag, const char **a, size_t *alen, const uint8_t **pin, size_t *pinlen)
1094 {
1095 const uint8_t *in = *pin;
1096 size_t inlen = *pinlen;
1097 size_t len;
1098
1099 if (!a || !alen || !pin || !(*pin) || !pinlen) {
1100 return -1;
1101 }
1102
1103 if (inlen-- <= 0 || *in++ != tag) {
1104 return 0;
1105 }
1106 if (asn1_length_from_der(&len, &in, &inlen) != 1
1107 || len <= 0) {
1108 return -1;
1109 }
1110 *a = (char *)in;
1111 *alen = len;
1112
1113 *pin = in + len;
1114 *pinlen = inlen - len;
1115 return 1;
1116 }
1117
asn1_utf8_string_from_der_ex(int tag,const char ** a,size_t * alen,const uint8_t ** in,size_t * inlen)1118 int asn1_utf8_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
1119 {
1120 return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen);
1121 }
1122
asn1_printable_string_from_der_ex(int tag,const char ** a,size_t * alen,const uint8_t ** in,size_t * inlen)1123 int asn1_printable_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
1124 {
1125 return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen);
1126 }
1127
asn1_ia5_string_from_der_ex(int tag,const char ** a,size_t * alen,const uint8_t ** in,size_t * inlen)1128 int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen)
1129 {
1130 return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen);
1131 }
1132
1133 /*
1134 int hh, mm, ss;
1135 struct tm when = {0};
1136
1137 sscanf_s(date, "%d:%d:%d", &hh, &mm, &ss);
1138
1139
1140 when.tm_hour = hh;
1141 when.tm_min = mm;
1142 when.tm_sec = ss;
1143
1144 time_t converted;
1145 converted = mktime(&when);
1146 */
1147
asn1_utc_time_from_der_ex(int tag,time_t * t,const uint8_t ** pin,size_t * pinlen)1148 int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen)
1149 {
1150 const uint8_t *in = *pin;
1151 size_t inlen = *pinlen;
1152 struct tm tm_val;
1153 char buf[sizeof("YYYYMMDDHHMMSSZ")] = {0};
1154 size_t len;
1155 int year;
1156
1157
1158 if (!t || !pin || !(*pin) || !pinlen) {
1159 return -1;
1160 }
1161 if (inlen-- <= 0 || *in++ != tag) {
1162 return 0;
1163 }
1164 if (asn1_length_from_der(&len, &in, &inlen) != 1
1165 || (len != sizeof("YYMMDDHHMMSSZ")-1 && len != sizeof("YYMMDDHHMMSS+HHMM")-1)) {
1166 return -1;
1167 }
1168 memcpy(buf + 2, in, len);
1169
1170 if (!isdigit(buf[2]) && !isdigit(buf[3])) {
1171 return -1;
1172 }
1173 year = (buf[2] - '0') * 10 + (buf[3] - '0');
1174 if (year >= 50) {
1175 buf[0] = '1';
1176 buf[1] = '9';
1177 } else {
1178 buf[0] = '2';
1179 buf[1] = '0';
1180 }
1181 if (len == sizeof("YYMMDDHHMMSSZ")-1) {
1182 // 这里应该自己写一个函数来解析
1183 if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { // 注意:这个函数在Windows上没有!!
1184 return -1;
1185 }
1186 } else {
1187 return -1;
1188 }
1189 *t = timegm(&tm_val); // FIXME: Windows !
1190
1191 *pin = in + len;
1192 *pinlen = inlen - len;
1193 return 1;
1194 }
1195
asn1_generalized_time_from_der_ex(int tag,time_t * t,const uint8_t ** pin,size_t * pinlen)1196 int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen)
1197 {
1198 int ret;
1199 const uint8_t *in = *pin;
1200 size_t inlen = *pinlen;
1201 struct tm tm_val;
1202 char buf[sizeof("YYYYMMDDHHMMSS+HHMM")] = {0};
1203 size_t len;
1204
1205 if ((ret = asn1_tag_from_der(tag, &in, &inlen)) != 1) {
1206 if (ret < 0) error_print();
1207 return ret;
1208 }
1209 if (asn1_length_from_der(&len, &in, &inlen) != 1) {
1210 error_print();
1211 return -1;
1212 }
1213 if (len != sizeof("YYYYMMDDHHMMSSZ")-1 && len != sizeof("YYYYMMDDHHMMSS+HHMM")-1) {
1214 error_print();
1215 return -1;
1216 }
1217 memcpy(buf, in, len);
1218
1219 if (len == sizeof("YYYYMMDDHHMMSSZ")-1) {
1220 if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) {
1221 error_print();
1222 return -1;
1223 }
1224 } else {
1225 // TODO: 处理这种情况
1226 error_print();
1227 return -2;
1228 }
1229 *t = timegm(&tm_val);
1230 *pin = in + len;
1231 *pinlen = inlen - len;
1232 return 1;
1233 }
1234
1235
asn1_check(int expr)1236 int asn1_check(int expr)
1237 {
1238 if (expr)
1239 return 1;
1240 error_print();
1241 return -1;
1242 }
1243
asn1_length_is_zero(size_t len)1244 int asn1_length_is_zero(size_t len)
1245 {
1246 if (len) {
1247 error_print();
1248 return -1;
1249 }
1250 return 1;
1251 }
1252
asn1_length_le(size_t len1,size_t len2)1253 int asn1_length_le(size_t len1, size_t len2)
1254 {
1255 if (len1 > len2) {
1256 error_print();
1257 format_print(stderr, 0, 0, "%s: %zu <= %zu failed\n", __FUNCTION__, len1, len2);
1258 return -1;
1259 }
1260 return 1;
1261 }
1262
asn1_object_identifier_equ(const uint32_t * a,size_t a_cnt,const uint32_t * b,size_t b_cnt)1263 int asn1_object_identifier_equ(const uint32_t *a, size_t a_cnt, const uint32_t *b, size_t b_cnt)
1264 {
1265 if (a_cnt == b_cnt
1266 && memcmp(a, b, b_cnt * sizeof(uint32_t)) == 0) {
1267 return 1;
1268 }
1269 return 0;
1270 }
1271
1272
asn1_sequence_of_int_to_der(const int * nums,size_t nums_cnt,uint8_t ** out,size_t * outlen)1273 int asn1_sequence_of_int_to_der(const int *nums, size_t nums_cnt, uint8_t **out, size_t *outlen)
1274 {
1275 size_t len = 0;
1276 size_t i;
1277 for (i = 0; i < nums_cnt; i++) {
1278 if (asn1_int_to_der(nums[i], NULL, &len) != 1) {
1279 error_print();
1280 return -1;
1281 }
1282 }
1283 if (asn1_sequence_header_to_der(len, out, outlen) != 1) {
1284 error_print();
1285 return -1;
1286 }
1287 for (i = 0; i < nums_cnt; i++) {
1288 if (asn1_int_to_der(nums[i], out, outlen) != 1) {
1289 error_print();
1290 return -1;
1291 }
1292 }
1293 return 1;
1294 }
1295
asn1_sequence_of_int_from_der(int * nums,size_t * nums_cnt,const uint8_t ** in,size_t * inlen)1296 int asn1_sequence_of_int_from_der(int *nums, size_t *nums_cnt, const uint8_t **in, size_t *inlen)
1297 {
1298 int ret;
1299 const uint8_t *d;
1300 size_t dlen;
1301
1302 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1303 if (ret < 0) error_print();
1304 return ret;
1305 }
1306 *nums_cnt = 0;
1307 while (dlen) {
1308 int num;
1309 if (asn1_int_from_der(&num, &d, &dlen) != 1) {
1310 error_print();
1311 return -1;
1312 }
1313 if (nums) {
1314 *nums++ = num;
1315 }
1316 (*nums_cnt)++;
1317 }
1318 return 1;
1319 }
1320
asn1_sequence_of_int_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1321 int asn1_sequence_of_int_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1322 {
1323 int val;
1324 format_print(fp, fmt, ind, "%s: ", label);
1325 while (dlen) {
1326 if (asn1_int_from_der(&val, &d, &dlen) != 1) {
1327 error_print();
1328 return -1;
1329 }
1330 fprintf(fp, "%d%s", val, dlen ? "," : "");
1331 }
1332 fprintf(fp, "\n");
1333 return 1;
1334 }
1335
1336
asn1_object_identifier_print(FILE * fp,int format,int indent,const char * label,const char * name,const uint32_t * nodes,size_t nodes_cnt)1337 int asn1_object_identifier_print(FILE *fp, int format, int indent, const char *label, const char *name,
1338 const uint32_t *nodes, size_t nodes_cnt)
1339 {
1340 size_t i;
1341 format_print(fp, format, indent, "%s: %s", label, name ? name : "(unknown)");
1342 if (nodes) {
1343 fprintf(fp, " (");
1344 for (i = 0; i < nodes_cnt - 1; i++) {
1345 fprintf(fp, "%d.", (int)nodes[i]);
1346 }
1347 fprintf(fp, "%d)", nodes[i]);
1348 }
1349 fprintf(fp, "\n");
1350 return 1;
1351 }
1352
asn1_string_print(FILE * fp,int fmt,int ind,const char * label,int tag,const uint8_t * d,size_t dlen)1353 int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen)
1354 {
1355 format_print(fp, fmt, ind, "%s: ", label);
1356 while (dlen--) {
1357 fprintf(fp, "%c", *d++);
1358 }
1359 fprintf(fp, "\n");
1360 return 1;
1361 }
1362
asn1_bits_print(FILE * fp,int fmt,int ind,const char * label,const char ** names,size_t names_cnt,int bits)1363 int asn1_bits_print(FILE *fp, int fmt, int ind, const char *label, const char **names, size_t names_cnt, int bits)
1364 {
1365 size_t i;
1366 format_print(fp, fmt, ind, "%s: ", label);
1367
1368 for (i = 0; i < names_cnt; i++) {
1369 if (bits & 0x01)
1370 fprintf(fp, "%s%s", names[i], bits >> 1 ? "," : "");
1371 bits >>= 1;
1372 }
1373 fprintf(fp, "\n");
1374 if (bits) {
1375 error_print();
1376 return -1;
1377 }
1378 return 1;
1379 }
1380
asn1_types_get_count(const uint8_t * d,size_t dlen,int tag,size_t * cnt)1381 int asn1_types_get_count(const uint8_t *d, size_t dlen, int tag, size_t *cnt)
1382 {
1383 error_print();
1384 return -1;
1385 }
1386
asn1_types_get_item_by_index(const uint8_t * d,size_t * dlen,int tag,int index,const uint8_t ** item_d,size_t * item_dlen)1387 int asn1_types_get_item_by_index(const uint8_t *d, size_t *dlen, int tag,
1388 int index, const uint8_t **item_d, size_t *item_dlen)
1389 {
1390 error_print();
1391 return -1;
1392 }
1393