|
9 | 9 |
|
10 | 10 | #ifdef LTC_MRSA |
11 | 11 |
|
| 12 | + |
| 13 | +/** |
| 14 | + Import an RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only] |
| 15 | +
|
| 16 | + The `key` passed into this function has to be already initialized and will |
| 17 | + NOT be free'd on error! |
| 18 | +
|
| 19 | + @param in The packet to import from |
| 20 | + @param inlen It's length (octets) |
| 21 | + @param key [out] Destination for newly imported key |
| 22 | + @return CRYPT_OK if successful |
| 23 | +*/ |
| 24 | +int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key) |
| 25 | +{ |
| 26 | + int err; |
| 27 | + unsigned long version = -1; |
| 28 | + |
| 29 | + err = der_decode_sequence_multi(in, inlen, LTC_ASN1_SHORT_INTEGER, 1UL, &version, |
| 30 | + LTC_ASN1_EOL, 0UL, NULL); |
| 31 | + |
| 32 | + if (err == CRYPT_OVERFLOW) { |
| 33 | + /* the version would fit into an LTC_ASN1_SHORT_INTEGER |
| 34 | + * so we try to decode as a public key |
| 35 | + */ |
| 36 | + if ((err = der_decode_sequence_multi(in, inlen, |
| 37 | + LTC_ASN1_INTEGER, 1UL, key->N, |
| 38 | + LTC_ASN1_INTEGER, 1UL, key->e, |
| 39 | + LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { |
| 40 | + key->type = PK_PUBLIC; |
| 41 | + } |
| 42 | + goto LBL_OUT; |
| 43 | + } else if (err != CRYPT_INPUT_TOO_LONG) { |
| 44 | + /* couldn't decode the version, so error out */ |
| 45 | + goto LBL_OUT; |
| 46 | + } |
| 47 | + |
| 48 | + if (version == 0) { |
| 49 | + /* it's a private key */ |
| 50 | + if ((err = der_decode_sequence_multi(in, inlen, |
| 51 | + LTC_ASN1_SHORT_INTEGER, 1UL, &version, |
| 52 | + LTC_ASN1_INTEGER, 1UL, key->N, |
| 53 | + LTC_ASN1_INTEGER, 1UL, key->e, |
| 54 | + LTC_ASN1_INTEGER, 1UL, key->d, |
| 55 | + LTC_ASN1_INTEGER, 1UL, key->p, |
| 56 | + LTC_ASN1_INTEGER, 1UL, key->q, |
| 57 | + LTC_ASN1_INTEGER, 1UL, key->dP, |
| 58 | + LTC_ASN1_INTEGER, 1UL, key->dQ, |
| 59 | + LTC_ASN1_INTEGER, 1UL, key->qP, |
| 60 | + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
| 61 | + goto LBL_OUT; |
| 62 | + } |
| 63 | + key->type = PK_PRIVATE; |
| 64 | + } else if (version == 1) { |
| 65 | + /* we don't support multi-prime RSA */ |
| 66 | + err = CRYPT_PK_INVALID_TYPE; |
| 67 | + goto LBL_OUT; |
| 68 | + } |
| 69 | + err = CRYPT_OK; |
| 70 | +LBL_OUT: |
| 71 | + return err; |
| 72 | +} |
| 73 | + |
12 | 74 | /** |
13 | | - Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1] |
| 75 | + Import multiple formats of RSA public and private keys. |
| 76 | +
|
| 77 | + RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only] |
| 78 | + SubjectPublicKeyInfo formatted public keys |
| 79 | +
|
14 | 80 | @param in The packet to import from |
15 | 81 | @param inlen It's length (octets) |
16 | 82 | @param key [out] Destination for newly imported key |
|
19 | 85 | int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) |
20 | 86 | { |
21 | 87 | int err; |
22 | | - void *zero; |
23 | 88 | unsigned char *tmpbuf=NULL; |
24 | 89 | unsigned long tmpbuf_len, len; |
25 | 90 |
|
@@ -60,50 +125,9 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) |
60 | 125 | } |
61 | 126 |
|
62 | 127 | /* not SSL public key, try to match against PKCS #1 standards */ |
63 | | - err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N, |
64 | | - LTC_ASN1_EOL, 0UL, NULL); |
65 | | - |
66 | | - if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { |
67 | | - goto LBL_ERR; |
68 | | - } |
69 | | - |
70 | | - if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { |
71 | | - if ((err = mp_init(&zero)) != CRYPT_OK) { |
72 | | - goto LBL_ERR; |
73 | | - } |
74 | | - /* it's a private key */ |
75 | | - if ((err = der_decode_sequence_multi(in, inlen, |
76 | | - LTC_ASN1_INTEGER, 1UL, zero, |
77 | | - LTC_ASN1_INTEGER, 1UL, key->N, |
78 | | - LTC_ASN1_INTEGER, 1UL, key->e, |
79 | | - LTC_ASN1_INTEGER, 1UL, key->d, |
80 | | - LTC_ASN1_INTEGER, 1UL, key->p, |
81 | | - LTC_ASN1_INTEGER, 1UL, key->q, |
82 | | - LTC_ASN1_INTEGER, 1UL, key->dP, |
83 | | - LTC_ASN1_INTEGER, 1UL, key->dQ, |
84 | | - LTC_ASN1_INTEGER, 1UL, key->qP, |
85 | | - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
86 | | - mp_clear(zero); |
87 | | - goto LBL_ERR; |
88 | | - } |
89 | | - mp_clear(zero); |
90 | | - key->type = PK_PRIVATE; |
91 | | - } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { |
92 | | - /* we don't support multi-prime RSA */ |
93 | | - err = CRYPT_PK_INVALID_TYPE; |
94 | | - goto LBL_ERR; |
95 | | - } else { |
96 | | - /* it's a public key and we lack e */ |
97 | | - if ((err = der_decode_sequence_multi(in, inlen, |
98 | | - LTC_ASN1_INTEGER, 1UL, key->N, |
99 | | - LTC_ASN1_INTEGER, 1UL, key->e, |
100 | | - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
101 | | - goto LBL_ERR; |
102 | | - } |
103 | | - key->type = PK_PUBLIC; |
| 128 | + if ((err = rsa_import_pkcs1(in, inlen, key)) == CRYPT_OK) { |
| 129 | + goto LBL_FREE; |
104 | 130 | } |
105 | | - err = CRYPT_OK; |
106 | | - goto LBL_FREE; |
107 | 131 |
|
108 | 132 | LBL_ERR: |
109 | 133 | rsa_free(key); |
|
0 commit comments