Mercurial > dropbear
comparison src/pk/rsa/rsa_import.c @ 210:4768b55c5240 libtomcrypt
propagate from branch 'au.asn.ucc.matt.ltc-orig' (head 33c416b902f1a44913d825bae7ad9a160f703ed3)
to branch 'au.asn.ucc.matt.dropbear.ltc' (head 4d6aec6e6121e13f68c11c149b6579c41cb63e74)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 06 Jul 2005 12:10:23 +0000 |
parents | 39d5d58461d6 |
children |
comparison
equal
deleted
inserted
replaced
199:8be64e2c86f4 | 210:4768b55c5240 |
---|---|
16 */ | 16 */ |
17 | 17 |
18 #ifdef MRSA | 18 #ifdef MRSA |
19 | 19 |
20 /** | 20 /** |
21 Import an RSAPublicKey or RSAPrivateKey [two-prime only, defined in PKCS #1 v2.1] | 21 Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1] |
22 @param in The packet to import from | 22 @param in The packet to import from |
23 @param inlen It's length (octets) | 23 @param inlen It's length (octets) |
24 @param key [out] Destination for newly imported key | 24 @param key [out] Destination for newly imported key |
25 @return CRYPT_OK if successful, upon error allocated memory is freed | 25 @return CRYPT_OK if successful, upon error allocated memory is freed |
26 */ | 26 */ |
27 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) | 27 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) |
28 { | 28 { |
29 unsigned long x, y; | 29 int err; |
30 int err; | 30 mp_int zero; |
31 | 31 |
32 LTC_ARGCHK(in != NULL); | 32 LTC_ARGCHK(in != NULL); |
33 LTC_ARGCHK(key != NULL); | 33 LTC_ARGCHK(key != NULL); |
34 | 34 |
35 /* init key */ | 35 /* init key */ |
36 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, | 36 if ((err = mp_init_multi(&zero, &key->e, &key->d, &key->N, &key->dQ, |
37 &key->p, &key->q, NULL)) != MP_OKAY) { | 37 &key->dP, &key->qP, &key->p, &key->q, NULL)) != MP_OKAY) { |
38 return mpi_to_ltc_error(err); | 38 return mpi_to_ltc_error(err); |
39 } | 39 } |
40 | 40 |
41 /* check the header */ | 41 if ((err = der_decode_sequence_multi(in, inlen, |
42 if (inlen < 4) { | 42 LTC_ASN1_INTEGER, 1UL, &key->N, |
43 return CRYPT_INVALID_PACKET; | 43 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
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; | 44 goto LBL_ERR; |
74 } | 45 } |
75 | 46 |
76 /* advance */ | |
77 inlen -= x; | |
78 in += x; | |
79 | |
80 if (mp_cmp_d(&key->N, 0) == MP_EQ) { | 47 if (mp_cmp_d(&key->N, 0) == MP_EQ) { |
81 /* it's a private key */ | 48 /* it's a private key */ |
82 if ((err = der_get_multi_integer(in, &inlen, &key->N, &key->e, | 49 if ((err = der_decode_sequence_multi(in, inlen, |
83 &key->d, &key->p, &key->q, &key->dP, | 50 LTC_ASN1_INTEGER, 1UL, &zero, |
84 &key->dQ, &key->qP, NULL)) != CRYPT_OK) { | 51 LTC_ASN1_INTEGER, 1UL, &key->N, |
52 LTC_ASN1_INTEGER, 1UL, &key->e, | |
53 LTC_ASN1_INTEGER, 1UL, &key->d, | |
54 LTC_ASN1_INTEGER, 1UL, &key->p, | |
55 LTC_ASN1_INTEGER, 1UL, &key->q, | |
56 LTC_ASN1_INTEGER, 1UL, &key->dP, | |
57 LTC_ASN1_INTEGER, 1UL, &key->dQ, | |
58 LTC_ASN1_INTEGER, 1UL, &key->qP, | |
59 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { | |
85 goto LBL_ERR; | 60 goto LBL_ERR; |
86 } | 61 } |
87 | |
88 key->type = PK_PRIVATE; | 62 key->type = PK_PRIVATE; |
89 } else if (mp_cmp_d(&key->N, 1) == MP_EQ) { | 63 } else if (mp_cmp_d(&key->N, 1) == MP_EQ) { |
90 /* we don't support multi-prime RSA */ | 64 /* we don't support multi-prime RSA */ |
91 err = CRYPT_PK_INVALID_TYPE; | 65 err = CRYPT_PK_INVALID_TYPE; |
92 goto LBL_ERR; | 66 goto LBL_ERR; |
93 } else { | 67 } else { |
94 /* it's a public key and we lack e */ | 68 /* it's a public key and we lack e */ |
95 if ((err = der_get_multi_integer(in, &inlen, &key->e, NULL)) != CRYPT_OK) { | 69 if ((err = der_decode_sequence_multi(in, inlen, |
70 LTC_ASN1_INTEGER, 1UL, &key->N, | |
71 LTC_ASN1_INTEGER, 1UL, &key->e, | |
72 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { | |
96 goto LBL_ERR; | 73 goto LBL_ERR; |
97 } | 74 } |
98 | 75 |
99 /* free up some ram */ | 76 /* free up some ram */ |
100 mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL); | 77 mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL); |
101 | |
102 key->type = PK_PUBLIC; | 78 key->type = PK_PUBLIC; |
103 } | 79 } |
104 return CRYPT_OK; | 80 return CRYPT_OK; |
105 LBL_ERR: | 81 LBL_ERR: |
106 mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, | 82 mp_clear_multi(&zero, &key->d, &key->e, &key->N, &key->dQ, &key->dP, |
107 &key->qP, &key->p, &key->q, NULL); | 83 &key->qP, &key->p, &key->q, NULL); |
108 return err; | 84 return err; |
109 } | 85 } |
110 | 86 |
111 #endif /* MRSA */ | 87 #endif /* MRSA */ |
112 | 88 |
89 | |
90 /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ | |
91 /* $Revision: 1.10 $ */ | |
92 /* $Date: 2005/06/03 18:48:28 $ */ |