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