2 * Routines for ASN.1 BER dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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.
63 #define subid_t guint32 /* ugly hack to get it to compile this symbol should be suppressed! */
65 #include <epan/tvbuff.h>
66 #include <plugins/asn1/asn1.h>
67 #include <epan/emem.h>
71 * NAME: asn1_open [API]
72 * SYNOPSIS: void asn1_open
78 * DESCRIPTION: Opens an ASN1 socket.
80 * asn1: pointer to ASN1 socket.
81 * tvb: Tvbuff for encoding.
82 * offset: Current offset in tvbuff.
83 * Encoding starts at the end of the buffer, and
84 * proceeds to the beginning.
89 asn1_open(ASN1_SCK
*asn1
, tvbuff_t
*tvb
, int offset
)
92 asn1
->offset
= offset
;
96 * NAME: asn1_close [API]
97 * SYNOPSIS: void asn1_close
102 * DESCRIPTION: Closes an ASN1 socket.
104 * asn1: pointer to ASN1 socket.
105 * offset: pointer to variable into which current offset is
111 asn1_close(ASN1_SCK
*asn1
, int *offset
)
113 *offset
= asn1
->offset
;
117 * NAME: asn1_octet_decode
118 * SYNOPSIS: int asn1_octet_decode
123 * DESCRIPTION: Decodes an octet.
124 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
127 asn1_octet_decode(ASN1_SCK
*asn1
, guchar
*ch
)
129 *ch
= tvb_get_guint8(asn1
->tvb
, asn1
->offset
);
131 return ASN1_ERR_NOERROR
;
136 * SYNOPSIS: int asn1_tag_get
141 * DESCRIPTION: Decodes a tag number, combining it with existing tag bits.
142 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
145 asn1_tag_get(ASN1_SCK
*asn1
, guint
*tag
)
151 ret
= asn1_octet_decode (asn1
, &ch
);
152 if (ret
!= ASN1_ERR_NOERROR
)
156 } while ((ch
& 0x80) == 0x80);
157 return ASN1_ERR_NOERROR
;
161 * NAME: asn1_tag_decode
162 * SYNOPSIS: int asn1_tag_decode
167 * DESCRIPTION: Decodes a tag number.
168 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
171 asn1_tag_decode(ASN1_SCK
*asn1
, guint
*tag
)
174 return asn1_tag_get(asn1
, tag
);
178 * NAME: asn1_id_decode
179 * SYNOPSIS: int asn1_id_decode
186 * DESCRIPTION: Decodes an identifier.
187 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
190 asn1_id_decode(ASN1_SCK
*asn1
, guint
*cls
, guint
*con
, guint
*tag
)
196 ret
= asn1_octet_decode (asn1
, &ch
);
197 if (ret
!= ASN1_ERR_NOERROR
)
199 *cls
= (ch
& 0xC0) >> 6;
200 *con
= (ch
& 0x20) >> 5;
203 ret
= asn1_tag_decode (asn1
, tag
);
204 if (ret
!= ASN1_ERR_NOERROR
)
207 return ASN1_ERR_NOERROR
;
211 * NAME: asn1_id_decode1
212 * SYNOPSIS: int asn1_id_decode1
217 * DESCRIPTION: Decodes an identifier.
218 * Like asn1_id_decode() except that the Class and Constructor
219 * bits are returned in the tag.
220 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
223 asn1_id_decode1(ASN1_SCK
*asn1
, guint
*tag
)
229 ret
= asn1_octet_decode (asn1
, &ch
);
230 if (ret
!= ASN1_ERR_NOERROR
)
234 if ((*tag
& 0x1F) == 0x1F) { /* high-tag-number format */
235 *tag
= ch
>> 5; /* leave just the Class and Constructor bits */
236 ret
= asn1_tag_get (asn1
, tag
);
237 if (ret
!= ASN1_ERR_NOERROR
)
240 return ASN1_ERR_NOERROR
;
244 * NAME: asn1_length_decode
245 * SYNOPSIS: int asn1_length_decode
251 * DESCRIPTION: Decodes an ASN1 length.
253 * asn1: pointer to ASN1 socket.
254 * def: Boolean - TRUE if length definite, FALSE if not
255 * len: length, if length is definite
256 * DESCRIPTION: Decodes a definite or indefinite length.
257 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
260 asn1_length_decode(ASN1_SCK
*asn1
, gboolean
*def
, guint
*len
)
265 ret
= asn1_octet_decode (asn1
, &ch
);
266 if (ret
!= ASN1_ERR_NOERROR
)
269 *def
= FALSE
; /* indefinite length */
271 *def
= TRUE
; /* definite length */
275 cnt
= (guchar
) (ch
& 0x7F);
278 ret
= asn1_octet_decode (asn1
, &ch
);
279 if (ret
!= ASN1_ERR_NOERROR
)
287 return ASN1_ERR_NOERROR
;
291 * NAME: asn1_header_decode [API]
292 * SYNOPSIS: int asn1_header_decode
301 * DESCRIPTION: Decodes an ASN1 header.
303 * asn1: pointer to ASN1 socket.
304 * cls: Class (see asn1.h)
305 * con: Primitive, Constructed (ASN1_PRI, ASN1_CON)
306 * tag: Tag (see asn1.h)
307 * defp: Boolean - TRUE if length definite, FALSE if not
308 * lenp: length, if length is definite
309 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
312 asn1_header_decode(ASN1_SCK
*asn1
, guint
*cls
, guint
*con
, guint
*tag
,
313 gboolean
*defp
, guint
*lenp
)
319 ret
= asn1_id_decode (asn1
, cls
, con
, tag
);
320 if (ret
!= ASN1_ERR_NOERROR
)
322 ret
= asn1_length_decode (asn1
, &def
, &len
);
323 if (ret
!= ASN1_ERR_NOERROR
)
327 return ASN1_ERR_NOERROR
;
332 * NAME: asn1_eoc [API]
333 * SYNOPSIS: gboolean asn1_eoc
338 * DESCRIPTION: Checks if decoding is at End Of Contents.
340 * asn1: pointer to ASN1 socket.
341 * eoc: offset of end of encoding, or -1 if indefinite.
342 * RETURNS: gboolean success
345 asn1_eoc ( ASN1_SCK
*asn1
, int eoc
)
348 return (tvb_get_guint8(asn1
->tvb
, asn1
->offset
) == 0x00
349 && tvb_get_guint8(asn1
->tvb
, asn1
->offset
+ 1) == 0x00);
351 return (asn1
->offset
>= eoc
);
355 * NAME: asn1_eoc_decode [API]
356 * SYNOPSIS: int asn1_eoc_decode
361 * DESCRIPTION: Decodes End Of Contents.
363 * asn1: pointer to ASN1 socket.
364 * eoc: offset of end of encoding, or -1 if indefinite.
365 * If eoc is -1 it decodes an ASN1 End Of
366 * Contents (0x00 0x00), so it has to be an
367 * indefinite length encoding. If eoc is a non-negative
368 * integer, it probably was filled by asn1_header_decode,
369 * and should refer to the octet after the last of the encoding.
370 * It is checked if this offset refers to the octet to be
371 * decoded. This only takes place in decoding a
372 * definite length encoding.
373 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
376 asn1_eoc_decode (ASN1_SCK
*asn1
, int eoc
)
382 ret
= asn1_octet_decode (asn1
, &ch
);
383 if (ret
!= ASN1_ERR_NOERROR
)
386 return ASN1_ERR_EOC_MISMATCH
;
387 ret
= asn1_octet_decode (asn1
, &ch
);
388 if (ret
!= ASN1_ERR_NOERROR
)
391 return ASN1_ERR_EOC_MISMATCH
;
392 return ASN1_ERR_NOERROR
;
394 if (asn1
->offset
!= eoc
)
395 return ASN1_ERR_LENGTH_MISMATCH
;
396 return ASN1_ERR_NOERROR
;
401 * NAME: asn1_null_decode [API]
402 * SYNOPSIS: int asn1_null_decode
407 * DESCRIPTION: Decodes Null.
409 * asn1: pointer to ASN1 socket.
410 * enc_len: length of encoding of value.
411 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
414 asn1_null_decode ( ASN1_SCK
*asn1
, int enc_len
)
416 int start_off
= asn1
->offset
;
418 asn1
->offset
+= enc_len
;
420 * Check for integer overflows.
421 * XXX - ASN1_ERR_LENGTH_MISMATCH seemed like the most appropriate
422 * error from the ones available. Should we make a new one?
424 if (asn1
->offset
< 0 || asn1
->offset
< start_off
)
425 return ASN1_ERR_LENGTH_MISMATCH
;
427 return ASN1_ERR_NOERROR
;
431 * NAME: asn1_bool_decode [API]
432 * SYNOPSIS: int asn1_bool_decode
438 * DESCRIPTION: Decodes Boolean.
440 * asn1: pointer to ASN1 socket.
441 * enc_len: length of encoding of value.
442 * bool: False, True (0, !0).
443 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
446 asn1_bool_decode ( ASN1_SCK
*asn1
, int enc_len
, gboolean
*boolean
)
452 return ASN1_ERR_LENGTH_MISMATCH
;
453 ret
= asn1_octet_decode (asn1
, &ch
);
454 if (ret
!= ASN1_ERR_NOERROR
)
456 *boolean
= ch
? TRUE
: FALSE
;
457 return ASN1_ERR_NOERROR
;
461 * NAME: asn1_int32_value_decode [API]
462 * SYNOPSIS: int asn1_int32_value_decode
468 * DESCRIPTION: Decodes value portion of Integer (which must be no more
471 * asn1: pointer to ASN1 socket.
472 * enc_len: length of encoding of value.
474 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
477 asn1_int32_value_decode ( ASN1_SCK
*asn1
, int enc_len
, gint32
*integer
)
484 eoc
= asn1
->offset
+ enc_len
;
485 ret
= asn1_octet_decode (asn1
, &ch
);
486 if (ret
!= ASN1_ERR_NOERROR
)
488 *integer
= (gint
) ch
;
490 while (asn1
->offset
< eoc
) {
491 if (++len
> sizeof (gint32
))
492 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE
;
493 ret
= asn1_octet_decode (asn1
, &ch
);
494 if (ret
!= ASN1_ERR_NOERROR
)
499 return ASN1_ERR_NOERROR
;
503 * NAME: asn1_int32_decode [API]
504 * SYNOPSIS: int asn1_int32_decode
510 * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
512 * asn1: pointer to ASN1 socket.
514 * nbytes: number of bytes used to encode it.
515 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
518 asn1_int32_decode ( ASN1_SCK
*asn1
, gint32
*integer
, guint
*nbytes
)
528 start
= asn1
->offset
;
529 ret
= asn1_header_decode (asn1
, &cls
, &con
, &tag
, &def
, &enc_len
);
530 if (ret
!= ASN1_ERR_NOERROR
)
532 if (cls
!= ASN1_UNI
|| con
!= ASN1_PRI
|| tag
!= ASN1_INT
) {
533 ret
= ASN1_ERR_WRONG_TYPE
;
537 ret
= ASN1_ERR_LENGTH_NOT_DEFINITE
;
540 ret
= asn1_int32_value_decode (asn1
, enc_len
, integer
);
543 *nbytes
= asn1
->offset
- start
;
548 * NAME: asn1_uint32_value_decode [API]
549 * SYNOPSIS: int asn1_uint32_value_decode
555 * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
556 * more than 32 bits).
558 * asn1: pointer to ASN1 socket.
559 * enc_len: length of encoding of value.
561 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
564 asn1_uint32_value_decode ( ASN1_SCK
*asn1
, int enc_len
, guint32
*integer
)
571 eoc
= asn1
->offset
+ enc_len
;
572 ret
= asn1_octet_decode (asn1
, &ch
);
573 if (ret
!= ASN1_ERR_NOERROR
)
580 while (asn1
->offset
< eoc
) {
581 if (++len
> sizeof (guint32
))
582 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE
;
583 ret
= asn1_octet_decode (asn1
, &ch
);
584 if (ret
!= ASN1_ERR_NOERROR
)
589 return ASN1_ERR_NOERROR
;
593 * NAME: asn1_uint32_decode [API]
594 * SYNOPSIS: int asn1_uint32_decode
600 * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
602 * asn1: pointer to ASN1 socket.
604 * nbytes: number of bytes used to encode it.
605 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
608 asn1_uint32_decode ( ASN1_SCK
*asn1
, guint32
*integer
, guint
*nbytes
)
618 start
= asn1
->offset
;
619 ret
= asn1_header_decode (asn1
, &cls
, &con
, &tag
, &def
, &enc_len
);
620 if (ret
!= ASN1_ERR_NOERROR
)
622 if (cls
!= ASN1_UNI
|| con
!= ASN1_PRI
|| tag
!= ASN1_INT
) {
623 ret
= ASN1_ERR_WRONG_TYPE
;
627 ret
= ASN1_ERR_LENGTH_NOT_DEFINITE
;
630 ret
= asn1_uint32_value_decode (asn1
, enc_len
, integer
);
633 *nbytes
= asn1
->offset
- start
;
638 * NAME: asn1_bits_decode [API]
639 * SYNOPSIS: int asn1_bits_decode
648 * DESCRIPTION: Decodes Bit String.
650 * asn1: pointer to ASN1 socket.
651 * enc_len: length of value.
652 * bits: pointer to variable we set to point to strring
653 * len: Size of Bit String in characters.
654 * unused: Number of unused bits in last character.
655 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
658 asn1_bits_decode ( ASN1_SCK
*asn1
, int enc_len
, guchar
**bits
,
659 guint
*len
, guchar
*unused
)
665 eoc
= asn1
->offset
+ enc_len
;
667 ret
= asn1_octet_decode (asn1
, unused
);
668 if (ret
!= ASN1_ERR_NOERROR
)
673 * First, make sure the entire string is in the tvbuff, and throw
674 * an exception if it isn't. If the length is bogus, this should
675 * keep us from trying to allocate an immensely large buffer.
676 * (It won't help if the length is *valid* but immensely large,
677 * but that's another matter; in any case, that would happen only
678 * if we had an immensely large tvbuff....)
681 tvb_ensure_bytes_exist(asn1
->tvb
, asn1
->offset
, enc_len
);
682 *bits
= (guchar
*)g_malloc (enc_len
);
685 * If the length is 0, we allocate a 1-byte buffer, as
686 * "g_malloc()" returns NULL if passed 0 as an argument,
687 * and our caller expects us to return a pointer to a
690 *bits
= (guchar
*)g_malloc (1);
694 while (asn1
->offset
< eoc
) {
695 ret
= asn1_octet_decode (asn1
, (guchar
*)ptr
++);
696 if (ret
!= ASN1_ERR_NOERROR
) {
702 *len
= (guint
) (ptr
- *bits
);
703 return ASN1_ERR_NOERROR
;
707 * NAME: asn1_string_value_decode [API]
708 * SYNOPSIS: int asn1_string_value_decode
714 * DESCRIPTION: Decodes value portion of string (Octet String, various
715 * character string types)
717 * asn1: pointer to ASN1 socket.
718 * enc_len: length of encoding of value.
719 * octets: pointer to variable we set to point to string,
720 * which is '\0' terminated for ease of use as C-string
721 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
724 asn1_string_value_decode ( ASN1_SCK
*asn1
, int enc_len
, guchar
**octets
)
731 * First, make sure the entire string is in the tvbuff, and throw
732 * an exception if it isn't. If the length is bogus, this should
733 * keep us from trying to allocate an immensely large buffer.
734 * (It won't help if the length is *valid* but immensely large,
735 * but that's another matter; in any case, that would happen only
736 * if we had an immensely large tvbuff....)
739 tvb_ensure_bytes_exist(asn1
->tvb
, asn1
->offset
, enc_len
);
740 *octets
= (guchar
*)g_malloc (enc_len
+1);
742 eoc
= asn1
->offset
+ enc_len
;
744 while (asn1
->offset
< eoc
) {
745 ret
= asn1_octet_decode (asn1
, (guchar
*)ptr
++);
746 if (ret
!= ASN1_ERR_NOERROR
) {
752 *(guchar
*)ptr
= '\0';
753 return ASN1_ERR_NOERROR
;
757 * NAME: asn1_string_decode [API]
758 * SYNOPSIS: int asn1_string_decode
766 * DESCRIPTION: Decodes string (Octet String, various character string
769 * asn1: pointer to ASN1 socket.
770 * octets: pointer to variable we set to point to string.
771 * str_len: length of octet_string.
772 * nbytes: number of bytes used to encode.
773 * expected_tag: tag expected for this type of string.
774 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
777 asn1_string_decode ( ASN1_SCK
*asn1
, guchar
**octets
, guint
*str_len
,
778 guint
*nbytes
, guint expected_tag
)
788 start
= asn1
->offset
;
789 ret
= asn1_header_decode (asn1
, &cls
, &con
, &tag
, &def
, &enc_len
);
790 if (ret
!= ASN1_ERR_NOERROR
)
792 if (cls
!= ASN1_UNI
|| con
!= ASN1_PRI
|| tag
!= expected_tag
) {
793 /* XXX - handle the constructed encoding? */
794 ret
= ASN1_ERR_WRONG_TYPE
;
798 ret
= ASN1_ERR_LENGTH_NOT_DEFINITE
;
802 ret
= asn1_string_value_decode (asn1
, enc_len
, octets
);
806 *nbytes
= asn1
->offset
- start
;
811 * NAME: asn1_octet_string_decode [API]
812 * SYNOPSIS: int asn1_octet_string_decode
819 * DESCRIPTION: Decodes Octet String.
821 * asn1: pointer to ASN1 socket.
822 * octets: pointer to variable we set to point to string.
823 * str_len: length of octet_string.
824 * nbytes: number of bytes used to encode.
825 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
828 asn1_octet_string_decode ( ASN1_SCK
*asn1
, guchar
**octets
, guint
*str_len
,
831 return asn1_string_decode(asn1
, octets
, str_len
, nbytes
, ASN1_OTS
);
835 * NAME: asn1_subid_decode
836 * SYNOPSIS: int asn1_subid_decode
841 * DESCRIPTION: Decodes Sub Identifier.
843 * asn1: pointer to ASN1 socket.
844 * subid: Sub Identifier.
845 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
848 asn1_subid_decode ( ASN1_SCK
*asn1
, subid_t
*subid
)
855 ret
= asn1_octet_decode(asn1
, &ch
);
856 if (ret
!= ASN1_ERR_NOERROR
)
860 } while ((ch
& 0x80) == 0x80);
861 return ASN1_ERR_NOERROR
;
865 * NAME: asn1_oid_value_decode [API]
866 * SYNOPSIS: int asn1_oid_value_decode
873 * DESCRIPTION: Decodes value portion of Object Identifier.
875 * asn1: pointer to ASN1 socket.
876 * enc_len: length of encoding of value.
877 * oid: pointer to variable we set to Object Identifier.
878 * len: Length of Object Identifier in gulongs.
879 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
882 asn1_oid_value_decode ( ASN1_SCK
*asn1
, int enc_len
, subid_t
**oid
, guint
*len
)
891 * First, make sure the entire string is in the tvbuff, and throw
892 * an exception if it isn't. If the length is bogus, this should
893 * keep us from trying to allocate an immensely large buffer.
894 * (It won't help if the length is *valid* but immensely large,
895 * but that's another matter; in any case, that would happen only
896 * if we had an immensely large tvbuff....)
900 return ASN1_ERR_LENGTH_MISMATCH
;
902 tvb_ensure_bytes_exist(asn1
->tvb
, asn1
->offset
, enc_len
);
904 eoc
= asn1
->offset
+ enc_len
;
907 *oid
= (guint32
*)g_malloc(size
* sizeof(gulong
));
910 ret
= asn1_subid_decode (asn1
, &subid
);
911 if (ret
!= ASN1_ERR_NOERROR
) {
919 } else if (subid
< 80) {
921 optr
[1] = subid
- 40;
924 optr
[1] = subid
- 80;
928 while (asn1
->offset
< eoc
) {
929 if (++(*len
) > size
) {
932 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE
;
934 ret
= asn1_subid_decode (asn1
, optr
++);
935 if (ret
!= ASN1_ERR_NOERROR
) {
941 return ASN1_ERR_NOERROR
;
945 * NAME: asn1_oid_decode [API]
946 * SYNOPSIS: int asn1_oid_decode
953 * DESCRIPTION: Decodes Object Identifier.
955 * asn1: pointer to ASN1 socket.
956 * oid: pointer to variable we set to Object Identifier.
957 * len: Length of Object Identifier in gulongs.
958 * nbytes: number of bytes used to encode.
959 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
962 asn1_oid_decode ( ASN1_SCK
*asn1
, subid_t
**oid
, guint
*len
, guint
*nbytes
)
972 start
= asn1
->offset
;
973 ret
= asn1_header_decode (asn1
, &cls
, &con
, &tag
, &def
, &enc_len
);
974 if (ret
!= ASN1_ERR_NOERROR
)
976 if (cls
!= ASN1_UNI
|| con
!= ASN1_PRI
|| tag
!= ASN1_OJI
) {
977 ret
= ASN1_ERR_WRONG_TYPE
;
981 ret
= ASN1_ERR_LENGTH_NOT_DEFINITE
;
985 ret
= asn1_oid_value_decode (asn1
, enc_len
, oid
, len
);
988 *nbytes
= asn1
->offset
- start
;
993 * NAME: asn1_sequence_decode [API]
994 * SYNOPSIS: int asn1_sequence_decode
1000 * DESCRIPTION: Decodes header for SEQUENCE.
1002 * asn1: pointer to ASN1 socket.
1003 * seq_len: length of sequence.
1004 * nbytes: number of bytes used to encode header.
1005 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
1008 asn1_sequence_decode ( ASN1_SCK
*asn1
, guint
*seq_len
, guint
*nbytes
)
1017 start
= asn1
->offset
;
1018 ret
= asn1_header_decode(asn1
, &cls
, &con
, &tag
,
1020 if (ret
!= ASN1_ERR_NOERROR
)
1022 if (cls
!= ASN1_UNI
|| con
!= ASN1_CON
|| tag
!= ASN1_SEQ
) {
1023 ret
= ASN1_ERR_WRONG_TYPE
;
1027 /* XXX - might some sequences have an indefinite length? */
1028 ret
= ASN1_ERR_LENGTH_NOT_DEFINITE
;
1031 ret
= ASN1_ERR_NOERROR
;
1034 *nbytes
= asn1
->offset
- start
;
1039 * NAME: asn1_err_to_str [API]
1040 * SYNOPSIS: const char *asn1_err_to_str
1044 * DESCRIPTION: Returns the string corresponding to an ASN.1 library error.
1046 * err: the error code
1047 * RETURNS: string for the error
1050 asn1_err_to_str(int err
)
1053 char errstrbuf
[14+1+1+11+1+1]; /* "Unknown error (%d)\0" */
1057 case ASN1_ERR_EOC_MISMATCH
:
1058 errstr
= "EOC mismatch";
1061 case ASN1_ERR_WRONG_TYPE
:
1062 errstr
= "Wrong type for that item";
1065 case ASN1_ERR_LENGTH_NOT_DEFINITE
:
1066 errstr
= "Length was indefinite";
1069 case ASN1_ERR_LENGTH_MISMATCH
:
1070 errstr
= "Length mismatch";
1073 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE
:
1074 errstr
= "Wrong length for that item's type";
1078 g_snprintf(errstrbuf
, sizeof errstrbuf
, "Unknown error (%d)", err
);
1079 errstr
= ep_strdup(errstrbuf
);