Home | History | Annotate | Download | only in sequence
      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