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