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