1/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10 */
11#include "tomcrypt.h"
12#include <stdarg.h>
13
14
15/**
16  @file der_decode_sequence_multi.c
17  ASN.1 DER, decode a SEQUENCE, Tom St Denis
18*/
19
20#ifdef LTC_DER
21
22/**
23  Decode a SEQUENCE type using a VA list
24  @param in    Input buffer
25  @param inlen Length of input in octets
26  @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
27  @return CRYPT_OK on success
28*/
29int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
30{
31   int           err, type;
32   unsigned long size, x;
33   void          *data;
34   va_list       args;
35   ltc_asn1_list *list;
36
37   LTC_ARGCHK(in    != NULL);
38
39   /* get size of output that will be required */
40   va_start(args, inlen);
41   x = 0;
42   for (;;) {
43       type = va_arg(args, int);
44       size = va_arg(args, unsigned long);
45       data = va_arg(args, void*);
46
47       if (type == LTC_ASN1_EOL) {
48          break;
49       }
50
51       switch (type) {
52           case LTC_ASN1_BOOLEAN:
53           case LTC_ASN1_INTEGER:
54           case LTC_ASN1_SHORT_INTEGER:
55           case LTC_ASN1_BIT_STRING:
56           case LTC_ASN1_OCTET_STRING:
57           case LTC_ASN1_NULL:
58           case LTC_ASN1_OBJECT_IDENTIFIER:
59           case LTC_ASN1_IA5_STRING:
60           case LTC_ASN1_PRINTABLE_STRING:
61           case LTC_ASN1_UTF8_STRING:
62           case LTC_ASN1_UTCTIME:
63           case LTC_ASN1_SET:
64           case LTC_ASN1_SETOF:
65           case LTC_ASN1_SEQUENCE:
66           case LTC_ASN1_CHOICE:
67                ++x;
68                break;
69
70           default:
71               va_end(args);
72               return CRYPT_INVALID_ARG;
73       }
74   }
75   va_end(args);
76
77   /* allocate structure for x elements */
78   if (x == 0) {
79      return CRYPT_NOP;
80   }
81
82   list = XCALLOC(sizeof(*list), x);
83   if (list == NULL) {
84      return CRYPT_MEM;
85   }
86
87   /* fill in the structure */
88   va_start(args, inlen);
89   x = 0;
90   for (;;) {
91       type = va_arg(args, int);
92       size = va_arg(args, unsigned long);
93       data = va_arg(args, void*);
94
95       if (type == LTC_ASN1_EOL) {
96          break;
97       }
98
99       switch (type) {
100           case LTC_ASN1_BOOLEAN:
101           case LTC_ASN1_INTEGER:
102           case LTC_ASN1_SHORT_INTEGER:
103           case LTC_ASN1_BIT_STRING:
104           case LTC_ASN1_OCTET_STRING:
105           case LTC_ASN1_NULL:
106           case LTC_ASN1_OBJECT_IDENTIFIER:
107           case LTC_ASN1_IA5_STRING:
108           case LTC_ASN1_PRINTABLE_STRING:
109           case LTC_ASN1_UTF8_STRING:
110           case LTC_ASN1_UTCTIME:
111           case LTC_ASN1_SEQUENCE:
112           case LTC_ASN1_SET:
113           case LTC_ASN1_SETOF:
114           case LTC_ASN1_CHOICE:
115                list[x].type   = type;
116                list[x].size   = size;
117                list[x++].data = data;
118                break;
119
120           default:
121               va_end(args);
122               err = CRYPT_INVALID_ARG;
123               goto LBL_ERR;
124       }
125   }
126   va_end(args);
127
128   err = der_decode_sequence(in, inlen, list, x);
129LBL_ERR:
130   XFREE(list);
131   return err;
132}
133
134#endif
135
136
137/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */
138/* $Revision: 1.12 $ */
139/* $Date: 2006/11/26 02:25:18 $ */
140