xref: /openbsd/lib/libcrypto/evp/evp_pkey.c (revision db3296cf)
1 /* evp_pkey.c */
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3  * project 1999.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include "cryptlib.h"
62 #include <openssl/x509.h>
63 #include <openssl/rand.h>
64 
65 #ifndef OPENSSL_NO_DSA
66 static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
67 #endif
68 
69 /* Extract a private key from a PKCS8 structure */
70 
71 EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
72 {
73 	EVP_PKEY *pkey = NULL;
74 #ifndef OPENSSL_NO_RSA
75 	RSA *rsa = NULL;
76 #endif
77 #ifndef OPENSSL_NO_DSA
78 	DSA *dsa = NULL;
79 	ASN1_INTEGER *privkey;
80 	ASN1_TYPE *t1, *t2, *param = NULL;
81 	STACK_OF(ASN1_TYPE) *ndsa = NULL;
82 	BN_CTX *ctx = NULL;
83 	int plen;
84 #endif
85 	X509_ALGOR *a;
86 	unsigned char *p;
87 	const unsigned char *cp;
88 	int pkeylen;
89 	char obj_tmp[80];
90 
91 	if(p8->pkey->type == V_ASN1_OCTET_STRING) {
92 		p8->broken = PKCS8_OK;
93 		p = p8->pkey->value.octet_string->data;
94 		pkeylen = p8->pkey->value.octet_string->length;
95 	} else {
96 		p8->broken = PKCS8_NO_OCTET;
97 		p = p8->pkey->value.sequence->data;
98 		pkeylen = p8->pkey->value.sequence->length;
99 	}
100 	if (!(pkey = EVP_PKEY_new())) {
101 		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
102 		return NULL;
103 	}
104 	a = p8->pkeyalg;
105 	switch (OBJ_obj2nid(a->algorithm))
106 	{
107 #ifndef OPENSSL_NO_RSA
108 		case NID_rsaEncryption:
109 		cp = p;
110 		if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
111 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
112 			return NULL;
113 		}
114 		EVP_PKEY_assign_RSA (pkey, rsa);
115 		break;
116 #endif
117 #ifndef OPENSSL_NO_DSA
118 		case NID_dsa:
119 		/* PKCS#8 DSA is weird: you just get a private key integer
120 	         * and parameters in the AlgorithmIdentifier the pubkey must
121 		 * be recalculated.
122 		 */
123 
124 		/* Check for broken DSA PKCS#8, UGH! */
125 		if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
126 		    if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
127 							  d2i_ASN1_TYPE,
128 							  ASN1_TYPE_free))) {
129 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
130 			goto dsaerr;
131 		    }
132 		    if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
133 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
134 			goto dsaerr;
135 		    }
136 		    /* Handle Two broken types:
137 		     * SEQUENCE {parameters, priv_key}
138 		     * SEQUENCE {pub_key, priv_key}
139 		     */
140 
141 		    t1 = sk_ASN1_TYPE_value(ndsa, 0);
142 		    t2 = sk_ASN1_TYPE_value(ndsa, 1);
143 		    if(t1->type == V_ASN1_SEQUENCE) {
144 			p8->broken = PKCS8_EMBEDDED_PARAM;
145 			param = t1;
146 		    } else if(a->parameter->type == V_ASN1_SEQUENCE) {
147 			p8->broken = PKCS8_NS_DB;
148 			param = a->parameter;
149 		    } else {
150 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
151 			goto dsaerr;
152 		    }
153 
154 		    if(t2->type != V_ASN1_INTEGER) {
155 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
156 			goto dsaerr;
157 		    }
158 		    privkey = t2->value.integer;
159 		} else {
160 			if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
161 				EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
162 				goto dsaerr;
163 			}
164 			param = p8->pkeyalg->parameter;
165 		}
166 		if (!param || (param->type != V_ASN1_SEQUENCE)) {
167 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
168 			goto dsaerr;
169 		}
170 		cp = p = param->value.sequence->data;
171 		plen = param->value.sequence->length;
172 		if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
173 			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
174 			goto dsaerr;
175 		}
176 		/* We have parameters now set private key */
177 		if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
178 			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
179 			goto dsaerr;
180 		}
181 		/* Calculate public key (ouch!) */
182 		if (!(dsa->pub_key = BN_new())) {
183 			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
184 			goto dsaerr;
185 		}
186 		if (!(ctx = BN_CTX_new())) {
187 			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
188 			goto dsaerr;
189 		}
190 
191 		if (!BN_mod_exp(dsa->pub_key, dsa->g,
192 						 dsa->priv_key, dsa->p, ctx)) {
193 
194 			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
195 			goto dsaerr;
196 		}
197 
198 		EVP_PKEY_assign_DSA(pkey, dsa);
199 		BN_CTX_free (ctx);
200 		if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
201 		else ASN1_INTEGER_free(privkey);
202 		break;
203 		dsaerr:
204 		BN_CTX_free (ctx);
205 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
206 		DSA_free(dsa);
207 		EVP_PKEY_free(pkey);
208 		return NULL;
209 		break;
210 #endif
211 		default:
212 		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
213 		if (!a->algorithm) strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
214 		else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
215 		ERR_add_error_data(2, "TYPE=", obj_tmp);
216 		EVP_PKEY_free (pkey);
217 		return NULL;
218 	}
219 	return pkey;
220 }
221 
222 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
223 {
224 	return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
225 }
226 
227 /* Turn a private key into a PKCS8 structure */
228 
229 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
230 {
231 	PKCS8_PRIV_KEY_INFO *p8;
232 
233 	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
234 		EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
235 		return NULL;
236 	}
237 	p8->broken = broken;
238 	ASN1_INTEGER_set (p8->version, 0);
239 	if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
240 		EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
241 		PKCS8_PRIV_KEY_INFO_free (p8);
242 		return NULL;
243 	}
244 	p8->pkey->type = V_ASN1_OCTET_STRING;
245 	switch (EVP_PKEY_type(pkey->type)) {
246 #ifndef OPENSSL_NO_RSA
247 		case EVP_PKEY_RSA:
248 
249 		if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;
250 
251 		p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
252 		p8->pkeyalg->parameter->type = V_ASN1_NULL;
253 		if (!ASN1_pack_string ((char *)pkey, i2d_PrivateKey,
254 					 &p8->pkey->value.octet_string)) {
255 			EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
256 			PKCS8_PRIV_KEY_INFO_free (p8);
257 			return NULL;
258 		}
259 		break;
260 #endif
261 #ifndef OPENSSL_NO_DSA
262 		case EVP_PKEY_DSA:
263 		if(!dsa_pkey2pkcs8(p8, pkey)) {
264 			PKCS8_PRIV_KEY_INFO_free (p8);
265 			return NULL;
266 		}
267 
268 		break;
269 #endif
270 		default:
271 		EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
272 		PKCS8_PRIV_KEY_INFO_free (p8);
273 		return NULL;
274 	}
275 	RAND_add(p8->pkey->value.octet_string->data,
276 		 p8->pkey->value.octet_string->length, 0);
277 	return p8;
278 }
279 
280 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
281 {
282 	switch (broken) {
283 
284 		case PKCS8_OK:
285 		p8->broken = PKCS8_OK;
286 		return p8;
287 		break;
288 
289 		case PKCS8_NO_OCTET:
290 		p8->broken = PKCS8_NO_OCTET;
291 		p8->pkey->type = V_ASN1_SEQUENCE;
292 		return p8;
293 		break;
294 
295 		default:
296 		EVPerr(EVP_F_EVP_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
297 		return NULL;
298 		break;
299 
300 	}
301 }
302 
303 #ifndef OPENSSL_NO_DSA
304 static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
305 {
306 	ASN1_STRING *params;
307 	ASN1_INTEGER *prkey;
308 	ASN1_TYPE *ttmp;
309 	STACK_OF(ASN1_TYPE) *ndsa;
310 	unsigned char *p, *q;
311 	int len;
312 
313 	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
314 	len = i2d_DSAparams (pkey->pkey.dsa, NULL);
315 	if (!(p = OPENSSL_malloc(len))) {
316 		EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
317 		PKCS8_PRIV_KEY_INFO_free (p8);
318 		return 0;
319 	}
320 	q = p;
321 	i2d_DSAparams (pkey->pkey.dsa, &q);
322 	params = ASN1_STRING_new();
323 	ASN1_STRING_set(params, p, len);
324 	OPENSSL_free(p);
325 	/* Get private key into integer */
326 	if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
327 		EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
328 		return 0;
329 	}
330 
331 	switch(p8->broken) {
332 
333 		case PKCS8_OK:
334 		case PKCS8_NO_OCTET:
335 
336 		if (!ASN1_pack_string((char *)prkey, i2d_ASN1_INTEGER,
337 					 &p8->pkey->value.octet_string)) {
338 			EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
339 			M_ASN1_INTEGER_free (prkey);
340 			return 0;
341 		}
342 
343 		M_ASN1_INTEGER_free (prkey);
344 		p8->pkeyalg->parameter->value.sequence = params;
345 		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
346 
347 		break;
348 
349 		case PKCS8_NS_DB:
350 
351 		p8->pkeyalg->parameter->value.sequence = params;
352 		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
353 		ndsa = sk_ASN1_TYPE_new_null();
354 		ttmp = ASN1_TYPE_new();
355 		if (!(ttmp->value.integer = BN_to_ASN1_INTEGER (pkey->pkey.dsa->pub_key, NULL))) {
356 			EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
357 			PKCS8_PRIV_KEY_INFO_free(p8);
358 			return 0;
359 		}
360 		ttmp->type = V_ASN1_INTEGER;
361 		sk_ASN1_TYPE_push(ndsa, ttmp);
362 
363 		ttmp = ASN1_TYPE_new();
364 		ttmp->value.integer = prkey;
365 		ttmp->type = V_ASN1_INTEGER;
366 		sk_ASN1_TYPE_push(ndsa, ttmp);
367 
368 		p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
369 
370 		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
371 					 &p8->pkey->value.octet_string->data,
372 					 &p8->pkey->value.octet_string->length)) {
373 
374 			EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
375 			sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
376 			M_ASN1_INTEGER_free(prkey);
377 			return 0;
378 		}
379 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
380 		break;
381 
382 		case PKCS8_EMBEDDED_PARAM:
383 
384 		p8->pkeyalg->parameter->type = V_ASN1_NULL;
385 		ndsa = sk_ASN1_TYPE_new_null();
386 		ttmp = ASN1_TYPE_new();
387 		ttmp->value.sequence = params;
388 		ttmp->type = V_ASN1_SEQUENCE;
389 		sk_ASN1_TYPE_push(ndsa, ttmp);
390 
391 		ttmp = ASN1_TYPE_new();
392 		ttmp->value.integer = prkey;
393 		ttmp->type = V_ASN1_INTEGER;
394 		sk_ASN1_TYPE_push(ndsa, ttmp);
395 
396 		p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
397 
398 		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
399 					 &p8->pkey->value.octet_string->data,
400 					 &p8->pkey->value.octet_string->length)) {
401 
402 			EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
403 			sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
404 			M_ASN1_INTEGER_free (prkey);
405 			return 0;
406 		}
407 		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
408 		break;
409 	}
410 	return 1;
411 }
412 #endif
413