Mercurial > dropbear
comparison rsa_import.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 | 6362d3854bb4 |
children |
comparison
equal
deleted
inserted
replaced
15:6362d3854bb4 | 143:5d99163f7e32 |
---|---|
11 | 11 |
12 #include "mycrypt.h" | 12 #include "mycrypt.h" |
13 | 13 |
14 #ifdef MRSA | 14 #ifdef MRSA |
15 | 15 |
16 /* import an RSAPublicKey or RSAPrivateKey [two-prime only, defined in PKCS #1 v2.1] */ | |
16 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) | 17 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) |
17 { | 18 { |
18 unsigned long x, y; | 19 unsigned long x; |
19 int err; | 20 int err; |
20 | 21 |
21 _ARGCHK(in != NULL); | 22 _ARGCHK(in != NULL); |
22 _ARGCHK(key != NULL); | 23 _ARGCHK(key != NULL); |
23 | 24 |
24 /* check length */ | |
25 if (inlen < (1+PACKET_SIZE)) { | |
26 return CRYPT_INVALID_PACKET; | |
27 } | |
28 | |
29 /* test packet header */ | |
30 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) { | |
31 return err; | |
32 } | |
33 | |
34 /* init key */ | 25 /* init key */ |
35 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, | 26 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, |
36 &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) { | 27 &key->p, &key->q, NULL)) != MP_OKAY) { |
37 return mpi_to_ltc_error(err); | 28 return mpi_to_ltc_error(err); |
38 } | 29 } |
39 | 30 |
40 /* get key type */ | 31 /* read first number, it's either N or 0 [0 == private key] */ |
41 y = PACKET_SIZE; | 32 x = inlen; |
42 key->type = (int)in[y++]; | 33 if ((err = der_get_multi_integer(in, &x, &key->N, NULL)) != CRYPT_OK) { |
43 | 34 goto __ERR; |
44 /* load the modulus */ | |
45 INPUT_BIGNUM(&key->N, in, x, y, inlen); | |
46 | |
47 /* load public exponent */ | |
48 INPUT_BIGNUM(&key->e, in, x, y, inlen); | |
49 | |
50 /* get private exponent */ | |
51 if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) { | |
52 INPUT_BIGNUM(&key->d, in, x, y, inlen); | |
53 } | 35 } |
54 | 36 |
55 /* get CRT private data if required */ | 37 /* advance */ |
56 if (key->type == PK_PRIVATE_OPTIMIZED) { | 38 inlen -= x; |
57 INPUT_BIGNUM(&key->dQ, in, x, y, inlen); | 39 in += x; |
58 INPUT_BIGNUM(&key->dP, in, x, y, inlen); | 40 |
59 INPUT_BIGNUM(&key->pQ, in, x, y, inlen); | 41 if (mp_cmp_d(&key->N, 0) == MP_EQ) { |
60 INPUT_BIGNUM(&key->qP, in, x, y, inlen); | 42 /* it's a private key */ |
61 INPUT_BIGNUM(&key->p, in, x, y, inlen); | 43 if ((err = der_get_multi_integer(in, &inlen, &key->N, &key->e, |
62 INPUT_BIGNUM(&key->q, in, x, y, inlen); | 44 &key->d, &key->p, &key->q, &key->dP, |
45 &key->dQ, &key->qP, NULL)) != CRYPT_OK) { | |
46 goto __ERR; | |
47 } | |
48 | |
49 key->type = PK_PRIVATE; | |
50 } else { | |
51 /* it's a public key and we lack e */ | |
52 if ((err = der_get_multi_integer(in, &inlen, &key->e, NULL)) != CRYPT_OK) { | |
53 goto __ERR; | |
54 } | |
55 | |
56 /* free up some ram */ | |
57 mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL); | |
58 | |
59 key->type = PK_PUBLIC; | |
63 } | 60 } |
64 | |
65 /* free up ram not required */ | |
66 if (key->type != PK_PRIVATE_OPTIMIZED) { | |
67 mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL); | |
68 } | |
69 if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { | |
70 mp_clear(&key->d); | |
71 } | |
72 | |
73 return CRYPT_OK; | 61 return CRYPT_OK; |
74 error: | 62 __ERR: |
75 mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, | 63 mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, |
76 &key->pQ, &key->qP, &key->p, &key->q, NULL); | 64 &key->qP, &key->p, &key->q, NULL); |
77 return err; | 65 return err; |
78 } | 66 } |
79 | 67 |
80 #endif /* MRSA */ | 68 #endif /* MRSA */ |
81 | 69 |