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