2 * Routines for ASN.1 BER dissection
4 * $Id: asn1.c,v 1.20 2003/06/24 06:05:47 guy Exp $
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;
141 * NAME: asn1_tag_decode
142 * SYNOPSIS: int asn1_tag_decode
147 * DESCRIPTION: Decodes a tag.
148 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
151 asn1_tag_decode(ASN1_SCK *asn1, guint *tag)
158 ret = asn1_octet_decode (asn1, &ch);
159 if (ret != ASN1_ERR_NOERROR)
163 } while ((ch & 0x80) == 0x80);
164 return ASN1_ERR_NOERROR;
168 * NAME: asn1_id_decode
169 * SYNOPSIS: int asn1_id_decode
176 * DESCRIPTION: Decodes an identifier.
177 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
180 asn1_id_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag)
185 ret = asn1_octet_decode (asn1, &ch);
186 if (ret != ASN1_ERR_NOERROR)
188 *cls = (ch & 0xC0) >> 6;
189 *con = (ch & 0x20) >> 5;
192 ret = asn1_tag_decode (asn1, tag);
193 if (ret != ASN1_ERR_NOERROR)
196 return ASN1_ERR_NOERROR;
200 * NAME: asn1_length_decode
201 * SYNOPSIS: int asn1_length_decode
207 * DESCRIPTION: Decodes an ASN1 length.
209 * asn1: pointer to ASN1 socket.
210 * def: Boolean - TRUE if length definite, FALSE if not
211 * len: length, if length is definite
212 * DESCRIPTION: Decodes a definite or indefinite length.
213 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
216 asn1_length_decode(ASN1_SCK *asn1, gboolean *def, guint *len)
221 ret = asn1_octet_decode (asn1, &ch);
222 if (ret != ASN1_ERR_NOERROR)
225 *def = FALSE; /* indefinite length */
227 *def = TRUE; /* definite length */
231 cnt = (guchar) (ch & 0x7F);
234 ret = asn1_octet_decode (asn1, &ch);
235 if (ret != ASN1_ERR_NOERROR)
243 return ASN1_ERR_NOERROR;
247 * NAME: asn1_header_decode [API]
248 * SYNOPSIS: int asn1_header_decode
257 * DESCRIPTION: Decodes an ASN1 header.
259 * asn1: pointer to ASN1 socket.
260 * cls: Class (see asn1.h)
261 * con: Primitive, Constructed (ASN1_PRI, ASN1_CON)
262 * tag: Tag (see asn1.h)
263 * defp: Boolean - TRUE if length definite, FALSE if not
264 * lenp: length, if length is definite
265 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
268 asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
269 gboolean *defp, guint *lenp)
274 ret = asn1_id_decode (asn1, cls, con, tag);
275 if (ret != ASN1_ERR_NOERROR)
277 ret = asn1_length_decode (asn1, &def, &len);
278 if (ret != ASN1_ERR_NOERROR)
282 return ASN1_ERR_NOERROR;
287 * NAME: asn1_eoc [API]
288 * SYNOPSIS: gboolean asn1_eoc
293 * DESCRIPTION: Checks if decoding is at End Of Contents.
295 * asn1: pointer to ASN1 socket.
296 * eoc: offset of end of encoding, or -1 if indefinite.
297 * RETURNS: gboolean success
300 asn1_eoc ( ASN1_SCK *asn1, int eoc)
303 return (tvb_get_guint8(asn1->tvb, asn1->offset) == 0x00
304 && tvb_get_guint8(asn1->tvb, asn1->offset + 1) == 0x00);
306 return (asn1->offset >= eoc);
310 * NAME: asn1_eoc_decode [API]
311 * SYNOPSIS: int asn1_eoc_decode
316 * DESCRIPTION: Decodes End Of Contents.
318 * asn1: pointer to ASN1 socket.
319 * eoc: offset of end of encoding, or -1 if indefinite.
320 * If eoc is -1 it decodes an ASN1 End Of
321 * Contents (0x00 0x00), so it has to be an
322 * indefinite length encoding. If eoc is a non-negative
323 * integer, it probably was filled by asn1_header_decode,
324 * and should refer to the octet after the last of the encoding.
325 * It is checked if this offset refers to the octet to be
326 * decoded. This only takes place in decoding a
327 * definite length encoding.
328 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
331 asn1_eoc_decode (ASN1_SCK *asn1, int eoc)
337 ret = asn1_octet_decode (asn1, &ch);
338 if (ret != ASN1_ERR_NOERROR)
341 return ASN1_ERR_EOC_MISMATCH;
342 ret = asn1_octet_decode (asn1, &ch);
343 if (ret != ASN1_ERR_NOERROR)
346 return ASN1_ERR_EOC_MISMATCH;
347 return ASN1_ERR_NOERROR;
349 if (asn1->offset != eoc)
350 return ASN1_ERR_LENGTH_MISMATCH;
351 return ASN1_ERR_NOERROR;
356 * NAME: asn1_null_decode [API]
357 * SYNOPSIS: int asn1_null_decode
362 * DESCRIPTION: Decodes Null.
364 * asn1: pointer to ASN1 socket.
365 * enc_len: length of encoding of value.
366 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
369 asn1_null_decode ( ASN1_SCK *asn1, int enc_len)
371 asn1->offset += enc_len;
372 return ASN1_ERR_NOERROR;
376 * NAME: asn1_bool_decode [API]
377 * SYNOPSIS: int asn1_bool_decode
383 * DESCRIPTION: Decodes Boolean.
385 * asn1: pointer to ASN1 socket.
386 * enc_len: length of encoding of value.
387 * bool: False, True (0, !0).
388 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
391 asn1_bool_decode ( ASN1_SCK *asn1, int enc_len, gboolean *boolean)
397 return ASN1_ERR_LENGTH_MISMATCH;
398 ret = asn1_octet_decode (asn1, &ch);
399 if (ret != ASN1_ERR_NOERROR)
401 *boolean = ch ? TRUE : FALSE;
402 return ASN1_ERR_NOERROR;
406 * NAME: asn1_int32_value_decode [API]
407 * SYNOPSIS: int asn1_int32_value_decode
413 * DESCRIPTION: Decodes value portion of Integer (which must be no more
416 * asn1: pointer to ASN1 socket.
417 * enc_len: length of encoding of value.
419 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
422 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
429 eoc = asn1->offset + enc_len;
430 ret = asn1_octet_decode (asn1, &ch);
431 if (ret != ASN1_ERR_NOERROR)
433 *integer = (gint) ch;
435 while (asn1->offset < eoc) {
436 if (++len > sizeof (gint32))
437 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
438 ret = asn1_octet_decode (asn1, &ch);
439 if (ret != ASN1_ERR_NOERROR)
444 return ASN1_ERR_NOERROR;
448 * NAME: asn1_int32_decode [API]
449 * SYNOPSIS: int asn1_int32_decode
455 * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
457 * asn1: pointer to ASN1 socket.
459 * nbytes: number of bytes used to encode it.
460 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
463 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
473 start = asn1->offset;
474 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
475 if (ret != ASN1_ERR_NOERROR)
477 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
478 ret = ASN1_ERR_WRONG_TYPE;
482 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
485 ret = asn1_int32_value_decode (asn1, enc_len, integer);
488 *nbytes = asn1->offset - start;
493 * NAME: asn1_uint32_value_decode [API]
494 * SYNOPSIS: int asn1_uint32_value_decode
500 * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
501 * more than 32 bits).
503 * asn1: pointer to ASN1 socket.
504 * enc_len: length of encoding of value.
506 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
509 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint *integer)
516 eoc = asn1->offset + enc_len;
517 ret = asn1_octet_decode (asn1, &ch);
518 if (ret != ASN1_ERR_NOERROR)
525 while (asn1->offset < eoc) {
526 if (++len > sizeof (guint32))
527 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
528 ret = asn1_octet_decode (asn1, &ch);
529 if (ret != ASN1_ERR_NOERROR)
534 return ASN1_ERR_NOERROR;
538 * NAME: asn1_uint32_decode [API]
539 * SYNOPSIS: int asn1_uint32_decode
545 * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
547 * asn1: pointer to ASN1 socket.
549 * nbytes: number of bytes used to encode it.
550 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
553 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
563 start = asn1->offset;
564 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
565 if (ret != ASN1_ERR_NOERROR)
567 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
568 ret = ASN1_ERR_WRONG_TYPE;
572 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
575 ret = asn1_uint32_value_decode (asn1, enc_len, integer);
578 *nbytes = asn1->offset - start;
583 * NAME: asn1_bits_decode [API]
584 * SYNOPSIS: int asn1_bits_decode
593 * DESCRIPTION: Decodes Bit String.
595 * asn1: pointer to ASN1 socket.
596 * enc_len: length of value.
597 * bits: pointer to variable we set to point to strring
598 * len: Size of Bit String in characters.
599 * unused: Number of unused bits in last character.
600 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
603 asn1_bits_decode ( ASN1_SCK *asn1, int enc_len, guchar **bits,
604 guint *len, guchar *unused)
610 eoc = asn1->offset + enc_len;
612 ret = asn1_octet_decode (asn1, unused);
613 if (ret != ASN1_ERR_NOERROR)
618 * First, make sure the entire string is in the tvbuff, and throw
619 * an exception if it isn't. If the length is bogus, this should
620 * keep us from trying to allocate an immensely large buffer.
621 * (It won't help if the length is *valid* but immensely large,
622 * but that's another matter; in any case, that would happen only
623 * if we had an immensely large tvbuff....)
626 tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
627 *bits = g_malloc (enc_len);
630 * If the length is 0, we allocate a 1-byte buffer, as
631 * "g_malloc()" returns NULL if passed 0 as an argument,
632 * and our caller expects us to return a pointer to a
635 *bits = g_malloc (1);
639 while (asn1->offset < eoc) {
640 ret = asn1_octet_decode (asn1, (guchar *)ptr++);
641 if (ret != ASN1_ERR_NOERROR) {
648 return ASN1_ERR_NOERROR;
652 * NAME: asn1_string_value_decode [API]
653 * SYNOPSIS: int asn1_string_value_decode
659 * DESCRIPTION: Decodes value portion of string (Octet String, various
660 * character string types)
662 * asn1: pointer to ASN1 socket.
663 * enc_len: length of encoding of value.
664 * octets: pointer to variable we set to point to string.
665 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
668 asn1_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
675 * First, make sure the entire string is in the tvbuff, and throw
676 * an exception if it isn't. If the length is bogus, this should
677 * keep us from trying to allocate an immensely large buffer.
678 * (It won't help if the length is *valid* but immensely large,
679 * but that's another matter; in any case, that would happen only
680 * if we had an immensely large tvbuff....)
683 tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
684 *octets = g_malloc (enc_len);
687 * If the length is 0, we allocate a 1-byte buffer, as
688 * "g_malloc()" returns NULL if passed 0 as an argument,
689 * and our caller expects us to return a pointer to a
692 *octets = g_malloc (1);
695 eoc = asn1->offset + enc_len;
697 while (asn1->offset < eoc) {
698 ret = asn1_octet_decode (asn1, (guchar *)ptr++);
699 if (ret != ASN1_ERR_NOERROR) {
705 return ASN1_ERR_NOERROR;
709 * NAME: asn1_string_decode [API]
710 * SYNOPSIS: int asn1_string_decode
718 * DESCRIPTION: Decodes string (Octet String, various character string
721 * asn1: pointer to ASN1 socket.
722 * octets: pointer to variable we set to point to string.
723 * str_len: length of octet_string.
724 * nbytes: number of bytes used to encode.
725 * expected_tag: tag expected for this type of string.
726 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
729 asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
730 guint *nbytes, guint expected_tag)
740 start = asn1->offset;
741 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
742 if (ret != ASN1_ERR_NOERROR)
744 if (cls != ASN1_UNI || con != ASN1_PRI || tag != expected_tag) {
745 /* XXX - handle the constructed encoding? */
746 ret = ASN1_ERR_WRONG_TYPE;
750 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
754 ret = asn1_string_value_decode (asn1, enc_len, octets);
758 *nbytes = asn1->offset - start;
763 * NAME: asn1_octet_string_decode [API]
764 * SYNOPSIS: int asn1_octet_string_decode
771 * DESCRIPTION: Decodes Octet String.
773 * asn1: pointer to ASN1 socket.
774 * octets: pointer to variable we set to point to string.
775 * str_len: length of octet_string.
776 * nbytes: number of bytes used to encode.
777 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
780 asn1_octet_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
783 return asn1_string_decode(asn1, octets, str_len, nbytes, ASN1_OTS);
787 * NAME: asn1_subid_decode
788 * SYNOPSIS: int asn1_subid_decode
793 * DESCRIPTION: Decodes Sub Identifier.
795 * asn1: pointer to ASN1 socket.
796 * subid: Sub Identifier.
797 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
800 asn1_subid_decode ( ASN1_SCK *asn1, subid_t *subid)
807 ret = asn1_octet_decode(asn1, &ch);
808 if (ret != ASN1_ERR_NOERROR)
812 } while ((ch & 0x80) == 0x80);
813 return ASN1_ERR_NOERROR;
817 * NAME: asn1_oid_value_decode [API]
818 * SYNOPSIS: int asn1_oid_value_decode
825 * DESCRIPTION: Decodes value portion of Object Identifier.
827 * asn1: pointer to ASN1 socket.
828 * enc_len: length of encoding of value.
829 * oid: pointer to variable we set to Object Identifier.
830 * len: Length of Object Identifier in gulongs.
831 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
834 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
843 * First, make sure the entire string is in the tvbuff, and throw
844 * an exception if it isn't. If the length is bogus, this should
845 * keep us from trying to allocate an immensely large buffer.
846 * (It won't help if the length is *valid* but immensely large,
847 * but that's another matter; in any case, that would happen only
848 * if we had an immensely large tvbuff....)
851 tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
853 eoc = asn1->offset + enc_len;
856 *oid = g_malloc(size * sizeof(gulong));
859 ret = asn1_subid_decode (asn1, &subid);
860 if (ret != ASN1_ERR_NOERROR) {
868 } else if (subid < 80) {
870 optr[1] = subid - 40;
873 optr[1] = subid - 80;
877 while (asn1->offset < eoc) {
878 if (++(*len) > size) {
881 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
883 ret = asn1_subid_decode (asn1, optr++);
884 if (ret != ASN1_ERR_NOERROR) {
890 return ASN1_ERR_NOERROR;
894 * NAME: asn1_oid_decode [API]
895 * SYNOPSIS: int asn1_oid_decode
902 * DESCRIPTION: Decodes Object Identifier.
904 * asn1: pointer to ASN1 socket.
905 * oid: pointer to variable we set to Object Identifier.
906 * len: Length of Object Identifier in gulongs.
907 * nbytes: number of bytes used to encode.
908 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
911 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
921 start = asn1->offset;
922 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
923 if (ret != ASN1_ERR_NOERROR)
925 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) {
926 ret = ASN1_ERR_WRONG_TYPE;
930 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
934 ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
937 *nbytes = asn1->offset - start;
942 * NAME: asn1_sequence_decode [API]
943 * SYNOPSIS: int asn1_sequence_decode
949 * DESCRIPTION: Decodes header for SEQUENCE.
951 * asn1: pointer to ASN1 socket.
952 * seq_len: length of sequence.
953 * nbytes: number of bytes used to encode header.
954 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
957 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
966 start = asn1->offset;
967 ret = asn1_header_decode(asn1, &cls, &con, &tag,
969 if (ret != ASN1_ERR_NOERROR)
971 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) {
972 ret = ASN1_ERR_WRONG_TYPE;
976 /* XXX - might some sequences have an indefinite length? */
977 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
980 ret = ASN1_ERR_NOERROR;
983 *nbytes = asn1->offset - start;
988 * NAME: asn1_err_to_str [API]
989 * SYNOPSIS: char *asn1_err_to_str
993 * DESCRIPTION: Returns the string corresponding to an ASN.1 library error.
995 * err: the error code
996 * RETURNS: string for the error
999 asn1_err_to_str(int err)
1002 char errstrbuf[14+1+1+11+1+1]; /* "Unknown error (%d)\0" */
1006 case ASN1_ERR_EOC_MISMATCH:
1007 errstr = "EOC mismatch";
1010 case ASN1_ERR_WRONG_TYPE:
1011 errstr = "Wrong type for that item";
1014 case ASN1_ERR_LENGTH_NOT_DEFINITE:
1015 errstr = "Length was indefinite";
1018 case ASN1_ERR_LENGTH_MISMATCH:
1019 errstr = "Length mismatch";
1022 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
1023 errstr = "Wrong length for that item's type";
1027 snprintf(errstrbuf, sizeof errstrbuf, "Unknown error (%d)", err);