Skip to content

Commit 26e3c02

Browse files
committed
add dsa_import_pkcs8()
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent b383b58 commit 26e3c02

File tree

9 files changed

+170
-51
lines changed

9 files changed

+170
-51
lines changed

src/headers/tomcrypt_pk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
463463
const dsa_key *key);
464464

465465
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
466+
int dsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
467+
const password_ctx *pw_ctx,
468+
dsa_key *key);
466469
int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key);
467470
int dsa_verify_key(const dsa_key *key, int *stat);
468471
int dsa_shared_secret(void *private_key, void *base,

src/headers/tomcrypt_private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,13 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
398398
#endif /* LTC_MECC */
399399

400400
#ifdef LTC_MDSA
401+
int dsa_int_init(dsa_key *key);
402+
int dsa_int_validate(const dsa_key *key, int *stat);
401403
int dsa_int_validate_xy(const dsa_key *key, int *stat);
402404
int dsa_int_validate_pqg(const dsa_key *key, int *stat);
403405
int dsa_int_validate_primes(const dsa_key *key, int *stat);
406+
int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key);
407+
int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key);
404408
#endif /* LTC_MDSA */
405409

406410

src/pk/dsa/dsa_generate_pqg.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,8 @@ int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_si
209209
{
210210
int err;
211211

212-
LTC_ARGCHK(key != NULL);
213-
LTC_ARGCHK(ltc_mp.name != NULL);
214-
215-
/* init mp_ints */
216-
if ((err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL)) != CRYPT_OK) {
217-
return err;
218-
}
212+
/* init key */
213+
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
219214
/* generate params */
220215
err = s_dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
221216
if (err != CRYPT_OK) {

src/pk/dsa/dsa_import.c

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@
99

1010
#ifdef LTC_MDSA
1111

12+
int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key)
13+
{
14+
int err;
15+
unsigned long zero = 0;
16+
/* get key type */
17+
if ((err = der_decode_sequence_multi(in, inlen,
18+
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
19+
LTC_ASN1_INTEGER, 1UL, key->p,
20+
LTC_ASN1_INTEGER, 1UL, key->q,
21+
LTC_ASN1_INTEGER, 1UL, key->g,
22+
LTC_ASN1_INTEGER, 1UL, key->y,
23+
LTC_ASN1_INTEGER, 1UL, key->x,
24+
LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
25+
26+
key->type = PK_PRIVATE;
27+
}
28+
return err;
29+
}
30+
1231
/**
1332
Import a DSA key
1433
@param in The binary packet to import from
@@ -19,18 +38,13 @@
1938
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
2039
{
2140
int err, stat;
22-
unsigned long zero = 0, len;
2341
unsigned char* tmpbuf = NULL;
2442
unsigned char flags[1];
2543

2644
LTC_ARGCHK(in != NULL);
27-
LTC_ARGCHK(key != NULL);
28-
LTC_ARGCHK(ltc_mp.name != NULL);
2945

3046
/* init key */
31-
if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
32-
return CRYPT_MEM;
33-
}
47+
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
3448

3549
/* try to match the old libtomcrypt format */
3650
err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
@@ -71,62 +85,44 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
7185
goto LBL_ERR;
7286
}
7387
}
74-
/* get key type */
75-
if ((err = der_decode_sequence_multi(in, inlen,
76-
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
77-
LTC_ASN1_INTEGER, 1UL, key->p,
78-
LTC_ASN1_INTEGER, 1UL, key->q,
79-
LTC_ASN1_INTEGER, 1UL, key->g,
80-
LTC_ASN1_INTEGER, 1UL, key->y,
81-
LTC_ASN1_INTEGER, 1UL, key->x,
82-
LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
8388

84-
key->type = PK_PRIVATE;
85-
} else { /* public */
89+
if ((err = dsa_import_pkcs1(in, inlen, key)) != CRYPT_OK) {
8690
ltc_asn1_list params[3];
87-
unsigned long tmpbuf_len = inlen;
91+
unsigned long tmpbuf_len = inlen, len;
8892

8993
LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
9094
LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
9195
LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
9296

9397
tmpbuf = XCALLOC(1, tmpbuf_len);
9498
if (tmpbuf == NULL) {
95-
err = CRYPT_MEM;
96-
goto LBL_ERR;
99+
return CRYPT_MEM;
97100
}
98101

99102
len = 3;
100103
err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_DSA,
101-
tmpbuf, &tmpbuf_len,
102-
LTC_ASN1_SEQUENCE, params, &len);
104+
tmpbuf, &tmpbuf_len,
105+
LTC_ASN1_SEQUENCE, params, &len);
103106
if (err != CRYPT_OK) {
104107
XFREE(tmpbuf);
105108
goto LBL_ERR;
106109
}
107110

108-
if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
111+
if ((err = der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
109112
XFREE(tmpbuf);
110113
goto LBL_ERR;
111114
}
112115

113-
XFREE(tmpbuf);
114116
key->type = PK_PUBLIC;
117+
XFREE(tmpbuf);
115118
}
116119

117120
LBL_OK:
118121
key->qord = mp_unsigned_bin_size(key->q);
119122

120-
/* quick p, q, g validation, without primality testing */
121-
if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) {
122-
goto LBL_ERR;
123-
}
124-
if (stat == 0) {
125-
err = CRYPT_INVALID_PACKET;
126-
goto LBL_ERR;
127-
}
128-
/* validate x, y */
129-
if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK) {
123+
/* quick p, q, g validation, without primality testing
124+
* + x, y validation */
125+
if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
130126
goto LBL_ERR;
131127
}
132128
if (stat == 0) {

src/pk/dsa/dsa_import_pkcs8.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
#include "tomcrypt_private.h"
4+
5+
/**
6+
@file dsa_import_pkcs8.c
7+
Import a PKCS DSA key
8+
*/
9+
10+
#ifdef LTC_MDSA
11+
12+
int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key)
13+
{
14+
int err, stat;
15+
16+
LTC_UNUSED_PARAM(alg_id);
17+
18+
if (!alg_id->child
19+
|| !LTC_ASN1_IS_TYPE(alg_id->child->next, LTC_ASN1_SEQUENCE)
20+
|| !LTC_ASN1_IS_TYPE(priv_key, LTC_ASN1_OCTET_STRING)) {
21+
return CRYPT_INVALID_PACKET;
22+
}
23+
if ((err = dsa_set_pqg_dsaparam(alg_id->child->next->data, alg_id->child->next->size, key)) != CRYPT_OK) {
24+
return err;
25+
}
26+
if ((err = der_decode_integer(priv_key->data, priv_key->size, key->x)) != CRYPT_OK) {
27+
goto LBL_ERR;
28+
}
29+
if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) {
30+
goto LBL_ERR;
31+
}
32+
33+
/* quick p, q, g validation, without primality testing
34+
* + x, y validation */
35+
if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
36+
goto LBL_ERR;
37+
}
38+
if (stat == 0) {
39+
err = CRYPT_INVALID_PACKET;
40+
goto LBL_ERR;
41+
}
42+
43+
key->qord = mp_unsigned_bin_size(key->q);
44+
key->type = PK_PRIVATE;
45+
46+
return err;
47+
LBL_ERR:
48+
dsa_free(key);
49+
return err;
50+
}
51+
/**
52+
Import an RSAPrivateKey in PKCS#8 format
53+
@param in The packet to import from
54+
@param inlen It's length (octets)
55+
@param pw_ctx The password context when decrypting the private key
56+
@param key [out] Destination for newly imported key
57+
@return CRYPT_OK if successful, upon error allocated memory is freed
58+
*/
59+
int dsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
60+
const password_ctx *pw_ctx,
61+
dsa_key *key)
62+
{
63+
int err;
64+
ltc_asn1_list *l = NULL;
65+
ltc_asn1_list *alg_id, *priv_key;
66+
enum ltc_oid_id pka;
67+
68+
LTC_ARGCHK(in != NULL);
69+
70+
if ((err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l)) != CRYPT_OK) {
71+
return err;
72+
}
73+
if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
74+
goto LBL_DER_FREE;
75+
}
76+
if (pka != LTC_OID_DSA) {
77+
err = CRYPT_INVALID_PACKET;
78+
goto LBL_DER_FREE;
79+
}
80+
81+
err = dsa_import_pkcs8_asn1(alg_id, priv_key, key);
82+
83+
LBL_DER_FREE:
84+
der_free_sequence_flexi(l);
85+
return err;
86+
}
87+
88+
#endif /* LTC_MRSA */

