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_encode_sequence_multi.c 17 ASN.1 DER, encode a SEQUENCE, Tom St Denis 18 */ 19 20 #ifdef LTC_DER 21 22 /** 23 Encode a SEQUENCE type using a VA list 24 @param out [out] Destination for data 25 @param outlen [in/out] Length of buffer and resulting length of output 26 @remark <...> is of the form <type, size, data> (int, unsigned long, void*) 27 @return CRYPT_OK on success 28 */ 29 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) 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(out != NULL); 38 LTC_ARGCHK(outlen != NULL); 39 40 /* get size of output that will be required */ 41 va_start(args, outlen); 42 x = 0; 43 for (;;) { 44 type = va_arg(args, int); 45 size = va_arg(args, unsigned long); 46 data = va_arg(args, void*); 47 48 if (type == LTC_ASN1_EOL) { 49 break; 50 } 51 52 switch (type) { 53 case LTC_ASN1_BOOLEAN: 54 case LTC_ASN1_INTEGER: 55 case LTC_ASN1_SHORT_INTEGER: 56 case LTC_ASN1_BIT_STRING: 57 case LTC_ASN1_OCTET_STRING: 58 case LTC_ASN1_NULL: 59 case LTC_ASN1_OBJECT_IDENTIFIER: 60 case LTC_ASN1_IA5_STRING: 61 case LTC_ASN1_PRINTABLE_STRING: 62 case LTC_ASN1_UTF8_STRING: 63 case LTC_ASN1_UTCTIME: 64 case LTC_ASN1_SEQUENCE: 65 case LTC_ASN1_SET: 66 case LTC_ASN1_SETOF: 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, outlen); 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 list[x].type = type; 115 list[x].size = size; 116 list[x++].data = data; 117 break; 118 119 default: 120 va_end(args); 121 err = CRYPT_INVALID_ARG; 122 goto LBL_ERR; 123 } 124 } 125 va_end(args); 126 127 err = der_encode_sequence(list, x, out, outlen); 128 LBL_ERR: 129 XFREE(list); 130 return err; 131 } 132 133 #endif 134 135 136 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */ 137 /* $Revision: 1.11 $ */ 138 /* $Date: 2006/11/26 02:25:18 $ */ 139