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 #include <stdarg.h>
11
12
13 /**
14 @file der_encode_sequence_multi.c
15 ASN.1 DER, encode a SEQUENCE, Tom St Denis
16 */
17
18 #ifdef LTC_DER
19
20 /**
21 Encode a SEQUENCE type using a VA list
22 @param out [out] Destination for data
23 @param outlen [in/out] Length of buffer and resulting length of output
24 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
25 @return CRYPT_OK on success
26 */
der_encode_sequence_multi(unsigned char * out,unsigned long * outlen,...)27 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
28 {
29 int err;
30 ltc_asn1_type type;
31 unsigned long size, x;
32 void *data;
33 va_list args;
34 ltc_asn1_list *list;
35
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* get size of output that will be required */
40 va_start(args, outlen);
41 x = 0;
42 for (;;) {
43 type = (ltc_asn1_type)va_arg(args, int);
44 size = va_arg(args, unsigned long);
45 data = va_arg(args, void*);
46 LTC_UNUSED_PARAM(size);
47 LTC_UNUSED_PARAM(data);
48
49 if (type == LTC_ASN1_EOL) {
50 break;
51 }
52
53 switch (type) {
54 case LTC_ASN1_BOOLEAN:
55 case LTC_ASN1_INTEGER:
56 case LTC_ASN1_SHORT_INTEGER:
57 case LTC_ASN1_BIT_STRING:
58 case LTC_ASN1_OCTET_STRING:
59 case LTC_ASN1_NULL:
60 case LTC_ASN1_OBJECT_IDENTIFIER:
61 case LTC_ASN1_IA5_STRING:
62 case LTC_ASN1_PRINTABLE_STRING:
63 case LTC_ASN1_UTF8_STRING:
64 case LTC_ASN1_UTCTIME:
65 case LTC_ASN1_SEQUENCE:
66 case LTC_ASN1_SET:
67 case LTC_ASN1_SETOF:
68 case LTC_ASN1_RAW_BIT_STRING:
69 case LTC_ASN1_GENERALIZEDTIME:
70 ++x;
71 break;
72
73 case LTC_ASN1_CHOICE:
74 case LTC_ASN1_CONSTRUCTED:
75 case LTC_ASN1_CONTEXT_SPECIFIC:
76 case LTC_ASN1_EOL:
77 case LTC_ASN1_TELETEX_STRING:
78 va_end(args);
79 return CRYPT_INVALID_ARG;
80 }
81 }
82 va_end(args);
83
84 /* allocate structure for x elements */
85 if (x == 0) {
86 return CRYPT_NOP;
87 }
88
89 list = XCALLOC(sizeof(*list), x);
90 if (list == NULL) {
91 return CRYPT_MEM;
92 }
93
94 /* fill in the structure */
95 va_start(args, outlen);
96 x = 0;
97 for (;;) {
98 type = (ltc_asn1_type)va_arg(args, int);
99 size = va_arg(args, unsigned long);
100 data = va_arg(args, void*);
101
102 if (type == LTC_ASN1_EOL) {
103 break;
104 }
105
106 switch (type) {
107 case LTC_ASN1_BOOLEAN:
108 case LTC_ASN1_INTEGER:
109 case LTC_ASN1_SHORT_INTEGER:
110 case LTC_ASN1_BIT_STRING:
111 case LTC_ASN1_OCTET_STRING:
112 case LTC_ASN1_NULL:
113 case LTC_ASN1_OBJECT_IDENTIFIER:
114 case LTC_ASN1_IA5_STRING:
115 case LTC_ASN1_PRINTABLE_STRING:
116 case LTC_ASN1_UTF8_STRING:
117 case LTC_ASN1_UTCTIME:
118 case LTC_ASN1_SEQUENCE:
119 case LTC_ASN1_SET:
120 case LTC_ASN1_SETOF:
121 case LTC_ASN1_RAW_BIT_STRING:
122 case LTC_ASN1_GENERALIZEDTIME:
123 LTC_SET_ASN1(list, x++, type, data, size);
124 break;
125
126 case LTC_ASN1_CHOICE:
127 case LTC_ASN1_CONSTRUCTED:
128 case LTC_ASN1_CONTEXT_SPECIFIC:
129 case LTC_ASN1_EOL:
130 case LTC_ASN1_TELETEX_STRING:
131 va_end(args);
132 err = CRYPT_INVALID_ARG;
133 goto LBL_ERR;
134 }
135 }
136 va_end(args);
137
138 err = der_encode_sequence(list, x, out, outlen);
139 LBL_ERR:
140 XFREE(list);
141 return err;
142 }
143
144 #endif
145
146
147 /* ref: HEAD -> master, tag: v1.18.2 */
148 /* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
149 /* commit time: 2018-07-01 22:49:01 +0200 */
150