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_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 */
der_encode_sequence_multi(unsigned char * out,unsigned long * outlen,...)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