@@ -44,13 +44,64 @@ static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_
4444 zeromem (iv , sizeof (iv ));
4545 return err ;
4646}
47- typedef int (* pkcs8_import )(const unsigned char * in , unsigned long inlen ,
48- password_ctx * pw_ctx ,
49- void * key );
50- typedef struct {
51- enum ltc_oid_id id ;
52- pkcs8_import fn ;
53- } p8_import_st ;
47+
48+ static int s_import_pkcs8 (unsigned char * pem , unsigned long l , ltc_pka_key * k , const password_ctx * pw_ctx )
49+ {
50+ int err ;
51+ enum ltc_oid_id pka ;
52+ ltc_asn1_list * alg_id , * priv_key ;
53+ ltc_asn1_list * p8_asn1 = NULL ;
54+ if ((err = pkcs8_decode_flexi (pem , l , pw_ctx , & p8_asn1 )) != CRYPT_OK ) {
55+ goto cleanup ;
56+ }
57+ if ((err = pkcs8_get_children (p8_asn1 , & pka , & alg_id , & priv_key )) != CRYPT_OK ) {
58+ goto cleanup ;
59+ }
60+ switch (pka ) {
61+ #ifdef LTC_MDH
62+ case LTC_OID_DH :
63+ err = dh_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .dh );
64+ k -> id = LTC_PKA_DH ;
65+ break ;
66+ #endif
67+ #ifdef LTC_MDSA
68+ case LTC_OID_DSA :
69+ err = dsa_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .dsa );
70+ k -> id = LTC_PKA_DSA ;
71+ break ;
72+ #endif
73+ #ifdef LTC_MRSA
74+ case LTC_OID_RSA :
75+ err = rsa_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .rsa );
76+ k -> id = LTC_PKA_RSA ;
77+ break ;
78+ #endif
79+ #ifdef LTC_MECC
80+ case LTC_OID_EC :
81+ err = ecc_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .ecc );
82+ k -> id = LTC_PKA_EC ;
83+ break ;
84+ #endif
85+ #ifdef LTC_CURVE25519
86+ case LTC_OID_X25519 :
87+ err = x25519_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .x25519 );
88+ k -> id = LTC_PKA_X25519 ;
89+ break ;
90+ case LTC_OID_ED25519 :
91+ err = ed25519_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .ed25519 );
92+ k -> id = LTC_PKA_ED25519 ;
93+ break ;
94+ #endif
95+ default :
96+ err = CRYPT_PK_INVALID_TYPE ;
97+ }
98+
99+ cleanup :
100+ if (p8_asn1 ) {
101+ der_sequence_free (p8_asn1 );
102+ }
103+ return err ;
104+ }
54105
55106static int s_decode (struct get_char * g , ltc_pka_key * k , const password_ctx * pw_ctx )
56107{
@@ -59,7 +110,10 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
59110 int err = CRYPT_ERROR ;
60111 struct pem_headers hdr = { 0 };
61112 struct password pw ;
62- ltc_asn1_list * p8_asn1 = NULL ;
113+ ltc_asn1_list * pub = NULL , * seqid , * id ;
114+ der_flexi_check flexi_should [4 ];
115+ enum ltc_oid_id oid_id ;
116+ enum ltc_pka_id pka ;
63117 XMEMSET (k , 0 , sizeof (* k ));
64118 w = LTC_PEM_READ_BUFSIZE * 2 ;
65119retry :
@@ -78,54 +132,33 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
78132 if (hdr .id == NULL )
79133 goto cleanup ;
80134 l = w ;
81- if (hdr .id -> pkcs8 ) {
82- enum ltc_oid_id pka ;
83- ltc_asn1_list * alg_id , * priv_key ;
84- if ((err = pkcs8_decode_flexi (pem , l , pw_ctx , & p8_asn1 )) != CRYPT_OK ) {
135+ if (hdr .id -> flags & pf_pkcs8 ) {
136+ err = s_import_pkcs8 (pem , l , k , pw_ctx );
137+ goto cleanup ;
138+ } else if (hdr .id -> flags & pf_public ) {
139+ if ((err = der_decode_sequence_flexi (pem , & w , & pub )) != CRYPT_OK ) {
85140 goto cleanup ;
86141 }
87- if ((err = pkcs8_get_children (p8_asn1 , & pka , & alg_id , & priv_key )) != CRYPT_OK ) {
142+ n = 0 ;
143+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n ++ , LTC_ASN1_SEQUENCE , & seqid );
144+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n ++ , LTC_ASN1_BIT_STRING , NULL );
145+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n , LTC_ASN1_EOL , NULL );
146+ if ((err = der_flexi_sequence_cmp (pub , flexi_should )) != CRYPT_OK ) {
88147 goto cleanup ;
89148 }
90- switch (pka ) {
91- #ifdef LTC_MDH
92- case LTC_OID_DH :
93- err = dh_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .dh );
94- k -> id = LTC_PKA_DH ;
95- break ;
96- #endif
97- #ifdef LTC_MDSA
98- case LTC_OID_DSA :
99- err = dsa_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .dsa );
100- k -> id = LTC_PKA_DSA ;
101- break ;
102- #endif
103- #ifdef LTC_MRSA
104- case LTC_OID_RSA :
105- err = rsa_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .rsa );
106- k -> id = LTC_PKA_RSA ;
107- break ;
108- #endif
109- #ifdef LTC_MECC
110- case LTC_OID_EC :
111- err = ecc_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .ecc );
112- k -> id = LTC_PKA_EC ;
113- break ;
114- #endif
115- #ifdef LTC_CURVE25519
116- case LTC_OID_X25519 :
117- err = x25519_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .x25519 );
118- k -> id = LTC_PKA_X25519 ;
119- break ;
120- case LTC_OID_ED25519 :
121- err = ed25519_import_pkcs8_asn1 (alg_id , priv_key , & k -> u .ed25519 );
122- k -> id = LTC_PKA_ED25519 ;
123- break ;
124- #endif
125- default :
126- err = CRYPT_PK_INVALID_TYPE ;
149+ n = 0 ;
150+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n ++ , LTC_ASN1_OBJECT_IDENTIFIER , & id );
151+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n , LTC_ASN1_EOL , NULL );
152+ err = der_flexi_sequence_cmp (seqid , flexi_should );
153+ if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG ) {
154+ goto cleanup ;
155+ }
156+ if ((err = pk_get_oid_from_asn1 (id , & oid_id )) != CRYPT_OK ) {
157+ goto cleanup ;
158+ }
159+ if ((err = pk_get_pka_id (oid_id , & pka )) != CRYPT_OK ) {
160+ goto cleanup ;
127161 }
128- goto cleanup ;
129162 } else if (hdr .encrypted ) {
130163 if ((pw_ctx == NULL ) || (pw_ctx -> callback == NULL )) {
131164 err = CRYPT_PW_CTX_MISSING ;
@@ -141,8 +174,11 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
141174 if ((err = s_decrypt_pem (pem , & l , & hdr )) != CRYPT_OK ) {
142175 goto cleanup ;
143176 }
177+ pka = hdr .id -> pka ;
178+ } else {
179+ pka = hdr .id -> pka ;
144180 }
145- switch (hdr . id -> pka ) {
181+ switch (pka ) {
146182#ifdef LTC_MDSA
147183 case LTC_OID_DSA :
148184 err = dsa_import (pem , l , & k -> u .dsa );
@@ -160,15 +196,25 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
160196 err = ecc_import_openssl (pem , l , & k -> u .ecc );
161197 k -> id = LTC_PKA_EC ;
162198 break ;
199+ #endif
200+ #ifdef LTC_CURVE25519
201+ case LTC_PKA_ED25519 :
202+ err = ed25519_import (pem , l , & k -> u .ed25519 );
203+ k -> id = LTC_PKA_ED25519 ;
204+ break ;
205+ case LTC_PKA_X25519 :
206+ err = x25519_import (pem , l , & k -> u .x25519 );
207+ k -> id = LTC_PKA_X25519 ;
208+ break ;
163209#endif
164210 default :
165211 err = CRYPT_PK_INVALID_TYPE ;
166212 goto cleanup ;
167213 }
168214
169215cleanup :
170- if (p8_asn1 ) {
171- der_sequence_free (p8_asn1 );
216+ if (pub ) {
217+ der_sequence_free (pub );
172218 }
173219 if (hdr .pw ) {
174220 zeromem (hdr .pw -> pw , hdr .pw -> l );
0 commit comments