version 0.3.33
[fms.git] / libs / libtomcrypt / 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  * 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 */
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 $ */