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_integer.c 15 ASN.1 DER, decode an integer, Tom St Denis 16 */ 17 18 19 #ifdef LTC_DER 20 21 /** 22 Read a mp_int integer 23 @param in The DER encoded data 24 @param inlen Size of DER encoded data 25 @param num The first mp_int to decode 26 @return CRYPT_OK if successful 27 */ 28 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) 29 { 30 unsigned long x, y, z; 31 int err; 32 33 LTC_ARGCHK(num != NULL); 34 LTC_ARGCHK(in != NULL); 35 36 /* min DER INTEGER is 0x02 01 00 == 0 */ 37 if (inlen < (1 + 1 + 1)) { 38 return CRYPT_INVALID_PACKET; 39 } 40 41 /* ok expect 0x02 when we AND with 0001 1111 [1F] */ 42 x = 0; 43 if ((in[x++] & 0x1F) != 0x02) { 44 return CRYPT_INVALID_PACKET; 45 } 46 47 /* now decode the len stuff */ 48 z = in[x++]; 49 50 if ((z & 0x80) == 0x00) { 51 /* short form */ 52 53 /* will it overflow? */ 54 if (x + z > inlen) { 55 return CRYPT_INVALID_PACKET; 56 } 57 58 /* no so read it */ 59 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { 60 return err; 61 } 62 } else { 63 /* long form */ 64 z &= 0x7F; 65 66 /* will number of length bytes overflow? (or > 4) */ 67 if (((x + z) > inlen) || (z > 4) || (z == 0)) { 68 return CRYPT_INVALID_PACKET; 69 } 70 71 /* now read it in */ 72 y = 0; 73 while (z--) { 74 y = ((unsigned long)(in[x++])) | (y << 8); 75 } 76 77 /* now will reading y bytes overrun? */ 78 if ((x + y) > inlen) { 79 return CRYPT_INVALID_PACKET; 80 } 81 82 /* no so read it */ 83 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { 84 return err; 85 } 86 } 87 88 /* see if it's negative */ 89 if (in[x] & 0x80) { 90 void *tmp; 91 if (mp_init(&tmp) != CRYPT_OK) { 92 return CRYPT_MEM; 93 } 94 95 if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { 96 mp_clear(tmp); 97 return CRYPT_MEM; 98 } 99 mp_clear(tmp); 100 } 101 102 return CRYPT_OK; 103 104 } 105 106 #endif 107 108 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ 109 /* $Revision: 1.4 $ */ 110 /* $Date: 2006/03/31 14:15:35 $ */ 111