2 * Routines for ASN.1 BER dissection
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
9 * Based on "g_asn1.c" from:
11 * GXSNMP -- An snmp mangament application
12 * Copyright (C) 1998 Gregory McLean & Jochen Friedrich
13 * Beholder RMON ethernet network monitor, Copyright (C) 1993 DNPAP group
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 * SYSTEM NAME: ASN1 Basic Encoding
35 * ORIGINAL AUTHOR(S): Dirk Wisse
37 * CREATION DATE: 1990/11/22
39 * DESCRIPTION: ASN1 Basic Encoding Rules.
41 * To decode this we must do:
43 * asn1_open (asn1, tvb, offset);
44 * asn1_header_decode (asn1, &end_of_seq, cls, con, tag, def, len);
45 * asn1_header_decode (asn1, &end_of_octs, cls, con, tag, def, len);
46 * asn1_octets_decode (asn1, end_of_octs, str, len);
47 * asn1_header_decode (asn1, &end_of_int, cls, con, tag);
48 * asn1_int_decode (asn1, end_of_int, &integer);
49 * asn1_eoc_decode (asn1, end_of_seq);
50 * asn1_close (asn1, &offset);
52 * For indefinite encoding end_of_seq and &end_of_seq in the
53 * example above should be replaced by NULL.
54 * For indefinite decoding nothing has to be changed.
55 * This can be very useful if you want to decode both
56 * definite and indefinite encodings.
69 #ifdef NEED_SNPRINTF_H
70 # include "snprintf.h"
73 #include <epan/tvbuff.h>
77 * NAME: asn1_open [API]
78 * SYNOPSIS: void asn1_open
84 * DESCRIPTION: Opens an ASN1 socket.
86 * asn1: pointer to ASN1 socket.
87 * tvb: Tvbuff for encoding.
88 * offset: Current offset in tvbuff.
89 * Encoding starts at the end of the buffer, and
90 * proceeds to the beginning.
95 asn1_open(ASN1_SCK *asn1, tvbuff_t *tvb, int offset)
98 asn1->offset = offset;
102 * NAME: asn1_close [API]
103 * SYNOPSIS: void asn1_close
108 * DESCRIPTION: Closes an ASN1 socket.
110 * asn1: pointer to ASN1 socket.
111 * offset: pointer to variable into which current offset is
117 asn1_close(ASN1_SCK *asn1, int *offset)
119 *offset = asn1->offset;
123 * NAME: asn1_octet_decode
124 * SYNOPSIS: int asn1_octet_decode
129 * DESCRIPTION: Decodes an octet.
130 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
133 asn1_octet_decode(ASN1_SCK *asn1, guchar *ch)
135 *ch = tvb_get_guint8(asn1->tvb, asn1->offset);
137 return ASN1_ERR_NOERROR;
142 * SYNOPSIS: int asn1_tag_get
147 * DESCRIPTION: Decodes a tag number, combining it with existing tag bits.
148 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
151 asn1_tag_get(ASN1_SCK *asn1, guint *tag)
157 ret = asn1_octet_decode (asn1, &ch);
158 if (ret != ASN1_ERR_NOERROR)
162 } while ((ch & 0x80) == 0x80);
163 return ASN1_ERR_NOERROR;
167 * NAME: asn1_tag_decode
168 * SYNOPSIS: int asn1_tag_decode
173 * DESCRIPTION: Decodes a tag number.
174 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
177 asn1_tag_decode(ASN1_SCK *asn1, guint *tag)
180 return asn1_tag_get(asn1, tag);
184 * NAME: asn1_id_decode
185 * SYNOPSIS: int asn1_id_decode
192 * DESCRIPTION: Decodes an identifier.
193 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
196 asn1_id_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag)
202 ret = asn1_octet_decode (asn1, &ch);
203 if (ret != ASN1_ERR_NOERROR)
205 *cls = (ch & 0xC0) >> 6;
206 *con = (ch & 0x20) >> 5;
209 ret = asn1_tag_decode (asn1, tag);
210 if (ret != ASN1_ERR_NOERROR)
213 return ASN1_ERR_NOERROR;
217 * NAME: asn1_id_decode1
218 * SYNOPSIS: int asn1_id_decode1
223 * DESCRIPTION: Decodes an identifier.
224 * Like asn1_id_decode() except that the Class and Constructor
225 * bits are returned in the tag.
226 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
229 asn1_id_decode1(ASN1_SCK *asn1, guint *tag)
235 ret = asn1_octet_decode (asn1, &ch);
236 if (ret != ASN1_ERR_NOERROR)
240 if ((*tag & 0x1F) == 0x1F) { /* high-tag-number format */
241 *tag = ch >> 5; /* leave just the Class and Constructor bits */
242 ret = asn1_tag_get (asn1, tag);
243 if (ret != ASN1_ERR_NOERROR)
246 return ASN1_ERR_NOERROR;
250 * NAME: asn1_length_decode
251 * SYNOPSIS: int asn1_length_decode
257 * DESCRIPTION: Decodes an ASN1 length.
259 * asn1: pointer to ASN1 socket.
260 * def: Boolean - TRUE if length definite, FALSE if not
261 * len: length, if length is definite
262 * DESCRIPTION: Decodes a definite or indefinite length.
263 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
266 asn1_length_decode(ASN1_SCK *asn1, gboolean *def, guint *len)
271 ret = asn1_octet_decode (asn1, &ch);
272 if (ret != ASN1_ERR_NOERROR)
275 *def = FALSE; /* indefinite length */
277 *def = TRUE; /* definite length */
281 cnt = (guchar) (ch & 0x7F);
284 ret = asn1_octet_decode (asn1, &ch);
285 if (ret != ASN1_ERR_NOERROR)
293 return ASN1_ERR_NOERROR;
297 * NAME: asn1_header_decode [API]
298 * SYNOPSIS: int asn1_header_decode
307 * DESCRIPTION: Decodes an ASN1 header.
309 * asn1: pointer to ASN1 socket.
310 * cls: Class (see asn1.h)
311 * con: Primitive, Constructed (ASN1_PRI, ASN1_CON)
312 * tag: Tag (see asn1.h)
313 * defp: Boolean - TRUE if length definite, FALSE if not
314 * lenp: length, if length is definite
315 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
318 asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
319 gboolean *defp, guint *lenp)
324 ret = asn1_id_decode (asn1, cls, con, tag);
325 if (ret != ASN1_ERR_NOERROR)
327 ret = asn1_length_decode (asn1, &def, &len);
328 if (ret != ASN1_ERR_NOERROR)
332 return ASN1_ERR_NOERROR;
337 * NAME: asn1_eoc [API]
338 * SYNOPSIS: gboolean asn1_eoc
343 * DESCRIPTION: Checks if decoding is at End Of Contents.
345 * asn1: pointer to ASN1 socket.
346 * eoc: offset of end of encoding, or -1 if indefinite.
347 * RETURNS: gboolean success
350 asn1_eoc ( ASN1_SCK *asn1, int eoc)
353 return (tvb_get_guint8(asn1->tvb, asn1->offset) == 0x00
354 && tvb_get_guint8(asn1->tvb, asn1->offset + 1) == 0x00);
356 return (asn1->offset >= eoc);
360 * NAME: asn1_eoc_decode [API]
361 * SYNOPSIS: int asn1_eoc_decode
366 * DESCRIPTION: Decodes End Of Contents.
368 * asn1: pointer to ASN1 socket.
369 * eoc: offset of end of encoding, or -1 if indefinite.
370 * If eoc is -1 it decodes an ASN1 End Of
371 * Contents (0x00 0x00), so it has to be an
372 * indefinite length encoding. If eoc is a non-negative
373 * integer, it probably was filled by asn1_header_decode,
374 * and should refer to the octet after the last of the encoding.
375 * It is checked if this offset refers to the octet to be
376 * decoded. This only takes place in decoding a
377 * definite length encoding.
378 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
381 asn1_eoc_decode (ASN1_SCK *asn1, int eoc)
387 ret = asn1_octet_decode (asn1, &ch);
388 if (ret != ASN1_ERR_NOERROR)
391 return ASN1_ERR_EOC_MISMATCH;
392 ret = asn1_octet_decode (asn1, &ch);
393 if (ret != ASN1_ERR_NOERROR)
396 return ASN1_ERR_EOC_MISMATCH;
397 return ASN1_ERR_NOERROR;
399 if (asn1->offset != eoc)
400 return ASN1_ERR_LENGTH_MISMATCH;
401 return ASN1_ERR_NOERROR;
406 * NAME: asn1_null_decode [API]
407 * SYNOPSIS: int asn1_null_decode
412 * DESCRIPTION: Decodes Null.
414 * asn1: pointer to ASN1 socket.
415 * enc_len: length of encoding of value.
416 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
419 asn1_null_decode ( ASN1_SCK *asn1, int enc_len)
421 asn1->offset += enc_len;
422 return ASN1_ERR_NOERROR;
426 * NAME: asn1_bool_decode [API]
427 * SYNOPSIS: int asn1_bool_decode
433 * DESCRIPTION: Decodes Boolean.
435 * asn1: pointer to ASN1 socket.
436 * enc_len: length of encoding of value.
437 * bool: False, True (0, !0).
438 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
441 asn1_bool_decode ( ASN1_SCK *asn1, int enc_len, gboolean *boolean)
447 return ASN1_ERR_LENGTH_MISMATCH;
448 ret = asn1_octet_decode (asn1, &ch);
449 if (ret != ASN1_ERR_NOERROR)
451 *boolean = ch ? TRUE : FALSE;
452 return ASN1_ERR_NOERROR;
456 * NAME: asn1_int32_value_decode [API]
457 * SYNOPSIS: int asn1_int32_value_decode
463 * DESCRIPTION: Decodes value portion of Integer (which must be no more
466 * asn1: pointer to ASN1 socket.
467 * enc_len: length of encoding of value.
469 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
472 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
479 eoc = asn1->offset + enc_len;
480 ret = asn1_octet_decode (asn1, &ch);
481 if (ret != ASN1_ERR_NOERROR)
483 *integer = (gint) ch;
485 while (asn1->offset < eoc) {
486 if (++len > sizeof (gint32))
487 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
488 ret = asn1_octet_decode (asn1, &ch);
489 if (ret != ASN1_ERR_NOERROR)
494 return ASN1_ERR_NOERROR;
498 * NAME: asn1_int32_decode [API]
499 * SYNOPSIS: int asn1_int32_decode
505 * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
507 * asn1: pointer to ASN1 socket.
509 * nbytes: number of bytes used to encode it.
510 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
513 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
523 start = asn1->offset;
524 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
525 if (ret != ASN1_ERR_NOERROR)
527 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
528 ret = ASN1_ERR_WRONG_TYPE;
532 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
535 ret = asn1_int32_value_decode (asn1, enc_len, integer);
538 *nbytes = asn1->offset - start;
543 * NAME: asn1_uint32_value_decode [API]
544 * SYNOPSIS: int asn1_uint32_value_decode
550 * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
551 * more than 32 bits).
553 * asn1: pointer to ASN1 socket.
554 * enc_len: length of encoding of value.
556 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
559 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint32 *integer)
566 eoc = asn1->offset + enc_len;
567 ret = asn1_octet_decode (asn1, &ch);
568 if (ret != ASN1_ERR_NOERROR)
575 while (asn1->offset < eoc) {
576 if (++len > sizeof (guint32))
577 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
578 ret = asn1_octet_decode (asn1, &ch);
579 if (ret != ASN1_ERR_NOERROR)
584 return ASN1_ERR_NOERROR;
588 * NAME: asn1_uint32_decode [API]
589 * SYNOPSIS: int asn1_uint32_decode
595 * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
597 * asn1: pointer to ASN1 socket.
599 * nbytes: number of bytes used to encode it.
600 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
603 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
613 start = asn1->offset;
614 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
615 if (ret != ASN1_ERR_NOERROR)
617 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
618 ret = ASN1_ERR_WRONG_TYPE;
622 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
625 ret = asn1_uint32_value_decode (asn1, enc_len, integer);
628 *nbytes = asn1->offset - start;
633 * NAME: asn1_bits_decode [API]
634 * SYNOPSIS: int asn1_bits_decode
643 * DESCRIPTION: Decodes Bit String.
645 * asn1: pointer to ASN1 socket.
646 * enc_len: length of value.
647 * bits: pointer to variable we set to point to strring
648 * len: Size of Bit String in characters.
649 * unused: Number of unused bits in last character.
650 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
653 asn1_bits_decode ( ASN1_SCK *asn1, int enc_len, guchar **bits,
654 guint *len, guchar *unused)
660 eoc = asn1->offset + enc_len;
662 ret = asn1_octet_decode (asn1, unused);
663 if (ret != ASN1_ERR_NOERROR)
668 * First, make sure the entire string is in the tvbuff, and throw
669 * an exception if it isn't. If the length is bogus, this should
670 * keep us from trying to allocate an immensely large buffer.
671 * (It won't help if the length is *valid* but immensely large,
672 * but that's another matter; in any case, that would happen only
673 * if we had an immensely large tvbuff....)
676 tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
677 *bits = g_malloc (enc_len);
680 * If the length is 0, we allocate a 1-byte buffer, as
681 * "g_malloc()" returns NULL if passed 0 as an argument,
682 * and our caller expects us to return a pointer to a
685 *bits = g_malloc (1);
689 while (asn1->offset < eoc) {
690 ret = asn1_octet_decode (asn1, (guchar *)ptr++);
691 if (ret != ASN1_ERR_NOERROR) {
698 return ASN1_ERR_NOERROR;
702 * NAME: asn1_string_value_decode [API]
703 * SYNOPSIS: int asn1_string_value_decode
709 * DESCRIPTION: Decodes value portion of string (Octet String, various
710 * character string types)
712 * asn1: pointer to ASN1 socket.
713 * enc_len: length of encoding of value.
714 * octets: pointer to variable we set to point to string,
715 * which is '\0' terminated for ease of use as C-string
716 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
719 asn1_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
726 * First, make sure the entire string is in the tvbuff, and throw
727 * an exception if it isn't. If the length is bogus, this should
728 * keep us from trying to allocate an immensely large buffer.
729 * (It won't help if the length is *valid* but immensely large,
730 * but that's another matter; in any case, that would happen only
731 * if we had an immensely large tvbuff....)
734 tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
735 *octets = g_malloc (enc_len+1);
737 eoc = asn1->offset + enc_len;
739 while (asn1->offset < eoc) {
740 ret = asn1_octet_decode (asn1, (guchar *)ptr++);
741 if (ret != ASN1_ERR_NOERROR) {
747 *(guchar *)ptr = '\0';
748 return ASN1_ERR_NOERROR;
752 * NAME: asn1_string_decode [API]
753 * SYNOPSIS: int asn1_string_decode
761 * DESCRIPTION: Decodes string (Octet String, various character string
764 * asn1: pointer to ASN1 socket.
765 * octets: pointer to variable we set to point to string.
766 * str_len: length of octet_string.
767 * nbytes: number of bytes used to encode.
768 * expected_tag: tag expected for this type of string.
769 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
772 asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
773 guint *nbytes, guint expected_tag)
783 start = asn1->offset;
784 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
785 if (ret != ASN1_ERR_NOERROR)
787 if (cls != ASN1_UNI || con != ASN1_PRI || tag != expected_tag) {
788 /* XXX - handle the constructed encoding? */
789 ret = ASN1_ERR_WRONG_TYPE;
793 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
797 ret = asn1_string_value_decode (asn1, enc_len, octets);
801 *nbytes = asn1->offset - start;
806 * NAME: asn1_octet_string_decode [API]
807 * SYNOPSIS: int asn1_octet_string_decode
814 * DESCRIPTION: Decodes Octet String.
816 * asn1: pointer to ASN1 socket.
817 * octets: pointer to variable we set to point to string.
818 * str_len: length of octet_string.
819 * nbytes: number of bytes used to encode.
820 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
823 asn1_octet_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
826 return asn1_string_decode(asn1, octets, str_len, nbytes, ASN1_OTS);
830 * NAME: asn1_subid_decode
831 * SYNOPSIS: int asn1_subid_decode
836 * DESCRIPTION: Decodes Sub Identifier.
838 * asn1: pointer to ASN1 socket.
839 * subid: Sub Identifier.
840 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
843 asn1_subid_decode ( ASN1_SCK *asn1, subid_t *subid)
850 ret = asn1_octet_decode(asn1, &ch);
851 if (ret != ASN1_ERR_NOERROR)
855 } while ((ch & 0x80) == 0x80);
856 return ASN1_ERR_NOERROR;
860 * NAME: asn1_oid_value_decode [API]
861 * SYNOPSIS: int asn1_oid_value_decode
868 * DESCRIPTION: Decodes value portion of Object Identifier.
870 * asn1: pointer to ASN1 socket.
871 * enc_len: length of encoding of value.
872 * oid: pointer to variable we set to Object Identifier.
873 * len: Length of Object Identifier in gulongs.
874 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
877 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
886 * First, make sure the entire string is in the tvbuff, and throw
887 * an exception if it isn't. If the length is bogus, this should
888 * keep us from trying to allocate an immensely large buffer.
889 * (It won't help if the length is *valid* but immensely large,
890 * but that's another matter; in any case, that would happen only
891 * if we had an immensely large tvbuff....)
894 tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
896 eoc = asn1->offset + enc_len;
899 *oid = g_malloc(size * sizeof(gulong));
902 ret = asn1_subid_decode (asn1, &subid);
903 if (ret != ASN1_ERR_NOERROR) {
911 } else if (subid < 80) {
913 optr[1] = subid - 40;
916 optr[1] = subid - 80;
920 while (asn1->offset < eoc) {
921 if (++(*len) > size) {
924 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
926 ret = asn1_subid_decode (asn1, optr++);
927 if (ret != ASN1_ERR_NOERROR) {
933 return ASN1_ERR_NOERROR;
937 * NAME: asn1_oid_decode [API]
938 * SYNOPSIS: int asn1_oid_decode
945 * DESCRIPTION: Decodes Object Identifier.
947 * asn1: pointer to ASN1 socket.
948 * oid: pointer to variable we set to Object Identifier.
949 * len: Length of Object Identifier in gulongs.
950 * nbytes: number of bytes used to encode.
951 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
954 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
964 start = asn1->offset;
965 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
966 if (ret != ASN1_ERR_NOERROR)
968 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) {
969 ret = ASN1_ERR_WRONG_TYPE;
973 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
977 ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
980 *nbytes = asn1->offset - start;
985 * NAME: asn1_sequence_decode [API]
986 * SYNOPSIS: int asn1_sequence_decode
992 * DESCRIPTION: Decodes header for SEQUENCE.
994 * asn1: pointer to ASN1 socket.
995 * seq_len: length of sequence.
996 * nbytes: number of bytes used to encode header.
997 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
1000 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
1009 start = asn1->offset;
1010 ret = asn1_header_decode(asn1, &cls, &con, &tag,
1012 if (ret != ASN1_ERR_NOERROR)
1014 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) {
1015 ret = ASN1_ERR_WRONG_TYPE;
1019 /* XXX - might some sequences have an indefinite length? */
1020 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
1023 ret = ASN1_ERR_NOERROR;
1026 *nbytes = asn1->offset - start;
1031 * NAME: asn1_err_to_str [API]
1032 * SYNOPSIS: char *asn1_err_to_str
1036 * DESCRIPTION: Returns the string corresponding to an ASN.1 library error.
1038 * err: the error code
1039 * RETURNS: string for the error
1042 asn1_err_to_str(int err)
1045 char errstrbuf[14+1+1+11+1+1]; /* "Unknown error (%d)\0" */
1049 case ASN1_ERR_EOC_MISMATCH:
1050 errstr = "EOC mismatch";
1053 case ASN1_ERR_WRONG_TYPE:
1054 errstr = "Wrong type for that item";
1057 case ASN1_ERR_LENGTH_NOT_DEFINITE:
1058 errstr = "Length was indefinite";
1061 case ASN1_ERR_LENGTH_MISMATCH:
1062 errstr = "Length mismatch";
1065 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
1066 errstr = "Wrong length for that item's type";
1070 snprintf(errstrbuf, sizeof errstrbuf, "Unknown error (%d)", err);