Home | History | Annotate | Download | only in bit
      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_decode_bit_string.c
     15   ASN.1 DER, encode a BIT STRING, Tom St Denis
     16 */
     17 
     18 
     19 #ifdef LTC_DER
     20 
     21 /**
     22   Store a BIT STRING
     23   @param in      The DER encoded BIT STRING
     24   @param inlen   The size of the DER BIT STRING
     25   @param out     [out] The array of bits stored (one per char)
     26   @param outlen  [in/out] The number of bits stored
     27   @return CRYPT_OK if successful
     28 */
     29 int der_decode_bit_string(const unsigned char *in,  unsigned long inlen,
     30                                 unsigned char *out, unsigned long *outlen)
     31 {
     32    unsigned long dlen, blen, x, y;
     33 
     34    LTC_ARGCHK(in     != NULL);
     35    LTC_ARGCHK(out    != NULL);
     36    LTC_ARGCHK(outlen != NULL);
     37 
     38    /* packet must be at least 4 bytes */
     39    if (inlen < 4) {
     40        return CRYPT_INVALID_ARG;
     41    }
     42 
     43    /* check for 0x03 */
     44    if ((in[0]&0x1F) != 0x03) {
     45       return CRYPT_INVALID_PACKET;
     46    }
     47 
     48     /* offset in the data */
     49     x = 1;
     50 
     51    /* get the length of the data */
     52    if (in[x] & 0x80) {
     53       /* long format get number of length bytes */
     54       y = in[x++] & 0x7F;
     55 
     56       /* invalid if 0 or > 2 */
     57       if (y == 0 || y > 2) {
     58          return CRYPT_INVALID_PACKET;
     59       }
     60 
     61       /* read the data len */
     62       dlen = 0;
     63       while (y--) {
     64          dlen = (dlen << 8) | (unsigned long)in[x++];
     65       }
     66    } else {
     67       /* short format */
     68       dlen = in[x++] & 0x7F;
     69    }
     70 
     71    /* is the data len too long or too short? */
     72    if ((dlen == 0) || (dlen + x > inlen)) {
     73        return CRYPT_INVALID_PACKET;
     74    }
     75 
     76    /* get padding count */
     77    blen = ((dlen - 1) << 3) - (in[x++] & 7);
     78 
     79    /* too many bits? */
     80    if (blen > *outlen) {
     81       *outlen = blen;
     82       return CRYPT_BUFFER_OVERFLOW;
     83    }
     84 
     85    /* decode/store the bits */
     86    for (y = 0; y < blen; y++) {
     87        out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
     88        if ((y & 7) == 7) {
     89           ++x;
     90        }
     91    }
     92 
     93    /* we done */
     94    *outlen = blen;
     95    return CRYPT_OK;
     96 }
     97 
     98 #endif
     99 
    100 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */
    101 /* $Revision: 1.4 $ */
    102 /* $Date: 2006/06/16 21:53:41 $ */
    103