2 * Routines for ASN.1 BER dissection
4 * $Id: asn1.c,v 1.3 2000/01/15 00:22:29 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.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., 675 Mass Ave, Cambridge, MA 02139, USA.
35 * SYSTEM NAME: ASN1 Basic Encoding
36 * ORIGINAL AUTHOR(S): Dirk Wisse
38 * CREATION DATE: 1990/11/22
40 * DESCRIPTION: ASN1 Basic Encoding Rules.
42 * To decode this we must do:
44 * asn1_open (asn1, buf_start, buf_len);
45 * asn1_header_decode (asn1, &end_of_seq, cls, con, tag, def, len);
46 * asn1_header_decode (asn1, &end_of_octs, cls, con, tag, def, len);
47 * asn1_octets_decode (asn1, end_of_octs, str, len);
48 * asn1_header_decode (asn1, &end_of_int, cls, con, tag);
49 * asn1_int_decode (asn1, end_of_int, &integer);
50 * asn1_eoc_decode (asn1, end_of_seq);
51 * asn1_close (asn1, &buf_start, &buf_len);
53 * For indefinite encoding end_of_seq and &end_of_seq in the
54 * example above should be replaced by NULL.
55 * For indefinite decoding nothing has to be changed.
56 * This can be very useful if you want to decode both
57 * definite and indefinite encodings.
64 #ifdef HAVE_SYS_TYPES_H
65 # include <sys/types.h>
76 * NAME: asn1_open [API]
77 * SYNOPSIS: void asn1_open
83 * DESCRIPTION: Opens an ASN1 socket.
85 * asn1: pointer to ASN1 socket.
86 * buf: Character buffer for encoding.
87 * len: Length of character buffer.
88 * Encoding starts at the end of the buffer, and
89 * proceeds to the beginning.
94 asn1_open(ASN1_SCK *asn1, const guchar *buf, guint len)
97 asn1->end = buf + len;
102 * NAME: asn1_close [API]
103 * SYNOPSIS: void asn1_close
109 * DESCRIPTION: Closes an ASN1 socket.
111 * asn1: pointer to ASN1 socket.
112 * buf: pointer to beginning of encoding.
113 * len: Length of encoding.
118 asn1_close(ASN1_SCK *asn1, const guchar **buf, guint *len)
120 *buf = asn1->pointer;
121 *len = asn1->end - asn1->pointer;
125 * NAME: asn1_octet_decode
126 * SYNOPSIS: int asn1_octet_decode
131 * DESCRIPTION: Decodes an octet.
132 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
135 asn1_octet_decode(ASN1_SCK *asn1, guchar *ch)
137 if (asn1->pointer >= asn1->end)
138 return ASN1_ERR_EMPTY;
139 *ch = *(asn1->pointer)++;
140 return ASN1_ERR_NOERROR;
144 * NAME: asn1_tag_decode
145 * SYNOPSIS: int asn1_tag_decode
150 * DESCRIPTION: Decodes a tag.
151 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
154 asn1_tag_decode(ASN1_SCK *asn1, guint *tag)
161 ret = asn1_octet_decode (asn1, &ch);
162 if (ret != ASN1_ERR_NOERROR)
166 } while ((ch & 0x80) == 0x80);
167 return ASN1_ERR_NOERROR;
171 * NAME: asn1_id_decode
172 * SYNOPSIS: int asn1_id_decode
179 * DESCRIPTION: Decodes an identifier.
180 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
183 asn1_id_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag)
188 ret = asn1_octet_decode (asn1, &ch);
189 if (ret != ASN1_ERR_NOERROR)
191 *cls = (ch & 0xC0) >> 6;
192 *con = (ch & 0x20) >> 5;
195 ret = asn1_tag_decode (asn1, tag);
196 if (ret != ASN1_ERR_NOERROR)
199 return ASN1_ERR_NOERROR;
203 * NAME: asn1_length_decode
204 * SYNOPSIS: int asn1_length_decode
210 * DESCRIPTION: Decodes an ASN1 length.
212 * asn1: pointer to ASN1 socket.
213 * def: Boolean - TRUE if length definite, FALSE if not
214 * len: length, if length is definite
215 * DESCRIPTION: Decodes a definite or indefinite length.
216 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
219 asn1_length_decode(ASN1_SCK *asn1, gboolean *def, guint *len)
224 ret = asn1_octet_decode (asn1, &ch);
225 if (ret != ASN1_ERR_NOERROR)
228 *def = FALSE; /* indefinite length */
230 *def = TRUE; /* definite length */
234 cnt = (guchar) (ch & 0x7F);
237 ret = asn1_octet_decode (asn1, &ch);
238 if (ret != ASN1_ERR_NOERROR)
246 return ASN1_ERR_NOERROR;
250 * NAME: asn1_header_decode [API]
251 * SYNOPSIS: int asn1_header_decode
260 * DESCRIPTION: Decodes an ASN1 header.
262 * asn1: pointer to ASN1 socket.
263 * cls: Class (see asn1.h)
264 * con: Primitive, Constructed (ASN1_PRI, ASN1_CON)
265 * tag: Tag (see asn1.h)
266 * defp: Boolean - TRUE if length definite, FALSE if not
267 * lenp: length, if length is definite
268 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
271 asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
272 gboolean *defp, guint *lenp)
277 ret = asn1_id_decode (asn1, cls, con, tag);
278 if (ret != ASN1_ERR_NOERROR)
280 ret = asn1_length_decode (asn1, &def, &len);
281 if (ret != ASN1_ERR_NOERROR)
285 return ASN1_ERR_NOERROR;
290 * NAME: asn1_eoc [API]
291 * SYNOPSIS: gboolean asn1_eoc
296 * DESCRIPTION: Checks if decoding is at End Of Contents.
298 * asn1: pointer to ASN1 socket.
299 * eoc: pointer to end of encoding or 0 if
301 * RETURNS: gboolean success
304 asn1_eoc ( ASN1_SCK *asn1, const guchar *eoc)
307 return (asn1->pointer [0] == 0x00 && asn1->pointer [1] == 0x00);
309 return (asn1->pointer >= eoc);
313 * NAME: asn1_eoc_decode [API]
314 * SYNOPSIS: int asn1_eoc_decode
319 * DESCRIPTION: Decodes End Of Contents.
321 * asn1: pointer to ASN1 socket.
322 * eoc: pointer to end of encoding or 0 if
324 * If eoc is 0 it decodes an ASN1 End Of
325 * Contents (0x00 0x00), so it has to be an
326 * indefinite length encoding. If eoc is a
327 * character pointer, it probably was filled by
328 * asn1_header_decode, and should point to the octet
329 * after the last of the encoding. It is checked
330 * if this pointer points to the octet to be
331 * decoded. This only takes place in decoding a
332 * definite length encoding.
333 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
336 asn1_eoc_decode (ASN1_SCK *asn1, const guchar *eoc)
342 ret = asn1_octet_decode (asn1, &ch);
343 if (ret != ASN1_ERR_NOERROR)
346 return ASN1_ERR_EOC_MISMATCH;
347 ret = asn1_octet_decode (asn1, &ch);
348 if (ret != ASN1_ERR_NOERROR)
351 return ASN1_ERR_EOC_MISMATCH;
352 return ASN1_ERR_NOERROR;
354 if (asn1->pointer != eoc)
355 return ASN1_ERR_LENGTH_MISMATCH;
356 return ASN1_ERR_NOERROR;
361 * NAME: asn1_null_decode [API]
362 * SYNOPSIS: int asn1_null_decode
367 * DESCRIPTION: Decodes Null.
369 * asn1: pointer to ASN1 socket.
370 * enc_len: length of encoding of value.
371 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
374 asn1_null_decode ( ASN1_SCK *asn1, int enc_len)
376 asn1->pointer += enc_len;
377 return ASN1_ERR_NOERROR;
381 * NAME: asn1_bool_decode [API]
382 * SYNOPSIS: int asn1_bool_decode
388 * DESCRIPTION: Decodes Boolean.
390 * asn1: pointer to ASN1 socket.
391 * enc_len: length of encoding of value.
392 * bool: False, True (0, !0).
393 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
396 asn1_bool_decode ( ASN1_SCK *asn1, int enc_len, gboolean *bool)
402 return ASN1_ERR_LENGTH_MISMATCH;
403 ret = asn1_octet_decode (asn1, &ch);
404 if (ret != ASN1_ERR_NOERROR)
406 *bool = ch ? TRUE : FALSE;
407 return ASN1_ERR_NOERROR;
411 * NAME: asn1_int32_value_decode [API]
412 * SYNOPSIS: int asn1_int32_value_decode
418 * DESCRIPTION: Decodes value portion of Integer (which must be no more
421 * asn1: pointer to ASN1 socket.
422 * enc_len: length of encoding of value.
424 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
427 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
434 eoc = asn1->pointer + enc_len;
435 ret = asn1_octet_decode (asn1, &ch);
436 if (ret != ASN1_ERR_NOERROR)
438 *integer = (gint) ch;
440 while (asn1->pointer < eoc) {
441 if (++len > sizeof (gint32))
442 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
443 ret = asn1_octet_decode (asn1, &ch);
444 if (ret != ASN1_ERR_NOERROR)
449 return ASN1_ERR_NOERROR;
453 * NAME: asn1_int32_decode [API]
454 * SYNOPSIS: int asn1_int32_decode
460 * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
462 * asn1: pointer to ASN1 socket.
464 * nbytes: number of bytes used to encode it.
465 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
468 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
478 start = asn1->pointer;
479 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
480 if (ret != ASN1_ERR_NOERROR)
482 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
483 ret = ASN1_ERR_WRONG_TYPE;
487 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
490 ret = asn1_int32_value_decode (asn1, enc_len, integer);
493 *nbytes = asn1->pointer - start;
498 * NAME: asn1_uint32_value_decode [API]
499 * SYNOPSIS: int asn1_uint32_value_decode
505 * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
506 * more than 32 bits).
508 * asn1: pointer to ASN1 socket.
509 * enc_len: length of encoding of value.
511 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
514 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint *integer)
521 eoc = asn1->pointer + enc_len;
522 ret = asn1_octet_decode (asn1, &ch);
523 if (ret != ASN1_ERR_NOERROR)
530 while (asn1->pointer < eoc) {
531 if (++len > sizeof (guint32))
532 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
533 ret = asn1_octet_decode (asn1, &ch);
534 if (ret != ASN1_ERR_NOERROR)
539 return ASN1_ERR_NOERROR;
543 * NAME: asn1_uint32_decode [API]
544 * SYNOPSIS: int asn1_uint32_decode
550 * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
552 * asn1: pointer to ASN1 socket.
554 * nbytes: number of bytes used to encode it.
555 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
558 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
568 start = asn1->pointer;
569 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
570 if (ret != ASN1_ERR_NOERROR)
572 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
573 ret = ASN1_ERR_WRONG_TYPE;
577 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
580 ret = asn1_uint32_value_decode (asn1, enc_len, integer);
583 *nbytes = asn1->pointer - start;
588 * NAME: asn1_bits_decode [API]
589 * SYNOPSIS: int asn1_bits_decode
598 * DESCRIPTION: Decodes Bit String.
600 * asn1: pointer to ASN1 socket.
601 * eoc: pointer to end of encoding or 0 if
603 * bits: pointer to begin of Bit String.
604 * size: Size of Bit String in characters.
605 * len: Length of Bit String in characters.
606 * unused: Number of unused bits in last character.
607 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
610 asn1_bits_decode ( ASN1_SCK *asn1, const guchar *eoc, guchar **bits,
611 guint *len, guchar *unused)
617 ret = asn1_octet_decode (asn1, unused);
618 if (ret != ASN1_ERR_NOERROR)
621 *bits = g_malloc(eoc - asn1->pointer);
622 while (asn1->pointer < eoc) {
623 ret = asn1_octet_decode (asn1, (guchar *)bits++);
624 if (ret != ASN1_ERR_NOERROR) {
630 return ASN1_ERR_NOERROR;
634 * NAME: asn1_octet_string_value_decode [API]
635 * SYNOPSIS: int asn1_octet_string_value_decode
641 * DESCRIPTION: Decodes value portion of Octet String.
643 * asn1: pointer to ASN1 socket.
644 * enc_len: length of encoding of value.
645 * octets: pointer to variable we set to point to string.
646 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
649 asn1_octet_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
655 eoc = asn1->pointer + enc_len;
656 *octets = g_malloc (enc_len);
658 while (asn1->pointer < eoc) {
659 ret = asn1_octet_decode (asn1, (guchar *)ptr++);
660 if (ret != ASN1_ERR_NOERROR) {
666 return ASN1_ERR_NOERROR;
670 * NAME: asn1_octet_string_decode [API]
671 * SYNOPSIS: int asn1_octet_string_decode
678 * DESCRIPTION: Decodes Octet String.
680 * asn1: pointer to ASN1 socket.
681 * octets: pointer to variable we set to point to string.
682 * str_len: length of octet_string.
683 * nbytes: number of bytes used to encode.
684 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
687 asn1_octet_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
698 start = asn1->pointer;
699 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
700 if (ret != ASN1_ERR_NOERROR)
702 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OTS) {
703 ret = ASN1_ERR_WRONG_TYPE;
707 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
711 ret = asn1_octet_string_value_decode (asn1, enc_len, octets);
715 *nbytes = asn1->pointer - start;
720 * NAME: asn1_subid_decode
721 * SYNOPSIS: int asn1_subid_decode
726 * DESCRIPTION: Decodes Sub Identifier.
728 * asn1: pointer to ASN1 socket.
729 * subid: Sub Identifier.
730 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
733 asn1_subid_decode ( ASN1_SCK *asn1, subid_t *subid)
740 ret = asn1_octet_decode(asn1, &ch);
741 if (ret != ASN1_ERR_NOERROR)
745 } while ((ch & 0x80) == 0x80);
746 return ASN1_ERR_NOERROR;
750 * NAME: asn1_oid_value_decode [API]
751 * SYNOPSIS: int asn1_oid_value_decode
758 * DESCRIPTION: Decodes value portion of Object Identifier.
760 * asn1: pointer to ASN1 socket.
761 * enc_len: length of encoding of value.
762 * oid: pointer to variable we set to Object Identifier.
763 * len: Length of Object Identifier in gulongs.
764 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
767 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
775 eoc = asn1->pointer + enc_len;
776 size = eoc - asn1->pointer + 1;
777 *oid = g_malloc(size * sizeof(gulong));
780 ret = asn1_subid_decode (asn1, &subid);
781 if (ret != ASN1_ERR_NOERROR) {
789 } else if (subid < 80) {
791 optr[1] = subid - 40;
794 optr[1] = subid - 80;
798 while (asn1->pointer < eoc) {
799 if (++(*len) > size) {
802 return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
804 ret = asn1_subid_decode (asn1, optr++);
805 if (ret != ASN1_ERR_NOERROR) {
811 return ASN1_ERR_NOERROR;
815 * NAME: asn1_oid_decode [API]
816 * SYNOPSIS: int asn1_oid_decode
823 * DESCRIPTION: Decodes Object Identifier.
825 * asn1: pointer to ASN1 socket.
826 * oid: pointer to variable we set to Object Identifier.
827 * len: Length of Object Identifier in gulongs.
828 * nbytes: number of bytes used to encode.
829 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
832 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
842 start = asn1->pointer;
843 ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
844 if (ret != ASN1_ERR_NOERROR)
846 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) {
847 ret = ASN1_ERR_WRONG_TYPE;
851 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
855 ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
858 *nbytes = asn1->pointer - start;
863 * NAME: asn1_sequence_decode [API]
864 * SYNOPSIS: int asn1_sequence_decode
870 * DESCRIPTION: Decodes header for SEQUENCE.
872 * asn1: pointer to ASN1 socket.
873 * seq_len: length of sequence.
874 * nbytes: number of bytes used to encode header.
875 * RETURNS: ASN1_ERR value (ASN1_ERR_NOERROR on success)
878 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
887 start = asn1->pointer;
888 ret = asn1_header_decode(asn1, &cls, &con, &tag,
890 if (ret != ASN1_ERR_NOERROR)
892 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) {
893 ret = ASN1_ERR_WRONG_TYPE;
897 /* XXX - might some sequences have an indefinite length? */
898 ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
901 ret = ASN1_ERR_NOERROR;
904 *nbytes = asn1->pointer - start;