Mercurial > dropbear
comparison src/pk/rsa/rsa_import.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 | 39d5d58461d6 |
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 rsa_import.c | |
15 Import a PKCS RSA key, Tom St Denis | |
16 */ | |
17 | |
18 #ifdef MRSA | |
19 | |
20 /** | |
21 Import an RSAPublicKey or RSAPrivateKey [two-prime only, defined in PKCS #1 v2.1] | |
22 @param in The packet to import from | |
23 @param inlen It's length (octets) | |
24 @param key [out] Destination for newly imported key | |
25 @return CRYPT_OK if successful, upon error allocated memory is freed | |
26 */ | |
27 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) | |
28 { | |
29 unsigned long x, y; | |
30 int err; | |
31 | |
32 LTC_ARGCHK(in != NULL); | |
33 LTC_ARGCHK(key != NULL); | |
34 | |
35 /* init key */ | |
36 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, | |
37 &key->p, &key->q, NULL)) != MP_OKAY) { | |
38 return mpi_to_ltc_error(err); | |
39 } | |
40 | |
41 /* check the header */ | |
42 if (inlen < 4) { | |
43 return CRYPT_INVALID_PACKET; | |
44 } | |
45 | |
46 /* should be 0x30 0x8{1|2} LL LL */ | |
47 if ((in[0] != 0x30) || ((in[1] != 0x81) && (in[1] != 0x82))) { | |
48 return CRYPT_INVALID_PACKET; | |
49 } | |
50 | |
51 /* ok all the ASN.1 params are fine so far, let's move up */ | |
52 x = ((unsigned long)in[2]); | |
53 y = 0; | |
54 if ((in[1] & ~0x80) == 2) { | |
55 x = (x << 8) + ((unsigned long)in[3]) + 1; | |
56 in += 1; | |
57 y = 1; | |
58 } | |
59 in += 3; /* advance input */ | |
60 x += 3; /* size of packet according to header */ | |
61 y += 3; /* used input */ | |
62 | |
63 if (x != inlen) { | |
64 return CRYPT_INVALID_PACKET; | |
65 } | |
66 | |
67 /* decrement inlen by the header size */ | |
68 inlen -= y; | |
69 | |
70 /* read first number, it's either N or 0 [0 == private key] */ | |
71 x = inlen; | |
72 if ((err = der_get_multi_integer(in, &x, &key->N, NULL)) != CRYPT_OK) { | |
73 goto LBL_ERR; | |
74 } | |
75 | |
76 /* advance */ | |
77 inlen -= x; | |
78 in += x; | |
79 | |
80 if (mp_cmp_d(&key->N, 0) == MP_EQ) { | |
81 /* it's a private key */ | |
82 if ((err = der_get_multi_integer(in, &inlen, &key->N, &key->e, | |
83 &key->d, &key->p, &key->q, &key->dP, | |
84 &key->dQ, &key->qP, NULL)) != CRYPT_OK) { | |
85 goto LBL_ERR; | |
86 } | |
87 | |
88 key->type = PK_PRIVATE; | |
89 } else if (mp_cmp_d(&key->N, 1) == MP_EQ) { | |
90 /* we don't support multi-prime RSA */ | |
91 err = CRYPT_PK_INVALID_TYPE; | |
92 goto LBL_ERR; | |
93 } else { | |
94 /* it's a public key and we lack e */ | |
95 if ((err = der_get_multi_integer(in, &inlen, &key->e, NULL)) != CRYPT_OK) { | |
96 goto LBL_ERR; | |
97 } | |
98 | |
99 /* free up some ram */ | |
100 mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL); | |
101 | |
102 key->type = PK_PUBLIC; | |
103 } | |
104 return CRYPT_OK; | |
105 LBL_ERR: | |
106 mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, | |
107 &key->qP, &key->p, &key->q, NULL); | |
108 return err; | |
109 } | |
110 | |
111 #endif /* MRSA */ | |
112 |