]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / sequence / der_encode_sequence_ex.c
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
11
12 /**
13   @file der_encode_sequence_ex.c
14   ASN.1 DER, encode a SEQUENCE, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20    Encode a SEQUENCE
21    @param list      The list of items to encode
22    @param inlen     The number of items in the list
23    @param out       [out] The destination
24    @param outlen    [in/out] The size of the output
25    @param type_of   LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
26    @return CRYPT_OK on success
27 */
28 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
29                            unsigned char *out,  unsigned long *outlen, int type_of)
30 {
31    int           err;
32    ltc_asn1_type type;
33    unsigned long size, x, y, z, i;
34    void          *data;
35
36    LTC_ARGCHK(list    != NULL);
37    LTC_ARGCHK(out     != NULL);
38    LTC_ARGCHK(outlen  != NULL);
39
40    /* get size of output that will be required */
41    y = 0; z = 0;
42    if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG;
43
44    /* too big ? */
45    if (*outlen < y) {
46       *outlen = y;
47       err = CRYPT_BUFFER_OVERFLOW;
48       goto LBL_ERR;
49    }
50
51    /* store header */
52    x = 0;
53    out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
54
55    if (z < 128) {
56       out[x++] = (unsigned char)z;
57    } else if (z < 256) {
58       out[x++] = 0x81;
59       out[x++] = (unsigned char)z;
60    } else if (z < 65536UL) {
61       out[x++] = 0x82;
62       out[x++] = (unsigned char)((z>>8UL)&255);
63       out[x++] = (unsigned char)(z&255);
64    } else if (z < 16777216UL) {
65       out[x++] = 0x83;
66       out[x++] = (unsigned char)((z>>16UL)&255);
67       out[x++] = (unsigned char)((z>>8UL)&255);
68       out[x++] = (unsigned char)(z&255);
69    }
70
71    /* store data */
72    *outlen -= x;
73    for (i = 0; i < inlen; i++) {
74        type = list[i].type;
75        size = list[i].size;
76        data = list[i].data;
77
78        if (type == LTC_ASN1_EOL) {
79           break;
80        }
81
82        switch (type) {
83             case LTC_ASN1_BOOLEAN:
84                z = *outlen;
85                if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
86                   goto LBL_ERR;
87                }
88                break;
89
90            case LTC_ASN1_INTEGER:
91                z = *outlen;
92                if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
93                   goto LBL_ERR;
94                }
95                break;
96
97            case LTC_ASN1_SHORT_INTEGER:
98                z = *outlen;
99                if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
100                   goto LBL_ERR;
101                }
102                break;
103
104            case LTC_ASN1_BIT_STRING:
105                z = *outlen;
106                if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
107                   goto LBL_ERR;
108                }
109                break;
110
111            case LTC_ASN1_RAW_BIT_STRING:
112                z = *outlen;
113                if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
114                   goto LBL_ERR;
115                }
116                break;
117
118            case LTC_ASN1_OCTET_STRING:
119                z = *outlen;
120                if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
121                   goto LBL_ERR;
122                }
123                break;
124
125            case LTC_ASN1_NULL:
126                out[x] = 0x05;
127                out[x+1] = 0x00;
128                z = 2;
129                break;
130
131            case LTC_ASN1_OBJECT_IDENTIFIER:
132                z = *outlen;
133                if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
134                   goto LBL_ERR;
135                }
136                break;
137
138            case LTC_ASN1_IA5_STRING:
139                z = *outlen;
140                if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
141                   goto LBL_ERR;
142                }
143                break;
144
145            case LTC_ASN1_PRINTABLE_STRING:
146                z = *outlen;
147                if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
148                   goto LBL_ERR;
149                }
150                break;
151
152            case LTC_ASN1_UTF8_STRING:
153                z = *outlen;
154                if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
155                   goto LBL_ERR;
156                }
157                break;
158
159            case LTC_ASN1_UTCTIME:
160                z = *outlen;
161                if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
162                   goto LBL_ERR;
163                }
164                break;
165
166            case LTC_ASN1_GENERALIZEDTIME:
167                z = *outlen;
168                if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) {
169                   goto LBL_ERR;
170                }
171                break;
172
173            case LTC_ASN1_SET:
174                z = *outlen;
175                if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
176                   goto LBL_ERR;
177                }
178                break;
179
180            case LTC_ASN1_SETOF:
181                z = *outlen;
182                if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
183                   goto LBL_ERR;
184                }
185                break;
186
187            case LTC_ASN1_SEQUENCE:
188                z = *outlen;
189                if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
190                   goto LBL_ERR;
191                }
192                break;
193
194            case LTC_ASN1_CHOICE:
195            case LTC_ASN1_CONSTRUCTED:
196            case LTC_ASN1_CONTEXT_SPECIFIC:
197            case LTC_ASN1_EOL:
198            case LTC_ASN1_TELETEX_STRING:
199                err = CRYPT_INVALID_ARG;
200                goto LBL_ERR;
201        }
202
203        x       += z;
204        *outlen -= z;
205    }
206    *outlen = x;
207    err = CRYPT_OK;
208
209 LBL_ERR:
210    return err;
211 }
212
213 #endif
214
215 /* ref:         $Format:%D$ */
216 /* git commit:  $Format:%H$ */
217 /* commit time: $Format:%ai$ */