@@ -26,50 +26,44 @@ static int s_ecc_import_private_with_oid(const unsigned char *in, unsigned long
2626
2727 /* try to load private key */
2828 err = der_decode_sequence (in , inlen , seq_priv , 4 );
29- if (err == CRYPT_OK ) {
30- /* load curve parameters for given curve OID */
31- len = sizeof (OID );
32- if ((err = pk_oid_num_to_str (curveoid , custom [0 ].size , OID , & len )) != CRYPT_OK ) { goto error ; }
33- if ((err = ecc_find_curve (OID , & curve )) != CRYPT_OK ) { goto error ; }
34- if ((err = ecc_set_curve (curve , key )) != CRYPT_OK ) { goto error ; }
35- /* load private+public key */
36- err = ecc_set_key (bin_k , seq_priv [1 ].size , PK_PRIVATE , key );
37- }
29+ if (err != CRYPT_OK ) { goto error ; }
30+ err = ecc_import_with_oid (bin_k , seq_priv [1 ].size , curveoid , custom [0 ].size , PK_PRIVATE , key );
31+ error :
32+ return err ;
33+ }
34+
35+ int ecc_import_with_oid (const unsigned char * in , unsigned long inlen , unsigned long * oid , unsigned long oid_len , int type , ecc_key * key )
36+ {
37+ char OID [256 ];
38+ unsigned long len ;
39+ const ltc_ecc_curve * curve ;
40+ int err ;
41+
42+ /* load curve parameters for given curve OID */
43+ len = sizeof (OID );
44+ if ((err = pk_oid_num_to_str (oid , oid_len , OID , & len )) != CRYPT_OK ) { goto error ; }
45+ if ((err = ecc_find_curve (OID , & curve )) != CRYPT_OK ) { goto error ; }
46+ if ((err = ecc_set_curve (curve , key )) != CRYPT_OK ) { goto error ; }
47+ /* load public key */
48+ err = ecc_set_key (in , inlen , type , key );
3849error :
3950 return err ;
4051}
4152
42- static int s_ecc_import_private_with_curve (const unsigned char * in , unsigned long inlen , ecc_key * key )
53+ int ecc_import_with_curve (const unsigned char * in , unsigned long inlen , int type , ecc_key * key )
4354{
4455 void * prime , * order , * a , * b , * gx , * gy ;
4556 ltc_asn1_list seq_fieldid [2 ], seq_curve [3 ], seq_ecparams [6 ], seq_priv [4 ], custom [2 ];
4657 unsigned char bin_a [ECC_MAXSIZE ], bin_b [ECC_MAXSIZE ], bin_k [ECC_MAXSIZE ];
4758 unsigned char bin_g [2 * ECC_MAXSIZE + 1 ], bin_xy [2 * ECC_MAXSIZE + 2 ], bin_seed [128 ];
48- unsigned long len_a , len_b , len_k , len_g ;
59+ unsigned long len_a , len_b , len_k , len_g , len_xy , len ;
4960 unsigned long cofactor = 0 , ecver = 0 , pkver = 0 , tmpoid [16 ];
5061 int err ;
5162
5263 if ((err = mp_init_multi (& prime , & order , & a , & b , & gx , & gy , LTC_NULL )) != CRYPT_OK ) {
5364 return err ;
5465 }
5566
56- /* ### try to load private key - curve parameters included */
57-
58- /* ECPrivateKey SEQUENCE */
59- LTC_SET_ASN1 (custom , 0 , LTC_ASN1_SEQUENCE , seq_ecparams , 6UL );
60- LTC_SET_ASN1 (custom , 1 , LTC_ASN1_RAW_BIT_STRING , bin_xy , 8UL * sizeof (bin_xy ));
61- LTC_SET_ASN1 (seq_priv , 0 , LTC_ASN1_SHORT_INTEGER , & pkver , 1UL );
62- LTC_SET_ASN1 (seq_priv , 1 , LTC_ASN1_OCTET_STRING , bin_k , sizeof (bin_k ));
63- LTC_SET_ASN1_CUSTOM_CONSTRUCTED (seq_priv , 2 , LTC_ASN1_CL_CONTEXT_SPECIFIC , 0 , custom ); /* context specific 0 */
64- LTC_SET_ASN1_CUSTOM_CONSTRUCTED (seq_priv , 3 , LTC_ASN1_CL_CONTEXT_SPECIFIC , 1 , custom + 1 ); /* context specific 1 */
65- /* ECParameters SEQUENCE */
66- LTC_SET_ASN1 (seq_ecparams , 0 , LTC_ASN1_SHORT_INTEGER , & ecver , 1UL );
67- LTC_SET_ASN1 (seq_ecparams , 1 , LTC_ASN1_SEQUENCE , seq_fieldid , 2UL );
68- LTC_SET_ASN1 (seq_ecparams , 2 , LTC_ASN1_SEQUENCE , seq_curve , 3UL );
69- LTC_SET_ASN1 (seq_ecparams , 3 , LTC_ASN1_OCTET_STRING , bin_g , sizeof (bin_g ));
70- LTC_SET_ASN1 (seq_ecparams , 4 , LTC_ASN1_INTEGER , order , 1UL );
71- LTC_SET_ASN1 (seq_ecparams , 5 , LTC_ASN1_SHORT_INTEGER , & cofactor , 1UL );
72- seq_ecparams [5 ].optional = 1 ;
7367 /* FieldID SEQUENCE */
7468 LTC_SET_ASN1 (seq_fieldid , 0 , LTC_ASN1_OBJECT_IDENTIFIER , tmpoid , 16UL );
7569 LTC_SET_ASN1 (seq_fieldid , 1 , LTC_ASN1_INTEGER , prime , 1UL );
@@ -78,10 +72,35 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon
7872 LTC_SET_ASN1 (seq_curve , 1 , LTC_ASN1_OCTET_STRING , bin_b , sizeof (bin_b ));
7973 LTC_SET_ASN1 (seq_curve , 2 , LTC_ASN1_RAW_BIT_STRING , bin_seed , 8UL * sizeof (bin_seed ));
8074 seq_curve [2 ].optional = 1 ;
81- /* try to load private key */
82- err = der_decode_sequence (in , inlen , seq_priv , 4 );
75+ /* ECParameters SEQUENCE */
76+ LTC_SET_ASN1 (seq_ecparams , 0 , LTC_ASN1_SHORT_INTEGER , & ecver , 1UL );
77+ LTC_SET_ASN1 (seq_ecparams , 1 , LTC_ASN1_SEQUENCE , seq_fieldid , 2UL );
78+ LTC_SET_ASN1 (seq_ecparams , 2 , LTC_ASN1_SEQUENCE , seq_curve , 3UL );
79+ LTC_SET_ASN1 (seq_ecparams , 3 , LTC_ASN1_OCTET_STRING , bin_g , sizeof (bin_g ));
80+ LTC_SET_ASN1 (seq_ecparams , 4 , LTC_ASN1_INTEGER , order , 1UL );
81+ LTC_SET_ASN1 (seq_ecparams , 5 , LTC_ASN1_SHORT_INTEGER , & cofactor , 1UL );
82+ seq_ecparams [5 ].optional = 1 ;
83+ if (type == PK_PRIVATE ) {
84+ /* ECPrivateKey SEQUENCE */
85+ LTC_SET_ASN1 (custom , 0 , LTC_ASN1_SEQUENCE , seq_ecparams , 6UL );
86+ LTC_SET_ASN1 (custom , 1 , LTC_ASN1_RAW_BIT_STRING , bin_xy , 8UL * sizeof (bin_xy ));
87+ LTC_SET_ASN1 (seq_priv , 0 , LTC_ASN1_SHORT_INTEGER , & pkver , 1UL );
88+ LTC_SET_ASN1 (seq_priv , 1 , LTC_ASN1_OCTET_STRING , bin_k , sizeof (bin_k ));
89+ LTC_SET_ASN1_CUSTOM_CONSTRUCTED (seq_priv , 2 , LTC_ASN1_CL_CONTEXT_SPECIFIC , 0 , custom ); /* context specific 0 */
90+ LTC_SET_ASN1_CUSTOM_CONSTRUCTED (seq_priv , 3 , LTC_ASN1_CL_CONTEXT_SPECIFIC , 1 , custom + 1 ); /* context specific 1 */
91+ /* try to load private key */
92+ err = der_decode_sequence (in , inlen , seq_priv , 4 );
93+ if (err == CRYPT_OK )
94+ len_k = seq_priv [1 ].size ;
95+ } else if (type == PK_PUBLIC ) {
96+ /* try to load public key */
97+ len_xy = sizeof (bin_xy );
98+ len = 6 ;
99+ err = x509_decode_subject_public_key_info (in , inlen , LTC_OID_EC , bin_xy , & len_xy , LTC_ASN1_SEQUENCE , seq_ecparams , & len );
100+ } else {
101+ err = CRYPT_PK_INVALID_TYPE ;
102+ }
83103 if (err == CRYPT_OK ) {
84- len_k = seq_priv [1 ].size ;
85104 len_a = seq_curve [0 ].size ;
86105 len_b = seq_curve [1 ].size ;
87106 len_g = seq_ecparams [3 ].size ;
@@ -91,8 +110,15 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon
91110 if ((err = ltc_ecc_import_point (bin_g , len_g , prime , a , b , gx , gy )) != CRYPT_OK ) { goto error ; }
92111 /* load curve parameters */
93112 if ((err = ecc_set_curve_from_mpis (a , b , prime , order , gx , gy , cofactor , key )) != CRYPT_OK ) { goto error ; }
94- /* load private+public key */
95- err = ecc_set_key (bin_k , len_k , PK_PRIVATE , key );
113+
114+ if (type == PK_PRIVATE ) {
115+ len_k = seq_priv [1 ].size ;
116+ /* load private+public key */
117+ err = ecc_set_key (bin_k , len_k , PK_PRIVATE , key );
118+ } else {
119+ /* load public key */
120+ err = ecc_set_key (bin_xy , len_xy , PK_PUBLIC , key );
121+ }
96122 }
97123error :
98124 mp_clear_multi (prime , order , a , b , gx , gy , LTC_NULL );
@@ -111,7 +137,7 @@ int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *ke
111137 goto success ;
112138 }
113139
114- err = s_ecc_import_private_with_curve (in , inlen , key );
140+ err = ecc_import_with_curve (in , inlen , PK_PRIVATE , key );
115141
116142success :
117143 return err ;
0 commit comments