]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/evp_pkey.c
Fix more error codes.
[thirdparty/openssl.git] / crypto / evp / evp_pkey.c
CommitLineData
cfcefcbe
DSH
1/* evp_pkey.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
4d94ae00 6 * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
cfcefcbe
DSH
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"
ec577822
BM
62#include <openssl/x509.h>
63#include <openssl/rand.h>
60a938c6
GT
64#include <openssl/rsa.h>
65#include <openssl/dsa.h>
0f814687 66#include <openssl/bn.h>
cfcefcbe 67
40928698 68#ifndef OPENSSL_NO_DSA
66430207 69static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
40928698 70#endif
14a7cfb3
BM
71#ifndef OPENSSL_NO_EC
72static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
4d94ae00 73#endif
66430207 74
cfcefcbe
DSH
75/* Extract a private key from a PKCS8 structure */
76
8afca8d9 77EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
cfcefcbe 78{
66430207 79 EVP_PKEY *pkey = NULL;
cf1b7d96 80#ifndef OPENSSL_NO_RSA
66430207 81 RSA *rsa = NULL;
f5d7a031 82#endif
cf1b7d96 83#ifndef OPENSSL_NO_DSA
66430207 84 DSA *dsa = NULL;
8ee4845b 85 ASN1_TYPE *t1, *t2;
0fbffe7a 86 ASN1_INTEGER *privkey;
8ee4845b 87 STACK_OF(ASN1_TYPE) *ndsa = NULL;
4d94ae00 88#endif
14a7cfb3
BM
89#ifndef OPENSSL_NO_EC
90 EC_KEY *eckey = NULL;
0fbffe7a 91 const unsigned char *p_tmp;
4d94ae00 92#endif
5488bb61 93#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
8ee4845b 94 ASN1_TYPE *param = NULL;
66430207 95 BN_CTX *ctx = NULL;
f5d7a031
UM
96 int plen;
97#endif
98 X509_ALGOR *a;
875a644a 99 const unsigned char *p;
0413ba42 100 const unsigned char *cp;
f5d7a031 101 int pkeylen;
4d94ae00 102 int nid;
cfcefcbe
DSH
103 char obj_tmp[80];
104
66430207
DSH
105 if(p8->pkey->type == V_ASN1_OCTET_STRING) {
106 p8->broken = PKCS8_OK;
cfcefcbe
DSH
107 p = p8->pkey->value.octet_string->data;
108 pkeylen = p8->pkey->value.octet_string->length;
66430207
DSH
109 } else {
110 p8->broken = PKCS8_NO_OCTET;
cfcefcbe
DSH
111 p = p8->pkey->value.sequence->data;
112 pkeylen = p8->pkey->value.sequence->length;
cfcefcbe
DSH
113 }
114 if (!(pkey = EVP_PKEY_new())) {
115 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
116 return NULL;
117 }
118 a = p8->pkeyalg;
4d94ae00
BM
119 nid = OBJ_obj2nid(a->algorithm);
120 switch(nid)
cfcefcbe 121 {
cf1b7d96 122#ifndef OPENSSL_NO_RSA
cfcefcbe 123 case NID_rsaEncryption:
0413ba42
RL
124 cp = p;
125 if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
cfcefcbe
DSH
126 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
127 return NULL;
128 }
129 EVP_PKEY_assign_RSA (pkey, rsa);
130 break;
f5d7a031 131#endif
8ee4845b 132#ifndef OPENSSL_NO_DSA
cfcefcbe 133 case NID_dsa:
8ee4845b 134 /* PKCS#8 DSA is weird: you just get a private key integer
cfcefcbe
DSH
135 * and parameters in the AlgorithmIdentifier the pubkey must
136 * be recalculated.
137 */
138
8ee4845b
BM
139 /* Check for broken DSA PKCS#8, UGH! */
140 if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
141 if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
371acb22 142 d2i_ASN1_TYPE,
8ee4845b
BM
143 ASN1_TYPE_free))) {
144 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
145 goto dsaerr;
146 }
147 if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
148 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
149 goto dsaerr;
150 }
66430207
DSH
151 /* Handle Two broken types:
152 * SEQUENCE {parameters, priv_key}
153 * SEQUENCE {pub_key, priv_key}
154 */
48fe0eec 155
8ee4845b
BM
156 t1 = sk_ASN1_TYPE_value(ndsa, 0);
157 t2 = sk_ASN1_TYPE_value(ndsa, 1);
158 if(t1->type == V_ASN1_SEQUENCE) {
66430207
DSH
159 p8->broken = PKCS8_EMBEDDED_PARAM;
160 param = t1;
8ee4845b 161 } else if(a->parameter->type == V_ASN1_SEQUENCE) {
66430207
DSH
162 p8->broken = PKCS8_NS_DB;
163 param = a->parameter;
8ee4845b 164 } else {
cfcefcbe 165 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
8ee4845b 166 goto dsaerr;
66430207
DSH
167 }
168
169 if(t2->type != V_ASN1_INTEGER) {
170 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
8ee4845b 171 goto dsaerr;
66430207
DSH
172 }
173 privkey = t2->value.integer;
8ee4845b
BM
174 } else {
175 if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
48fe0eec 176 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
8ee4845b 177 goto dsaerr;
48fe0eec
DSH
178 }
179 param = p8->pkeyalg->parameter;
180 }
8ee4845b 181 if (!param || (param->type != V_ASN1_SEQUENCE)) {
66430207 182 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
8ee4845b 183 goto dsaerr;
cfcefcbe 184 }
a4aba800 185 cp = p = param->value.sequence->data;
66430207 186 plen = param->value.sequence->length;
8ee4845b
BM
187 if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
188 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
189 goto dsaerr;
190 }
191 /* We have parameters now set private key */
192 if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
193 EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
194 goto dsaerr;
195 }
196 /* Calculate public key (ouch!) */
197 if (!(dsa->pub_key = BN_new())) {
198 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
199 goto dsaerr;
200 }
201 if (!(ctx = BN_CTX_new())) {
cfcefcbe 202 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
8ee4845b 203 goto dsaerr;
cfcefcbe 204 }
8ee4845b
BM
205
206 if (!BN_mod_exp(dsa->pub_key, dsa->g,
207 dsa->priv_key, dsa->p, ctx)) {
208
209 EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
210 goto dsaerr;
211 }
212
213 EVP_PKEY_assign_DSA(pkey, dsa);
214 BN_CTX_free (ctx);
215 if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
216 else ASN1_INTEGER_free(privkey);
217 break;
218 dsaerr:
219 BN_CTX_free (ctx);
220 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
221 DSA_free(dsa);
222 EVP_PKEY_free(pkey);
223 return NULL;
224 break;
225#endif
226#ifndef OPENSSL_NO_EC
227 case NID_X9_62_id_ecPublicKey:
0fbffe7a
BM
228 p_tmp = p;
229 /* extract the ec parameters */
8ee4845b 230 param = p8->pkeyalg->parameter;
4d94ae00 231
8ee4845b
BM
232 if (!param || ((param->type != V_ASN1_SEQUENCE) &&
233 (param->type != V_ASN1_OBJECT)))
4d94ae00 234 {
8ee4845b
BM
235 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
236 goto ecerr;
237 }
238
239 if (param->type == V_ASN1_SEQUENCE)
240 {
241 cp = p = param->value.sequence->data;
242 plen = param->value.sequence->length;
243
244 if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
4d94ae00 245 {
8ee4845b
BM
246 EVPerr(EVP_F_EVP_PKCS82PKEY,
247 EVP_R_DECODE_ERROR);
248 goto ecerr;
4d94ae00 249 }
8ee4845b
BM
250 }
251 else
252 {
253 cp = p = param->value.object->data;
254 plen = param->value.object->length;
255
256 /* type == V_ASN1_OBJECT => the parameters are given
257 * by an asn1 OID
258 */
259 if ((eckey = EC_KEY_new()) == NULL)
4d94ae00 260 {
8ee4845b
BM
261 EVPerr(EVP_F_EVP_PKCS82PKEY,
262 ERR_R_MALLOC_FAILURE);
263 goto ecerr;
4d94ae00 264 }
8b15c740 265 if ((eckey->group = EC_GROUP_new_by_curve_name(
8ee4845b
BM
266 OBJ_obj2nid(a->parameter->value.object))) == NULL)
267 goto ecerr;
268 EC_GROUP_set_asn1_flag(eckey->group,
269 OPENSSL_EC_NAMED_CURVE);
270 }
271
272 /* We have parameters now set private key */
0fbffe7a 273 if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
8ee4845b 274 {
0fbffe7a 275 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
8ee4845b
BM
276 goto ecerr;
277 }
0fbffe7a
BM
278
279 /* calculate public key (if necessary) */
280 if (!eckey->pub_key)
8ee4845b 281 {
0fbffe7a
BM
282 /* the public key was not included in the SEC1 private
283 * key => calculate the public key */
284 eckey->pub_key = EC_POINT_new(eckey->group);
285 if (!eckey->pub_key)
286 {
287 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
288 goto ecerr;
289 }
290 if (!EC_POINT_copy(eckey->pub_key,
291 EC_GROUP_get0_generator(eckey->group)))
292 {
293 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
294 goto ecerr;
295 }
296 if (!EC_POINT_mul(eckey->group, eckey->pub_key,
297 eckey->priv_key, NULL, NULL, ctx))
298 {
299 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
300 goto ecerr;
301 }
8ee4845b
BM
302 }
303
304 EVP_PKEY_assign_EC_KEY(pkey, eckey);
305 if (ctx)
306 BN_CTX_free(ctx);
66430207 307 break;
8ee4845b
BM
308ecerr:
309 if (ctx)
310 BN_CTX_free(ctx);
311 if (eckey)
14a7cfb3 312 EC_KEY_free(eckey);
8ee4845b
BM
313 if (pkey)
314 EVP_PKEY_free(pkey);
66430207 315 return NULL;
f5d7a031 316#endif
cfcefcbe
DSH
317 default:
318 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
d420ac2c 319 if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
cfcefcbe
DSH
320 else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
321 ERR_add_error_data(2, "TYPE=", obj_tmp);
322 EVP_PKEY_free (pkey);
323 return NULL;
324 }
325 return pkey;
326}
327
66430207
DSH
328PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
329{
330 return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
331}
332
cfcefcbe
DSH
333/* Turn a private key into a PKCS8 structure */
334
66430207 335PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
cfcefcbe
DSH
336{
337 PKCS8_PRIV_KEY_INFO *p8;
66430207 338
cfcefcbe 339 if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
8afca8d9 340 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
cfcefcbe
DSH
341 return NULL;
342 }
66430207 343 p8->broken = broken;
a0e7c8ee 344 if (!ASN1_INTEGER_set(p8->version, 0)) {
8afca8d9 345 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
346 PKCS8_PRIV_KEY_INFO_free (p8);
347 return NULL;
348 }
cfcefcbe 349 if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
8afca8d9 350 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
cfcefcbe
DSH
351 PKCS8_PRIV_KEY_INFO_free (p8);
352 return NULL;
353 }
66430207 354 p8->pkey->type = V_ASN1_OCTET_STRING;
cfcefcbe 355 switch (EVP_PKEY_type(pkey->type)) {
cf1b7d96 356#ifndef OPENSSL_NO_RSA
cfcefcbe
DSH
357 case EVP_PKEY_RSA:
358
66430207
DSH
359 if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;
360
cfcefcbe
DSH
361 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
362 p8->pkeyalg->parameter->type = V_ASN1_NULL;
41a15c4f 363 if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey,
cfcefcbe 364 &p8->pkey->value.octet_string)) {
8afca8d9 365 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
cfcefcbe
DSH
366 PKCS8_PRIV_KEY_INFO_free (p8);
367 return NULL;
368 }
369 break;
f5d7a031 370#endif
cf1b7d96 371#ifndef OPENSSL_NO_DSA
cfcefcbe 372 case EVP_PKEY_DSA:
66430207 373 if(!dsa_pkey2pkcs8(p8, pkey)) {
cfcefcbe
DSH
374 PKCS8_PRIV_KEY_INFO_free (p8);
375 return NULL;
376 }
66430207 377
cfcefcbe 378 break;
f5d7a031 379#endif
5488bb61
BM
380#ifndef OPENSSL_NO_EC
381 case EVP_PKEY_EC:
14a7cfb3 382 if (!eckey_pkey2pkcs8(p8, pkey))
4d94ae00
BM
383 {
384 PKCS8_PRIV_KEY_INFO_free(p8);
385 return(NULL);
386 }
387 break;
388#endif
cfcefcbe 389 default:
8afca8d9 390 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
cfcefcbe
DSH
391 PKCS8_PRIV_KEY_INFO_free (p8);
392 return NULL;
393 }
eb952088 394 RAND_add(p8->pkey->value.octet_string->data,
875a644a 395 p8->pkey->value.octet_string->length, 0.0);
cfcefcbe
DSH
396 return p8;
397}
398
6b691a5c 399PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
cfcefcbe
DSH
400{
401 switch (broken) {
402
403 case PKCS8_OK:
404 p8->broken = PKCS8_OK;
405 return p8;
406 break;
407
408 case PKCS8_NO_OCTET:
409 p8->broken = PKCS8_NO_OCTET;
410 p8->pkey->type = V_ASN1_SEQUENCE;
411 return p8;
412 break;
413
414 default:
8afca8d9 415 EVPerr(EVP_F_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
cfcefcbe 416 return NULL;
cfcefcbe
DSH
417 }
418}
419
cf1b7d96 420#ifndef OPENSSL_NO_DSA
66430207
DSH
421static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
422{
a0e7c8ee
DSH
423 ASN1_STRING *params = NULL;
424 ASN1_INTEGER *prkey = NULL;
425 ASN1_TYPE *ttmp = NULL;
426 STACK_OF(ASN1_TYPE) *ndsa = NULL;
427 unsigned char *p = NULL, *q;
66430207 428 int len;
371acb22 429
66430207
DSH
430 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
431 len = i2d_DSAparams (pkey->pkey.dsa, NULL);
26a3a48d 432 if (!(p = OPENSSL_malloc(len))) {
8afca8d9 433 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee 434 goto err;
66430207
DSH
435 }
436 q = p;
437 i2d_DSAparams (pkey->pkey.dsa, &q);
a0e7c8ee 438 if (!(params = ASN1_STRING_new())) {
8afca8d9 439 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
440 goto err;
441 }
442 if (!ASN1_STRING_set(params, p, len)) {
8afca8d9 443 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
444 goto err;
445 }
26a3a48d 446 OPENSSL_free(p);
a0e7c8ee 447 p = NULL;
66430207
DSH
448 /* Get private key into integer */
449 if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
8afca8d9 450 EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
a0e7c8ee 451 goto err;
66430207
DSH
452 }
453
454 switch(p8->broken) {
cfcefcbe 455
66430207
DSH
456 case PKCS8_OK:
457 case PKCS8_NO_OCTET:
458
41a15c4f 459 if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
66430207 460 &p8->pkey->value.octet_string)) {
8afca8d9 461 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee 462 goto err;
66430207
DSH
463 }
464
465 M_ASN1_INTEGER_free (prkey);
a0e7c8ee 466 prkey = NULL;
66430207 467 p8->pkeyalg->parameter->value.sequence = params;
a0e7c8ee 468 params = NULL;
66430207
DSH
469 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
470
471 break;
472
473 case PKCS8_NS_DB:
474
475 p8->pkeyalg->parameter->value.sequence = params;
a0e7c8ee 476 params = NULL;
66430207 477 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
a0e7c8ee 478 if (!(ndsa = sk_ASN1_TYPE_new_null())) {
8afca8d9 479 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
480 goto err;
481 }
482 if (!(ttmp = ASN1_TYPE_new())) {
8afca8d9 483 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
484 goto err;
485 }
486 if (!(ttmp->value.integer =
487 BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
8afca8d9 488 EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
a0e7c8ee 489 goto err;
66430207
DSH
490 }
491 ttmp->type = V_ASN1_INTEGER;
a0e7c8ee 492 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
8afca8d9 493 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
494 goto err;
495 }
66430207 496
a0e7c8ee 497 if (!(ttmp = ASN1_TYPE_new())) {
8afca8d9 498 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
499 goto err;
500 }
66430207 501 ttmp->value.integer = prkey;
a0e7c8ee 502 prkey = NULL;
66430207 503 ttmp->type = V_ASN1_INTEGER;
a0e7c8ee 504 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
8afca8d9 505 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
506 goto err;
507 }
508 ttmp = NULL;
66430207 509
a0e7c8ee 510 if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
8afca8d9 511 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
512 goto err;
513 }
66430207 514
371acb22 515 if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
66430207
DSH
516 &p8->pkey->value.octet_string->data,
517 &p8->pkey->value.octet_string->length)) {
518
8afca8d9 519 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee 520 goto err;
66430207 521 }
371acb22 522 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
66430207
DSH
523 break;
524
525 case PKCS8_EMBEDDED_PARAM:
526
527 p8->pkeyalg->parameter->type = V_ASN1_NULL;
a0e7c8ee 528 if (!(ndsa = sk_ASN1_TYPE_new_null())) {
8afca8d9 529 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
530 goto err;
531 }
532 if (!(ttmp = ASN1_TYPE_new())) {
8afca8d9 533 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
534 goto err;
535 }
66430207 536 ttmp->value.sequence = params;
a0e7c8ee 537 params = NULL;
66430207 538 ttmp->type = V_ASN1_SEQUENCE;
a0e7c8ee 539 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
8afca8d9 540 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
541 goto err;
542 }
66430207 543
a0e7c8ee 544 if (!(ttmp = ASN1_TYPE_new())) {
8afca8d9 545 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
546 goto err;
547 }
66430207 548 ttmp->value.integer = prkey;
a0e7c8ee 549 prkey = NULL;
66430207 550 ttmp->type = V_ASN1_INTEGER;
a0e7c8ee 551 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
8afca8d9 552 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
553 goto err;
554 }
555 ttmp = NULL;
66430207 556
a0e7c8ee 557 if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
8afca8d9 558 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee
DSH
559 goto err;
560 }
66430207 561
371acb22 562 if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
66430207
DSH
563 &p8->pkey->value.octet_string->data,
564 &p8->pkey->value.octet_string->length)) {
565
8afca8d9 566 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
a0e7c8ee 567 goto err;
66430207 568 }
371acb22 569 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
66430207
DSH
570 break;
571 }
572 return 1;
a0e7c8ee
DSH
573err:
574 if (p != NULL) OPENSSL_free(p);
575 if (params != NULL) ASN1_STRING_free(params);
576 if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
577 if (ttmp != NULL) ASN1_TYPE_free(ttmp);
578 if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
579 return 0;
66430207
DSH
580}
581#endif
4d94ae00 582
14a7cfb3
BM
583#ifndef OPENSSL_NO_EC
584static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
4d94ae00 585{
8ee4845b 586 EC_KEY *eckey;
8ee4845b 587 unsigned char *p, *pp;
0fbffe7a
BM
588 int nid, i, ret = 0;
589 unsigned int tmp_flags;
4d94ae00 590
14a7cfb3 591 if (pkey->pkey.eckey == NULL || pkey->pkey.eckey->group == NULL)
4d94ae00 592 {
8afca8d9 593 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
4d94ae00
BM
594 return 0;
595 }
8ee4845b
BM
596 eckey = pkey->pkey.eckey;
597
598 /* set the ec parameters OID */
599 if (p8->pkeyalg->algorithm)
600 ASN1_OBJECT_free(p8->pkeyalg->algorithm);
601
602 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
603
604 /* set the ec parameters */
605
606 if (p8->pkeyalg->parameter)
4d94ae00 607 {
8ee4845b
BM
608 ASN1_TYPE_free(p8->pkeyalg->parameter);
609 p8->pkeyalg->parameter = NULL;
4d94ae00 610 }
8ee4845b
BM
611
612 if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
4d94ae00 613 {
8afca8d9 614 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
4d94ae00 615 return 0;
4d94ae00 616 }
8ee4845b
BM
617
618 if (EC_GROUP_get_asn1_flag(eckey->group)
7dc17a6c 619 && (nid = EC_GROUP_get_curve_name(eckey->group)))
4d94ae00 620 {
8ee4845b
BM
621 /* we have a 'named curve' => just set the OID */
622 p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
623 p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
4d94ae00 624 }
8ee4845b 625 else /* explicit parameters */
4d94ae00 626 {
8ee4845b 627 if ((i = i2d_ECParameters(eckey, NULL)) == 0)
4d94ae00 628 {
8afca8d9 629 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
4d94ae00
BM
630 return 0;
631 }
8ee4845b 632 if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
4d94ae00 633 {
8afca8d9 634 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
4d94ae00 635 return 0;
8ee4845b
BM
636 }
637 pp = p;
638 if (!i2d_ECParameters(eckey, &pp))
4d94ae00 639 {
8afca8d9 640 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
4d94ae00
BM
641 OPENSSL_free(p);
642 return 0;
643 }
8ee4845b
BM
644 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
645 if ((p8->pkeyalg->parameter->value.sequence
646 = ASN1_STRING_new()) == NULL)
4d94ae00 647 {
8afca8d9 648 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
8ee4845b 649 OPENSSL_free(p);
4d94ae00
BM
650 return 0;
651 }
8ee4845b 652 ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
4d94ae00 653 OPENSSL_free(p);
8ee4845b 654 }
4d94ae00 655
8ee4845b 656 /* set the private key */
0fbffe7a
BM
657
658 /* do not include the parameters in the SEC1 private key
659 * see PKCS#11 12.11 */
660 tmp_flags = pkey->pkey.eckey->enc_flag;
661 pkey->pkey.eckey->enc_flag |= EC_PKEY_NO_PARAMETERS;
662 i = i2d_ECPrivateKey(pkey->pkey.eckey, NULL);
663 if (!i)
664 {
665 pkey->pkey.eckey->enc_flag = tmp_flags;
8afca8d9 666 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
0fbffe7a
BM
667 return 0;
668 }
669 p = (unsigned char *) OPENSSL_malloc(i);
670 if (!p)
8ee4845b 671 {
0fbffe7a 672 pkey->pkey.eckey->enc_flag = tmp_flags;
8afca8d9 673 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
8ee4845b
BM
674 return 0;
675 }
0fbffe7a
BM
676 pp = p;
677 if (!i2d_ECPrivateKey(pkey->pkey.eckey, &pp))
678 {
679 pkey->pkey.eckey->enc_flag = tmp_flags;
8afca8d9 680 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
0fbffe7a
BM
681 OPENSSL_free(p);
682 return 0;
683 }
684 /* restore old encoding flags */
685 pkey->pkey.eckey->enc_flag = tmp_flags;
4d94ae00 686
8ee4845b 687 switch(p8->broken) {
4d94ae00 688
8ee4845b 689 case PKCS8_OK:
0fbffe7a
BM
690 p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
691 if (!p8->pkey->value.octet_string ||
692 !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
693 (const void *)p, i))
694
4d94ae00 695 {
8afca8d9 696 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
4d94ae00 697 }
0fbffe7a
BM
698 else
699 ret = 1;
8ee4845b
BM
700 break;
701 case PKCS8_NO_OCTET: /* RSA specific */
702 case PKCS8_NS_DB: /* DSA specific */
703 case PKCS8_EMBEDDED_PARAM: /* DSA specific */
704 default:
8afca8d9 705 EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
4d94ae00 706 }
0fbffe7a
BM
707 OPENSSL_cleanse(p, (size_t)i);
708 OPENSSL_free(p);
709 return ret;
4d94ae00
BM
710}
711#endif