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 (at) gmail.com, http://libtomcrypt.com 10 */ 11 #include "tomcrypt.h" 12 13 /** 14 @file der_decode_choice.c 15 ASN.1 DER, decode a CHOICE, Tom St Denis 16 */ 17 18 #ifdef LTC_DER 19 20 /** 21 Decode a CHOICE 22 @param in The DER encoded input 23 @param inlen [in/out] The size of the input and resulting size of read type 24 @param list The list of items to decode 25 @param outlen The number of items in the list 26 @return CRYPT_OK on success 27 */ 28 int der_decode_choice(const unsigned char *in, unsigned long *inlen, 29 ltc_asn1_list *list, unsigned long outlen) 30 { 31 unsigned long size, x, z; 32 void *data; 33 34 LTC_ARGCHK(in != NULL); 35 LTC_ARGCHK(inlen != NULL); 36 LTC_ARGCHK(list != NULL); 37 38 /* get blk size */ 39 if (*inlen < 2) { 40 return CRYPT_INVALID_PACKET; 41 } 42 43 /* set all of the "used" flags to zero */ 44 for (x = 0; x < outlen; x++) { 45 list[x].used = 0; 46 } 47 48 /* now scan until we have a winner */ 49 for (x = 0; x < outlen; x++) { 50 size = list[x].size; 51 data = list[x].data; 52 53 switch (list[x].type) { 54 case LTC_ASN1_INTEGER: 55 if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { 56 if (der_length_integer(data, &z) == CRYPT_OK) { 57 list[x].used = 1; 58 *inlen = z; 59 return CRYPT_OK; 60 } 61 } 62 break; 63 64 case LTC_ASN1_SHORT_INTEGER: 65 if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { 66 if (der_length_short_integer(size, &z) == CRYPT_OK) { 67 list[x].used = 1; 68 *inlen = z; 69 return CRYPT_OK; 70 } 71 } 72 break; 73 74 case LTC_ASN1_BIT_STRING: 75 if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { 76 if (der_length_bit_string(size, &z) == CRYPT_OK) { 77 list[x].used = 1; 78 list[x].size = size; 79 *inlen = z; 80 return CRYPT_OK; 81 } 82 } 83 break; 84 85 case LTC_ASN1_OCTET_STRING: 86 if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { 87 if (der_length_octet_string(size, &z) == CRYPT_OK) { 88 list[x].used = 1; 89 list[x].size = size; 90 *inlen = z; 91 return CRYPT_OK; 92 } 93 } 94 break; 95 96 case LTC_ASN1_NULL: 97 if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { 98 *inlen = 2; 99 list[x].used = 1; 100 return CRYPT_OK; 101 } 102 break; 103 104 case LTC_ASN1_OBJECT_IDENTIFIER: 105 if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { 106 if (der_length_object_identifier(data, 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_IA5_STRING: 116 if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { 117 if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { 118 list[x].used = 1; 119 list[x].size = size; 120 *inlen = z; 121 return CRYPT_OK; 122 } 123 } 124 break; 125 126 127 case LTC_ASN1_PRINTABLE_STRING: 128 if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { 129 if (der_length_printable_string(data, size, &z) == CRYPT_OK) { 130 list[x].used = 1; 131 list[x].size = size; 132 *inlen = z; 133 return CRYPT_OK; 134 } 135 } 136 break; 137 138 case LTC_ASN1_UTF8_STRING: 139 if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { 140 if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { 141 list[x].used = 1; 142 list[x].size = size; 143 *inlen = z; 144 return CRYPT_OK; 145 } 146 } 147 break; 148 149 case LTC_ASN1_UTCTIME: 150 z = *inlen; 151 if (der_decode_utctime(in, &z, data) == CRYPT_OK) { 152 list[x].used = 1; 153 *inlen = z; 154 return CRYPT_OK; 155 } 156 break; 157 158 case LTC_ASN1_SET: 159 case LTC_ASN1_SETOF: 160 case LTC_ASN1_SEQUENCE: 161 if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { 162 if (der_length_sequence(data, size, &z) == CRYPT_OK) { 163 list[x].used = 1; 164 *inlen = z; 165 return CRYPT_OK; 166 } 167 } 168 break; 169 170 default: 171 return CRYPT_INVALID_ARG; 172 } 173 } 174 175 return CRYPT_INVALID_PACKET; 176 } 177 178 #endif 179 180 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ 181 /* $Revision: 1.8 $ */ 182 /* $Date: 2006/12/06 02:23:49 $ */ 183