Skip to content

Commit 4a1477e

Browse files
committed
add (private) rsa_import_pkcs1()
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 3bf3dff commit 4a1477e

File tree

3 files changed

+78
-66
lines changed

3 files changed

+78
-66
lines changed

src/headers/tomcrypt_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ int rsa_init(rsa_key *key);
236236
void rsa_shrink_key(rsa_key *key);
237237
int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e,
238238
rsa_key *key); /* used by op-tee */
239+
int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key);
239240
#endif /* LTC_MRSA */
240241

241242
/* ---- DH Routines ---- */

src/pk/rsa/rsa_import.c

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,74 @@
99

1010
#ifdef LTC_MRSA
1111

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+
1274
/**
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+
1480
@param in The packet to import from
1581
@param inlen It's length (octets)
1682
@param key [out] Destination for newly imported key
@@ -19,7 +85,6 @@
1985
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
2086
{
2187
int err;
22-
void *zero;
2388
unsigned char *tmpbuf=NULL;
2489
unsigned long tmpbuf_len, len;
2590

@@ -60,50 +125,9 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
60125
}
61126

62127
/* 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;
104130
}
105-
err = CRYPT_OK;
106-
goto LBL_FREE;
107131

108132
LBL_ERR:
109133
rsa_free(key);

src/pk/rsa/rsa_import_pkcs8.c

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
4646
rsa_key *key)
4747
{
4848
int err;
49-
void *zero, *iter;
5049
unsigned char *buf1 = NULL, *buf2 = NULL;
5150
unsigned long buf1len, buf2len;
52-
unsigned long oid[16];
51+
unsigned long oid[16], version;
5352
const char *rsaoid;
5453
ltc_asn1_list alg_seq[2], top_seq[3];
5554
ltc_asn1_list *l = NULL;
@@ -72,9 +71,8 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
7271
buf2 = XMALLOC(buf2len);
7372
if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE1; }
7473

75-
if ((err = mp_init_multi(&zero, &iter, NULL)) != CRYPT_OK) { goto LBL_FREE2; }
7674
/* init key */
77-
if ((err = rsa_init(key)) != CRYPT_OK) { goto LBL_FREE3; }
75+
if ((err = rsa_init(key)) != CRYPT_OK) { goto LBL_FREE2; }
7876

7977
/* try to decode encrypted priv key */
8078
if ((err = pkcs8_decode_flexi(in, inlen, passwd, passwdlen, &l)) != CRYPT_OK) {
@@ -86,7 +84,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
8684
/* try to decode unencrypted priv key */
8785
LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL);
8886
LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_NULL, NULL, 0UL);
89-
LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL);
87+
LTC_SET_ASN1(top_seq, 0, LTC_ASN1_SHORT_INTEGER, &version, 1UL);
9088
LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL);
9189
LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len);
9290
err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL);
@@ -97,28 +95,17 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
9795
goto LBL_ERR;
9896
}
9997

100-
err = der_decode_sequence_multi(buf1, top_seq[2].size,
101-
LTC_ASN1_INTEGER, 1UL, zero,
102-
LTC_ASN1_INTEGER, 1UL, key->N,
103-
LTC_ASN1_INTEGER, 1UL, key->e,
104-
LTC_ASN1_INTEGER, 1UL, key->d,
105-
LTC_ASN1_INTEGER, 1UL, key->p,
106-
LTC_ASN1_INTEGER, 1UL, key->q,
107-
LTC_ASN1_INTEGER, 1UL, key->dP,
108-
LTC_ASN1_INTEGER, 1UL, key->dQ,
109-
LTC_ASN1_INTEGER, 1UL, key->qP,
110-
LTC_ASN1_EOL, 0UL, NULL);
111-
if (err != CRYPT_OK) { goto LBL_ERR; }
98+
if ((err = rsa_import_pkcs1(buf1, top_seq[2].size, key)) != CRYPT_OK) {
99+
goto LBL_ERR;
100+
}
112101
key->type = PK_PRIVATE;
113102
err = CRYPT_OK;
114-
goto LBL_FREE3;
103+
goto LBL_FREE2;
115104

116105
LBL_ERR:
117106
rsa_free(key);
118-
LBL_FREE3:
119-
mp_clear_multi(iter, zero, NULL);
120-
if (l) der_free_sequence_flexi(l);
121107
LBL_FREE2:
108+
if (l) der_free_sequence_flexi(l);
122109
XFREE(buf2);
123110
LBL_FREE1:
124111
XFREE(buf1);

0 commit comments

Comments
 (0)