ec_asn1.c revision 296465
1/* crypto/ec/ec_asn1.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2003 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 <string.h>
60#include "ec_lcl.h"
61#include <openssl/err.h>
62#include <openssl/asn1t.h>
63#include <openssl/objects.h>
64
65int EC_GROUP_get_basis_type(const EC_GROUP *group)
66{
67    int i = 0;
68
69    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
70        NID_X9_62_characteristic_two_field)
71        /* everything else is currently not supported */
72        return 0;
73
74    while (group->poly[i] != 0)
75        i++;
76
77    if (i == 4)
78        return NID_X9_62_ppBasis;
79    else if (i == 2)
80        return NID_X9_62_tpBasis;
81    else
82        /* everything else is currently not supported */
83        return 0;
84}
85
86int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
87{
88    if (group == NULL)
89        return 0;
90
91    if (EC_GROUP_method_of(group)->group_set_curve !=
92        ec_GF2m_simple_group_set_curve || !((group->poly[0] != 0)
93                                            && (group->poly[1] != 0)
94                                            && (group->poly[2] == 0))) {
95        ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
96              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
97        return 0;
98    }
99
100    if (k)
101        *k = group->poly[1];
102
103    return 1;
104}
105
106int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
107                                   unsigned int *k2, unsigned int *k3)
108{
109    if (group == NULL)
110        return 0;
111
112    if (EC_GROUP_method_of(group)->group_set_curve !=
113        ec_GF2m_simple_group_set_curve || !((group->poly[0] != 0)
114                                            && (group->poly[1] != 0)
115                                            && (group->poly[2] != 0)
116                                            && (group->poly[3] != 0)
117                                            && (group->poly[4] == 0))) {
118        ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
119              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
120        return 0;
121    }
122
123    if (k1)
124        *k1 = group->poly[3];
125    if (k2)
126        *k2 = group->poly[2];
127    if (k3)
128        *k3 = group->poly[1];
129
130    return 1;
131}
132
133/* some structures needed for the asn1 encoding */
134typedef struct x9_62_pentanomial_st {
135    long k1;
136    long k2;
137    long k3;
138} X9_62_PENTANOMIAL;
139
140typedef struct x9_62_characteristic_two_st {
141    long m;
142    ASN1_OBJECT *type;
143    union {
144        char *ptr;
145        /* NID_X9_62_onBasis */
146        ASN1_NULL *onBasis;
147        /* NID_X9_62_tpBasis */
148        ASN1_INTEGER *tpBasis;
149        /* NID_X9_62_ppBasis */
150        X9_62_PENTANOMIAL *ppBasis;
151        /* anything else */
152        ASN1_TYPE *other;
153    } p;
154} X9_62_CHARACTERISTIC_TWO;
155
156typedef struct x9_62_fieldid_st {
157    ASN1_OBJECT *fieldType;
158    union {
159        char *ptr;
160        /* NID_X9_62_prime_field */
161        ASN1_INTEGER *prime;
162        /* NID_X9_62_characteristic_two_field */
163        X9_62_CHARACTERISTIC_TWO *char_two;
164        /* anything else */
165        ASN1_TYPE *other;
166    } p;
167} X9_62_FIELDID;
168
169typedef struct x9_62_curve_st {
170    ASN1_OCTET_STRING *a;
171    ASN1_OCTET_STRING *b;
172    ASN1_BIT_STRING *seed;
173} X9_62_CURVE;
174
175typedef struct ec_parameters_st {
176    long version;
177    X9_62_FIELDID *fieldID;
178    X9_62_CURVE *curve;
179    ASN1_OCTET_STRING *base;
180    ASN1_INTEGER *order;
181    ASN1_INTEGER *cofactor;
182} ECPARAMETERS;
183
184struct ecpk_parameters_st {
185    int type;
186    union {
187        ASN1_OBJECT *named_curve;
188        ECPARAMETERS *parameters;
189        ASN1_NULL *implicitlyCA;
190    } value;
191} /* ECPKPARAMETERS */ ;
192
193/* SEC1 ECPrivateKey */
194typedef struct ec_privatekey_st {
195    long version;
196    ASN1_OCTET_STRING *privateKey;
197    ECPKPARAMETERS *parameters;
198    ASN1_BIT_STRING *publicKey;
199} EC_PRIVATEKEY;
200
201/* the OpenSSL ASN.1 definitions */
202ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
203        ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
204        ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
205        ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
206} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
207
208DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
209IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
210
211ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
212
213ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
214        ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
215        ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
216        ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
217} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
218
219ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
220        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
221        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
222        ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
223} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
224
225DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
226IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
227
228ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
229
230ASN1_ADB(X9_62_FIELDID) = {
231        ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
232        ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
233} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
234
235ASN1_SEQUENCE(X9_62_FIELDID) = {
236        ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
237        ASN1_ADB_OBJECT(X9_62_FIELDID)
238} ASN1_SEQUENCE_END(X9_62_FIELDID)
239
240ASN1_SEQUENCE(X9_62_CURVE) = {
241        ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
242        ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
243        ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
244} ASN1_SEQUENCE_END(X9_62_CURVE)
245
246ASN1_SEQUENCE(ECPARAMETERS) = {
247        ASN1_SIMPLE(ECPARAMETERS, version, LONG),
248        ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
249        ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
250        ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
251        ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
252        ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
253} ASN1_SEQUENCE_END(ECPARAMETERS)
254
255DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
256IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
257
258ASN1_CHOICE(ECPKPARAMETERS) = {
259        ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
260        ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
261        ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
262} ASN1_CHOICE_END(ECPKPARAMETERS)
263
264DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
265DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
266IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
267
268ASN1_SEQUENCE(EC_PRIVATEKEY) = {
269        ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
270        ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
271        ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
272        ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
273} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
274
275DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
276DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
277IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
278
279/* some declarations of internal function */
280
281/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
282static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
283/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
284static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
285/*
286 * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS
287 * object
288 */
289static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
290/*
291 * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP
292 * object
293 */
294static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,
295                                              ECPARAMETERS *);
296/*
297 * ec_asn1_pkparameters2group() creates a EC_GROUP object from a
298 * ECPKPARAMETERS object
299 */
300static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
301/*
302 * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
303 * EC_GROUP object
304 */
305static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
306                                                  ECPKPARAMETERS *);
307
308/* the function definitions */
309
310static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
311{
312    int ok = 0, nid;
313    BIGNUM *tmp = NULL;
314
315    if (group == NULL || field == NULL)
316        return 0;
317
318    /* clear the old values (if necessary) */
319    if (field->fieldType != NULL)
320        ASN1_OBJECT_free(field->fieldType);
321    if (field->p.other != NULL)
322        ASN1_TYPE_free(field->p.other);
323
324    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
325    /* set OID for the field */
326    if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
327        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
328        goto err;
329    }
330
331    if (nid == NID_X9_62_prime_field) {
332        if ((tmp = BN_new()) == NULL) {
333            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
334            goto err;
335        }
336        /* the parameters are specified by the prime number p */
337        if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
338            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
339            goto err;
340        }
341        /* set the prime number */
342        field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
343        if (field->p.prime == NULL) {
344            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
345            goto err;
346        }
347    } else {                    /* nid == NID_X9_62_characteristic_two_field */
348
349        int field_type;
350        X9_62_CHARACTERISTIC_TWO *char_two;
351
352        field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
353        char_two = field->p.char_two;
354
355        if (char_two == NULL) {
356            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
357            goto err;
358        }
359
360        char_two->m = (long)EC_GROUP_get_degree(group);
361
362        field_type = EC_GROUP_get_basis_type(group);
363
364        if (field_type == 0) {
365            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
366            goto err;
367        }
368        /* set base type OID */
369        if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
370            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
371            goto err;
372        }
373
374        if (field_type == NID_X9_62_tpBasis) {
375            unsigned int k;
376
377            if (!EC_GROUP_get_trinomial_basis(group, &k))
378                goto err;
379
380            char_two->p.tpBasis = ASN1_INTEGER_new();
381            if (!char_two->p.tpBasis) {
382                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
383                goto err;
384            }
385            if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) {
386                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
387                goto err;
388            }
389        } else if (field_type == NID_X9_62_ppBasis) {
390            unsigned int k1, k2, k3;
391
392            if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
393                goto err;
394
395            char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
396            if (!char_two->p.ppBasis) {
397                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
398                goto err;
399            }
400
401            /* set k? values */
402            char_two->p.ppBasis->k1 = (long)k1;
403            char_two->p.ppBasis->k2 = (long)k2;
404            char_two->p.ppBasis->k3 = (long)k3;
405        } else {                /* field_type == NID_X9_62_onBasis */
406
407            /* for ONB the parameters are (asn1) NULL */
408            char_two->p.onBasis = ASN1_NULL_new();
409            if (!char_two->p.onBasis) {
410                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
411                goto err;
412            }
413        }
414    }
415
416    ok = 1;
417
418 err:if (tmp)
419        BN_free(tmp);
420    return (ok);
421}
422
423static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
424{
425    int ok = 0, nid;
426    BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
427    unsigned char *buffer_1 = NULL, *buffer_2 = NULL,
428        *a_buf = NULL, *b_buf = NULL;
429    size_t len_1, len_2;
430    unsigned char char_zero = 0;
431
432    if (!group || !curve || !curve->a || !curve->b)
433        return 0;
434
435    if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
436        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
437        goto err;
438    }
439
440    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
441
442    /* get a and b */
443    if (nid == NID_X9_62_prime_field) {
444        if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
445            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
446            goto err;
447        }
448    } else {                    /* nid == NID_X9_62_characteristic_two_field */
449
450        if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
451            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
452            goto err;
453        }
454    }
455
456    len_1 = (size_t)BN_num_bytes(tmp_1);
457    len_2 = (size_t)BN_num_bytes(tmp_2);
458
459    if (len_1 == 0) {
460        /* len_1 == 0 => a == 0 */
461        a_buf = &char_zero;
462        len_1 = 1;
463    } else {
464        if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) {
465            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
466            goto err;
467        }
468        if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
469            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
470            goto err;
471        }
472        a_buf = buffer_1;
473    }
474
475    if (len_2 == 0) {
476        /* len_2 == 0 => b == 0 */
477        b_buf = &char_zero;
478        len_2 = 1;
479    } else {
480        if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) {
481            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
482            goto err;
483        }
484        if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
485            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
486            goto err;
487        }
488        b_buf = buffer_2;
489    }
490
491    /* set a and b */
492    if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
493        !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
494        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
495        goto err;
496    }
497
498    /* set the seed (optional) */
499    if (group->seed) {
500        if (!curve->seed)
501            if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
502                ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
503                goto err;
504            }
505        curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
506        curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
507        if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
508                                 (int)group->seed_len)) {
509            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
510            goto err;
511        }
512    } else {
513        if (curve->seed) {
514            ASN1_BIT_STRING_free(curve->seed);
515            curve->seed = NULL;
516        }
517    }
518
519    ok = 1;
520
521 err:if (buffer_1)
522        OPENSSL_free(buffer_1);
523    if (buffer_2)
524        OPENSSL_free(buffer_2);
525    if (tmp_1)
526        BN_free(tmp_1);
527    if (tmp_2)
528        BN_free(tmp_2);
529    return (ok);
530}
531
532static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
533                                              ECPARAMETERS *param)
534{
535    int ok = 0;
536    size_t len = 0;
537    ECPARAMETERS *ret = NULL;
538    BIGNUM *tmp = NULL;
539    unsigned char *buffer = NULL;
540    const EC_POINT *point = NULL;
541    point_conversion_form_t form;
542
543    if ((tmp = BN_new()) == NULL) {
544        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
545        goto err;
546    }
547
548    if (param == NULL) {
549        if ((ret = ECPARAMETERS_new()) == NULL) {
550            ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
551            goto err;
552        }
553    } else
554        ret = param;
555
556    /* set the version (always one) */
557    ret->version = (long)0x1;
558
559    /* set the fieldID */
560    if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
561        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
562        goto err;
563    }
564
565    /* set the curve */
566    if (!ec_asn1_group2curve(group, ret->curve)) {
567        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
568        goto err;
569    }
570
571    /* set the base point */
572    if ((point = EC_GROUP_get0_generator(group)) == NULL) {
573        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
574        goto err;
575    }
576
577    form = EC_GROUP_get_point_conversion_form(group);
578
579    len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
580    if (len == 0) {
581        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
582        goto err;
583    }
584    if ((buffer = OPENSSL_malloc(len)) == NULL) {
585        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
586        goto err;
587    }
588    if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
589        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
590        goto err;
591    }
592    if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
593        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
594        goto err;
595    }
596    if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
597        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
598        goto err;
599    }
600
601    /* set the order */
602    if (!EC_GROUP_get_order(group, tmp, NULL)) {
603        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
604        goto err;
605    }
606    ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
607    if (ret->order == NULL) {
608        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
609        goto err;
610    }
611
612    /* set the cofactor (optional) */
613    if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
614        ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
615        if (ret->cofactor == NULL) {
616            ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
617            goto err;
618        }
619    }
620
621    ok = 1;
622
623 err:if (!ok) {
624        if (ret && !param)
625            ECPARAMETERS_free(ret);
626        ret = NULL;
627    }
628    if (tmp)
629        BN_free(tmp);
630    if (buffer)
631        OPENSSL_free(buffer);
632    return (ret);
633}
634
635ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
636                                           ECPKPARAMETERS *params)
637{
638    int ok = 1, tmp;
639    ECPKPARAMETERS *ret = params;
640
641    if (ret == NULL) {
642        if ((ret = ECPKPARAMETERS_new()) == NULL) {
643            ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE);
644            return NULL;
645        }
646    } else {
647        if (ret->type == 0 && ret->value.named_curve)
648            ASN1_OBJECT_free(ret->value.named_curve);
649        else if (ret->type == 1 && ret->value.parameters)
650            ECPARAMETERS_free(ret->value.parameters);
651    }
652
653    if (EC_GROUP_get_asn1_flag(group)) {
654        /*
655         * use the asn1 OID to describe the the elliptic curve parameters
656         */
657        tmp = EC_GROUP_get_curve_name(group);
658        if (tmp) {
659            ret->type = 0;
660            if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
661                ok = 0;
662        } else
663            /* we don't kmow the nid => ERROR */
664            ok = 0;
665    } else {
666        /* use the ECPARAMETERS structure */
667        ret->type = 1;
668        if ((ret->value.parameters =
669             ec_asn1_group2parameters(group, NULL)) == NULL)
670            ok = 0;
671    }
672
673    if (!ok) {
674        ECPKPARAMETERS_free(ret);
675        return NULL;
676    }
677    return ret;
678}
679
680static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
681{
682    int ok = 0, tmp;
683    EC_GROUP *ret = NULL;
684    BIGNUM *p = NULL, *a = NULL, *b = NULL;
685    EC_POINT *point = NULL;
686    long field_bits;
687
688    if (!params->fieldID || !params->fieldID->fieldType ||
689        !params->fieldID->p.ptr) {
690        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
691        goto err;
692    }
693
694    /* now extract the curve parameters a and b */
695    if (!params->curve || !params->curve->a ||
696        !params->curve->a->data || !params->curve->b ||
697        !params->curve->b->data) {
698        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
699        goto err;
700    }
701    a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
702    if (a == NULL) {
703        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
704        goto err;
705    }
706    b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
707    if (b == NULL) {
708        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
709        goto err;
710    }
711
712    /* get the field parameters */
713    tmp = OBJ_obj2nid(params->fieldID->fieldType);
714
715    if (tmp == NID_X9_62_characteristic_two_field) {
716        X9_62_CHARACTERISTIC_TWO *char_two;
717
718        char_two = params->fieldID->p.char_two;
719
720        field_bits = char_two->m;
721        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
722            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
723            goto err;
724        }
725
726        if ((p = BN_new()) == NULL) {
727            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
728            goto err;
729        }
730
731        /* get the base type */
732        tmp = OBJ_obj2nid(char_two->type);
733
734        if (tmp == NID_X9_62_tpBasis) {
735            long tmp_long;
736
737            if (!char_two->p.tpBasis) {
738                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
739                goto err;
740            }
741
742            tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
743
744            if (!(char_two->m > tmp_long && tmp_long > 0)) {
745                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
746                      EC_R_INVALID_TRINOMIAL_BASIS);
747                goto err;
748            }
749
750            /* create the polynomial */
751            if (!BN_set_bit(p, (int)char_two->m))
752                goto err;
753            if (!BN_set_bit(p, (int)tmp_long))
754                goto err;
755            if (!BN_set_bit(p, 0))
756                goto err;
757        } else if (tmp == NID_X9_62_ppBasis) {
758            X9_62_PENTANOMIAL *penta;
759
760            penta = char_two->p.ppBasis;
761            if (!penta) {
762                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
763                goto err;
764            }
765
766            if (!
767                (char_two->m > penta->k3 && penta->k3 > penta->k2
768                 && penta->k2 > penta->k1 && penta->k1 > 0)) {
769                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
770                      EC_R_INVALID_PENTANOMIAL_BASIS);
771                goto err;
772            }
773
774            /* create the polynomial */
775            if (!BN_set_bit(p, (int)char_two->m))
776                goto err;
777            if (!BN_set_bit(p, (int)penta->k1))
778                goto err;
779            if (!BN_set_bit(p, (int)penta->k2))
780                goto err;
781            if (!BN_set_bit(p, (int)penta->k3))
782                goto err;
783            if (!BN_set_bit(p, 0))
784                goto err;
785        } else if (tmp == NID_X9_62_onBasis) {
786            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
787            goto err;
788        } else {                /* error */
789
790            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
791            goto err;
792        }
793
794        /* create the EC_GROUP structure */
795        ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
796    } else if (tmp == NID_X9_62_prime_field) {
797        /* we have a curve over a prime field */
798        /* extract the prime number */
799        if (!params->fieldID->p.prime) {
800            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
801            goto err;
802        }
803        p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
804        if (p == NULL) {
805            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
806            goto err;
807        }
808
809        if (BN_is_negative(p) || BN_is_zero(p)) {
810            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
811            goto err;
812        }
813
814        field_bits = BN_num_bits(p);
815        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
816            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
817            goto err;
818        }
819
820        /* create the EC_GROUP structure */
821        ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
822    } else {
823        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
824        goto err;
825    }
826
827    if (ret == NULL) {
828        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
829        goto err;
830    }
831
832    /* extract seed (optional) */
833    if (params->curve->seed != NULL) {
834        if (ret->seed != NULL)
835            OPENSSL_free(ret->seed);
836        if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) {
837            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
838            goto err;
839        }
840        memcpy(ret->seed, params->curve->seed->data,
841               params->curve->seed->length);
842        ret->seed_len = params->curve->seed->length;
843    }
844
845    if (!params->order || !params->base || !params->base->data) {
846        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
847        goto err;
848    }
849
850    if ((point = EC_POINT_new(ret)) == NULL)
851        goto err;
852
853    /* set the point conversion form */
854    EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
855                                       (params->base->data[0] & ~0x01));
856
857    /* extract the ec point */
858    if (!EC_POINT_oct2point(ret, point, params->base->data,
859                            params->base->length, NULL)) {
860        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
861        goto err;
862    }
863
864    /* extract the order */
865    if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
866        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
867        goto err;
868    }
869    if (BN_is_negative(a) || BN_is_zero(a)) {
870        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
871        goto err;
872    }
873    if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
874        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
875        goto err;
876    }
877
878    /* extract the cofactor (optional) */
879    if (params->cofactor == NULL) {
880        if (b) {
881            BN_free(b);
882            b = NULL;
883        }
884    } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
885        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
886        goto err;
887    }
888    /* set the generator, order and cofactor (if present) */
889    if (!EC_GROUP_set_generator(ret, point, a, b)) {
890        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
891        goto err;
892    }
893
894    ok = 1;
895
896 err:if (!ok) {
897        if (ret)
898            EC_GROUP_clear_free(ret);
899        ret = NULL;
900    }
901
902    if (p)
903        BN_free(p);
904    if (a)
905        BN_free(a);
906    if (b)
907        BN_free(b);
908    if (point)
909        EC_POINT_free(point);
910    return (ret);
911}
912
913EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
914{
915    EC_GROUP *ret = NULL;
916    int tmp = 0;
917
918    if (params == NULL) {
919        ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS);
920        return NULL;
921    }
922
923    if (params->type == 0) {    /* the curve is given by an OID */
924        tmp = OBJ_obj2nid(params->value.named_curve);
925        if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
926            ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
927                  EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
928            return NULL;
929        }
930        EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
931    } else if (params->type == 1) { /* the parameters are given by a
932                                     * ECPARAMETERS structure */
933        ret = ec_asn1_parameters2group(params->value.parameters);
934        if (!ret) {
935            ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
936            return NULL;
937        }
938        EC_GROUP_set_asn1_flag(ret, 0x0);
939    } else if (params->type == 2) { /* implicitlyCA */
940        return NULL;
941    } else {
942        ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
943        return NULL;
944    }
945
946    return ret;
947}
948
949/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
950
951EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
952{
953    EC_GROUP *group = NULL;
954    ECPKPARAMETERS *params = NULL;
955
956    if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
957        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
958        ECPKPARAMETERS_free(params);
959        return NULL;
960    }
961
962    if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
963        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
964        return NULL;
965    }
966
967    if (a && *a)
968        EC_GROUP_clear_free(*a);
969    if (a)
970        *a = group;
971
972    ECPKPARAMETERS_free(params);
973    return (group);
974}
975
976int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
977{
978    int ret = 0;
979    ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
980    if (tmp == NULL) {
981        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
982        return 0;
983    }
984    if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
985        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
986        ECPKPARAMETERS_free(tmp);
987        return 0;
988    }
989    ECPKPARAMETERS_free(tmp);
990    return (ret);
991}
992
993/* some EC_KEY functions */
994
995EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
996{
997    int ok = 0;
998    EC_KEY *ret = NULL;
999    EC_PRIVATEKEY *priv_key = NULL;
1000
1001    if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1002        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1003        return NULL;
1004    }
1005
1006    if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) {
1007        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1008        EC_PRIVATEKEY_free(priv_key);
1009        return NULL;
1010    }
1011
1012    if (a == NULL || *a == NULL) {
1013        if ((ret = EC_KEY_new()) == NULL) {
1014            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1015            goto err;
1016        }
1017    } else
1018        ret = *a;
1019
1020    if (priv_key->parameters) {
1021        if (ret->group)
1022            EC_GROUP_clear_free(ret->group);
1023        ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1024    }
1025
1026    if (ret->group == NULL) {
1027        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1028        goto err;
1029    }
1030
1031    ret->version = priv_key->version;
1032
1033    if (priv_key->privateKey) {
1034        ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
1035                                  M_ASN1_STRING_length(priv_key->privateKey),
1036                                  ret->priv_key);
1037        if (ret->priv_key == NULL) {
1038            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB);
1039            goto err;
1040        }
1041    } else {
1042        ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
1043        goto err;
1044    }
1045
1046    if (priv_key->publicKey) {
1047        const unsigned char *pub_oct;
1048        size_t pub_oct_len;
1049
1050        if (ret->pub_key)
1051            EC_POINT_clear_free(ret->pub_key);
1052        ret->pub_key = EC_POINT_new(ret->group);
1053        if (ret->pub_key == NULL) {
1054            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1055            goto err;
1056        }
1057        pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
1058        pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1059        /* save the point conversion form */
1060        ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
1061        if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1062                                pub_oct, pub_oct_len, NULL)) {
1063            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1064            goto err;
1065        }
1066    }
1067
1068    if (a)
1069        *a = ret;
1070    ok = 1;
1071 err:
1072    if (!ok) {
1073        if (ret && (a == NULL || *a != ret))
1074            EC_KEY_free(ret);
1075        ret = NULL;
1076    }
1077
1078    if (priv_key)
1079        EC_PRIVATEKEY_free(priv_key);
1080
1081    return (ret);
1082}
1083
1084int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1085{
1086    int ret = 0, ok = 0;
1087    unsigned char *buffer = NULL;
1088    size_t buf_len = 0, tmp_len;
1089    EC_PRIVATEKEY *priv_key = NULL;
1090
1091    if (a == NULL || a->group == NULL || a->priv_key == NULL) {
1092        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
1093        goto err;
1094    }
1095
1096    if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1097        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1098        goto err;
1099    }
1100
1101    priv_key->version = a->version;
1102
1103    buf_len = (size_t)BN_num_bytes(a->priv_key);
1104    buffer = OPENSSL_malloc(buf_len);
1105    if (buffer == NULL) {
1106        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1107        goto err;
1108    }
1109
1110    if (!BN_bn2bin(a->priv_key, buffer)) {
1111        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1112        goto err;
1113    }
1114
1115    if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
1116        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1117        goto err;
1118    }
1119
1120    if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1121        if ((priv_key->parameters =
1122             ec_asn1_group2pkparameters(a->group,
1123                                        priv_key->parameters)) == NULL) {
1124            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1125            goto err;
1126        }
1127    }
1128
1129    if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
1130        priv_key->publicKey = M_ASN1_BIT_STRING_new();
1131        if (priv_key->publicKey == NULL) {
1132            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1133            goto err;
1134        }
1135
1136        tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1137                                     a->conv_form, NULL, 0, NULL);
1138
1139        if (tmp_len > buf_len) {
1140            unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1141            if (!tmp_buffer) {
1142                ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1143                goto err;
1144            }
1145            buffer = tmp_buffer;
1146            buf_len = tmp_len;
1147        }
1148
1149        if (!EC_POINT_point2oct(a->group, a->pub_key,
1150                                a->conv_form, buffer, buf_len, NULL)) {
1151            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1152            goto err;
1153        }
1154
1155        priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
1156        priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1157        if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
1158            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1159            goto err;
1160        }
1161    }
1162
1163    if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
1164        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1165        goto err;
1166    }
1167    ok = 1;
1168 err:
1169    if (buffer)
1170        OPENSSL_free(buffer);
1171    if (priv_key)
1172        EC_PRIVATEKEY_free(priv_key);
1173    return (ok ? ret : 0);
1174}
1175
1176int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1177{
1178    if (a == NULL) {
1179        ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1180        return 0;
1181    }
1182    return i2d_ECPKParameters(a->group, out);
1183}
1184
1185EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1186{
1187    EC_KEY *ret;
1188
1189    if (in == NULL || *in == NULL) {
1190        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1191        return NULL;
1192    }
1193
1194    if (a == NULL || *a == NULL) {
1195        if ((ret = EC_KEY_new()) == NULL) {
1196            ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1197            return NULL;
1198        }
1199    } else
1200        ret = *a;
1201
1202    if (!d2i_ECPKParameters(&ret->group, in, len)) {
1203        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1204        if (a == NULL || *a != ret)
1205             EC_KEY_free(ret);
1206        return NULL;
1207    }
1208
1209    if (a)
1210        *a = ret;
1211
1212    return ret;
1213}
1214
1215EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1216{
1217    EC_KEY *ret = NULL;
1218
1219    if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
1220        /*
1221         * sorry, but a EC_GROUP-structur is necessary to set the public key
1222         */
1223        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1224        return 0;
1225    }
1226    ret = *a;
1227    if (ret->pub_key == NULL &&
1228        (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
1229        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1230        return 0;
1231    }
1232    if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
1233        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1234        return 0;
1235    }
1236    /* save the point conversion form */
1237    ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
1238    *in += len;
1239    return ret;
1240}
1241
1242int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1243{
1244    size_t buf_len = 0;
1245    int new_buffer = 0;
1246
1247    if (a == NULL) {
1248        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1249        return 0;
1250    }
1251
1252    buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1253                                 a->conv_form, NULL, 0, NULL);
1254
1255    if (out == NULL || buf_len == 0)
1256        /* out == NULL => just return the length of the octet string */
1257        return buf_len;
1258
1259    if (*out == NULL) {
1260        if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
1261            ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1262            return 0;
1263        }
1264        new_buffer = 1;
1265    }
1266    if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1267                            *out, buf_len, NULL)) {
1268        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1269        OPENSSL_free(*out);
1270        *out = NULL;
1271        return 0;
1272    }
1273    if (!new_buffer)
1274        *out += buf_len;
1275    return buf_len;
1276}
1277