src/pk/dsa/dsa_init.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
#include "tomcrypt_private.h"
4+
5+
6+
#ifdef LTC_MDSA
7+
8+
/**
9+
Init DSA key
10+
@param key [out] the key to init
11+
@return CRYPT_OK if successful.
12+
*/
13+
int dsa_int_init(dsa_key *key)
14+
{
15+
LTC_ARGCHK(key != NULL);
16+
LTC_ARGCHK(ltc_mp.name != NULL);
17+
18+
/* init key */
19+
return mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
20+
}
21+
22+
#endif

src/pk/dsa/dsa_set.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,9 @@ int dsa_set_pqg(const unsigned char *p, unsigned long plen,
2626
LTC_ARGCHK(p != NULL);
2727
LTC_ARGCHK(q != NULL);
2828
LTC_ARGCHK(g != NULL);
29-
LTC_ARGCHK(key != NULL);
30-
LTC_ARGCHK(ltc_mp.name != NULL);
3129

3230
/* init key */
33-
err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
34-
if (err != CRYPT_OK) return err;
31+
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
3532

3633
if ((err = mp_read_unsigned_bin(key->p, (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; }
3734
if ((err = mp_read_unsigned_bin(key->g, (unsigned char *)g , glen)) != CRYPT_OK) { goto LBL_ERR; }

src/pk/dsa/dsa_set_pqg_dsaparam.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamle
2525
LTC_ARGCHK(ltc_mp.name != NULL);
2626

2727
/* init key */
28-
err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
29-
if (err != CRYPT_OK) return err;
28+
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
3029

3130
if ((err = der_decode_sequence_multi(dsaparam, dsaparamlen,
3231
LTC_ASN1_INTEGER, 1UL, key->p,

src/pk/dsa/dsa_verify_key.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ int dsa_verify_key(const dsa_key *key, int *stat)
2727
err = dsa_int_validate_primes(key, stat);
2828
if (err != CRYPT_OK || *stat == 0) return err;
2929

30-
err = dsa_int_validate_pqg(key, stat);
31-
if (err != CRYPT_OK || *stat == 0) return err;
32-
33-
return dsa_int_validate_xy(key, stat);
30+
return dsa_int_validate(key, stat);
3431
}
3532

3633
/**
@@ -186,4 +183,22 @@ int dsa_int_validate_xy(const dsa_key *key, int *stat)
186183
return err;
187184
}
188185

186+
/**
187+
Validation of DSA params (p, q, g) and DSA key (x and y)
188+
189+
@param key The key to validate
190+
@param stat [out] Result of test, 1==valid, 0==invalid
191+
@return CRYPT_OK if successful
192+
*/
193+
int dsa_int_validate(const dsa_key *key, int *stat)
194+
{
195+
int err;
196+
197+
err = dsa_int_validate_pqg(key, stat);
198+
if (err != CRYPT_OK || *stat == 0) return err;
199+
200+
return dsa_int_validate_xy(key, stat);
201+
202+
}
203+
189204
#endif

0 commit comments

Comments
 (0)