1238384Sjkim/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2238384Sjkim * project 2006. 3238384Sjkim */ 4238384Sjkim/* ==================================================================== 5238384Sjkim * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 6238384Sjkim * 7238384Sjkim * Redistribution and use in source and binary forms, with or without 8238384Sjkim * modification, are permitted provided that the following conditions 9238384Sjkim * are met: 10238384Sjkim * 11238384Sjkim * 1. Redistributions of source code must retain the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer. 13238384Sjkim * 14238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 15238384Sjkim * notice, this list of conditions and the following disclaimer in 16238384Sjkim * the documentation and/or other materials provided with the 17238384Sjkim * distribution. 18238384Sjkim * 19238384Sjkim * 3. All advertising materials mentioning features or use of this 20238384Sjkim * software must display the following acknowledgment: 21238384Sjkim * "This product includes software developed by the OpenSSL Project 22238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23238384Sjkim * 24238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25238384Sjkim * endorse or promote products derived from this software without 26238384Sjkim * prior written permission. For written permission, please contact 27238384Sjkim * licensing@OpenSSL.org. 28238384Sjkim * 29238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 30238384Sjkim * nor may "OpenSSL" appear in their names without prior written 31238384Sjkim * permission of the OpenSSL Project. 32238384Sjkim * 33238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 34238384Sjkim * acknowledgment: 35238384Sjkim * "This product includes software developed by the OpenSSL Project 36238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37238384Sjkim * 38238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 50238384Sjkim * ==================================================================== 51238384Sjkim * 52238384Sjkim * This product includes cryptographic software written by Eric Young 53238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 54238384Sjkim * Hudson (tjh@cryptsoft.com). 55238384Sjkim * 56238384Sjkim */ 57238384Sjkim 58238384Sjkim#include <stdio.h> 59238384Sjkim#include "cryptlib.h" 60238384Sjkim#include <openssl/x509.h> 61238384Sjkim#include <openssl/ec.h> 62238384Sjkim#include <openssl/bn.h> 63238384Sjkim#ifndef OPENSSL_NO_CMS 64238384Sjkim#include <openssl/cms.h> 65238384Sjkim#endif 66238384Sjkim#include "asn1_locl.h" 67238384Sjkim 68238384Sjkimstatic int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) 69238384Sjkim { 70238384Sjkim const EC_GROUP *group; 71238384Sjkim int nid; 72238384Sjkim if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 73238384Sjkim { 74238384Sjkim ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); 75238384Sjkim return 0; 76238384Sjkim } 77238384Sjkim if (EC_GROUP_get_asn1_flag(group) 78238384Sjkim && (nid = EC_GROUP_get_curve_name(group))) 79238384Sjkim /* we have a 'named curve' => just set the OID */ 80238384Sjkim { 81238384Sjkim *ppval = OBJ_nid2obj(nid); 82238384Sjkim *pptype = V_ASN1_OBJECT; 83238384Sjkim } 84238384Sjkim else /* explicit parameters */ 85238384Sjkim { 86238384Sjkim ASN1_STRING *pstr = NULL; 87238384Sjkim pstr = ASN1_STRING_new(); 88238384Sjkim if (!pstr) 89238384Sjkim return 0; 90238384Sjkim pstr->length = i2d_ECParameters(ec_key, &pstr->data); 91279264Sdelphij if (pstr->length <= 0) 92238384Sjkim { 93238384Sjkim ASN1_STRING_free(pstr); 94238384Sjkim ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); 95238384Sjkim return 0; 96238384Sjkim } 97238384Sjkim *ppval = pstr; 98238384Sjkim *pptype = V_ASN1_SEQUENCE; 99238384Sjkim } 100238384Sjkim return 1; 101238384Sjkim } 102238384Sjkim 103238384Sjkimstatic int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 104238384Sjkim { 105238384Sjkim EC_KEY *ec_key = pkey->pkey.ec; 106238384Sjkim void *pval = NULL; 107238384Sjkim int ptype; 108238384Sjkim unsigned char *penc = NULL, *p; 109238384Sjkim int penclen; 110238384Sjkim 111238384Sjkim if (!eckey_param2type(&ptype, &pval, ec_key)) 112238384Sjkim { 113238384Sjkim ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); 114238384Sjkim return 0; 115238384Sjkim } 116238384Sjkim penclen = i2o_ECPublicKey(ec_key, NULL); 117238384Sjkim if (penclen <= 0) 118238384Sjkim goto err; 119238384Sjkim penc = OPENSSL_malloc(penclen); 120238384Sjkim if (!penc) 121238384Sjkim goto err; 122238384Sjkim p = penc; 123238384Sjkim penclen = i2o_ECPublicKey(ec_key, &p); 124238384Sjkim if (penclen <= 0) 125238384Sjkim goto err; 126238384Sjkim if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), 127238384Sjkim ptype, pval, penc, penclen)) 128238384Sjkim return 1; 129238384Sjkim err: 130238384Sjkim if (ptype == V_ASN1_OBJECT) 131238384Sjkim ASN1_OBJECT_free(pval); 132238384Sjkim else 133238384Sjkim ASN1_STRING_free(pval); 134238384Sjkim if (penc) 135238384Sjkim OPENSSL_free(penc); 136238384Sjkim return 0; 137238384Sjkim } 138238384Sjkim 139238384Sjkimstatic EC_KEY *eckey_type2param(int ptype, void *pval) 140238384Sjkim { 141238384Sjkim EC_KEY *eckey = NULL; 142238384Sjkim if (ptype == V_ASN1_SEQUENCE) 143238384Sjkim { 144238384Sjkim ASN1_STRING *pstr = pval; 145238384Sjkim const unsigned char *pm = NULL; 146238384Sjkim int pmlen; 147238384Sjkim pm = pstr->data; 148238384Sjkim pmlen = pstr->length; 149238384Sjkim if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) 150238384Sjkim { 151238384Sjkim ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 152238384Sjkim goto ecerr; 153238384Sjkim } 154238384Sjkim } 155238384Sjkim else if (ptype == V_ASN1_OBJECT) 156238384Sjkim { 157238384Sjkim ASN1_OBJECT *poid = pval; 158238384Sjkim EC_GROUP *group; 159238384Sjkim 160238384Sjkim /* type == V_ASN1_OBJECT => the parameters are given 161238384Sjkim * by an asn1 OID 162238384Sjkim */ 163238384Sjkim if ((eckey = EC_KEY_new()) == NULL) 164238384Sjkim { 165238384Sjkim ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); 166238384Sjkim goto ecerr; 167238384Sjkim } 168238384Sjkim group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); 169238384Sjkim if (group == NULL) 170238384Sjkim goto ecerr; 171238384Sjkim EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 172238384Sjkim if (EC_KEY_set_group(eckey, group) == 0) 173238384Sjkim goto ecerr; 174238384Sjkim EC_GROUP_free(group); 175238384Sjkim } 176238384Sjkim else 177238384Sjkim { 178238384Sjkim ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 179238384Sjkim goto ecerr; 180238384Sjkim } 181238384Sjkim 182238384Sjkim return eckey; 183238384Sjkim 184238384Sjkim ecerr: 185238384Sjkim if (eckey) 186238384Sjkim EC_KEY_free(eckey); 187238384Sjkim return NULL; 188238384Sjkim } 189238384Sjkim 190238384Sjkimstatic int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 191238384Sjkim { 192238384Sjkim const unsigned char *p = NULL; 193238384Sjkim void *pval; 194238384Sjkim int ptype, pklen; 195238384Sjkim EC_KEY *eckey = NULL; 196238384Sjkim X509_ALGOR *palg; 197238384Sjkim 198238384Sjkim if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 199238384Sjkim return 0; 200238384Sjkim X509_ALGOR_get0(NULL, &ptype, &pval, palg); 201238384Sjkim 202238384Sjkim eckey = eckey_type2param(ptype, pval); 203238384Sjkim 204238384Sjkim if (!eckey) 205238384Sjkim { 206238384Sjkim ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); 207238384Sjkim return 0; 208238384Sjkim } 209238384Sjkim 210238384Sjkim /* We have parameters now set public key */ 211238384Sjkim if (!o2i_ECPublicKey(&eckey, &p, pklen)) 212238384Sjkim { 213238384Sjkim ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); 214238384Sjkim goto ecerr; 215238384Sjkim } 216238384Sjkim 217238384Sjkim EVP_PKEY_assign_EC_KEY(pkey, eckey); 218238384Sjkim return 1; 219238384Sjkim 220238384Sjkim ecerr: 221238384Sjkim if (eckey) 222238384Sjkim EC_KEY_free(eckey); 223238384Sjkim return 0; 224238384Sjkim } 225238384Sjkim 226238384Sjkimstatic int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 227238384Sjkim { 228238384Sjkim int r; 229238384Sjkim const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 230238384Sjkim const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), 231238384Sjkim *pb = EC_KEY_get0_public_key(b->pkey.ec); 232238384Sjkim r = EC_POINT_cmp(group, pa, pb, NULL); 233238384Sjkim if (r == 0) 234238384Sjkim return 1; 235238384Sjkim if (r == 1) 236238384Sjkim return 0; 237238384Sjkim return -2; 238238384Sjkim } 239238384Sjkim 240238384Sjkimstatic int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 241238384Sjkim { 242238384Sjkim const unsigned char *p = NULL; 243238384Sjkim void *pval; 244238384Sjkim int ptype, pklen; 245238384Sjkim EC_KEY *eckey = NULL; 246238384Sjkim X509_ALGOR *palg; 247238384Sjkim 248238384Sjkim if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 249238384Sjkim return 0; 250238384Sjkim X509_ALGOR_get0(NULL, &ptype, &pval, palg); 251238384Sjkim 252238384Sjkim eckey = eckey_type2param(ptype, pval); 253238384Sjkim 254238384Sjkim if (!eckey) 255238384Sjkim goto ecliberr; 256238384Sjkim 257238384Sjkim /* We have parameters now set private key */ 258238384Sjkim if (!d2i_ECPrivateKey(&eckey, &p, pklen)) 259238384Sjkim { 260238384Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); 261238384Sjkim goto ecerr; 262238384Sjkim } 263238384Sjkim 264238384Sjkim /* calculate public key (if necessary) */ 265238384Sjkim if (EC_KEY_get0_public_key(eckey) == NULL) 266238384Sjkim { 267238384Sjkim const BIGNUM *priv_key; 268238384Sjkim const EC_GROUP *group; 269238384Sjkim EC_POINT *pub_key; 270238384Sjkim /* the public key was not included in the SEC1 private 271238384Sjkim * key => calculate the public key */ 272238384Sjkim group = EC_KEY_get0_group(eckey); 273238384Sjkim pub_key = EC_POINT_new(group); 274238384Sjkim if (pub_key == NULL) 275238384Sjkim { 276238384Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 277238384Sjkim goto ecliberr; 278238384Sjkim } 279238384Sjkim if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) 280238384Sjkim { 281238384Sjkim EC_POINT_free(pub_key); 282238384Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 283238384Sjkim goto ecliberr; 284238384Sjkim } 285238384Sjkim priv_key = EC_KEY_get0_private_key(eckey); 286238384Sjkim if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) 287238384Sjkim { 288238384Sjkim EC_POINT_free(pub_key); 289238384Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 290238384Sjkim goto ecliberr; 291238384Sjkim } 292238384Sjkim if (EC_KEY_set_public_key(eckey, pub_key) == 0) 293238384Sjkim { 294238384Sjkim EC_POINT_free(pub_key); 295238384Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 296238384Sjkim goto ecliberr; 297238384Sjkim } 298238384Sjkim EC_POINT_free(pub_key); 299238384Sjkim } 300238384Sjkim 301238384Sjkim EVP_PKEY_assign_EC_KEY(pkey, eckey); 302238384Sjkim return 1; 303238384Sjkim 304238384Sjkim ecliberr: 305238384Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 306238384Sjkim ecerr: 307238384Sjkim if (eckey) 308238384Sjkim EC_KEY_free(eckey); 309238384Sjkim return 0; 310238384Sjkim } 311238384Sjkim 312238384Sjkimstatic int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 313238384Sjkim{ 314238384Sjkim EC_KEY *ec_key; 315238384Sjkim unsigned char *ep, *p; 316238384Sjkim int eplen, ptype; 317238384Sjkim void *pval; 318238384Sjkim unsigned int tmp_flags, old_flags; 319238384Sjkim 320238384Sjkim ec_key = pkey->pkey.ec; 321238384Sjkim 322238384Sjkim if (!eckey_param2type(&ptype, &pval, ec_key)) 323238384Sjkim { 324238384Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); 325238384Sjkim return 0; 326238384Sjkim } 327238384Sjkim 328238384Sjkim /* set the private key */ 329238384Sjkim 330238384Sjkim /* do not include the parameters in the SEC1 private key 331238384Sjkim * see PKCS#11 12.11 */ 332238384Sjkim old_flags = EC_KEY_get_enc_flags(ec_key); 333238384Sjkim tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; 334238384Sjkim EC_KEY_set_enc_flags(ec_key, tmp_flags); 335238384Sjkim eplen = i2d_ECPrivateKey(ec_key, NULL); 336238384Sjkim if (!eplen) 337238384Sjkim { 338238384Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 339238384Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 340238384Sjkim return 0; 341238384Sjkim } 342238384Sjkim ep = (unsigned char *) OPENSSL_malloc(eplen); 343238384Sjkim if (!ep) 344238384Sjkim { 345238384Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 346238384Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 347238384Sjkim return 0; 348238384Sjkim } 349238384Sjkim p = ep; 350238384Sjkim if (!i2d_ECPrivateKey(ec_key, &p)) 351238384Sjkim { 352238384Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 353238384Sjkim OPENSSL_free(ep); 354238384Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 355279264Sdelphij return 0; 356238384Sjkim } 357238384Sjkim /* restore old encoding flags */ 358238384Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 359238384Sjkim 360238384Sjkim if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, 361238384Sjkim ptype, pval, ep, eplen)) 362238384Sjkim return 0; 363238384Sjkim 364238384Sjkim return 1; 365238384Sjkim} 366238384Sjkim 367238384Sjkimstatic int int_ec_size(const EVP_PKEY *pkey) 368238384Sjkim { 369238384Sjkim return ECDSA_size(pkey->pkey.ec); 370238384Sjkim } 371238384Sjkim 372238384Sjkimstatic int ec_bits(const EVP_PKEY *pkey) 373238384Sjkim { 374238384Sjkim BIGNUM *order = BN_new(); 375238384Sjkim const EC_GROUP *group; 376238384Sjkim int ret; 377238384Sjkim 378238384Sjkim if (!order) 379238384Sjkim { 380238384Sjkim ERR_clear_error(); 381238384Sjkim return 0; 382238384Sjkim } 383238384Sjkim group = EC_KEY_get0_group(pkey->pkey.ec); 384238384Sjkim if (!EC_GROUP_get_order(group, order, NULL)) 385238384Sjkim { 386238384Sjkim ERR_clear_error(); 387238384Sjkim return 0; 388238384Sjkim } 389238384Sjkim 390238384Sjkim ret = BN_num_bits(order); 391238384Sjkim BN_free(order); 392238384Sjkim return ret; 393238384Sjkim } 394238384Sjkim 395238384Sjkimstatic int ec_missing_parameters(const EVP_PKEY *pkey) 396238384Sjkim { 397238384Sjkim if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) 398238384Sjkim return 1; 399238384Sjkim return 0; 400238384Sjkim } 401238384Sjkim 402238384Sjkimstatic int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 403238384Sjkim { 404238384Sjkim EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); 405238384Sjkim if (group == NULL) 406238384Sjkim return 0; 407238384Sjkim if (EC_KEY_set_group(to->pkey.ec, group) == 0) 408238384Sjkim return 0; 409238384Sjkim EC_GROUP_free(group); 410238384Sjkim return 1; 411238384Sjkim } 412238384Sjkim 413238384Sjkimstatic int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 414238384Sjkim { 415238384Sjkim const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), 416238384Sjkim *group_b = EC_KEY_get0_group(b->pkey.ec); 417238384Sjkim if (EC_GROUP_cmp(group_a, group_b, NULL)) 418238384Sjkim return 0; 419238384Sjkim else 420238384Sjkim return 1; 421238384Sjkim } 422238384Sjkim 423238384Sjkimstatic void int_ec_free(EVP_PKEY *pkey) 424238384Sjkim { 425238384Sjkim EC_KEY_free(pkey->pkey.ec); 426238384Sjkim } 427238384Sjkim 428238384Sjkimstatic int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) 429238384Sjkim { 430238384Sjkim unsigned char *buffer=NULL; 431238384Sjkim const char *ecstr; 432238384Sjkim size_t buf_len=0, i; 433238384Sjkim int ret=0, reason=ERR_R_BIO_LIB; 434238384Sjkim BIGNUM *pub_key=NULL, *order=NULL; 435238384Sjkim BN_CTX *ctx=NULL; 436238384Sjkim const EC_GROUP *group; 437238384Sjkim const EC_POINT *public_key; 438238384Sjkim const BIGNUM *priv_key; 439238384Sjkim 440238384Sjkim if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) 441238384Sjkim { 442238384Sjkim reason = ERR_R_PASSED_NULL_PARAMETER; 443238384Sjkim goto err; 444238384Sjkim } 445238384Sjkim 446238384Sjkim ctx = BN_CTX_new(); 447238384Sjkim if (ctx == NULL) 448238384Sjkim { 449238384Sjkim reason = ERR_R_MALLOC_FAILURE; 450238384Sjkim goto err; 451238384Sjkim } 452238384Sjkim 453238384Sjkim if (ktype > 0) 454238384Sjkim { 455238384Sjkim public_key = EC_KEY_get0_public_key(x); 456279264Sdelphij if (public_key != NULL) 457238384Sjkim { 458279264Sdelphij if ((pub_key = EC_POINT_point2bn(group, public_key, 459279264Sdelphij EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) 460279264Sdelphij { 461279264Sdelphij reason = ERR_R_EC_LIB; 462279264Sdelphij goto err; 463279264Sdelphij } 464279264Sdelphij buf_len = (size_t)BN_num_bytes(pub_key); 465238384Sjkim } 466238384Sjkim } 467238384Sjkim 468238384Sjkim if (ktype == 2) 469238384Sjkim { 470238384Sjkim priv_key = EC_KEY_get0_private_key(x); 471238384Sjkim if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) 472238384Sjkim buf_len = i; 473238384Sjkim } 474238384Sjkim else 475238384Sjkim priv_key = NULL; 476238384Sjkim 477238384Sjkim if (ktype > 0) 478238384Sjkim { 479238384Sjkim buf_len += 10; 480238384Sjkim if ((buffer = OPENSSL_malloc(buf_len)) == NULL) 481238384Sjkim { 482238384Sjkim reason = ERR_R_MALLOC_FAILURE; 483238384Sjkim goto err; 484238384Sjkim } 485238384Sjkim } 486238384Sjkim if (ktype == 2) 487238384Sjkim ecstr = "Private-Key"; 488238384Sjkim else if (ktype == 1) 489238384Sjkim ecstr = "Public-Key"; 490238384Sjkim else 491238384Sjkim ecstr = "ECDSA-Parameters"; 492238384Sjkim 493238384Sjkim if (!BIO_indent(bp, off, 128)) 494238384Sjkim goto err; 495238384Sjkim if ((order = BN_new()) == NULL) 496238384Sjkim goto err; 497238384Sjkim if (!EC_GROUP_get_order(group, order, NULL)) 498238384Sjkim goto err; 499238384Sjkim if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, 500238384Sjkim BN_num_bits(order)) <= 0) goto err; 501238384Sjkim 502238384Sjkim if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 503238384Sjkim buffer, off)) 504238384Sjkim goto err; 505238384Sjkim if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, 506238384Sjkim buffer, off)) 507238384Sjkim goto err; 508238384Sjkim if (!ECPKParameters_print(bp, group, off)) 509238384Sjkim goto err; 510238384Sjkim ret=1; 511238384Sjkimerr: 512238384Sjkim if (!ret) 513238384Sjkim ECerr(EC_F_DO_EC_KEY_PRINT, reason); 514238384Sjkim if (pub_key) 515238384Sjkim BN_free(pub_key); 516238384Sjkim if (order) 517238384Sjkim BN_free(order); 518238384Sjkim if (ctx) 519238384Sjkim BN_CTX_free(ctx); 520238384Sjkim if (buffer != NULL) 521238384Sjkim OPENSSL_free(buffer); 522238384Sjkim return(ret); 523238384Sjkim } 524238384Sjkim 525238384Sjkimstatic int eckey_param_decode(EVP_PKEY *pkey, 526238384Sjkim const unsigned char **pder, int derlen) 527238384Sjkim { 528238384Sjkim EC_KEY *eckey; 529238384Sjkim if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) 530238384Sjkim { 531238384Sjkim ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); 532238384Sjkim return 0; 533238384Sjkim } 534238384Sjkim EVP_PKEY_assign_EC_KEY(pkey, eckey); 535238384Sjkim return 1; 536238384Sjkim } 537238384Sjkim 538238384Sjkimstatic int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 539238384Sjkim { 540238384Sjkim return i2d_ECParameters(pkey->pkey.ec, pder); 541238384Sjkim } 542238384Sjkim 543238384Sjkimstatic int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 544238384Sjkim ASN1_PCTX *ctx) 545238384Sjkim { 546238384Sjkim return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); 547238384Sjkim } 548238384Sjkim 549238384Sjkimstatic int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 550238384Sjkim ASN1_PCTX *ctx) 551238384Sjkim { 552238384Sjkim return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); 553238384Sjkim } 554238384Sjkim 555238384Sjkim 556238384Sjkimstatic int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 557238384Sjkim ASN1_PCTX *ctx) 558238384Sjkim { 559238384Sjkim return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); 560238384Sjkim } 561238384Sjkim 562238384Sjkimstatic int old_ec_priv_decode(EVP_PKEY *pkey, 563238384Sjkim const unsigned char **pder, int derlen) 564238384Sjkim { 565238384Sjkim EC_KEY *ec; 566238384Sjkim if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen))) 567238384Sjkim { 568238384Sjkim ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); 569238384Sjkim return 0; 570238384Sjkim } 571238384Sjkim EVP_PKEY_assign_EC_KEY(pkey, ec); 572238384Sjkim return 1; 573238384Sjkim } 574238384Sjkim 575238384Sjkimstatic int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 576238384Sjkim { 577238384Sjkim return i2d_ECPrivateKey(pkey->pkey.ec, pder); 578238384Sjkim } 579238384Sjkim 580238384Sjkimstatic int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 581238384Sjkim { 582238384Sjkim switch (op) 583238384Sjkim { 584238384Sjkim case ASN1_PKEY_CTRL_PKCS7_SIGN: 585238384Sjkim if (arg1 == 0) 586238384Sjkim { 587238384Sjkim int snid, hnid; 588238384Sjkim X509_ALGOR *alg1, *alg2; 589238384Sjkim PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 590238384Sjkim if (alg1 == NULL || alg1->algorithm == NULL) 591238384Sjkim return -1; 592238384Sjkim hnid = OBJ_obj2nid(alg1->algorithm); 593238384Sjkim if (hnid == NID_undef) 594238384Sjkim return -1; 595238384Sjkim if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 596238384Sjkim return -1; 597238384Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 598238384Sjkim } 599238384Sjkim return 1; 600238384Sjkim#ifndef OPENSSL_NO_CMS 601238384Sjkim case ASN1_PKEY_CTRL_CMS_SIGN: 602238384Sjkim if (arg1 == 0) 603238384Sjkim { 604238384Sjkim int snid, hnid; 605238384Sjkim X509_ALGOR *alg1, *alg2; 606238384Sjkim CMS_SignerInfo_get0_algs(arg2, NULL, NULL, 607238384Sjkim &alg1, &alg2); 608238384Sjkim if (alg1 == NULL || alg1->algorithm == NULL) 609238384Sjkim return -1; 610238384Sjkim hnid = OBJ_obj2nid(alg1->algorithm); 611238384Sjkim if (hnid == NID_undef) 612238384Sjkim return -1; 613238384Sjkim if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 614238384Sjkim return -1; 615238384Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 616238384Sjkim } 617238384Sjkim return 1; 618238384Sjkim#endif 619238384Sjkim 620238384Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 621238384Sjkim *(int *)arg2 = NID_sha1; 622238384Sjkim return 2; 623238384Sjkim 624238384Sjkim default: 625238384Sjkim return -2; 626238384Sjkim 627238384Sjkim } 628238384Sjkim 629238384Sjkim } 630238384Sjkim 631238384Sjkimconst EVP_PKEY_ASN1_METHOD eckey_asn1_meth = 632238384Sjkim { 633238384Sjkim EVP_PKEY_EC, 634238384Sjkim EVP_PKEY_EC, 635238384Sjkim 0, 636238384Sjkim "EC", 637238384Sjkim "OpenSSL EC algorithm", 638238384Sjkim 639238384Sjkim eckey_pub_decode, 640238384Sjkim eckey_pub_encode, 641238384Sjkim eckey_pub_cmp, 642238384Sjkim eckey_pub_print, 643238384Sjkim 644238384Sjkim eckey_priv_decode, 645238384Sjkim eckey_priv_encode, 646238384Sjkim eckey_priv_print, 647238384Sjkim 648238384Sjkim int_ec_size, 649238384Sjkim ec_bits, 650238384Sjkim 651238384Sjkim eckey_param_decode, 652238384Sjkim eckey_param_encode, 653238384Sjkim ec_missing_parameters, 654238384Sjkim ec_copy_parameters, 655238384Sjkim ec_cmp_parameters, 656238384Sjkim eckey_param_print, 657238384Sjkim 0, 658238384Sjkim 659238384Sjkim int_ec_free, 660238384Sjkim ec_pkey_ctrl, 661238384Sjkim old_ec_priv_decode, 662238384Sjkim old_ec_priv_encode 663238384Sjkim }; 664