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