Home | History | Annotate | Download | only in ec
      1 /* Written by Nils Larsch for the OpenSSL project. */
      2 /* ====================================================================
      3  * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in
     14  *    the documentation and/or other materials provided with the
     15  *    distribution.
     16  *
     17  * 3. All advertising materials mentioning features or use of this
     18  *    software must display the following acknowledgment:
     19  *    "This product includes software developed by the OpenSSL Project
     20  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     21  *
     22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     23  *    endorse or promote products derived from this software without
     24  *    prior written permission. For written permission, please contact
     25  *    licensing (at) OpenSSL.org.
     26  *
     27  * 5. Products derived from this software may not be called "OpenSSL"
     28  *    nor may "OpenSSL" appear in their names without prior written
     29  *    permission of the OpenSSL Project.
     30  *
     31  * 6. Redistributions of any form whatsoever must retain the following
     32  *    acknowledgment:
     33  *    "This product includes software developed by the OpenSSL Project
     34  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     35  *
     36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     47  * OF THE POSSIBILITY OF SUCH DAMAGE.
     48  * ====================================================================
     49  *
     50  * This product includes cryptographic software written by Eric Young
     51  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     52  * Hudson (tjh (at) cryptsoft.com). */
     53 
     54 #include <openssl/ec.h>
     55 
     56 #include <openssl/asn1.h>
     57 #include <openssl/asn1t.h>
     58 #include <openssl/bn.h>
     59 #include <openssl/err.h>
     60 #include <openssl/mem.h>
     61 #include <openssl/obj.h>
     62 
     63 #include "internal.h"
     64 
     65 
     66 typedef struct x9_62_fieldid_st {
     67   ASN1_OBJECT *fieldType;
     68   union {
     69     char *ptr;
     70     /* NID_X9_62_prime_field */
     71     ASN1_INTEGER *prime;
     72     /* anything else */
     73     ASN1_TYPE *other;
     74   } p;
     75 } X9_62_FIELDID;
     76 
     77 ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
     78 
     79 ASN1_ADB(X9_62_FIELDID) = {
     80   ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
     81 } ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
     82 
     83 ASN1_SEQUENCE(X9_62_FIELDID) = {
     84   ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
     85   ASN1_ADB_OBJECT(X9_62_FIELDID)
     86 } ASN1_SEQUENCE_END(X9_62_FIELDID);
     87 
     88 typedef struct x9_62_curve_st {
     89   ASN1_OCTET_STRING *a;
     90   ASN1_OCTET_STRING *b;
     91   ASN1_BIT_STRING *seed;
     92 } X9_62_CURVE;
     93 
     94 ASN1_SEQUENCE(X9_62_CURVE) = {
     95   ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
     96   ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
     97   ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
     98 } ASN1_SEQUENCE_END(X9_62_CURVE);
     99 
    100 typedef struct ec_parameters_st {
    101   long version;
    102   X9_62_FIELDID *fieldID;
    103   X9_62_CURVE *curve;
    104   ASN1_OCTET_STRING *base;
    105   ASN1_INTEGER *order;
    106   ASN1_INTEGER *cofactor;
    107 } ECPARAMETERS;
    108 
    109 ASN1_SEQUENCE(ECPARAMETERS) = {
    110     ASN1_SIMPLE(ECPARAMETERS, version, LONG),
    111     ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
    112     ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
    113     ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
    114     ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
    115     ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
    116 } ASN1_SEQUENCE_END(ECPARAMETERS);
    117 
    118 DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
    119 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
    120 
    121 typedef struct ecpk_parameters_st {
    122   int type;
    123   union {
    124     ASN1_OBJECT *named_curve;
    125     ECPARAMETERS *parameters;
    126   } value;
    127 } ECPKPARAMETERS;
    128 
    129 /* SEC1 ECPrivateKey */
    130 typedef struct ec_privatekey_st {
    131   long version;
    132   ASN1_OCTET_STRING *privateKey;
    133   ECPKPARAMETERS *parameters;
    134   ASN1_BIT_STRING *publicKey;
    135 } EC_PRIVATEKEY;
    136 
    137 ASN1_CHOICE(ECPKPARAMETERS) = {
    138     ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
    139     ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
    140 } ASN1_CHOICE_END(ECPKPARAMETERS);
    141 
    142 DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
    143 DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS);
    144 IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
    145 
    146 ASN1_SEQUENCE(EC_PRIVATEKEY) = {
    147     ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
    148     ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
    149     ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
    150     ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1),
    151 } ASN1_SEQUENCE_END(EC_PRIVATEKEY);
    152 
    153 DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
    154 DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY);
    155 IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
    156 
    157 
    158 ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
    159                                            ECPKPARAMETERS *params) {
    160   int ok = 0, nid;
    161   ECPKPARAMETERS *ret = params;
    162 
    163   if (ret == NULL) {
    164     ret = ECPKPARAMETERS_new();
    165     if (ret == NULL) {
    166       OPENSSL_PUT_ERROR(EC, ec_asn1_group2pkparameters, ERR_R_MALLOC_FAILURE);
    167       return NULL;
    168     }
    169   } else {
    170     if (ret->value.named_curve) {
    171       ASN1_OBJECT_free(ret->value.named_curve);
    172     }
    173   }
    174 
    175   /* use the ASN.1 OID to describe the the elliptic curve parameters. */
    176   nid = EC_GROUP_get_curve_name(group);
    177   if (nid) {
    178     ret->type = 0;
    179     ret->value.named_curve = (ASN1_OBJECT*) OBJ_nid2obj(nid);
    180     ok = ret->value.named_curve != NULL;
    181   }
    182 
    183   if (!ok) {
    184     ECPKPARAMETERS_free(ret);
    185     return NULL;
    186   }
    187 
    188   return ret;
    189 }
    190 
    191 EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
    192   EC_GROUP *ret = NULL;
    193   int nid = NID_undef;
    194 
    195   if (params == NULL) {
    196     OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_MISSING_PARAMETERS);
    197     return NULL;
    198   }
    199 
    200   if (params->type == 0) {
    201     nid = OBJ_obj2nid(params->value.named_curve);
    202   } else if (params->type == 1) {
    203     /* We don't support arbitary curves so we attempt to recognise it from the
    204      * group order. */
    205     const ECPARAMETERS *ecparams = params->value.parameters;
    206     unsigned i;
    207     const struct built_in_curve *curve;
    208 
    209     for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    210       curve = &OPENSSL_built_in_curves[i];
    211       const unsigned param_len = curve->data->param_len;
    212       if (ecparams->order->length == param_len &&
    213           memcmp(ecparams->order->data, &curve->data->data[param_len * 5],
    214                  param_len) == 0) {
    215         nid = curve->nid;
    216         break;
    217       }
    218     }
    219   }
    220 
    221   if (nid == NID_undef) {
    222     OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_NON_NAMED_CURVE);
    223     return NULL;
    224   }
    225 
    226   ret = EC_GROUP_new_by_curve_name(nid);
    227   if (ret == NULL) {
    228     OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group,
    229                       EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
    230     return NULL;
    231   }
    232 
    233   return ret;
    234 }
    235 
    236 static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
    237                                     long len) {
    238   EC_GROUP *group = NULL;
    239   ECPKPARAMETERS *params = NULL;
    240 
    241   params = d2i_ECPKPARAMETERS(NULL, inp, len);
    242   if (params == NULL) {
    243     OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_D2I_ECPKPARAMETERS_FAILURE);
    244     ECPKPARAMETERS_free(params);
    245     return NULL;
    246   }
    247 
    248   group = ec_asn1_pkparameters2group(params);
    249   if (group == NULL) {
    250     OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_PKPARAMETERS2GROUP_FAILURE);
    251     ECPKPARAMETERS_free(params);
    252     return NULL;
    253   }
    254 
    255   if (groupp && *groupp) {
    256     EC_GROUP_free(*groupp);
    257   }
    258   if (groupp) {
    259     *groupp = group;
    260   }
    261 
    262   ECPKPARAMETERS_free(params);
    263   return group;
    264 }
    265 
    266 static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
    267   int ret = 0;
    268   ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL);
    269   if (tmp == NULL) {
    270     OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_GROUP2PKPARAMETERS_FAILURE);
    271     return 0;
    272   }
    273   ret = i2d_ECPKPARAMETERS(tmp, outp);
    274   if (ret == 0) {
    275     OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_I2D_ECPKPARAMETERS_FAILURE);
    276     ECPKPARAMETERS_free(tmp);
    277     return 0;
    278   }
    279   ECPKPARAMETERS_free(tmp);
    280   return ret;
    281 }
    282 
    283 EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
    284   int ok = 0;
    285   EC_KEY *ret = NULL;
    286   EC_PRIVATEKEY *priv_key = NULL;
    287 
    288   priv_key = EC_PRIVATEKEY_new();
    289   if (priv_key == NULL) {
    290     OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE);
    291     return NULL;
    292   }
    293 
    294   priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len);
    295   if (priv_key == NULL) {
    296     OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
    297     EC_PRIVATEKEY_free(priv_key);
    298     return NULL;
    299   }
    300 
    301   if (a == NULL || *a == NULL) {
    302     ret = EC_KEY_new();
    303     if (ret == NULL) {
    304       OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE);
    305       goto err;
    306     }
    307     if (a) {
    308       *a = ret;
    309     }
    310   } else {
    311     ret = *a;
    312   }
    313 
    314   if (priv_key->parameters) {
    315     if (ret->group) {
    316       EC_GROUP_free(ret->group);
    317     }
    318     ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
    319   }
    320 
    321   if (ret->group == NULL) {
    322     OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
    323     goto err;
    324   }
    325 
    326   ret->version = priv_key->version;
    327 
    328   if (priv_key->privateKey) {
    329     ret->priv_key =
    330         BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
    331                   M_ASN1_STRING_length(priv_key->privateKey), ret->priv_key);
    332     if (ret->priv_key == NULL) {
    333       OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_BN_LIB);
    334       goto err;
    335     }
    336   } else {
    337     OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_MISSING_PRIVATE_KEY);
    338     goto err;
    339   }
    340 
    341   /* TODO(fork): loading the public key is silly. Why not calculate it? */
    342   if (priv_key->publicKey) {
    343     const uint8_t *pub_oct;
    344     size_t pub_oct_len;
    345 
    346     if (ret->pub_key) {
    347       EC_POINT_free(ret->pub_key);
    348     }
    349     ret->pub_key = EC_POINT_new(ret->group);
    350     if (ret->pub_key == NULL) {
    351       OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
    352       goto err;
    353     }
    354     pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
    355     pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
    356     /* save the point conversion form */
    357     ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
    358     if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
    359                             NULL)) {
    360       OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
    361       goto err;
    362     }
    363   }
    364 
    365   ok = 1;
    366 
    367 err:
    368   if (!ok) {
    369     if (ret) {
    370       EC_KEY_free(ret);
    371     }
    372     ret = NULL;
    373   }
    374 
    375   if (priv_key) {
    376     EC_PRIVATEKEY_free(priv_key);
    377   }
    378 
    379   return ret;
    380 }
    381 
    382 int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
    383   int ret = 0, ok = 0;
    384   uint8_t *buffer = NULL;
    385   size_t buf_len = 0, tmp_len;
    386   EC_PRIVATEKEY *priv_key = NULL;
    387 
    388   if (key == NULL || key->group == NULL || key->priv_key == NULL) {
    389     OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
    390     goto err;
    391   }
    392 
    393   priv_key = EC_PRIVATEKEY_new();
    394   if (priv_key == NULL) {
    395     OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
    396     goto err;
    397   }
    398 
    399   priv_key->version = key->version;
    400 
    401   buf_len = BN_num_bytes(key->priv_key);
    402   buffer = OPENSSL_malloc(buf_len);
    403   if (buffer == NULL) {
    404     OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
    405     goto err;
    406   }
    407 
    408   if (!BN_bn2bin(key->priv_key, buffer)) {
    409     OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_BN_LIB);
    410     goto err;
    411   }
    412 
    413   if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
    414     OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
    415     goto err;
    416   }
    417 
    418   /* TODO(fork): replace this flexibility with key sensible default? */
    419   if (!(key->enc_flag & EC_PKEY_NO_PARAMETERS)) {
    420     if ((priv_key->parameters = ec_asn1_group2pkparameters(
    421              key->group, priv_key->parameters)) == NULL) {
    422       OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
    423       goto err;
    424     }
    425   }
    426 
    427   /* TODO(fork): replace this flexibility with key sensible default? */
    428   if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
    429     priv_key->publicKey = M_ASN1_BIT_STRING_new();
    430     if (priv_key->publicKey == NULL) {
    431       OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
    432       goto err;
    433     }
    434 
    435     tmp_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
    436                                  0, NULL);
    437 
    438     if (tmp_len > buf_len) {
    439       uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
    440       if (!tmp_buffer) {
    441         OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
    442         goto err;
    443       }
    444       buffer = tmp_buffer;
    445       buf_len = tmp_len;
    446     }
    447 
    448     if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
    449                             buf_len, NULL)) {
    450       OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
    451       goto err;
    452     }
    453 
    454     priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    455     priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    456     if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
    457       OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
    458       goto err;
    459     }
    460   }
    461 
    462   ret = i2d_EC_PRIVATEKEY(priv_key, outp);
    463   if (ret == 0) {
    464     OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
    465     goto err;
    466   }
    467   ok = 1;
    468 
    469 err:
    470   if (buffer) {
    471     OPENSSL_free(buffer);
    472   }
    473   if (priv_key) {
    474     EC_PRIVATEKEY_free(priv_key);
    475   }
    476   return (ok ? ret : 0);
    477 }
    478 
    479 int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
    480   if (key == NULL) {
    481     OPENSSL_PUT_ERROR(EC, i2d_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
    482     return 0;
    483   }
    484   return i2d_ECPKParameters(key->group, outp);
    485 }
    486 
    487 EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
    488   EC_KEY *ret;
    489 
    490   if (inp == NULL || *inp == NULL) {
    491     OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
    492     return NULL;
    493   }
    494 
    495   if (key == NULL || *key == NULL) {
    496     ret = EC_KEY_new();
    497     if (ret == NULL) {
    498       OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_MALLOC_FAILURE);
    499       return NULL;
    500     }
    501     if (key) {
    502       *key = ret;
    503     }
    504   } else {
    505     ret = *key;
    506   }
    507 
    508   if (!d2i_ECPKParameters(&ret->group, inp, len)) {
    509     OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_EC_LIB);
    510     return NULL;
    511   }
    512 
    513   return ret;
    514 }
    515 
    516 EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
    517   EC_KEY *ret = NULL;
    518 
    519   if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
    520     OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
    521     return 0;
    522   }
    523   ret = *keyp;
    524   if (ret->pub_key == NULL &&
    525       (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
    526     OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_MALLOC_FAILURE);
    527     return 0;
    528   }
    529   if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
    530     OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_EC_LIB);
    531     return 0;
    532   }
    533   /* save the point conversion form */
    534   ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01);
    535   *inp += len;
    536   return ret;
    537 }
    538 
    539 int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
    540   size_t buf_len = 0;
    541   int new_buffer = 0;
    542 
    543   if (key == NULL) {
    544     OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
    545     return 0;
    546   }
    547 
    548   buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
    549                                0, NULL);
    550 
    551   if (outp == NULL || buf_len == 0) {
    552     /* out == NULL => just return the length of the octet string */
    553     return buf_len;
    554   }
    555 
    556   if (*outp == NULL) {
    557     *outp = OPENSSL_malloc(buf_len);
    558     if (*outp == NULL) {
    559       OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_MALLOC_FAILURE);
    560       return 0;
    561     }
    562     new_buffer = 1;
    563   }
    564   if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
    565                           buf_len, NULL)) {
    566     OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_EC_LIB);
    567     if (new_buffer) {
    568       OPENSSL_free(*outp);
    569       *outp = NULL;
    570     }
    571     return 0;
    572   }
    573 
    574   if (!new_buffer) {
    575     *outp += buf_len;
    576   }
    577   return buf_len;
    578 }
    579