1296341Sdelphij/* 2296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 3296341Sdelphij * 2006. 4238384Sjkim */ 5238384Sjkim/* ==================================================================== 6238384Sjkim * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7238384Sjkim * 8238384Sjkim * Redistribution and use in source and binary forms, with or without 9238384Sjkim * modification, are permitted provided that the following conditions 10238384Sjkim * are met: 11238384Sjkim * 12238384Sjkim * 1. Redistributions of source code must retain the above copyright 13296341Sdelphij * notice, this list of conditions and the following disclaimer. 14238384Sjkim * 15238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16238384Sjkim * notice, this list of conditions and the following disclaimer in 17238384Sjkim * the documentation and/or other materials provided with the 18238384Sjkim * distribution. 19238384Sjkim * 20238384Sjkim * 3. All advertising materials mentioning features or use of this 21238384Sjkim * software must display the following acknowledgment: 22238384Sjkim * "This product includes software developed by the OpenSSL Project 23238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24238384Sjkim * 25238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26238384Sjkim * endorse or promote products derived from this software without 27238384Sjkim * prior written permission. For written permission, please contact 28238384Sjkim * licensing@OpenSSL.org. 29238384Sjkim * 30238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 31238384Sjkim * nor may "OpenSSL" appear in their names without prior written 32238384Sjkim * permission of the OpenSSL Project. 33238384Sjkim * 34238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 35238384Sjkim * acknowledgment: 36238384Sjkim * "This product includes software developed by the OpenSSL Project 37238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38238384Sjkim * 39238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 51238384Sjkim * ==================================================================== 52238384Sjkim * 53238384Sjkim * This product includes cryptographic software written by Eric Young 54238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 55238384Sjkim * Hudson (tjh@cryptsoft.com). 56238384Sjkim * 57238384Sjkim */ 58238384Sjkim 59238384Sjkim#include <stdio.h> 60238384Sjkim#include "cryptlib.h" 61238384Sjkim#include <openssl/x509.h> 62238384Sjkim#include <openssl/ec.h> 63238384Sjkim#include <openssl/bn.h> 64238384Sjkim#ifndef OPENSSL_NO_CMS 65296341Sdelphij# include <openssl/cms.h> 66238384Sjkim#endif 67238384Sjkim#include "asn1_locl.h" 68238384Sjkim 69238384Sjkimstatic int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) 70296341Sdelphij{ 71296341Sdelphij const EC_GROUP *group; 72296341Sdelphij int nid; 73296341Sdelphij if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 74296341Sdelphij ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); 75296341Sdelphij return 0; 76296341Sdelphij } 77296341Sdelphij if (EC_GROUP_get_asn1_flag(group) 78296341Sdelphij && (nid = EC_GROUP_get_curve_name(group))) 79296341Sdelphij /* we have a 'named curve' => just set the OID */ 80296341Sdelphij { 81296341Sdelphij *ppval = OBJ_nid2obj(nid); 82296341Sdelphij *pptype = V_ASN1_OBJECT; 83296341Sdelphij } else { /* explicit parameters */ 84238384Sjkim 85296341Sdelphij ASN1_STRING *pstr = NULL; 86296341Sdelphij pstr = ASN1_STRING_new(); 87296341Sdelphij if (!pstr) 88296341Sdelphij return 0; 89296341Sdelphij pstr->length = i2d_ECParameters(ec_key, &pstr->data); 90296341Sdelphij if (pstr->length <= 0) { 91296341Sdelphij ASN1_STRING_free(pstr); 92296341Sdelphij ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); 93296341Sdelphij return 0; 94296341Sdelphij } 95296341Sdelphij *ppval = pstr; 96296341Sdelphij *pptype = V_ASN1_SEQUENCE; 97296341Sdelphij } 98296341Sdelphij return 1; 99296341Sdelphij} 100296341Sdelphij 101238384Sjkimstatic int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 102296341Sdelphij{ 103296341Sdelphij EC_KEY *ec_key = pkey->pkey.ec; 104296341Sdelphij void *pval = NULL; 105296341Sdelphij int ptype; 106296341Sdelphij unsigned char *penc = NULL, *p; 107296341Sdelphij int penclen; 108238384Sjkim 109296341Sdelphij if (!eckey_param2type(&ptype, &pval, ec_key)) { 110296341Sdelphij ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); 111296341Sdelphij return 0; 112296341Sdelphij } 113296341Sdelphij penclen = i2o_ECPublicKey(ec_key, NULL); 114296341Sdelphij if (penclen <= 0) 115296341Sdelphij goto err; 116296341Sdelphij penc = OPENSSL_malloc(penclen); 117296341Sdelphij if (!penc) 118296341Sdelphij goto err; 119296341Sdelphij p = penc; 120296341Sdelphij penclen = i2o_ECPublicKey(ec_key, &p); 121296341Sdelphij if (penclen <= 0) 122296341Sdelphij goto err; 123296341Sdelphij if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), 124296341Sdelphij ptype, pval, penc, penclen)) 125296341Sdelphij return 1; 126296341Sdelphij err: 127296341Sdelphij if (ptype == V_ASN1_OBJECT) 128296341Sdelphij ASN1_OBJECT_free(pval); 129296341Sdelphij else 130296341Sdelphij ASN1_STRING_free(pval); 131296341Sdelphij if (penc) 132296341Sdelphij OPENSSL_free(penc); 133296341Sdelphij return 0; 134296341Sdelphij} 135238384Sjkim 136238384Sjkimstatic EC_KEY *eckey_type2param(int ptype, void *pval) 137296341Sdelphij{ 138296341Sdelphij EC_KEY *eckey = NULL; 139296341Sdelphij if (ptype == V_ASN1_SEQUENCE) { 140296341Sdelphij ASN1_STRING *pstr = pval; 141296341Sdelphij const unsigned char *pm = NULL; 142296341Sdelphij int pmlen; 143296341Sdelphij pm = pstr->data; 144296341Sdelphij pmlen = pstr->length; 145296341Sdelphij if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { 146296341Sdelphij ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 147296341Sdelphij goto ecerr; 148296341Sdelphij } 149296341Sdelphij } else if (ptype == V_ASN1_OBJECT) { 150296341Sdelphij ASN1_OBJECT *poid = pval; 151296341Sdelphij EC_GROUP *group; 152238384Sjkim 153296341Sdelphij /* 154296341Sdelphij * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID 155296341Sdelphij */ 156296341Sdelphij if ((eckey = EC_KEY_new()) == NULL) { 157296341Sdelphij ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); 158296341Sdelphij goto ecerr; 159296341Sdelphij } 160296341Sdelphij group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); 161296341Sdelphij if (group == NULL) 162296341Sdelphij goto ecerr; 163296341Sdelphij EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 164296341Sdelphij if (EC_KEY_set_group(eckey, group) == 0) 165296341Sdelphij goto ecerr; 166296341Sdelphij EC_GROUP_free(group); 167296341Sdelphij } else { 168296341Sdelphij ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 169296341Sdelphij goto ecerr; 170296341Sdelphij } 171238384Sjkim 172296341Sdelphij return eckey; 173238384Sjkim 174296341Sdelphij ecerr: 175296341Sdelphij if (eckey) 176296341Sdelphij EC_KEY_free(eckey); 177296341Sdelphij return NULL; 178296341Sdelphij} 179238384Sjkim 180238384Sjkimstatic int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 181296341Sdelphij{ 182296341Sdelphij const unsigned char *p = NULL; 183296341Sdelphij void *pval; 184296341Sdelphij int ptype, pklen; 185296341Sdelphij EC_KEY *eckey = NULL; 186296341Sdelphij X509_ALGOR *palg; 187238384Sjkim 188296341Sdelphij if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 189296341Sdelphij return 0; 190296341Sdelphij X509_ALGOR_get0(NULL, &ptype, &pval, palg); 191238384Sjkim 192296341Sdelphij eckey = eckey_type2param(ptype, pval); 193238384Sjkim 194296341Sdelphij if (!eckey) { 195296341Sdelphij ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); 196296341Sdelphij return 0; 197296341Sdelphij } 198238384Sjkim 199296341Sdelphij /* We have parameters now set public key */ 200296341Sdelphij if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 201296341Sdelphij ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); 202296341Sdelphij goto ecerr; 203296341Sdelphij } 204238384Sjkim 205296341Sdelphij EVP_PKEY_assign_EC_KEY(pkey, eckey); 206296341Sdelphij return 1; 207238384Sjkim 208296341Sdelphij ecerr: 209296341Sdelphij if (eckey) 210296341Sdelphij EC_KEY_free(eckey); 211296341Sdelphij return 0; 212296341Sdelphij} 213238384Sjkim 214238384Sjkimstatic int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 215296341Sdelphij{ 216296341Sdelphij int r; 217296341Sdelphij const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 218296341Sdelphij const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), 219296341Sdelphij *pb = EC_KEY_get0_public_key(b->pkey.ec); 220296341Sdelphij r = EC_POINT_cmp(group, pa, pb, NULL); 221296341Sdelphij if (r == 0) 222296341Sdelphij return 1; 223296341Sdelphij if (r == 1) 224296341Sdelphij return 0; 225296341Sdelphij return -2; 226296341Sdelphij} 227238384Sjkim 228238384Sjkimstatic int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 229296341Sdelphij{ 230296341Sdelphij const unsigned char *p = NULL; 231296341Sdelphij void *pval; 232296341Sdelphij int ptype, pklen; 233296341Sdelphij EC_KEY *eckey = NULL; 234296341Sdelphij X509_ALGOR *palg; 235238384Sjkim 236296341Sdelphij if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 237296341Sdelphij return 0; 238296341Sdelphij X509_ALGOR_get0(NULL, &ptype, &pval, palg); 239238384Sjkim 240296341Sdelphij eckey = eckey_type2param(ptype, pval); 241238384Sjkim 242296341Sdelphij if (!eckey) 243296341Sdelphij goto ecliberr; 244238384Sjkim 245296341Sdelphij /* We have parameters now set private key */ 246296341Sdelphij if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { 247296341Sdelphij ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); 248296341Sdelphij goto ecerr; 249296341Sdelphij } 250238384Sjkim 251296341Sdelphij /* calculate public key (if necessary) */ 252296341Sdelphij if (EC_KEY_get0_public_key(eckey) == NULL) { 253296341Sdelphij const BIGNUM *priv_key; 254296341Sdelphij const EC_GROUP *group; 255296341Sdelphij EC_POINT *pub_key; 256296341Sdelphij /* 257296341Sdelphij * the public key was not included in the SEC1 private key => 258296341Sdelphij * calculate the public key 259296341Sdelphij */ 260296341Sdelphij group = EC_KEY_get0_group(eckey); 261296341Sdelphij pub_key = EC_POINT_new(group); 262296341Sdelphij if (pub_key == NULL) { 263296341Sdelphij ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 264296341Sdelphij goto ecliberr; 265296341Sdelphij } 266296341Sdelphij if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 267296341Sdelphij EC_POINT_free(pub_key); 268296341Sdelphij ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 269296341Sdelphij goto ecliberr; 270296341Sdelphij } 271296341Sdelphij priv_key = EC_KEY_get0_private_key(eckey); 272296341Sdelphij if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { 273296341Sdelphij EC_POINT_free(pub_key); 274296341Sdelphij ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 275296341Sdelphij goto ecliberr; 276296341Sdelphij } 277296341Sdelphij if (EC_KEY_set_public_key(eckey, pub_key) == 0) { 278296341Sdelphij EC_POINT_free(pub_key); 279296341Sdelphij ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 280296341Sdelphij goto ecliberr; 281296341Sdelphij } 282296341Sdelphij EC_POINT_free(pub_key); 283296341Sdelphij } 284238384Sjkim 285296341Sdelphij EVP_PKEY_assign_EC_KEY(pkey, eckey); 286296341Sdelphij return 1; 287238384Sjkim 288296341Sdelphij ecliberr: 289296341Sdelphij ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 290296341Sdelphij ecerr: 291296341Sdelphij if (eckey) 292296341Sdelphij EC_KEY_free(eckey); 293296341Sdelphij return 0; 294296341Sdelphij} 295238384Sjkim 296238384Sjkimstatic int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 297238384Sjkim{ 298296341Sdelphij EC_KEY *ec_key; 299296341Sdelphij unsigned char *ep, *p; 300296341Sdelphij int eplen, ptype; 301296341Sdelphij void *pval; 302296341Sdelphij unsigned int tmp_flags, old_flags; 303238384Sjkim 304296341Sdelphij ec_key = pkey->pkey.ec; 305238384Sjkim 306296341Sdelphij if (!eckey_param2type(&ptype, &pval, ec_key)) { 307296341Sdelphij ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); 308296341Sdelphij return 0; 309296341Sdelphij } 310238384Sjkim 311296341Sdelphij /* set the private key */ 312238384Sjkim 313296341Sdelphij /* 314296341Sdelphij * do not include the parameters in the SEC1 private key see PKCS#11 315296341Sdelphij * 12.11 316296341Sdelphij */ 317296341Sdelphij old_flags = EC_KEY_get_enc_flags(ec_key); 318296341Sdelphij tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; 319296341Sdelphij EC_KEY_set_enc_flags(ec_key, tmp_flags); 320296341Sdelphij eplen = i2d_ECPrivateKey(ec_key, NULL); 321296341Sdelphij if (!eplen) { 322296341Sdelphij EC_KEY_set_enc_flags(ec_key, old_flags); 323296341Sdelphij ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 324296341Sdelphij return 0; 325296341Sdelphij } 326296341Sdelphij ep = (unsigned char *)OPENSSL_malloc(eplen); 327296341Sdelphij if (!ep) { 328296341Sdelphij EC_KEY_set_enc_flags(ec_key, old_flags); 329296341Sdelphij ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 330296341Sdelphij return 0; 331296341Sdelphij } 332296341Sdelphij p = ep; 333296341Sdelphij if (!i2d_ECPrivateKey(ec_key, &p)) { 334296341Sdelphij EC_KEY_set_enc_flags(ec_key, old_flags); 335296341Sdelphij OPENSSL_free(ep); 336296341Sdelphij ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 337296341Sdelphij return 0; 338296341Sdelphij } 339296341Sdelphij /* restore old encoding flags */ 340296341Sdelphij EC_KEY_set_enc_flags(ec_key, old_flags); 341238384Sjkim 342296341Sdelphij if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, 343296341Sdelphij ptype, pval, ep, eplen)) 344296341Sdelphij return 0; 345238384Sjkim 346296341Sdelphij return 1; 347238384Sjkim} 348238384Sjkim 349238384Sjkimstatic int int_ec_size(const EVP_PKEY *pkey) 350296341Sdelphij{ 351296341Sdelphij return ECDSA_size(pkey->pkey.ec); 352296341Sdelphij} 353238384Sjkim 354238384Sjkimstatic int ec_bits(const EVP_PKEY *pkey) 355296341Sdelphij{ 356296341Sdelphij BIGNUM *order = BN_new(); 357296341Sdelphij const EC_GROUP *group; 358296341Sdelphij int ret; 359238384Sjkim 360296341Sdelphij if (!order) { 361296341Sdelphij ERR_clear_error(); 362296341Sdelphij return 0; 363296341Sdelphij } 364296341Sdelphij group = EC_KEY_get0_group(pkey->pkey.ec); 365296341Sdelphij if (!EC_GROUP_get_order(group, order, NULL)) { 366296341Sdelphij ERR_clear_error(); 367296341Sdelphij return 0; 368296341Sdelphij } 369238384Sjkim 370296341Sdelphij ret = BN_num_bits(order); 371296341Sdelphij BN_free(order); 372296341Sdelphij return ret; 373296341Sdelphij} 374238384Sjkim 375238384Sjkimstatic int ec_missing_parameters(const EVP_PKEY *pkey) 376296341Sdelphij{ 377296341Sdelphij if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) 378296341Sdelphij return 1; 379296341Sdelphij return 0; 380296341Sdelphij} 381238384Sjkim 382238384Sjkimstatic int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 383296341Sdelphij{ 384296341Sdelphij EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); 385296341Sdelphij if (group == NULL) 386296341Sdelphij return 0; 387296341Sdelphij if (EC_KEY_set_group(to->pkey.ec, group) == 0) 388296341Sdelphij return 0; 389296341Sdelphij EC_GROUP_free(group); 390296341Sdelphij return 1; 391296341Sdelphij} 392238384Sjkim 393238384Sjkimstatic int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 394296341Sdelphij{ 395296341Sdelphij const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), 396296341Sdelphij *group_b = EC_KEY_get0_group(b->pkey.ec); 397296341Sdelphij if (EC_GROUP_cmp(group_a, group_b, NULL)) 398296341Sdelphij return 0; 399296341Sdelphij else 400296341Sdelphij return 1; 401296341Sdelphij} 402238384Sjkim 403238384Sjkimstatic void int_ec_free(EVP_PKEY *pkey) 404296341Sdelphij{ 405296341Sdelphij EC_KEY_free(pkey->pkey.ec); 406296341Sdelphij} 407238384Sjkim 408238384Sjkimstatic int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) 409296341Sdelphij{ 410296341Sdelphij unsigned char *buffer = NULL; 411296341Sdelphij const char *ecstr; 412296341Sdelphij size_t buf_len = 0, i; 413296341Sdelphij int ret = 0, reason = ERR_R_BIO_LIB; 414296341Sdelphij BIGNUM *pub_key = NULL, *order = NULL; 415296341Sdelphij BN_CTX *ctx = NULL; 416296341Sdelphij const EC_GROUP *group; 417296341Sdelphij const EC_POINT *public_key; 418296341Sdelphij const BIGNUM *priv_key; 419238384Sjkim 420296341Sdelphij if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 421296341Sdelphij reason = ERR_R_PASSED_NULL_PARAMETER; 422296341Sdelphij goto err; 423296341Sdelphij } 424238384Sjkim 425296341Sdelphij ctx = BN_CTX_new(); 426296341Sdelphij if (ctx == NULL) { 427296341Sdelphij reason = ERR_R_MALLOC_FAILURE; 428296341Sdelphij goto err; 429296341Sdelphij } 430238384Sjkim 431296341Sdelphij if (ktype > 0) { 432296341Sdelphij public_key = EC_KEY_get0_public_key(x); 433296341Sdelphij if (public_key != NULL) { 434296341Sdelphij if ((pub_key = EC_POINT_point2bn(group, public_key, 435296341Sdelphij EC_KEY_get_conv_form(x), NULL, 436296341Sdelphij ctx)) == NULL) { 437296341Sdelphij reason = ERR_R_EC_LIB; 438296341Sdelphij goto err; 439296341Sdelphij } 440296341Sdelphij buf_len = (size_t)BN_num_bytes(pub_key); 441296341Sdelphij } 442296341Sdelphij } 443238384Sjkim 444296341Sdelphij if (ktype == 2) { 445296341Sdelphij priv_key = EC_KEY_get0_private_key(x); 446296341Sdelphij if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) 447296341Sdelphij buf_len = i; 448296341Sdelphij } else 449296341Sdelphij priv_key = NULL; 450238384Sjkim 451296341Sdelphij if (ktype > 0) { 452296341Sdelphij buf_len += 10; 453296341Sdelphij if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { 454296341Sdelphij reason = ERR_R_MALLOC_FAILURE; 455296341Sdelphij goto err; 456296341Sdelphij } 457296341Sdelphij } 458296341Sdelphij if (ktype == 2) 459296341Sdelphij ecstr = "Private-Key"; 460296341Sdelphij else if (ktype == 1) 461296341Sdelphij ecstr = "Public-Key"; 462296341Sdelphij else 463296341Sdelphij ecstr = "ECDSA-Parameters"; 464238384Sjkim 465296341Sdelphij if (!BIO_indent(bp, off, 128)) 466296341Sdelphij goto err; 467296341Sdelphij if ((order = BN_new()) == NULL) 468296341Sdelphij goto err; 469296341Sdelphij if (!EC_GROUP_get_order(group, order, NULL)) 470296341Sdelphij goto err; 471296341Sdelphij if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) 472296341Sdelphij goto err; 473296341Sdelphij 474296341Sdelphij if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 475296341Sdelphij buffer, off)) 476296341Sdelphij goto err; 477296341Sdelphij if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, 478296341Sdelphij buffer, off)) 479296341Sdelphij goto err; 480296341Sdelphij if (!ECPKParameters_print(bp, group, off)) 481296341Sdelphij goto err; 482296341Sdelphij ret = 1; 483296341Sdelphij err: 484296341Sdelphij if (!ret) 485296341Sdelphij ECerr(EC_F_DO_EC_KEY_PRINT, reason); 486296341Sdelphij if (pub_key) 487296341Sdelphij BN_free(pub_key); 488296341Sdelphij if (order) 489296341Sdelphij BN_free(order); 490296341Sdelphij if (ctx) 491296341Sdelphij BN_CTX_free(ctx); 492296341Sdelphij if (buffer != NULL) 493296341Sdelphij OPENSSL_free(buffer); 494296341Sdelphij return (ret); 495296341Sdelphij} 496296341Sdelphij 497238384Sjkimstatic int eckey_param_decode(EVP_PKEY *pkey, 498296341Sdelphij const unsigned char **pder, int derlen) 499296341Sdelphij{ 500296341Sdelphij EC_KEY *eckey; 501296341Sdelphij if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { 502296341Sdelphij ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); 503296341Sdelphij return 0; 504296341Sdelphij } 505296341Sdelphij EVP_PKEY_assign_EC_KEY(pkey, eckey); 506296341Sdelphij return 1; 507296341Sdelphij} 508238384Sjkim 509238384Sjkimstatic int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 510296341Sdelphij{ 511296341Sdelphij return i2d_ECParameters(pkey->pkey.ec, pder); 512296341Sdelphij} 513238384Sjkim 514238384Sjkimstatic int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 515296341Sdelphij ASN1_PCTX *ctx) 516296341Sdelphij{ 517296341Sdelphij return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); 518296341Sdelphij} 519238384Sjkim 520238384Sjkimstatic int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 521296341Sdelphij ASN1_PCTX *ctx) 522296341Sdelphij{ 523296341Sdelphij return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); 524296341Sdelphij} 525238384Sjkim 526238384Sjkimstatic int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 527296341Sdelphij ASN1_PCTX *ctx) 528296341Sdelphij{ 529296341Sdelphij return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); 530296341Sdelphij} 531238384Sjkim 532238384Sjkimstatic int old_ec_priv_decode(EVP_PKEY *pkey, 533296341Sdelphij const unsigned char **pder, int derlen) 534296341Sdelphij{ 535296341Sdelphij EC_KEY *ec; 536296341Sdelphij if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { 537296341Sdelphij ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); 538296341Sdelphij return 0; 539296341Sdelphij } 540296341Sdelphij EVP_PKEY_assign_EC_KEY(pkey, ec); 541296341Sdelphij return 1; 542296341Sdelphij} 543238384Sjkim 544238384Sjkimstatic int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 545296341Sdelphij{ 546296341Sdelphij return i2d_ECPrivateKey(pkey->pkey.ec, pder); 547296341Sdelphij} 548238384Sjkim 549238384Sjkimstatic int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 550296341Sdelphij{ 551296341Sdelphij switch (op) { 552296341Sdelphij case ASN1_PKEY_CTRL_PKCS7_SIGN: 553296341Sdelphij if (arg1 == 0) { 554296341Sdelphij int snid, hnid; 555296341Sdelphij X509_ALGOR *alg1, *alg2; 556296341Sdelphij PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 557296341Sdelphij if (alg1 == NULL || alg1->algorithm == NULL) 558296341Sdelphij return -1; 559296341Sdelphij hnid = OBJ_obj2nid(alg1->algorithm); 560296341Sdelphij if (hnid == NID_undef) 561296341Sdelphij return -1; 562296341Sdelphij if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 563296341Sdelphij return -1; 564296341Sdelphij X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 565296341Sdelphij } 566296341Sdelphij return 1; 567238384Sjkim#ifndef OPENSSL_NO_CMS 568296341Sdelphij case ASN1_PKEY_CTRL_CMS_SIGN: 569296341Sdelphij if (arg1 == 0) { 570296341Sdelphij int snid, hnid; 571296341Sdelphij X509_ALGOR *alg1, *alg2; 572296341Sdelphij CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 573296341Sdelphij if (alg1 == NULL || alg1->algorithm == NULL) 574296341Sdelphij return -1; 575296341Sdelphij hnid = OBJ_obj2nid(alg1->algorithm); 576296341Sdelphij if (hnid == NID_undef) 577296341Sdelphij return -1; 578296341Sdelphij if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 579296341Sdelphij return -1; 580296341Sdelphij X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 581296341Sdelphij } 582296341Sdelphij return 1; 583238384Sjkim#endif 584238384Sjkim 585296341Sdelphij case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 586296341Sdelphij *(int *)arg2 = NID_sha1; 587296341Sdelphij return 2; 588238384Sjkim 589296341Sdelphij default: 590296341Sdelphij return -2; 591238384Sjkim 592296341Sdelphij } 593238384Sjkim 594296341Sdelphij} 595238384Sjkim 596296341Sdelphijconst EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { 597296341Sdelphij EVP_PKEY_EC, 598296341Sdelphij EVP_PKEY_EC, 599296341Sdelphij 0, 600296341Sdelphij "EC", 601296341Sdelphij "OpenSSL EC algorithm", 602238384Sjkim 603296341Sdelphij eckey_pub_decode, 604296341Sdelphij eckey_pub_encode, 605296341Sdelphij eckey_pub_cmp, 606296341Sdelphij eckey_pub_print, 607238384Sjkim 608296341Sdelphij eckey_priv_decode, 609296341Sdelphij eckey_priv_encode, 610296341Sdelphij eckey_priv_print, 611238384Sjkim 612296341Sdelphij int_ec_size, 613296341Sdelphij ec_bits, 614238384Sjkim 615296341Sdelphij eckey_param_decode, 616296341Sdelphij eckey_param_encode, 617296341Sdelphij ec_missing_parameters, 618296341Sdelphij ec_copy_parameters, 619296341Sdelphij ec_cmp_parameters, 620296341Sdelphij eckey_param_print, 621296341Sdelphij 0, 622238384Sjkim 623296341Sdelphij int_ec_free, 624296341Sdelphij ec_pkey_ctrl, 625296341Sdelphij old_ec_priv_decode, 626296341Sdelphij old_ec_priv_encode 627296341Sdelphij}; 628