comparison src/pk/asn1/der/der_decode_integer.c @ 191:1c15b283127b libtomcrypt-orig

Import of libtomcrypt 1.02 with manual path rename rearrangement etc
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 May 2005 13:23:02 +0000
parents
children
comparison
equal deleted inserted replaced
143:5d99163f7e32 191:1c15b283127b
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, [email protected], http://libtomcrypt.org
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 /* decodes a DER INTEGER in [in]. You have to tell this function
22 * how many bytes are available [inlen]. It will then attempt to
23 * read the INTEGER. If all goes well it stores the number of bytes
24 * read in [inlen] and the number in [num].
25 */
26 /**
27 Read a mp_int integer
28 @param in The DER encoded data
29 @param inlen [in] Size of the in data, [out] number of bytes read
30 @param num The first mp_int to decode
31 @return CRYPT_OK if successful
32 */
33 int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num)
34 {
35 unsigned long tmplen, y, z;
36
37 LTC_ARGCHK(num != NULL);
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(inlen != NULL);
40
41 /* save copy of max output size */
42 tmplen = *inlen;
43 *inlen = 0;
44
45 /* min DER INTEGER is 0x02 01 00 == 0 */
46 if (tmplen < (1 + 1 + 1)) {
47 return CRYPT_INVALID_PACKET;
48 }
49
50 /* ok expect 0x02 when we AND with 0011 1111 [3F] */
51 if ((*in++ & 0x3F) != 0x02) {
52 return CRYPT_INVALID_PACKET;
53 }
54 ++(*inlen);
55
56 /* now decode the len stuff */
57 z = *in++;
58 ++(*inlen);
59
60 if ((z & 0x80) == 0x00) {
61 /* short form */
62
63 /* will it overflow? */
64 if (*inlen + z > tmplen) {
65 return CRYPT_INVALID_PACKET;
66 }
67
68 /* no so read it */
69 (*inlen) += z;
70 return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z));
71 } else {
72 /* long form */
73 z &= 0x7F;
74
75 /* will number of length bytes overflow? (or > 4) */
76 if (((*inlen + z) > tmplen) || (z > 4)) {
77 return CRYPT_INVALID_PACKET;
78 }
79
80 /* now read it in */
81 y = 0;
82 while (z--) {
83 y = ((unsigned long)(*in++)) | (y << 8);
84 ++(*inlen);
85 }
86
87 /* now will reading y bytes overrun? */
88 if ((*inlen + y) > tmplen) {
89 return CRYPT_INVALID_PACKET;
90 }
91
92 /* no so read it */
93 (*inlen) += y;
94 return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y));
95 }
96 }
97
98 #endif