sensitivity of packet range options fine tuning:
[obnox/wireshark/wip.git] / asn1.c
1 /* asn1.c
2  * Routines for ASN.1 BER dissection
3  *
4  * $Id: asn1.c,v 1.23 2003/11/09 22:57:52 guy Exp $
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     asn1->offset += enc_len;
422     return ASN1_ERR_NOERROR;
423 }
424
425 /*
426  * NAME:        asn1_bool_decode                                [API]
427  * SYNOPSIS:    int asn1_bool_decode
428  *                  (
429  *                      ASN1_SCK *asn1,
430  *                      int      enc_len,
431  *                      gboolean *boolean
432  *                  )
433  * DESCRIPTION: Decodes Boolean.
434  *              Parameters:
435  *              asn1:    pointer to ASN1 socket.
436  *              enc_len: length of encoding of value.
437  *              bool:    False, True (0, !0).
438  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
439  */
440 int
441 asn1_bool_decode ( ASN1_SCK *asn1, int enc_len, gboolean *boolean)
442 {
443     int    ret;
444     guchar ch;
445
446     if (enc_len != 1)
447       return ASN1_ERR_LENGTH_MISMATCH;
448     ret = asn1_octet_decode (asn1, &ch);
449     if (ret != ASN1_ERR_NOERROR)
450         return ret;
451     *boolean = ch ? TRUE : FALSE;
452     return ASN1_ERR_NOERROR;
453 }
454
455 /*
456  * NAME:        asn1_int32_value_decode                                [API]
457  * SYNOPSIS:    int asn1_int32_value_decode
458  *                  (
459  *                      ASN1_SCK *asn1,
460  *                      int      enc_len,
461  *                      gint32   *integer
462  *                  )
463  * DESCRIPTION: Decodes value portion of Integer (which must be no more
464  *              than 32 bits).
465  *              Parameters:
466  *              asn1:    pointer to ASN1 socket.
467  *              enc_len: length of encoding of value.
468  *              integer: Integer.
469  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
470  */
471 int
472 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
473 {
474     int          ret;
475     int          eoc;
476     guchar       ch;
477     guint        len;
478
479     eoc = asn1->offset + enc_len;
480     ret = asn1_octet_decode (asn1, &ch);
481     if (ret != ASN1_ERR_NOERROR)
482         return ret;
483     *integer = (gint) ch;
484     len = 1;
485     while (asn1->offset < eoc) {
486         if (++len > sizeof (gint32))
487             return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
488         ret = asn1_octet_decode (asn1, &ch);
489         if (ret != ASN1_ERR_NOERROR)
490             return ret;
491         *integer <<= 8;
492         *integer |= ch;
493     }
494     return ASN1_ERR_NOERROR;
495 }
496
497 /*
498  * NAME:        asn1_int32_decode                                [API]
499  * SYNOPSIS:    int asn1_int32_decode
500  *                  (
501  *                      ASN1_SCK *asn1,
502  *                      gint32   *integer,
503  *                      guint    *nbytes,
504  *                  )
505  * DESCRIPTION: Decodes Integer (which must be no more than 32 bits).
506  *              Parameters:
507  *              asn1:    pointer to ASN1 socket.
508  *              integer: Integer.
509  *              nbytes:  number of bytes used to encode it.
510  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
511  */
512 int
513 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
514 {
515     int          ret;
516     int          start;
517     guint        cls;
518     guint        con;
519     guint        tag;
520     gboolean     def;
521     guint        enc_len;
522
523     start = asn1->offset;
524     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
525     if (ret != ASN1_ERR_NOERROR)
526         goto done;
527     if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
528         ret = ASN1_ERR_WRONG_TYPE;
529         goto done;
530     }
531     if (!def) {
532         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
533         goto done;
534     }
535     ret = asn1_int32_value_decode (asn1, enc_len, integer);
536
537 done:
538     *nbytes = asn1->offset - start;
539     return ret;
540 }
541
542 /*
543  * NAME:        asn1_uint32_value_decode                             [API]
544  * SYNOPSIS:    int asn1_uint32_value_decode
545  *                  (
546  *                      ASN1_SCK *asn1,
547  *                      int      enc_len,
548  *                      guint32  *integer
549  *                  )
550  * DESCRIPTION: Decodes value part of Unsigned Integer (which must be no
551  *              more than 32 bits).
552  *              Parameters:
553  *              asn1:    pointer to ASN1 socket.
554  *              enc_len: length of encoding of value.
555  *              integer: Integer.
556  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
557  */
558 int
559 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint32 *integer)
560 {
561     int          ret;
562     int          eoc;
563     guchar       ch;
564     guint        len;
565
566     eoc = asn1->offset + enc_len;
567     ret = asn1_octet_decode (asn1, &ch);
568     if (ret != ASN1_ERR_NOERROR)
569         return ret;
570     *integer = ch;
571     if (ch == 0)
572         len = 0;
573     else
574         len = 1;
575     while (asn1->offset < eoc) {
576         if (++len > sizeof (guint32))
577             return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
578         ret = asn1_octet_decode (asn1, &ch);
579         if (ret != ASN1_ERR_NOERROR)
580             return ret;
581         *integer <<= 8;
582         *integer |= ch;
583     }
584     return ASN1_ERR_NOERROR;
585 }
586
587 /*
588  * NAME:        asn1_uint32_decode                             [API]
589  * SYNOPSIS:    int asn1_uint32_decode
590  *                  (
591  *                      ASN1_SCK *asn1,
592  *                      guint32  *integer,
593  *                      guint    *nbytes,
594  *                  )
595  * DESCRIPTION: Decodes Unsigned Integer (which must be no more than 32 bits).
596  *              Parameters:
597  *              asn1:    pointer to ASN1 socket.
598  *              integer: Integer.
599  *              nbytes:  number of bytes used to encode it.
600  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
601  */
602 int
603 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
604 {
605     int          ret;
606     int          start;
607     guint        cls;
608     guint        con;
609     guint        tag;
610     gboolean     def;
611     guint        enc_len;
612
613     start = asn1->offset;
614     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
615     if (ret != ASN1_ERR_NOERROR)
616         goto done;
617     if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT) {
618         ret = ASN1_ERR_WRONG_TYPE;
619         goto done;
620     }
621     if (!def) {
622         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
623         goto done;
624     }
625     ret = asn1_uint32_value_decode (asn1, enc_len, integer);
626
627 done:
628     *nbytes = asn1->offset - start;
629     return ret;
630 }
631
632 /*
633  * NAME:        asn1_bits_decode                                [API]
634  * SYNOPSIS:    int asn1_bits_decode
635  *                  (
636  *                      ASN1_SCK  *asn1,
637  *                      int        eoc,
638  *                      guchar    *bits,
639  *                      guint      size,
640  *                      guint      len,
641  *                      guchar     unused
642  *                  )
643  * DESCRIPTION: Decodes Bit String.
644  *              Parameters:
645  *              asn1:    pointer to ASN1 socket.
646  *              enc_len: length of value.
647  *              bits:    pointer to variable we set to point to strring
648  *              len:     Size of Bit String in characters.
649  *              unused:  Number of unused bits in last character.
650  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
651  */
652 int
653 asn1_bits_decode ( ASN1_SCK *asn1, int enc_len, guchar **bits,
654                      guint *len, guchar *unused)
655 {
656     int ret;
657     int eoc;
658     guchar *ptr;
659
660     eoc = asn1->offset + enc_len;
661     *bits = NULL;
662     ret = asn1_octet_decode (asn1, unused);
663     if (ret != ASN1_ERR_NOERROR)
664         return ret;
665     *len = 0;
666
667     /*
668      * First, make sure the entire string is in the tvbuff, and throw
669      * an exception if it isn't.  If the length is bogus, this should
670      * keep us from trying to allocate an immensely large buffer.
671      * (It won't help if the length is *valid* but immensely large,
672      * but that's another matter; in any case, that would happen only
673      * if we had an immensely large tvbuff....)
674      */
675     if (enc_len != 0) {
676         tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
677         *bits = g_malloc (enc_len);
678     } else {
679         /*
680          * If the length is 0, we allocate a 1-byte buffer, as
681          * "g_malloc()" returns NULL if passed 0 as an argument,
682          * and our caller expects us to return a pointer to a
683          * buffer.
684          */
685         *bits = g_malloc (1);
686     }
687
688     ptr = *bits;
689     while (asn1->offset < eoc) {
690         ret = asn1_octet_decode (asn1, (guchar *)ptr++);
691         if (ret != ASN1_ERR_NOERROR) {
692             g_free(*bits);
693             *bits = NULL;
694             return ret;
695         }
696     }
697     *len = ptr - *bits;
698     return ASN1_ERR_NOERROR;
699 }
700
701 /*
702  * NAME:        asn1_string_value_decode                       [API]
703  * SYNOPSIS:    int asn1_string_value_decode
704  *                  (
705  *                      ASN1_SCK *asn1,
706  *                      int      enc_len,
707  *                      guchar   **octets
708  *                  )
709  * DESCRIPTION: Decodes value portion of string (Octet String, various
710  *              character string types)
711  *              Parameters:
712  *              asn1:    pointer to ASN1 socket.
713  *              enc_len: length of encoding of value.
714  *              octets:  pointer to variable we set to point to string,
715  *                       which is '\0' terminated for ease of use as C-string
716  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
717  */
718 int
719 asn1_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
720 {
721     int          ret;
722     int          eoc;
723     guchar       *ptr;
724
725     /*
726      * First, make sure the entire string is in the tvbuff, and throw
727      * an exception if it isn't.  If the length is bogus, this should
728      * keep us from trying to allocate an immensely large buffer.
729      * (It won't help if the length is *valid* but immensely large,
730      * but that's another matter; in any case, that would happen only
731      * if we had an immensely large tvbuff....)
732      */
733     if (enc_len != 0)
734         tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
735     *octets = g_malloc (enc_len+1);
736
737     eoc = asn1->offset + enc_len;
738     ptr = *octets;
739     while (asn1->offset < eoc) {
740         ret = asn1_octet_decode (asn1, (guchar *)ptr++);
741         if (ret != ASN1_ERR_NOERROR) {
742             g_free(*octets);
743             *octets = NULL;
744             return ret;
745         }
746     }
747     *(guchar *)ptr = '\0';
748     return ASN1_ERR_NOERROR;
749 }
750
751 /*
752  * NAME:        asn1_string_decode                             [API]
753  * SYNOPSIS:    int asn1_string_decode
754  *                  (
755  *                      ASN1_SCK  *asn1,
756  *                      guchar    **octets,
757  *                      guint     *str_len,
758  *                      guint     *nbytes,
759  *                      guint     expected_tag
760  *                  )
761  * DESCRIPTION: Decodes string (Octet String, various character string
762  *              types)
763  *              Parameters:
764  *              asn1:         pointer to ASN1 socket.
765  *              octets:       pointer to variable we set to point to string.
766  *              str_len:      length of octet_string.
767  *              nbytes:       number of bytes used to encode.
768  *              expected_tag: tag expected for this type of string.
769  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
770  */
771 int
772 asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
773                         guint *nbytes, guint expected_tag)
774 {
775     int          ret;
776     int          start;
777     int          enc_len;
778     guint        cls;
779     guint        con;
780     guint        tag;
781     gboolean     def;
782
783     start = asn1->offset;
784     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
785     if (ret != ASN1_ERR_NOERROR)
786         goto done;
787     if (cls != ASN1_UNI || con != ASN1_PRI || tag != expected_tag) {
788         /* XXX - handle the constructed encoding? */
789         ret = ASN1_ERR_WRONG_TYPE;
790         goto done;
791     }
792     if (!def) {
793         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
794         goto done;
795     }
796
797     ret = asn1_string_value_decode (asn1, enc_len, octets);
798     *str_len = enc_len;
799
800 done:
801     *nbytes = asn1->offset - start;
802     return ret;
803 }
804
805 /*
806  * NAME:        asn1_octet_string_decode                             [API]
807  * SYNOPSIS:    int asn1_octet_string_decode
808  *                  (
809  *                      ASN1_SCK  *asn1,
810  *                      guchar    **octets,
811  *                      guint     *str_len,
812  *                      guint     *nbytes,
813  *                  )
814  * DESCRIPTION: Decodes Octet String.
815  *              Parameters:
816  *              asn1:    pointer to ASN1 socket.
817  *              octets:  pointer to variable we set to point to string.
818  *              str_len: length of octet_string.
819  *              nbytes:  number of bytes used to encode.
820  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
821  */
822 int
823 asn1_octet_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
824                         guint *nbytes)
825 {
826     return asn1_string_decode(asn1, octets, str_len, nbytes, ASN1_OTS);
827 }
828
829 /*
830  * NAME:        asn1_subid_decode
831  * SYNOPSIS:    int asn1_subid_decode
832  *                  (
833  *                      ASN1_SCK *asn1,
834  *                      subid_t  *subid
835  *                  )
836  * DESCRIPTION: Decodes Sub Identifier.
837  *              Parameters:
838  *              asn1:  pointer to ASN1 socket.
839  *              subid: Sub Identifier.
840  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
841  */
842 int
843 asn1_subid_decode ( ASN1_SCK *asn1, subid_t *subid)
844 {
845     int    ret;
846     guchar ch;
847
848     *subid = 0;
849     do {
850         ret = asn1_octet_decode(asn1, &ch);
851         if (ret != ASN1_ERR_NOERROR)
852             return ret;
853         *subid <<= 7;
854         *subid |= ch & 0x7F;
855     } while ((ch & 0x80) == 0x80);
856     return ASN1_ERR_NOERROR;
857 }
858
859 /*
860  * NAME:        asn1_oid_value_decode                                [API]
861  * SYNOPSIS:    int asn1_oid_value_decode
862  *                  (
863  *                      ASN1_SCK *asn1,
864  *                      int      enc_len,
865  *                      subid_t  **oid,
866  *                      guint    *len
867  *                  )
868  * DESCRIPTION: Decodes value portion of Object Identifier.
869  *              Parameters:
870  *              asn1:    pointer to ASN1 socket.
871  *              enc_len: length of encoding of value.
872  *              oid:     pointer to variable we set to Object Identifier.
873  *              len:     Length of Object Identifier in gulongs.
874  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
875  */
876 int
877 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
878 {
879     int          ret;
880     int          eoc;
881     subid_t      subid;
882     guint        size;
883     subid_t      *optr;
884
885     /*
886      * First, make sure the entire string is in the tvbuff, and throw
887      * an exception if it isn't.  If the length is bogus, this should
888      * keep us from trying to allocate an immensely large buffer.
889      * (It won't help if the length is *valid* but immensely large,
890      * but that's another matter; in any case, that would happen only
891      * if we had an immensely large tvbuff....)
892      */
893     if (enc_len != 0)
894         tvb_ensure_bytes_exist(asn1->tvb, asn1->offset, enc_len);
895
896     eoc = asn1->offset + enc_len;
897
898     size = enc_len + 1;
899     *oid = g_malloc(size * sizeof(gulong));
900     optr = *oid;
901
902     ret = asn1_subid_decode (asn1, &subid);
903     if (ret != ASN1_ERR_NOERROR) {
904         g_free(*oid);
905         *oid = NULL;
906         return ret;
907     }
908     if (subid < 40) {
909         optr[0] = 0;
910         optr[1] = subid;
911     } else if (subid < 80) {
912         optr[0] = 1;
913         optr[1] = subid - 40;
914     } else {
915         optr[0] = 2;
916         optr[1] = subid - 80;
917     }
918     *len = 2;
919     optr += 2;
920     while (asn1->offset < eoc) {
921         if (++(*len) > size) {
922             g_free(*oid);
923             *oid = NULL;
924             return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
925         }
926         ret = asn1_subid_decode (asn1, optr++);
927         if (ret != ASN1_ERR_NOERROR) {
928             g_free(*oid);
929             *oid = NULL;
930             return ret;
931         }
932     }
933     return ASN1_ERR_NOERROR;
934 }
935
936 /*
937  * NAME:        asn1_oid_decode                                [API]
938  * SYNOPSIS:    int asn1_oid_decode
939  *                  (
940  *                      ASN1_SCK *asn1,
941  *                      subid_t  **oid,
942  *                      guint    *len,
943  *                      guint    *nbytes
944  *                  )
945  * DESCRIPTION: Decodes Object Identifier.
946  *              Parameters:
947  *              asn1:   pointer to ASN1 socket.
948  *              oid:    pointer to variable we set to Object Identifier.
949  *              len:    Length of Object Identifier in gulongs.
950  *              nbytes: number of bytes used to encode.
951  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
952  */
953 int
954 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
955 {
956     int          ret;
957     int          start;
958     guint        cls;
959     guint        con;
960     guint        tag;
961     gboolean     def;
962     guint        enc_len;
963
964     start = asn1->offset;
965     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
966     if (ret != ASN1_ERR_NOERROR)
967         goto done;
968     if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI) {
969         ret = ASN1_ERR_WRONG_TYPE;
970         goto done;
971     }
972     if (!def) {
973         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
974         goto done;
975     }
976
977     ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
978
979 done:
980     *nbytes = asn1->offset - start;
981     return ret;
982 }
983
984 /*
985  * NAME:        asn1_sequence_decode                             [API]
986  * SYNOPSIS:    int asn1_sequence_decode
987  *                  (
988  *                      ASN1_SCK  *asn1,
989  *                      guint     *seq_len,
990  *                      guint     *nbytes
991  *                  )
992  * DESCRIPTION: Decodes header for SEQUENCE.
993  *              Parameters:
994  *              asn1:    pointer to ASN1 socket.
995  *              seq_len: length of sequence.
996  *              nbytes:  number of bytes used to encode header.
997  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
998  */
999 int
1000 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
1001 {
1002     int          ret;
1003     int          start;
1004     guint        cls;
1005     guint        con;
1006     guint        tag;
1007     gboolean     def;
1008
1009     start = asn1->offset;
1010     ret = asn1_header_decode(asn1, &cls, &con, &tag,
1011             &def, seq_len);
1012     if (ret != ASN1_ERR_NOERROR)
1013         goto done;
1014     if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ) {
1015         ret = ASN1_ERR_WRONG_TYPE;
1016         goto done;
1017     }
1018     if (!def) {
1019         /* XXX - might some sequences have an indefinite length? */
1020         ret = ASN1_ERR_LENGTH_NOT_DEFINITE;
1021         goto done;
1022     }
1023     ret = ASN1_ERR_NOERROR;
1024
1025 done:
1026     *nbytes = asn1->offset - start;
1027     return ret;
1028 }
1029
1030 /*
1031  * NAME:        asn1_err_to_str                             [API]
1032  * SYNOPSIS:    char *asn1_err_to_str
1033  *                  (
1034  *                      int     err
1035  *                  )
1036  * DESCRIPTION: Returns the string corresponding to an ASN.1 library error.
1037  *              Parameters:
1038  *              err: the error code
1039  * RETURNS:     string for the error
1040  */
1041 char *
1042 asn1_err_to_str(int err)
1043 {
1044     char         *errstr;
1045     char         errstrbuf[14+1+1+11+1+1];      /* "Unknown error (%d)\0" */
1046
1047     switch (err) {
1048
1049     case ASN1_ERR_EOC_MISMATCH:
1050         errstr = "EOC mismatch";
1051         break;
1052
1053     case ASN1_ERR_WRONG_TYPE:
1054         errstr = "Wrong type for that item";
1055         break;
1056
1057     case ASN1_ERR_LENGTH_NOT_DEFINITE:
1058         errstr = "Length was indefinite";
1059         break;
1060
1061     case ASN1_ERR_LENGTH_MISMATCH:
1062         errstr = "Length mismatch";
1063         break;
1064
1065     case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
1066         errstr = "Wrong length for that item's type";
1067         break;
1068
1069     default:
1070         snprintf(errstrbuf, sizeof errstrbuf, "Unknown error (%d)", err);
1071         errstr = errstrbuf;
1072         break;
1073     }
1074     return errstr;
1075 }