@@ -45,6 +45,71 @@ static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_
4545 return err ;
4646}
4747
48+ static int s_get_pka (ltc_asn1_list * pub , enum ltc_pka_id * pka )
49+ {
50+ der_flexi_check flexi_should [4 ];
51+ ltc_asn1_list * seqid , * id ;
52+ enum ltc_oid_id oid_id ;
53+ int err ;
54+ unsigned long n = 0 ;
55+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n ++ , LTC_ASN1_SEQUENCE , & seqid );
56+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n ++ , LTC_ASN1_BIT_STRING , NULL );
57+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n , LTC_ASN1_EOL , NULL );
58+ if ((err = der_flexi_sequence_cmp (pub , flexi_should )) != CRYPT_OK ) {
59+ return err ;
60+ }
61+ n = 0 ;
62+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n ++ , LTC_ASN1_OBJECT_IDENTIFIER , & id );
63+ LTC_SET_DER_FLEXI_CHECK (flexi_should , n , LTC_ASN1_EOL , NULL );
64+ err = der_flexi_sequence_cmp (seqid , flexi_should );
65+ if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG ) {
66+ return err ;
67+ }
68+ if ((err = pk_get_oid_from_asn1 (id , & oid_id )) != CRYPT_OK ) {
69+ return err ;
70+ }
71+ return pk_get_pka_id (oid_id , pka );
72+ }
73+
74+ typedef int (* import_fn )(const unsigned char * , unsigned long , void * );
75+
76+ static import_fn s_import_x509_fns [LTC_PKA_NUM ] = {
77+ #ifdef LTC_MRSA
78+ [LTC_PKA_RSA ] = (import_fn )rsa_import_x509 ,
79+ #endif
80+ #ifdef LTC_MECC
81+ [LTC_PKA_EC ] = (import_fn )ecc_import_x509 ,
82+ #endif
83+ #ifdef LTC_CURVE25519
84+ [LTC_PKA_X25519 ] = (import_fn )x25519_import_x509 ,
85+ [LTC_PKA_ED25519 ] = (import_fn )ed25519_import_x509 ,
86+ #endif
87+ };
88+
89+ static int s_import_x509 (unsigned char * pem , unsigned long l , ltc_pka_key * k )
90+ {
91+ enum ltc_pka_id pka = LTC_PKA_UNDEF ;
92+ ltc_asn1_list * d , * spki ;
93+ int err ;
94+ if ((err = x509_decode_spki (pem , l , & d , & spki )) != CRYPT_OK ) {
95+ return err ;
96+ }
97+ err = s_get_pka (spki , & pka );
98+ der_free_sequence_flexi (d );
99+ if (err != CRYPT_OK ) {
100+ return err ;
101+ }
102+ if (pka < 0
103+ || pka > sizeof (s_import_x509_fns )/sizeof (s_import_x509_fns [0 ])
104+ || s_import_x509_fns [pka ] == NULL ) {
105+ return CRYPT_PK_INVALID_TYPE ;
106+ }
107+ if ((err = s_import_x509_fns [pka ](pem , l , & k -> u )) == CRYPT_OK ) {
108+ k -> id = pka ;
109+ }
110+ return err ;
111+ }
112+
48113static int s_import_pkcs8 (unsigned char * pem , unsigned long l , ltc_pka_key * k , const password_ctx * pw_ctx )
49114{
50115 int err ;
@@ -103,16 +168,41 @@ static int s_import_pkcs8(unsigned char *pem, unsigned long l, ltc_pka_key *k, c
103168 return err ;
104169}
105170
171+ int s_extract_pka (unsigned char * pem , unsigned long w , enum ltc_pka_id * pka )
172+ {
173+ ltc_asn1_list * pub ;
174+ int err = CRYPT_ERROR ;
175+ if ((err = der_decode_sequence_flexi (pem , & w , & pub )) != CRYPT_OK ) {
176+ return err ;
177+ }
178+ err = s_get_pka (pub , pka );
179+ der_sequence_free (pub );
180+ return err ;
181+ }
182+
183+ static import_fn s_import_openssl_fns [LTC_PKA_NUM ] = {
184+ #ifdef LTC_MRSA
185+ [LTC_PKA_RSA ] = (import_fn )rsa_import ,
186+ #endif
187+ #ifdef LTC_MDSA
188+ [LTC_PKA_DSA ] = (import_fn )dsa_import ,
189+ #endif
190+ #ifdef LTC_MECC
191+ [LTC_PKA_EC ] = (import_fn )ecc_import_openssl ,
192+ #endif
193+ #ifdef LTC_CURVE25519
194+ [LTC_PKA_X25519 ] = (import_fn )x25519_import ,
195+ [LTC_PKA_ED25519 ] = (import_fn )ed25519_import ,
196+ #endif
197+ };
198+
106199static int s_decode (struct get_char * g , ltc_pka_key * k , const password_ctx * pw_ctx )
107200{
108201 unsigned char * pem = NULL ;
109202 unsigned long w , l , n ;
110203 int err = CRYPT_ERROR ;
111204 struct pem_headers hdr = { 0 };
112205 struct password pw ;
113- ltc_asn1_list * pub = NULL , * seqid , * id ;
114- der_flexi_check flexi_should [4 ];
115- enum ltc_oid_id oid_id ;
116206 enum ltc_pka_id pka ;
117207 XMEMSET (k , 0 , sizeof (* k ));
118208 w = LTC_PEM_READ_BUFSIZE * 2 ;
@@ -135,28 +225,11 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
135225 if (hdr .id -> flags & pf_pkcs8 ) {
136226 err = s_import_pkcs8 (pem , l , k , pw_ctx );
137227 goto cleanup ;
138- } else if (hdr .id -> flags & pf_public ) {
139- if ((err = der_decode_sequence_flexi (pem , & w , & pub )) != CRYPT_OK ) {
140- goto cleanup ;
141- }
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 ) {
147- goto cleanup ;
148- }
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 ) {
228+ } else if (hdr .id -> flags == pf_x509 ) {
229+ err = s_import_x509 (pem , l , k );
230+ goto cleanup ;
231+ } else if ((hdr .id -> flags & pf_public ) && hdr .id -> pka == LTC_PKA_UNDEF ) {
232+ if ((err = s_extract_pka (pem , w , & pka )) != CRYPT_OK ) {
160233 goto cleanup ;
161234 }
162235 } else if (hdr .encrypted ) {
@@ -178,44 +251,18 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
178251 } else {
179252 pka = hdr .id -> pka ;
180253 }
181- switch (pka ) {
182- #ifdef LTC_MDSA
183- case LTC_OID_DSA :
184- err = dsa_import (pem , l , & k -> u .dsa );
185- k -> id = LTC_PKA_DSA ;
186- break ;
187- #endif
188- #ifdef LTC_MRSA
189- case LTC_OID_RSA :
190- err = rsa_import (pem , l , & k -> u .rsa );
191- k -> id = LTC_PKA_RSA ;
192- break ;
193- #endif
194- #ifdef LTC_MECC
195- case LTC_OID_EC :
196- err = ecc_import_openssl (pem , l , & k -> u .ecc );
197- k -> id = LTC_PKA_EC ;
198- 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 ;
209- #endif
210- default :
211- err = CRYPT_PK_INVALID_TYPE ;
212- goto cleanup ;
254+
255+ if (pka < 0
256+ || pka > sizeof (s_import_openssl_fns )/sizeof (s_import_openssl_fns [0 ])
257+ || s_import_openssl_fns [pka ] == NULL ) {
258+ err = CRYPT_PK_INVALID_TYPE ;
259+ goto cleanup ;
260+ }
261+ if ((err = s_import_openssl_fns [pka ](pem , l , & k -> u )) == CRYPT_OK ) {
262+ k -> id = pka ;
213263 }
214264
215265cleanup :
216- if (pub ) {
217- der_sequence_free (pub );
218- }
219266 if (hdr .pw ) {
220267 zeromem (hdr .pw -> pw , hdr .pw -> l );
221268 XFREE (hdr .pw -> pw );
0 commit comments