Skip to content

Commit 4f36e03

Browse files
committed
re-factor ecc_import_openssl()
... into several smaller functions
1 parent 05d397d commit 4f36e03

File tree

3 files changed

+144
-86
lines changed

3 files changed

+144
-86
lines changed

src/headers/tomcrypt_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ int dh_check_pubkey(const dh_key *key);
195195
int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key);
196196
int ecc_copy_dp(const ecc_key *srckey, ecc_key *key);
197197
int ecc_set_dp_by_size(int size, ecc_key *key);
198+
int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key);
198199

199200
/* low level functions */
200201
ecc_point *ltc_ecc_new_point(void);

src/pk/ecc/ecc_import_openssl.c

Lines changed: 49 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -11,84 +11,22 @@
1111

1212
#ifdef LTC_MECC
1313

14-
int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key)
14+
static int _ecc_import_private_with_oid(const unsigned char *in, unsigned long inlen, ecc_key *key)
1515
{
16-
void *prime, *order, *a, *b, *gx, *gy;
17-
ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2];
18-
unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE];
19-
unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
20-
unsigned long len_a, len_b, len_k, len_g, len_xy, len_oid, len;
21-
unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16], curveoid[16];
16+
ltc_asn1_list seq_priv[4], custom[2];
17+
unsigned char bin_xy[2*ECC_MAXSIZE+2], bin_k[ECC_MAXSIZE];
18+
unsigned long len, pkver = 0, curveoid[16];
2219
char OID[256];
2320
const ltc_ecc_curve *curve;
2421
int err;
2522

26-
if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) {
27-
return err;
28-
}
29-
30-
/* ### 1. try to load public key - no curve parameters just curve OID */
31-
32-
len_xy = sizeof(bin_xy);
33-
len_oid = 16;
34-
err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy,
35-
LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid);
36-
if (err == CRYPT_OK) {
37-
/* load curve parameters for given curve OID */
38-
len = sizeof(OID);
39-
if ((err = pk_oid_num_to_str(curveoid, len_oid, OID, &len)) != CRYPT_OK) { goto error; }
40-
if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK) { goto error; }
41-
if ((err = ecc_set_dp(curve, key)) != CRYPT_OK) { goto error; }
42-
/* load public key */
43-
if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; }
44-
goto success;
45-
}
46-
47-
/* ### 2. try to load public key - curve parameters included */
48-
49-
/* ECParameters SEQUENCE */
50-
LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
51-
LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
52-
LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
53-
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
54-
LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
55-
LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
56-
seq_ecparams[5].optional = 1;
57-
/* FieldID SEQUENCE */
58-
LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
59-
LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
60-
/* Curve SEQUENCE */
61-
LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
62-
LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
63-
LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128);
64-
seq_curve[2].optional = 1;
65-
/* try to load public key */
66-
len_xy = sizeof(bin_xy);
67-
len = 6;
68-
err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len);
69-
70-
if (err == CRYPT_OK) {
71-
len_a = seq_curve[0].size;
72-
len_b = seq_curve[1].size;
73-
len_g = seq_ecparams[3].size;
74-
/* create bignums */
75-
if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
76-
if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
77-
if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
78-
/* load curve parameters */
79-
if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; }
80-
/* load public key */
81-
if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; }
82-
goto success;
83-
}
84-
85-
/* ### 3. try to load private key - no curve parameters just curve OID */
23+
/* ### try to load private key - no curve parameters just curve OID */
8624

8725
/* ECPrivateKey SEQUENCE */
8826
LTC_SET_ASN1(custom, 0, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL);
89-
LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2));
27+
LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8u*sizeof(bin_xy));
9028
LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
91-
LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE);
29+
LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k));
9230
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */
9331
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */
9432

@@ -101,39 +39,54 @@ int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *ke
10139
if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK) { goto error; }
10240
if ((err = ecc_set_dp(curve, key)) != CRYPT_OK) { goto error; }
10341
/* load private+public key */
104-
if ((err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key)) != CRYPT_OK) { goto error; }
105-
goto success;
42+
err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key);
43+
}
44+
error:
45+
return err;
46+
}
47+
48+
static int _ecc_import_private_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key)
49+
{
50+
void *prime, *order, *a, *b, *gx, *gy;
51+
ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2];
52+
unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE];
53+
unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
54+
unsigned long len_a, len_b, len_k, len_g;
55+
unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16];
56+
int err;
57+
58+
if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) {
59+
return err;
10660
}
10761

108-
/* ### 4. try to load private key - curve parameters included */
62+
/* ### try to load private key - curve parameters included */
10963

