2 * Routines for ASN.1 BER dissection
4 * $Id: asn1.c,v 1.10 2002/02/21 02:05:53 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.
63 #ifdef HAVE_SYS_TYPES_H
64 # include <sys/types.h>
74 #include <epan/tvbuff.h>
78 * NAME: asn1_open [API]
79 * SYNOPSIS: void asn1_open
85 * DESCRIPTION: Opens an ASN1 socket.
87 * asn1: pointer to ASN1 socket.
88 * tvb: Tvbuff for encoding.
89 * offset: Current offset in tvbuff.
90 * Encoding starts at the end of the buffer, and
91 * proceeds to the beginning.
96 asn1_open(ASN1_SCK *asn1, tvbuff_t *tvb, int offset)
99 asn1->offset = offset;
103 * NAME: asn1_close [API]
104 * SYNOPSIS: void asn1_close
109 * DESCRIPTION: Closes an ASN1 socket.
111 * asn1: pointer to ASN1 socket.
112 * offset: pointer to variable into which current offset is
118 asn1_close(ASN1_SCK *asn1, int *offset)
120 *offset = asn1->offset;
124 * NAME: asn1_octet_decode
125 * SYNOPSIS: int asn1_octet_decode
130 * DESCRIPTION: Decodes an octet.
131 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
134 asn1_octet_decode(ASN1_SCK *asn1, guchar *ch)
136 *ch = tvb_get_guint8(asn1->tvb, asn1->offset);
138 return ASN1_ERR_NOERROR;
142 * NAME: asn1_tag_decode
143 * SYNOPSIS: int asn1_tag_decode
148 * DESCRIPTION: Decodes a tag.
149 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
152 asn1_tag_decode(ASN1_SCK *asn1, guint *tag)
159 ret = asn1_octet_decode (asn1, &ch);
160 if (ret != ASN1_ERR_NOERROR)
164 } while ((ch & 0x80) == 0x80);
165 return ASN1_ERR_NOERROR;
169 * NAME: asn1_id_decode
170 * SYNOPSIS: int asn1_id_decode
177 * DESCRIPTION: Decodes an identifier.
178 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
181 asn1_id_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag)
186 ret = asn1_octet_decode (asn1, &ch);
187 if (ret != ASN1_ERR_NOERROR)
189 *cls = (ch & 0xC0) >> 6;
190 *con = (ch & 0x20) >> 5;
193 ret = asn1_tag_decode (asn1, tag);
194 if (ret != ASN1_ERR_NOERROR)
197 return ASN1_ERR_NOERROR;
201 * NAME: asn1_length_decode
202 * SYNOPSIS: int asn1_length_decode
208 * DESCRIPTION: Decodes an ASN1 length.
210 * asn1: pointer to ASN1 socket.
211 * def: Boolean - TRUE if length definite, FALSE if not
212 * len: length, if length is definite
213 * DESCRIPTION: Decodes a definite or indefinite length.
214 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
217 asn1_length_decode(ASN1_SCK *asn1, gboolean *def, guint *len)
222 ret = asn1_octet_decode (asn1, &ch);
223 if (ret != ASN1_ERR_NOERROR)
226 *def = FALSE; /* indefinite length */
228 *def = TRUE; /* definite length */
232 cnt = (guchar) (ch & 0x7F);
235 ret = asn1_octet_decode (asn1, &ch);
236 if (ret != ASN1_ERR_NOERROR)
244 return ASN1_ERR_NOERROR;
248 * NAME: asn1_header_decode [API]
249 * SYNOPSIS: int asn1_header_decode
258 * DESCRIPTION: Decodes an ASN1 header.
260 * asn1: pointer to ASN1 socket.
261 * cls: Class (see asn1.h)
262 * con: Primitive, Constructed (ASN1_PRI, ASN1_CON)
263 * tag: Tag (see asn1.h)
264 * defp: Boolean - TRUE if length definite, FALSE if not
265 * lenp: length, if length is definite
266 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
269 asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
270 gboolean *defp, guint *lenp)
275 ret = asn1_id_decode (asn1, cls, con, tag);
276 if (ret != ASN1_ERR_NOERROR)
278 ret = asn1_length_decode (asn1, &def, &len);
279 if (ret != ASN1_ERR_NOERROR)
283 return ASN1_ERR_NOERROR;
288 * NAME: asn1_eoc [API]
289 * SYNOPSIS: gboolean asn1_eoc
294 * DESCRIPTION: Checks if decoding is at End Of Contents.
296 * asn1: pointer to ASN1 socket.
297 * eoc: offset of end of encoding, or -1 if indefinite.
298 * RETURNS: gboolean success
301 asn1_eoc ( ASN1_SCK *asn1, int eoc)
304 return (tvb_get_guint8(asn1->tvb, asn1->offset) == 0x00
305 && tvb_get_guint8(asn1->tvb, asn1->offset + 1) == 0x00);
307 return (asn1->offset >= eoc);
311 * NAME: asn1_eoc_decode [API]
312 * SYNOPSIS: int asn1_eoc_decode
317 * DESCRIPTION: Decodes End Of Contents.
319 * asn1: pointer to ASN1 socket.
320 * eoc: offset of end of encoding, or -1 if indefinite.
321 * If eoc is -1 it decodes an ASN1 End Of
322 * Contents (0x00 0x00), so it has to be an
323 * indefinite length encoding. If eoc is a non-negative
324 * integer, it probably was filled by asn1_header_decode,
325 * and should refer to the octet after the last of the encoding.
326 * It is checked if this offset refers to the octet to be
327 * decoded. This only takes place in decoding a
328 * definite length encoding.
329 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
332 asn1_eoc_decode (ASN1_SCK *asn1, int eoc)
338 ret = asn1_octet_decode (asn1, &ch);
339 if (ret != ASN1_ERR_NOERROR)
342 return ASN1_ERR_EOC_MISMATCH;
343 ret = asn1_octet_decode (asn1, &ch);
344 if (ret != ASN1_ERR_NOERROR)
347 return ASN1_ERR_EOC_MISMATCH;
348 return ASN1_ERR_NOERROR;
350 if (asn1->offset != eoc)
351 return ASN1_ERR_LENGTH_MISMATCH;
352 return ASN1_ERR_NOERROR;
357 * NAME: asn1_null_decode [API]
358 * SYNOPSIS: int asn1_null_decode
363 * DESCRIPTION: Decodes Null.
365 * asn1: pointer to ASN1 socket.
366 * enc_len: length of encoding of value.
367 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
370 asn1_null_decode ( ASN1_SCK *asn1, int enc_len)
372 asn1->offset += enc_len;
373 return ASN1_ERR_NOERROR;
377 * NAME: asn1_bool_decode [API]
378 * SYNOPSIS: int asn1_bool_decode
384 * DESCRIPTION: Decodes Boolean.
386 * asn1: pointer to ASN1 socket.
387 * enc_len: length of encoding of value.
388 * bool: False, True (0, !0).
389 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
392 asn1_bool_decode ( ASN1_SCK *asn1, int enc_len, gboolean *bool)
398 return ASN1_ERR_LENGTH_MISMATCH;
399 ret = asn1_octet_decode (asn1, &ch);
400 if (ret != ASN1_ERR_NOERROR)
402 *bool = ch ? TRUE : FALSE;
403 return ASN1_ERR_NOERROR;
407 * NAME: asn1_int32_value_decode [API]
408 * SYNOPSIS: int asn1_int32_value_decode
414 * DESCRIPTION: Decodes value portion of Integer (which must be no more
417 * asn1: pointer to ASN1 socket.
418 * enc_len: length of encoding of value.
420 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
423 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
430 eoc = asn1->offset + enc_len;
431 ret = asn1_octet_decode (asn1, &ch);
432 if (ret != ASN1_ERR_NOERROR)
434 *integer = (gint) ch;
436 while (asn1->offset < eoc) {
437 if (++len > sizeof (gint32))
438 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
439 ret = asn1_octet_decode (asn1, &ch);
440 if (ret != ASN1_ERR_NOERROR)
445 return ASN1_ERR_NOERROR;
449 * NAME: asn1_int32_decode [API]
450 * SYNOPSIS: int asn1_int32_decode
456 * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
458 * asn1: pointer to ASN1 socket.
460 * nbytes: number of bytes used to encode it.
461 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
464 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
474 start = asn1->offset;
475 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
476 if (ret != ASN1_ERR_NOERROR)
478 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
479 ret = ASN1_ERR_WRONG_TYPE;
483 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
486 ret = asn1_int32_value_decode (asn1, enc_len, integer);
489 *nbytes = asn1->offset - start;
494 * NAME: asn1_uint32_value_decode [API]
495 * SYNOPSIS: int asn1_uint32_value_decode
501 * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
502 * more than 32 bits).
504 * asn1: pointer to ASN1 socket.
505 * enc_len: length of encoding of value.
507 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
510 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint *integer)
517 eoc = asn1->offset + enc_len;
518 ret = asn1_octet_decode (asn1, &ch);
519 if (ret != ASN1_ERR_NOERROR)
526 while (asn1->offset < eoc) {
527 if (++len > sizeof (guint32))
528 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
529 ret = asn1_octet_decode (asn1, &ch);
530 if (ret != ASN1_ERR_NOERROR)
535 return ASN1_ERR_NOERROR;
539 * NAME: asn1_uint32_decode [API]
540 * SYNOPSIS: int asn1_uint32_decode
546 * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
548 * asn1: pointer to ASN1 socket.
550 * nbytes: number of bytes used to encode it.
551 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
554 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
564 start = asn1->offset;
565 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
566 if (ret != ASN1_ERR_NOERROR)
568 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
569 ret = ASN1_ERR_WRONG_TYPE;
573 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
576 ret = asn1_uint32_value_decode (asn1, enc_len, integer);
579 *nbytes = asn1->offset - start;
584 * NAME: asn1_bits_decode [API]
585 * SYNOPSIS: int asn1_bits_decode
594 * DESCRIPTION: Decodes Bit String.
596 * asn1: pointer to ASN1 socket.
597 * eoc: offset of end of encoding, or -1 if indefinite.
598 * bits: pointer to begin of Bit String.
599 * size: Size of Bit String in characters.
600 * len: Length of Bit String in characters.
601 * unused: Number of unused bits in last character.
602 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
605 asn1_bits_decode ( ASN1_SCK *asn1, int eoc, guchar **bits,
606 guint *len, guchar *unused)
612 ret = asn1_octet_decode (asn1, unused);
613 if (ret != ASN1_ERR_NOERROR)
616 *bits = g_malloc(eoc - asn1->offset);
617 while (asn1->offset < eoc) {
618 ret = asn1_octet_decode (asn1, (guchar *)bits++);
619 if (ret != ASN1_ERR_NOERROR) {
625 return ASN1_ERR_NOERROR;
629 * NAME: asn1_string_value_decode [API]
630 * SYNOPSIS: int asn1_string_value_decode
636 * DESCRIPTION: Decodes value portion of string (Octet String, various
637 * character string types)
639 * asn1: pointer to ASN1 socket.
640 * enc_len: length of encoding of value.
641 * octets: pointer to variable we set to point to string.
642 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
645 asn1_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
651 eoc = asn1->offset + enc_len;
654 * Check for an overflow, and clamp "eoc" at the maximum if we
657 if (eoc < asn1->offset || eoc < 0)
661 * First, make sure the entire string is in the tvbuff, and throw
662 * an exception if it isn't. If the length is bogus, this should
663 * keep us from trying to allocate an immensely large buffer.
664 * (It won't help if the length is *valid* but immensely large,
665 * but that's another matter.)
667 * We do that by attempting to fetch the last byte (if the length
671 tvb_get_guint8(asn1->tvb, eoc - 1);
673 *octets = g_malloc (enc_len);
675 while (asn1->offset < eoc) {
676 ret = asn1_octet_decode (asn1, (guchar *)ptr++);
677 if (ret != ASN1_ERR_NOERROR) {
683 return ASN1_ERR_NOERROR;
687 * NAME: asn1_string_decode [API]
688 * SYNOPSIS: int asn1_string_decode
696 * DESCRIPTION: Decodes string (Octet String, various character string
699 * asn1: pointer to ASN1 socket.
700 * octets: pointer to variable we set to point to string.
701 * str_len: length of octet_string.
702 * nbytes: number of bytes used to encode.
703 * expected_tag: tag expected for this type of string.
704 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
707 asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
708 guint *nbytes, guint expected_tag)
718 start = asn1->offset;
719 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
720 if (ret != ASN1_ERR_NOERROR)
722 if (cls != ASN1_UNI || con != ASN1_PRI || tag != expected_tag) {
723 /* XXX - handle the constructed encoding? */
724 ret = ASN1_ERR_WRONG_TYPE;
728 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
732 ret = asn1_string_value_decode (asn1, enc_len, octets);
736 *nbytes = asn1->offset - start;
741 * NAME: asn1_octet_string_decode [API]
742 * SYNOPSIS: int asn1_octet_string_decode
749 * DESCRIPTION: Decodes Octet String.
751 * asn1: pointer to ASN1 socket.
752 * octets: pointer to variable we set to point to string.
753 * str_len: length of octet_string.
754 * nbytes: number of bytes used to encode.
755 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
758 asn1_octet_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
761 return asn1_string_decode(asn1, octets, str_len, nbytes, ASN1_OTS);
765 * NAME: asn1_subid_decode
766 * SYNOPSIS: int asn1_subid_decode
771 * DESCRIPTION: Decodes Sub Identifier.
773 * asn1: pointer to ASN1 socket.
774 * subid: Sub Identifier.
775 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
778 asn1_subid_decode ( ASN1_SCK *asn1, subid_t *subid)
785 ret = asn1_octet_decode(asn1, &ch);
786 if (ret != ASN1_ERR_NOERROR)
790 } while ((ch & 0x80) == 0x80);
791 return ASN1_ERR_NOERROR;
795 * NAME: asn1_oid_value_decode [API]
796 * SYNOPSIS: int asn1_oid_value_decode
803 * DESCRIPTION: Decodes value portion of Object Identifier.
805 * asn1: pointer to ASN1 socket.
806 * enc_len: length of encoding of value.
807 * oid: pointer to variable we set to Object Identifier.
808 * len: Length of Object Identifier in gulongs.
809 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
812 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
820 eoc = asn1->offset + enc_len;
823 * Check for an overflow, and clamp "eoc" at the maximum if we
826 if (eoc < asn1->offset || eoc < 0)
830 * First, make sure the entire string is in the tvbuff, and throw
831 * an exception if it isn't. If the length is bogus, this should
832 * keep us from trying to allocate an immensely large buffer.
833 * (It won't help if the length is *valid* but immensely large,
834 * but that's another matter.)
836 * We do that by attempting to fetch the last byte (if the length
840 tvb_get_guint8(asn1->tvb, eoc - 1);
843 *oid = g_malloc(size * sizeof(gulong));
846 ret = asn1_subid_decode (asn1, &subid);
847 if (ret != ASN1_ERR_NOERROR) {
855 } else if (subid < 80) {
857 optr[1] = subid - 40;
860 optr[1] = subid - 80;
864 while (asn1->offset < eoc) {
865 if (++(*len) > size) {
868 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
870 ret = asn1_subid_decode (asn1, optr++);
871 if (ret != ASN1_ERR_NOERROR) {
877 return ASN1_ERR_NOERROR;
881 * NAME: asn1_oid_decode [API]
882 * SYNOPSIS: int asn1_oid_decode
889 * DESCRIPTION: Decodes Object Identifier.
891 * asn1: pointer to ASN1 socket.
892 * oid: pointer to variable we set to Object Identifier.
893 * len: Length of Object Identifier in gulongs.
894 * nbytes: number of bytes used to encode.
895 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
898 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
908 start = asn1->offset;
909 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
910 if (ret != ASN1_ERR_NOERROR)
912 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) {
913 ret = ASN1_ERR_WRONG_TYPE;
917 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
921 ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
924 *nbytes = asn1->offset - start;
929 * NAME: asn1_sequence_decode [API]
930 * SYNOPSIS: int asn1_sequence_decode
936 * DESCRIPTION: Decodes header for SEQUENCE.
938 * asn1: pointer to ASN1 socket.
939 * seq_len: length of sequence.
940 * nbytes: number of bytes used to encode header.
941 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
944 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
953 start = asn1->offset;
954 ret = asn1_header_decode(asn1, &cls, &con, &tag,
956 if (ret != ASN1_ERR_NOERROR)
958 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) {
959 ret = ASN1_ERR_WRONG_TYPE;
963 /* XXX - might some sequences have an indefinite length? */
964 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
967 ret = ASN1_ERR_NOERROR;
970 *nbytes = asn1->offset - start;