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 #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 */ 29 int 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); 129 LBL_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