comparison der_decode_integer.c @ 143:5d99163f7e32 libtomcrypt-orig

import of libtomcrypt 0.99
author Matt Johnston <matt@ucc.asn.au>
date Sun, 19 Dec 2004 11:34:45 +0000
parents
children
comparison
equal deleted inserted replaced
15:6362d3854bb4 143:5d99163f7e32
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
12 #include "mycrypt.h"
13
14
15 /* decodes a DER INTEGER in [in]. You have to tell this function
16 * how many bytes are available [inlen]. It will then attempt to
17 * read the INTEGER. If all goes well it stores the number of bytes
18 * read in [inlen] and the number in [num].
19 */
20 int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num)
21 {
22 unsigned long tmplen, y, z;
23
24 _ARGCHK(num != NULL);
25 _ARGCHK(in != NULL);
26 _ARGCHK(inlen != NULL);
27
28 /* save copy of max output size */
29 tmplen = *inlen;
30 *inlen = 0;
31
32 /* min DER INTEGER is 0x02 01 00 == 0 */
33 if (tmplen < (1 + 1 + 1)) {
34 return CRYPT_INVALID_PACKET;
35 }
36
37 /* ok expect 0x02 when we AND with 0011 1111 [3F] */
38 if ((*in++ & 0x3F) != 0x02) {
39 return CRYPT_INVALID_PACKET;
40 }
41 ++(*inlen);
42
43 /* now decode the len stuff */
44 z = *in++;
45 ++(*inlen);
46
47 if ((z & 0x80) == 0x00) {
48 /* short form */
49
50 /* will it overflow? */
51 if (*inlen + z > tmplen) {
52 return CRYPT_INVALID_PACKET;
53 }
54
55 /* no so read it */
56 (*inlen) += z;
57 return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z));
58 } else {
59 /* long form */
60 z &= 0x7F;
61
62 /* will number of length bytes overflow? (or > 4) */
63 if (((*inlen + z) > tmplen) || (z > 4)) {
64 return CRYPT_INVALID_PACKET;
65 }
66
67 /* now read it in */
68 y = 0;
69 while (z--) {
70 y = ((unsigned long)(*in++)) | (y << 8);
71 ++(*inlen);
72 }
73
74 /* now will reading y bytes overrun? */
75 if ((*inlen + y) > tmplen) {
76 return CRYPT_INVALID_PACKET;
77 }
78
79 /* no so read it */
80 (*inlen) += y;
81 return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y));
82 }
83 }