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 (at) 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 $ */ 170