]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / choice / der_decode_choice.c
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 #include "tomcrypt.h"
10
11 /**
12   @file der_decode_choice.c
13   ASN.1 DER, decode a CHOICE, Tom St Denis
14 */
15
16 #ifdef LTC_DER
17
18 /**
19    Decode a CHOICE
20    @param in       The DER encoded input
21    @param inlen    [in/out] The size of the input and resulting size of read type
22    @param list     The list of items to decode
23    @param outlen   The number of items in the list
24    @return CRYPT_OK on success
25 */
26 int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
27                             ltc_asn1_list *list, unsigned long  outlen)
28 {
29    unsigned long size, x, z;
30    void          *data;
31
32    LTC_ARGCHK(in    != NULL);
33    LTC_ARGCHK(inlen != NULL);
34    LTC_ARGCHK(list  != NULL);
35
36    /* get blk size */
37    if (*inlen < 2) {
38       return CRYPT_INVALID_PACKET;
39    }
40
41    /* set all of the "used" flags to zero */
42    for (x = 0; x < outlen; x++) {
43        list[x].used = 0;
44    }
45
46    /* now scan until we have a winner */
47    for (x = 0; x < outlen; x++) {
48        size = list[x].size;
49        data = list[x].data;
50
51        switch (list[x].type) {
52            case LTC_ASN1_BOOLEAN:
53                if (der_decode_boolean(in, *inlen, data) == CRYPT_OK) {
54                   if (der_length_boolean(&z) == CRYPT_OK) {
55                       list[x].used = 1;
56                       *inlen       = z;
57                       return CRYPT_OK;
58                   }
59                }
60                break;
61
62            case LTC_ASN1_INTEGER:
63                if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
64                   if (der_length_integer(data, &z) == CRYPT_OK) {
65                       list[x].used = 1;
66                       *inlen       = z;
67                       return CRYPT_OK;
68                   }
69                }
70                break;
71
72            case LTC_ASN1_SHORT_INTEGER:
73                if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
74                   if (der_length_short_integer(size, &z) == CRYPT_OK) {
75                       list[x].used = 1;
76                       *inlen       = z;
77                       return CRYPT_OK;
78                   }
79                }
80                break;
81
82            case LTC_ASN1_BIT_STRING:
83                if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
84                   if (der_length_bit_string(size, &z) == CRYPT_OK) {
85                      list[x].used = 1;
86                      list[x].size = size;
87                      *inlen       = z;
88                      return CRYPT_OK;
89                   }
90                }
91                break;
92
93            case LTC_ASN1_RAW_BIT_STRING:
94                if (der_decode_raw_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
95                   if (der_length_bit_string(size, &z) == CRYPT_OK) {
96                      list[x].used = 1;
97                      list[x].size = size;
98                      *inlen       = z;
99                      return CRYPT_OK;
100                   }
101                }
102                break;
103
104            case LTC_ASN1_OCTET_STRING:
105                if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
106                   if (der_length_octet_string(size, &z) == CRYPT_OK) {
107                      list[x].used = 1;
108                      list[x].size = size;
109                      *inlen       = z;
110                      return CRYPT_OK;
111                   }
112                }
113                break;
114
115            case LTC_ASN1_NULL:
116                if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
117                   *inlen = 2;
118                   list[x].used   = 1;
119                   return CRYPT_OK;
120                }
121                break;
122
123            case LTC_ASN1_OBJECT_IDENTIFIER:
124                if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
125                   if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
126                      list[x].used = 1;
127                      list[x].size = size;
128                      *inlen       = z;
129                      return CRYPT_OK;
130                   }
131                }
132                break;
133
134            case LTC_ASN1_TELETEX_STRING:
135                if (der_decode_teletex_string(in, *inlen, data, &size) == CRYPT_OK) {
136                   if (der_length_teletex_string(data, size, &z) == CRYPT_OK) {
137                      list[x].used = 1;
138                      list[x].size = size;
139                      *inlen       = z;
140                      return CRYPT_OK;
141                   }
142                }
143                break;
144
145            case LTC_ASN1_IA5_STRING:
146                if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
147                   if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
148                      list[x].used = 1;
149                      list[x].size = size;
150                      *inlen       = z;
151                      return CRYPT_OK;
152                   }
153                }
154                break;
155
156            case LTC_ASN1_PRINTABLE_STRING:
157                if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
158                   if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
159                      list[x].used = 1;
160                      list[x].size = size;
161                      *inlen       = z;
162                      return CRYPT_OK;
163                   }
164                }
165                break;
166
167            case LTC_ASN1_UTF8_STRING:
168                if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
169                   if (der_length_utf8_string(data, size, &z) == CRYPT_OK) {
170                      list[x].used = 1;
171                      list[x].size = size;
172                      *inlen       = z;
173                      return CRYPT_OK;
174                   }
175                }
176                break;
177
178            case LTC_ASN1_UTCTIME:
179                z = *inlen;
180                if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
181                   list[x].used = 1;
182                   *inlen       = z;
183                   return CRYPT_OK;
184                }
185                break;
186
187            case LTC_ASN1_GENERALIZEDTIME:
188                z = *inlen;
189                if (der_decode_generalizedtime(in, &z, data) == CRYPT_OK) {
190                   list[x].used = 1;
191                   *inlen       = z;
192                   return CRYPT_OK;
193                }
194                break;
195
196            case LTC_ASN1_SET:
197            case LTC_ASN1_SETOF:
198            case LTC_ASN1_SEQUENCE:
199                if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
200                   if (der_length_sequence(data, size, &z) == CRYPT_OK) {
201                      list[x].used = 1;
202                      *inlen       = z;
203                      return CRYPT_OK;
204                   }
205                }
206                break;
207
208            case LTC_ASN1_CHOICE:
209            case LTC_ASN1_CONSTRUCTED:
210            case LTC_ASN1_CONTEXT_SPECIFIC:
211            case LTC_ASN1_EOL:
212                return CRYPT_INVALID_ARG;
213        }
214    }
215
216    return CRYPT_INVALID_PACKET;
217 }
218
219 #endif
220
221 /* ref:         $Format:%D$ */
222 /* git commit:  $Format:%H$ */
223 /* commit time: $Format:%ai$ */