11064
/* ECPrivateKey SEQUENCE */
11165
LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
112-
LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2));
66+
LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8u*sizeof(bin_xy));
11367
LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
114-
LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE);
68+
LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k));
11569
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */
11670
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */
11771
/* ECParameters SEQUENCE */
11872
LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
11973
LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
12074
LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
121-
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
75+
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g));
12276
LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
12377
LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
12478
seq_ecparams[5].optional = 1;
12579
/* FieldID SEQUENCE */
12680
LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
12781
LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
12882
/* Curve SEQUENCE */
129-
LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
130-
LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
131-
LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128);
83+
LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, sizeof(bin_a));
84+
LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b));
85+
LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, sizeof(bin_seed));
13286
seq_curve[2].optional = 1;
13387
/* try to load private key */
13488
err = der_decode_sequence(in, inlen, seq_priv, 4);
13589
if (err == CRYPT_OK) {
136-
len_xy = custom[1].size;
13790
len_k = seq_priv[1].size;
13891
len_a = seq_curve[0].size;
13992
len_b = seq_curve[1].size;
@@ -145,17 +98,28 @@ int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *ke
14598
/* load curve parameters */
14699
if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; }
147100
/* load private+public key */
148-
if ((err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key)) != CRYPT_OK) { goto error; }
101+
err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key);
102+
}
103+
error:
104+
mp_clear_multi(prime, order, a, b, gx, gy, NULL);
105+
return err;
106+
}
107+
108+
int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key)
109+
{
110+
int err;
111+
112+
if ((err = ecc_import_subject_public_key_info(in, inlen, key)) == CRYPT_OK) {
149113
goto success;
150114
}
151115

152-
/* ### 5. all attempts failed */
153-
goto error;
116+
if ((err = _ecc_import_private_with_oid(in, inlen, key)) == CRYPT_OK) {
117+
goto success;
118+
}
119+
120+
err = _ecc_import_private_with_curve(in, inlen, key);
154121

155122
success:
156-
err = CRYPT_OK;
157-
error:
158-
mp_clear_multi(prime, order, a, b, gx, gy, NULL);
159123
return err;
160124
}
161125

src/pk/ecc/ecc_import_x509.c

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,99 @@
1010

1111
#ifdef LTC_MECC
1212

13+
static int _ecc_import_x509_with_oid(const unsigned char *in, unsigned long inlen, ecc_key *key)
14+
{
15+
unsigned char bin_xy[2*ECC_MAXSIZE+2];
16+
unsigned long curveoid[16];
17+
unsigned long len_xy, len_oid, len;
18+
char OID[256];
19+
const ltc_ecc_curve *curve;
20+
int err;
21+
22+
len_xy = sizeof(bin_xy);
23+
len_oid = 16;
24+
err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy,
25+
LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid);
26+
if (err == CRYPT_OK) {
27+
/* load curve parameters for given curve OID */
28+
len = sizeof(OID);
29+
if ((err = pk_oid_num_to_str(curveoid, len_oid, OID, &len)) != CRYPT_OK) { goto error; }
30+
if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK) { goto error; }
31+
if ((err = ecc_set_dp(curve, key)) != CRYPT_OK) { goto error; }
32+
/* load public key */
33+
err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key);
34+
}
35+
error:
36+
return err;
37+
}
38+
39+
static int _ecc_import_x509_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key)
40+
{
41+
void *prime, *order, *a, *b, *gx, *gy;
42+
ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6];
43+
unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE];
44+
unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
45+
unsigned long len_a, len_b, len_g, len_xy, len;
46+
unsigned long cofactor = 0, ecver = 0, tmpoid[16];
47+
int err;
48+
49+
if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) {
50+
return err;
51+
}
52+
53+
/* ECParameters SEQUENCE */
54+
LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
55+
LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
56+
LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
57+
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g));
58+
LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
59+
LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
60+
seq_ecparams[5].optional = 1;
61+
/* FieldID SEQUENCE */
62+
LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
63+
LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
64+
/* Curve SEQUENCE */
65+
LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, sizeof(bin_a));
66+
LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b));
67+
LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, 8u*sizeof(bin_seed));
68+
seq_curve[2].optional = 1;
69+
/* try to load public key */
70+
len_xy = sizeof(bin_xy);
71+
len = 6;
72+
err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len);
73+
74+
if (err == CRYPT_OK) {
75+
len_a = seq_curve[0].size;
76+
len_b = seq_curve[1].size;
77+
len_g = seq_ecparams[3].size;
78+
/* create bignums */
79+
if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
80+
if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
81+
if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
82+
/* load curve parameters */
83+
if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; }
84+
/* load public key */
85+
err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key);
86+
}
87+
error:
88+
mp_clear_multi(prime, order, a, b, gx, gy, NULL);
89+
return err;
90+
}
91+
92+
int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key)
93+
{
94+
int err;
95+
96+
if ((err = _ecc_import_x509_with_oid(in, inlen, key)) == CRYPT_OK) {
97+
goto success;
98+
}
99+
100+
err = _ecc_import_x509_with_curve(in, inlen, key);
101+
102+
success:
103+
return err;
104+
}
105+
13106
/**
14107
Import an ECC key from a X.509 certificate
15108
@param in The packet to import from
@@ -38,7 +131,7 @@ int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key)
38131
l->child && l->child->type == LTC_ASN1_SEQUENCE &&
39132
l->child->child && l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER &&
40133
l->child->next && l->child->next->type == LTC_ASN1_BIT_STRING) {
41-
err = ecc_import_openssl(l->data, l->size, key);
134+
err = ecc_import_subject_public_key_info(l->data, l->size, key);
42135
goto LBL_DONE;
43136
}
44137
l = l->next;

0 commit comments

Comments
 (0)