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