From Albert Chin: get rid of C99/GCCisms (initializing automatic
[obnox/wireshark/wip.git] / asn1.c
1 /* asn1.c
2  * Routines for ASN.1 BER dissection
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  *
9  * Based on "g_asn1.c" from:
10  *
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
14  *
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.
19  *
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.
24  *
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.
28  */
29
30 /*
31  * MODULE INFORMATION
32  * ------------------
33  *     FILE     NAME:       g_asn1.c
34  *     SYSTEM   NAME:       ASN1 Basic Encoding
35  *     ORIGINAL AUTHOR(S):  Dirk Wisse
36  *     VERSION  NUMBER:     1
37  *     CREATION DATE:       1990/11/22
38  *
39  * DESCRIPTION: ASN1 Basic Encoding Rules.
40  *
41  *              To decode this we must do:
42  *
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);
51  *
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.
57  */
58
59 #ifdef HAVE_CONFIG_H
60 # include "config.h"
61 #endif
62
63 #include <stdio.h>
64
65 #include <limits.h>
66
67 #include <glib.h>
68
69 #ifdef NEED_SNPRINTF_H
70 # include "snprintf.h"
71 #endif
72
73 #include <epan/tvbuff.h>
74 #include "asn1.h"
75
76 /*
77  * NAME:        asn1_open                                   [API]
78  * SYNOPSIS:    void asn1_open
79  *                  (
80  *                      ASN1_SCK *asn1,
81  *                      tvbuff_t *tvb,
82  *                      int       offset
83  *                  )
84  * DESCRIPTION: Opens an ASN1 socket.
85  *              Parameters:
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.
91  * RETURNS:     void
92  */
93
94 void
95 asn1_open(ASN1_SCK *asn1, tvbuff_t *tvb, int offset)
96 {
97     asn1->tvb = tvb;
98     asn1->offset = offset;
99 }
100
101 /*
102  * NAME:        asn1_close                                  [API]
103  * SYNOPSIS:    void asn1_close
104  *                  (
105  *                      ASN1_SCK   *asn1,
106  *                      int        *offset
107  *                  )
108  * DESCRIPTION: Closes an ASN1 socket.
109  *              Parameters:
110  *              asn1:   pointer to ASN1 socket.
111  *              offset: pointer to variable into which current offset is
112  *              to be put.
113  * RETURNS:     void
114  */
115
116 void
117 asn1_close(ASN1_SCK *asn1, int *offset)
118 {
119     *offset = asn1->offset;
120 }
121
122 /*
123  * NAME:        asn1_octet_decode
124  * SYNOPSIS:    int asn1_octet_decode
125  *                  (
126  *                      ASN1_SCK *asn1,
127  *                      guchar   *ch
128  *                  )
129  * DESCRIPTION: Decodes an octet.
130  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
131  */
132 int
133 asn1_octet_decode(ASN1_SCK *asn1, guchar *ch)
134 {
135     *ch = tvb_get_guint8(asn1->tvb, asn1->offset);
136     asn1->offset++;
137     return ASN1_ERR_NOERROR;
138 }
139
140 /*
141  * NAME:        asn1_tag_get
142  * SYNOPSIS:    int asn1_tag_get
143  *                  (
144  *                      ASN1_SCK *asn1,
145  *                      guint    *tag
146  *                  )
147  * DESCRIPTION: Decodes a tag number, combining it with existing tag bits.
148  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
149  */
150 static int
151 asn1_tag_get(ASN1_SCK *asn1, guint *tag)
152 {
153     int    ret;
154     guchar ch;
155
156     do {
157         ret = asn1_octet_decode (asn1, &ch);
158         if (ret != ASN1_ERR_NOERROR)
159             return ret;
160         *tag <<= 7;
161         *tag |= ch & 0x7F;
162     } while ((ch & 0x80) == 0x80);
163     return ASN1_ERR_NOERROR;
164 }
165
166 /*
167  * NAME:        asn1_tag_decode
168  * SYNOPSIS:    int asn1_tag_decode
169  *                  (
170  *                      ASN1_SCK *asn1,
171  *                      guint    *tag
172  *                  )
173  * DESCRIPTION: Decodes a tag number.
174  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
175  */
176 int
177 asn1_tag_decode(ASN1_SCK *asn1, guint *tag)
178 {
179     *tag = 0;
180     return asn1_tag_get(asn1, tag);
181 }
182
183 /*
184  * NAME:        asn1_id_decode
185  * SYNOPSIS:    int asn1_id_decode
186  *                  (
187  *                      ASN1_SCK *asn1,
188  *                      guint    *cls,
189  *                      guint    *con,
190  *                      guint    *tag
191  *                  )
192  * DESCRIPTION: Decodes an identifier.
193  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
194  */
195 int
196 asn1_id_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag)
197 {
198     int    ret;
199     guchar ch;
200
201     *tag = 0;
202     ret = asn1_octet_decode (asn1, &ch);
203     if (ret != ASN1_ERR_NOERROR)
204         return ret;
205     *cls = (ch & 0xC0) >> 6;
206     *con = (ch & 0x20) >> 5;
207     *tag = (ch & 0x1F);
208     if (*tag == 0x1F) {
209         ret = asn1_tag_decode (asn1, tag);
210         if (ret != ASN1_ERR_NOERROR)
211             return ret;
212     }
213     return ASN1_ERR_NOERROR;
214 }
215
216 /*
217  * NAME:        asn1_id_decode1
218  * SYNOPSIS:    int asn1_id_decode1
219  *                  (
220  *                      ASN1_SCK *asn1,
221  *                      guint    *tag
222  *                  )
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)
227  */
228 int
229 asn1_id_decode1(ASN1_SCK *asn1, guint *tag)
230 {
231     int    ret;
232     guchar ch;
233
234     *tag = 0;
235     ret = asn1_octet_decode (asn1, &ch);
236     if (ret != ASN1_ERR_NOERROR)
237         return ret;
238
239     *tag = ch;
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)
244             return ret;
245     }
246     return ASN1_ERR_NOERROR;
247 }
248
249 /*
250  * NAME:        asn1_length_decode
251  * SYNOPSIS:    int asn1_length_decode
252  *                  (
253  *                      ASN1_SCK *asn1,
254  *                      gboolean *def,
255  *                      guint    *len
256  *                  )
257  * DESCRIPTION: Decodes an ASN1 length.
258  *              Parameters:
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)
264  */
265 int
266 asn1_length_decode(ASN1_SCK *asn1, gboolean *def, guint *len)
267 {
268     int    ret;
269     guchar ch, cnt;
270
271     ret = asn1_octet_decode (asn1, &ch);
272     if (ret != ASN1_ERR_NOERROR)
273         return ret;
274     if (ch == 0x80)
275         *def = FALSE;           /* indefinite length */
276     else {
277         *def = TRUE;            /* definite length */
278         if (ch < 0x80)
279             *len = ch;
280         else {
281             cnt = (guchar) (ch & 0x7F);
282             *len = 0;
283             while (cnt > 0) {
284                 ret = asn1_octet_decode (asn1, &ch);
285                 if (ret != ASN1_ERR_NOERROR)
286                     return ret;
287                 *len <<= 8;
288                 *len |= ch;
289                 cnt--;
290             }
291         }
292     }
293     return ASN1_ERR_NOERROR;
294 }
295
296 /*
297  * NAME:        asn1_header_decode                                [API]
298  * SYNOPSIS:    int asn1_header_decode
299  *                  (
300  *                      ASN1_SCK *asn1,
301  *                      guint    *cls,
302  *                      guint    *con,
303  *                      guint    *tag
304  *                      gboolean *defp,
305  *                      guint    *lenp
306  *                  )
307  * DESCRIPTION: Decodes an ASN1 header.
308  *              Parameters:
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)
316  */
317 int
318 asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
319                         gboolean *defp, guint *lenp)
320 {
321     int   ret;
322     guint def, len;
323
324     ret = asn1_id_decode (asn1, cls, con, tag);
325     if (ret != ASN1_ERR_NOERROR)
326         return ret;
327     ret = asn1_length_decode (asn1, &def, &len);
328     if (ret != ASN1_ERR_NOERROR)
329         return ret;
330     *defp = def;
331     *lenp = len;
332     return ASN1_ERR_NOERROR;
333 }
334
335
336 /*
337  * NAME:        asn1_eoc                                   [API]
338  * SYNOPSIS:    gboolean asn1_eoc
339  *                  (
340  *                      ASN1_SCK *asn1,
341  *                      int       eoc
342  *                  )
343  * DESCRIPTION: Checks if decoding is at End Of Contents.
344  *              Parameters:
345  *              asn1: pointer to ASN1 socket.
346  *              eoc: offset of end of encoding, or -1 if indefinite.
347  * RETURNS:     gboolean success
348  */
349 gboolean
350 asn1_eoc ( ASN1_SCK *asn1, int eoc)
351 {
352     if (eoc == -1)
353         return (tvb_get_guint8(asn1->tvb, asn1->offset) == 0x00
354                 && tvb_get_guint8(asn1->tvb, asn1->offset + 1) == 0x00);
355     else
356         return (asn1->offset >= eoc);
357 }
358
359 /*
360  * NAME:        asn1_eoc_decode                                [API]
361  * SYNOPSIS:    int asn1_eoc_decode
362  *                  (
363  *                      ASN1_SCK  *asn1,
364  *                      int       eoc
365  *                  )
366  * DESCRIPTION: Decodes End Of Contents.
367  *              Parameters:
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)
379  */
380 int
381 asn1_eoc_decode (ASN1_SCK *asn1, int eoc)
382 {
383     int    ret;
384     guchar ch;
385
386     if (eoc == -1) {
387         ret = asn1_octet_decode (asn1, &ch);
388         if (ret != ASN1_ERR_NOERROR)
389             return ret;
390       if (ch != 0x00)
391         return ASN1_ERR_EOC_MISMATCH;
392       ret = asn1_octet_decode (asn1, &ch);
393       if (ret != ASN1_ERR_NOERROR)
394         return ret;
395       if (ch != 0x00)
396         return ASN1_ERR_EOC_MISMATCH;
397       return ASN1_ERR_NOERROR;
398   } else {
399       if (asn1->offset != eoc)
400         return ASN1_ERR_LENGTH_MISMATCH;
401       return ASN1_ERR_NOERROR;
402     }
403 }
404
405 /*
406  * NAME:        asn1_null_decode                                [API]
407  * SYNOPSIS:    int asn1_null_decode
408  *                  (
409  *                      ASN1_SCK *asn1,
410  *                      int      enc_len
411  *                  )
412  * DESCRIPTION: Decodes Null.
413  *              Parameters:
414  *              asn1:    pointer to ASN1 socket.
415  *              enc_len: length of encoding of value.
416  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
417  */
418 int
419 asn1_null_decode ( ASN1_SCK *asn1, int enc_len)
420 {
421     int start_off = asn1->offset;
422
423     asn1->offset += enc_len;
424     /*
425      * Check for integer overflows.  
426      * XXX - ASN1_ERR_LENGTH_MISMATCH seemed like the most appropriate
427      *       error from the ones available.  Should we make a new one?
428      */
429     if (asn1->offset < 0 || asn1->offset < start_off)
430         return ASN1_ERR_LENGTH_MISMATCH;
431
432     return ASN1_ERR_NOERROR;
433 }
434
435 /*
436  * NAME:        asn1_bool_decode                                [API]
437  * SYNOPSIS:    int asn1_bool_decode
438  *                  (
439  *                      ASN1_SCK *asn1,
440  *                      int      enc_len,
441  *                      gboolean *boolean
442  *                  )
443  * DESCRIPTION: Decodes Boolean.
444  *              Parameters:
445  *              asn1:    pointer to ASN1 socket.
446  *              enc_len: length of encoding of value.
447  *              bool:    False, True (0, !0).
448  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
449  */
450 int
451 asn1_bool_decode ( ASN1_SCK *asn1, int enc_len, gboolean *boolean)
452 {
453     int    ret;
454     guchar ch;
455
456     if (enc_len != 1)
457       return ASN1_ERR_LENGTH_MISMATCH;
458     ret = asn1_octet_decode (asn1, &ch);
459     if (ret != ASN1_ERR_NOERROR)
460         return ret;
461     *boolean = ch ? TRUE : FALSE;
462     return ASN1_ERR_NOERROR;
463 }
464
465 /*
466  * NAME:        asn1_int32_value_decode                                [API]
467  * SYNOPSIS:    int asn1_int32_value_decode
468  *                  (
469  *                      ASN1_SCK *asn1,
470  *                      int      enc_len,
471  *                      gint32   *integer
472  *                  )
473  * DESCRIPTION: Decodes value portion of Integer (which must be no more
474  *              than 32 bits).
475  *              Parameters:
476  *              asn1:    pointer to ASN1 socket.
477  *              enc_len: length of encoding of value.
478  *              integer: Integer.
479  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
480  */
481 int
482 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
483 {
484     int          ret;
485     int          eoc;
486     guchar       ch;
487     guint        len;
488
489     eoc = asn1->offset + enc_len;
490     ret = asn1_octet_decode (asn1, &ch);
491     if (ret != ASN1_ERR_NOERROR)
492         return ret;
493     *integer = (gint) ch;
494     len = 1;
495     while (asn1->offset < eoc) {
496         if (++len > sizeof (gint32))
497             return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
498         ret = asn1_octet_decode (asn1, &ch);
499         if (ret != ASN1_ERR_NOERROR)
500             return ret;
501         *integer <<= 8;
502         *integer |= ch;
503     }
504     return ASN1_ERR_NOERROR;
505 }
506
507 /*
508  * NAME:        asn1_int32_decode                                [API]
509  * SYNOPSIS:    int asn1_int32_decode
510  *                  (
511  *                      ASN1_SCK *asn1,
512  *                      gint32   *integer,
513  *                      guint    *nbytes,
514  *                  )
515  * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
516  *              Parameters:
517  *              asn1:    pointer to ASN1 socket.
518  *              integer: Integer.
519  *              nbytes:  number of bytes used to encode it.
520  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
521  */
522 int
523 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
524 {
525     int          ret;
526     int          start;
527     guint        cls;
528     guint        con;
529     guint        tag;
530     gboolean     def;
531     guint        enc_len;
532
533     start = asn1->offset;
534     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
535     if (ret != ASN1_ERR_NOERROR)
536         goto done;
537     if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
538         ret = ASN1_ERR_WRONG_TYPE;
539         goto done;
540     }
541     if (!def) {
542         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
543         goto done;
544     }
545     ret = asn1_int32_value_decode (asn1, enc_len, integer);
546
547 done:
548     *nbytes = asn1->offset - start;
549     return ret;
550 }
551
552 /*
553  * NAME:        asn1_uint32_value_decode                             [API]
554  * SYNOPSIS:    int asn1_uint32_value_decode
555  *                  (
556  *                      ASN1_SCK *asn1,
557  *                      int      enc_len,
558  *                      guint32  *integer
559  *                  )
560  * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
561  *              more than 32 bits).
562  *              Parameters:
563  *              asn1:    pointer to ASN1 socket.
564  *              enc_len: length of encoding of value.
565  *              integer: Integer.
566  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
567  */
568 int
569 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint32 *integer)
570 {
571     int          ret;
572     int          eoc;
573     guchar       ch;
574     guint        len;
575
576     eoc = asn1->offset + enc_len;
577     ret = asn1_octet_decode (asn1, &ch);
578     if (ret != ASN1_ERR_NOERROR)
579         return ret;
580     *integer = ch;
581     if (ch == 0)
582         len = 0;
583     else
584         len = 1;
585     while (asn1->offset < eoc) {
586         if (++len > sizeof (guint32))
587             return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
588         ret = asn1_octet_decode (asn1, &ch);
589         if (ret != ASN1_ERR_NOERROR)
590             return ret;
591         *integer <<= 8;
592         *integer |= ch;
593     }
594     return ASN1_ERR_NOERROR;
595 }
596
597 /*
598  * NAME:        asn1_uint32_decode                             [API]
599  * SYNOPSIS:    int asn1_uint32_decode
600  *                  (
601  *                      ASN1_SCK *asn1,
602  *                      guint32  *integer,
603  *                      guint    *nbytes,
604  *                  )
605  * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
606  *              Parameters:
607  *              asn1:    pointer to ASN1 socket.
608  *              integer: Integer.
609  *              nbytes:  number of bytes used to encode it.
610  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
611  */
612 int
613 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
614 {
615     int          ret;
616     int          start;
617     guint        cls;
618     guint        con;
619     guint        tag;
620     gboolean     def;
621     guint        enc_len;
622
623     start = asn1->offset;
624     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
625     if (ret != ASN1_ERR_NOERROR)
626         goto done;
627     if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
628         ret = ASN1_ERR_WRONG_TYPE;
629         goto done;
630     }
631     if (!def) {
632         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
633         goto done;
634     }
635     ret = asn1_uint32_value_decode (asn1, enc_len, integer);
636
637 done:
638     *nbytes = asn1->offset - start;
639     return ret;
640 }
641
642 /*
643  * NAME:        asn1_bits_decode                                [API]
644  * SYNOPSIS:    int asn1_bits_decode
645  *                  (
646  *                      ASN1_SCK  *asn1,
647  *                      int        eoc,
648  *                      guchar    *bits,
649  *                      guint      size,
650  *                      guint      len,
651  *                      guchar     unused
652  *                  )
653  * DESCRIPTION: Decodes Bit String.
654  *              Parameters:
655  *              asn1:    pointer to ASN1 socket.
656  *              enc_len: length of value.
657  *              bits:    pointer to variable we set to point to strring
658  *              len:     Size of Bit String in characters.
659  *              unused:  Number of unused bits in last character.
660  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
661  */
662 int
663 asn1_bits_decode ( ASN1_SCK *asn1, int enc_len, guchar **bits,
664                      guint *len, guchar *unused)
665 {
666     int ret;
667     int eoc;
668     guchar *ptr;
669
670     eoc = asn1->offset + enc_len;
671     *bits = NULL;
672     ret = asn1_octet_decode (asn1, unused);
673     if (ret != ASN1_ERR_NOERROR)
674         return ret;
675     *len = 0;
676
677     /*
678      * First, make sure the entire string is in the tvbuff, and throw
679      * an exception if it isn't.  If the length is bogus, this should
680      * keep us from trying to allocate an immensely large buffer.
681      * (It won't help if the length is *valid* but immensely large,
682      * but that's another matter; in any case, that would happen only
683      * if we had an immensely large tvbuff....)
684      */
685     if (enc_len != 0) {
686         tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
687         *bits = g_malloc (enc_len);
688     } else {
689         /*
690          * If the length is 0, we allocate a 1-byte buffer, as
691          * "g_malloc()" returns NULL if passed 0 as an argument,
692          * and our caller expects us to return a pointer to a
693          * buffer.
694          */
695         *bits = g_malloc (1);
696     }
697
698     ptr = *bits;
699     while (asn1->offset < eoc) {
700         ret = asn1_octet_decode (asn1, (guchar *)ptr++);
701         if (ret != ASN1_ERR_NOERROR) {
702             g_free(*bits);
703             *bits = NULL;
704             return ret;
705         }
706     }
707     *len = ptr - *bits;
708     return ASN1_ERR_NOERROR;
709 }
710
711 /*
712  * NAME:        asn1_string_value_decode                       [API]
713  * SYNOPSIS:    int asn1_string_value_decode
714  *                  (
715  *                      ASN1_SCK *asn1,
716  *                      int      enc_len,
717  *                      guchar   **octets
718  *                  )
719  * DESCRIPTION: Decodes value portion of string (Octet String, various
720  *              character string types)
721  *              Parameters:
722  *              asn1:    pointer to ASN1 socket.
723  *              enc_len: length of encoding of value.
724  *              octets:  pointer to variable we set to point to string,
725  *                       which is '\0' terminated for ease of use as C-string
726  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
727  */
728 int
729 asn1_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
730 {
731     int          ret;
732     int          eoc;
733     guchar       *ptr;
734
735     /*
736      * First, make sure the entire string is in the tvbuff, and throw
737      * an exception if it isn't.  If the length is bogus, this should
738      * keep us from trying to allocate an immensely large buffer.
739      * (It won't help if the length is *valid* but immensely large,
740      * but that's another matter; in any case, that would happen only
741      * if we had an immensely large tvbuff....)
742      */
743     if (enc_len != 0)
744         tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
745     *octets = g_malloc (enc_len+1);
746
747     eoc = asn1->offset + enc_len;
748     ptr = *octets;
749     while (asn1->offset < eoc) {
750         ret = asn1_octet_decode (asn1, (guchar *)ptr++);
751         if (ret != ASN1_ERR_NOERROR) {
752             g_free(*octets);
753             *octets = NULL;
754             return ret;
755         }
756     }
757     *(guchar *)ptr = '\0';
758     return ASN1_ERR_NOERROR;
759 }
760
761 /*
762  * NAME:        asn1_string_decode                             [API]
763  * SYNOPSIS:    int asn1_string_decode
764  *                  (
765  *                      ASN1_SCK  *asn1,
766  *                      guchar    **octets,
767  *                      guint     *str_len,
768  *                      guint     *nbytes,
769  *                      guint     expected_tag
770  *                  )
771  * DESCRIPTION: Decodes string (Octet String, various character string
772  *              types)
773  *              Parameters:
774  *              asn1:         pointer to ASN1 socket.
775  *              octets:       pointer to variable we set to point to string.
776  *              str_len:      length of octet_string.
777  *              nbytes:       number of bytes used to encode.
778  *              expected_tag: tag expected for this type of string.
779  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
780  */
781 int
782 asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
783                         guint *nbytes, guint expected_tag)
784 {
785     int          ret;
786     int          start;
787     int          enc_len;
788     guint        cls;
789     guint        con;
790     guint        tag;
791     gboolean     def;
792
793     start = asn1->offset;
794     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
795     if (ret != ASN1_ERR_NOERROR)
796         goto done;
797     if (cls != ASN1_UNI || con != ASN1_PRI || tag != expected_tag) {
798         /* XXX - handle the constructed encoding? */
799         ret = ASN1_ERR_WRONG_TYPE;
800         goto done;
801     }
802     if (!def) {
803         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
804         goto done;
805     }
806
807     ret = asn1_string_value_decode (asn1, enc_len, octets);
808     *str_len = enc_len;
809
810 done:
811     *nbytes = asn1->offset - start;
812     return ret;
813 }
814
815 /*
816  * NAME:        asn1_octet_string_decode                             [API]
817  * SYNOPSIS:    int asn1_octet_string_decode
818  *                  (
819  *                      ASN1_SCK  *asn1,
820  *                      guchar    **octets,
821  *                      guint     *str_len,
822  *                      guint     *nbytes,
823  *                  )
824  * DESCRIPTION: Decodes Octet String.
825  *              Parameters:
826  *              asn1:    pointer to ASN1 socket.
827  *              octets:  pointer to variable we set to point to string.
828  *              str_len: length of octet_string.
829  *              nbytes:  number of bytes used to encode.
830  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
831  */
832 int
833 asn1_octet_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
834                         guint *nbytes)
835 {
836     return asn1_string_decode(asn1, octets, str_len, nbytes, ASN1_OTS);
837 }
838
839 /*
840  * NAME:        asn1_subid_decode
841  * SYNOPSIS:    int asn1_subid_decode
842  *                  (
843  *                      ASN1_SCK *asn1,
844  *                      subid_t  *subid
845  *                  )
846  * DESCRIPTION: Decodes Sub Identifier.
847  *              Parameters:
848  *              asn1:  pointer to ASN1 socket.
849  *              subid: Sub Identifier.
850  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
851  */
852 int
853 asn1_subid_decode ( ASN1_SCK *asn1, subid_t *subid)
854 {
855     int    ret;
856     guchar ch;
857
858     *subid = 0;
859     do {
860         ret = asn1_octet_decode(asn1, &ch);
861         if (ret != ASN1_ERR_NOERROR)
862             return ret;
863         *subid <<= 7;
864         *subid |= ch & 0x7F;
865     } while ((ch & 0x80) == 0x80);
866     return ASN1_ERR_NOERROR;
867 }
868
869 /*
870  * NAME:        asn1_oid_value_decode                                [API]
871  * SYNOPSIS:    int asn1_oid_value_decode
872  *                  (
873  *                      ASN1_SCK *asn1,
874  *                      int      enc_len,
875  *                      subid_t  **oid,
876  *                      guint    *len
877  *                  )
878  * DESCRIPTION: Decodes value portion of Object Identifier.
879  *              Parameters:
880  *              asn1:    pointer to ASN1 socket.
881  *              enc_len: length of encoding of value.
882  *              oid:     pointer to variable we set to Object Identifier.
883  *              len:     Length of Object Identifier in gulongs.
884  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
885  */
886 int
887 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
888 {
889     int          ret;
890     int          eoc;
891     subid_t      subid;
892     guint        size;
893     subid_t      *optr;
894
895     /*
896      * First, make sure the entire string is in the tvbuff, and throw
897      * an exception if it isn't.  If the length is bogus, this should
898      * keep us from trying to allocate an immensely large buffer.
899      * (It won't help if the length is *valid* but immensely large,
900      * but that's another matter; in any case, that would happen only
901      * if we had an immensely large tvbuff....)
902      */
903     if (enc_len != 0)
904         tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
905
906     eoc = asn1->offset + enc_len;
907
908     size = enc_len + 1;
909     *oid = g_malloc(size * sizeof(gulong));
910     optr = *oid;
911
912     ret = asn1_subid_decode (asn1, &subid);
913     if (ret != ASN1_ERR_NOERROR) {
914         g_free(*oid);
915         *oid = NULL;
916         return ret;
917     }
918     if (subid < 40) {
919         optr[0] = 0;
920         optr[1] = subid;
921     } else if (subid < 80) {
922         optr[0] = 1;
923         optr[1] = subid - 40;
924     } else {
925         optr[0] = 2;
926         optr[1] = subid - 80;
927     }
928     *len = 2;
929     optr += 2;
930     while (asn1->offset < eoc) {
931         if (++(*len) > size) {
932             g_free(*oid);
933             *oid = NULL;
934             return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
935         }
936         ret = asn1_subid_decode (asn1, optr++);
937         if (ret != ASN1_ERR_NOERROR) {
938             g_free(*oid);
939             *oid = NULL;
940             return ret;
941         }
942     }
943     return ASN1_ERR_NOERROR;
944 }
945
946 /*
947  * NAME:        asn1_oid_decode                                [API]
948  * SYNOPSIS:    int asn1_oid_decode
949  *                  (
950  *                      ASN1_SCK *asn1,
951  *                      subid_t  **oid,
952  *                      guint    *len,
953  *                      guint    *nbytes
954  *                  )
955  * DESCRIPTION: Decodes Object Identifier.
956  *              Parameters:
957  *              asn1:   pointer to ASN1 socket.
958  *              oid:    pointer to variable we set to Object Identifier.
959  *              len:    Length of Object Identifier in gulongs.
960  *              nbytes: number of bytes used to encode.
961  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
962  */
963 int
964 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
965 {
966     int          ret;
967     int          start;
968     guint        cls;
969     guint        con;
970     guint        tag;
971     gboolean     def;
972     guint        enc_len;
973
974     start = asn1->offset;
975     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
976     if (ret != ASN1_ERR_NOERROR)
977         goto done;
978     if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) {
979         ret = ASN1_ERR_WRONG_TYPE;
980         goto done;
981     }
982     if (!def) {
983         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
984         goto done;
985     }
986
987     ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
988
989 done:
990     *nbytes = asn1->offset - start;
991     return ret;
992 }
993
994 /*
995  * NAME:        asn1_sequence_decode                             [API]
996  * SYNOPSIS:    int asn1_sequence_decode
997  *                  (
998  *                      ASN1_SCK  *asn1,
999  *                      guint     *seq_len,
1000  *                      guint     *nbytes
1001  *                  )
1002  * DESCRIPTION: Decodes header for SEQUENCE.
1003  *              Parameters:
1004  *              asn1:    pointer to ASN1 socket.
1005  *              seq_len: length of sequence.
1006  *              nbytes:  number of bytes used to encode header.
1007  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
1008  */
1009 int
1010 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
1011 {
1012     int          ret;
1013     int          start;
1014     guint        cls;
1015     guint        con;
1016     guint        tag;
1017     gboolean     def;
1018
1019     start = asn1->offset;
1020     ret = asn1_header_decode(asn1, &cls, &con, &tag,
1021             &def, seq_len);
1022     if (ret != ASN1_ERR_NOERROR)
1023         goto done;
1024     if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) {
1025         ret = ASN1_ERR_WRONG_TYPE;
1026         goto done;
1027     }
1028     if (!def) {
1029         /* XXX - might some sequences have an indefinite length? */
1030         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
1031         goto done;
1032     }
1033     ret = ASN1_ERR_NOERROR;
1034
1035 done:
1036     *nbytes = asn1->offset - start;
1037     return ret;
1038 }
1039
1040 /*
1041  * NAME:        asn1_err_to_str                             [API]
1042  * SYNOPSIS:    char *asn1_err_to_str
1043  *                  (
1044  *                      int     err
1045  *                  )
1046  * DESCRIPTION: Returns the string corresponding to an ASN.1 library error.
1047  *              Parameters:
1048  *              err: the error code
1049  * RETURNS:     string for the error
1050  */
1051 char *
1052 asn1_err_to_str(int err)
1053 {
1054     char         *errstr;
1055     char         errstrbuf[14+1+1+11+1+1];      /* "Unknown error (%d)\0" */
1056
1057     switch (err) {
1058
1059     case ASN1_ERR_EOC_MISMATCH:
1060         errstr = "EOC mismatch";
1061         break;
1062
1063     case ASN1_ERR_WRONG_TYPE:
1064         errstr = "Wrong type for that item";
1065         break;
1066
1067     case ASN1_ERR_LENGTH_NOT_DEFINITE:
1068         errstr = "Length was indefinite";
1069         break;
1070
1071     case ASN1_ERR_LENGTH_MISMATCH:
1072         errstr = "Length mismatch";
1073         break;
1074
1075     case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
1076         errstr = "Wrong length for that item's type";
1077         break;
1078
1079     default:
1080         snprintf(errstrbuf, sizeof errstrbuf, "Unknown error (%d)", err);
1081         errstr = errstrbuf;
1082         break;
1083     }
1084     return errstr;
1085 }