1280304Sjkim/* 2280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 3280304Sjkim * 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 13280304Sjkim * 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 65280304Sjkim# include <openssl/cms.h> 66238384Sjkim#endif 67238384Sjkim#include "asn1_locl.h" 68238384Sjkim 69238384Sjkimstatic int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) 70280304Sjkim{ 71280304Sjkim const EC_GROUP *group; 72280304Sjkim int nid; 73280304Sjkim if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 74280304Sjkim ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); 75280304Sjkim return 0; 76280304Sjkim } 77280304Sjkim if (EC_GROUP_get_asn1_flag(group) 78280304Sjkim && (nid = EC_GROUP_get_curve_name(group))) 79280304Sjkim /* we have a 'named curve' => just set the OID */ 80280304Sjkim { 81280304Sjkim *ppval = OBJ_nid2obj(nid); 82280304Sjkim *pptype = V_ASN1_OBJECT; 83280304Sjkim } else { /* explicit parameters */ 84238384Sjkim 85280304Sjkim ASN1_STRING *pstr = NULL; 86280304Sjkim pstr = ASN1_STRING_new(); 87280304Sjkim if (!pstr) 88280304Sjkim return 0; 89280304Sjkim pstr->length = i2d_ECParameters(ec_key, &pstr->data); 90280304Sjkim if (pstr->length <= 0) { 91280304Sjkim ASN1_STRING_free(pstr); 92280304Sjkim ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); 93280304Sjkim return 0; 94280304Sjkim } 95280304Sjkim *ppval = pstr; 96280304Sjkim *pptype = V_ASN1_SEQUENCE; 97280304Sjkim } 98280304Sjkim return 1; 99280304Sjkim} 100280304Sjkim 101238384Sjkimstatic int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 102280304Sjkim{ 103280304Sjkim EC_KEY *ec_key = pkey->pkey.ec; 104280304Sjkim void *pval = NULL; 105280304Sjkim int ptype; 106280304Sjkim unsigned char *penc = NULL, *p; 107280304Sjkim int penclen; 108238384Sjkim 109280304Sjkim if (!eckey_param2type(&ptype, &pval, ec_key)) { 110280304Sjkim ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); 111280304Sjkim return 0; 112280304Sjkim } 113280304Sjkim penclen = i2o_ECPublicKey(ec_key, NULL); 114280304Sjkim if (penclen <= 0) 115280304Sjkim goto err; 116280304Sjkim penc = OPENSSL_malloc(penclen); 117280304Sjkim if (!penc) 118280304Sjkim goto err; 119280304Sjkim p = penc; 120280304Sjkim penclen = i2o_ECPublicKey(ec_key, &p); 121280304Sjkim if (penclen <= 0) 122280304Sjkim goto err; 123280304Sjkim if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), 124280304Sjkim ptype, pval, penc, penclen)) 125280304Sjkim return 1; 126280304Sjkim err: 127280304Sjkim if (ptype == V_ASN1_OBJECT) 128280304Sjkim ASN1_OBJECT_free(pval); 129280304Sjkim else 130280304Sjkim ASN1_STRING_free(pval); 131280304Sjkim if (penc) 132280304Sjkim OPENSSL_free(penc); 133280304Sjkim return 0; 134280304Sjkim} 135238384Sjkim 136238384Sjkimstatic EC_KEY *eckey_type2param(int ptype, void *pval) 137280304Sjkim{ 138280304Sjkim EC_KEY *eckey = NULL; 139280304Sjkim if (ptype == V_ASN1_SEQUENCE) { 140280304Sjkim ASN1_STRING *pstr = pval; 141280304Sjkim const unsigned char *pm = NULL; 142280304Sjkim int pmlen; 143280304Sjkim pm = pstr->data; 144280304Sjkim pmlen = pstr->length; 145280304Sjkim if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { 146280304Sjkim ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 147280304Sjkim goto ecerr; 148280304Sjkim } 149280304Sjkim } else if (ptype == V_ASN1_OBJECT) { 150280304Sjkim ASN1_OBJECT *poid = pval; 151280304Sjkim EC_GROUP *group; 152238384Sjkim 153280304Sjkim /* 154280304Sjkim * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID 155280304Sjkim */ 156280304Sjkim if ((eckey = EC_KEY_new()) == NULL) { 157280304Sjkim ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); 158280304Sjkim goto ecerr; 159280304Sjkim } 160280304Sjkim group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); 161280304Sjkim if (group == NULL) 162280304Sjkim goto ecerr; 163280304Sjkim EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 164280304Sjkim if (EC_KEY_set_group(eckey, group) == 0) 165280304Sjkim goto ecerr; 166280304Sjkim EC_GROUP_free(group); 167280304Sjkim } else { 168280304Sjkim ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 169280304Sjkim goto ecerr; 170280304Sjkim } 171238384Sjkim 172280304Sjkim return eckey; 173238384Sjkim 174280304Sjkim ecerr: 175280304Sjkim if (eckey) 176280304Sjkim EC_KEY_free(eckey); 177280304Sjkim return NULL; 178280304Sjkim} 179238384Sjkim 180238384Sjkimstatic int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 181280304Sjkim{ 182280304Sjkim const unsigned char *p = NULL; 183280304Sjkim void *pval; 184280304Sjkim int ptype, pklen; 185280304Sjkim EC_KEY *eckey = NULL; 186280304Sjkim X509_ALGOR *palg; 187238384Sjkim 188280304Sjkim if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 189280304Sjkim return 0; 190280304Sjkim X509_ALGOR_get0(NULL, &ptype, &pval, palg); 191238384Sjkim 192280304Sjkim eckey = eckey_type2param(ptype, pval); 193238384Sjkim 194280304Sjkim if (!eckey) { 195280304Sjkim ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); 196280304Sjkim return 0; 197280304Sjkim } 198238384Sjkim 199280304Sjkim /* We have parameters now set public key */ 200280304Sjkim if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 201280304Sjkim ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); 202280304Sjkim goto ecerr; 203280304Sjkim } 204238384Sjkim 205280304Sjkim EVP_PKEY_assign_EC_KEY(pkey, eckey); 206280304Sjkim return 1; 207238384Sjkim 208280304Sjkim ecerr: 209280304Sjkim if (eckey) 210280304Sjkim EC_KEY_free(eckey); 211280304Sjkim return 0; 212280304Sjkim} 213238384Sjkim 214238384Sjkimstatic int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 215280304Sjkim{ 216280304Sjkim int r; 217280304Sjkim const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 218280304Sjkim const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), 219280304Sjkim *pb = EC_KEY_get0_public_key(b->pkey.ec); 220280304Sjkim r = EC_POINT_cmp(group, pa, pb, NULL); 221280304Sjkim if (r == 0) 222280304Sjkim return 1; 223280304Sjkim if (r == 1) 224280304Sjkim return 0; 225280304Sjkim return -2; 226280304Sjkim} 227238384Sjkim 228238384Sjkimstatic int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 229280304Sjkim{ 230280304Sjkim const unsigned char *p = NULL; 231280304Sjkim void *pval; 232280304Sjkim int ptype, pklen; 233280304Sjkim EC_KEY *eckey = NULL; 234280304Sjkim X509_ALGOR *palg; 235238384Sjkim 236280304Sjkim if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 237280304Sjkim return 0; 238280304Sjkim X509_ALGOR_get0(NULL, &ptype, &pval, palg); 239238384Sjkim 240280304Sjkim eckey = eckey_type2param(ptype, pval); 241238384Sjkim 242280304Sjkim if (!eckey) 243280304Sjkim goto ecliberr; 244238384Sjkim 245280304Sjkim /* We have parameters now set private key */ 246280304Sjkim if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { 247280304Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); 248280304Sjkim goto ecerr; 249280304Sjkim } 250238384Sjkim 251280304Sjkim /* calculate public key (if necessary) */ 252280304Sjkim if (EC_KEY_get0_public_key(eckey) == NULL) { 253280304Sjkim const BIGNUM *priv_key; 254280304Sjkim const EC_GROUP *group; 255280304Sjkim EC_POINT *pub_key; 256280304Sjkim /* 257280304Sjkim * the public key was not included in the SEC1 private key => 258280304Sjkim * calculate the public key 259280304Sjkim */ 260280304Sjkim group = EC_KEY_get0_group(eckey); 261280304Sjkim pub_key = EC_POINT_new(group); 262280304Sjkim if (pub_key == NULL) { 263280304Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 264280304Sjkim goto ecliberr; 265280304Sjkim } 266280304Sjkim if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 267280304Sjkim EC_POINT_free(pub_key); 268280304Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 269280304Sjkim goto ecliberr; 270280304Sjkim } 271280304Sjkim priv_key = EC_KEY_get0_private_key(eckey); 272280304Sjkim if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { 273280304Sjkim EC_POINT_free(pub_key); 274280304Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 275280304Sjkim goto ecliberr; 276280304Sjkim } 277280304Sjkim if (EC_KEY_set_public_key(eckey, pub_key) == 0) { 278280304Sjkim EC_POINT_free(pub_key); 279280304Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 280280304Sjkim goto ecliberr; 281280304Sjkim } 282280304Sjkim EC_POINT_free(pub_key); 283280304Sjkim } 284238384Sjkim 285280304Sjkim EVP_PKEY_assign_EC_KEY(pkey, eckey); 286280304Sjkim return 1; 287238384Sjkim 288280304Sjkim ecliberr: 289280304Sjkim ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 290280304Sjkim ecerr: 291280304Sjkim if (eckey) 292280304Sjkim EC_KEY_free(eckey); 293280304Sjkim return 0; 294280304Sjkim} 295238384Sjkim 296238384Sjkimstatic int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 297238384Sjkim{ 298280304Sjkim EC_KEY *ec_key; 299280304Sjkim unsigned char *ep, *p; 300280304Sjkim int eplen, ptype; 301280304Sjkim void *pval; 302280304Sjkim unsigned int tmp_flags, old_flags; 303238384Sjkim 304280304Sjkim ec_key = pkey->pkey.ec; 305238384Sjkim 306280304Sjkim if (!eckey_param2type(&ptype, &pval, ec_key)) { 307280304Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); 308280304Sjkim return 0; 309280304Sjkim } 310238384Sjkim 311280304Sjkim /* set the private key */ 312238384Sjkim 313280304Sjkim /* 314280304Sjkim * do not include the parameters in the SEC1 private key see PKCS#11 315280304Sjkim * 12.11 316280304Sjkim */ 317280304Sjkim old_flags = EC_KEY_get_enc_flags(ec_key); 318280304Sjkim tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; 319280304Sjkim EC_KEY_set_enc_flags(ec_key, tmp_flags); 320280304Sjkim eplen = i2d_ECPrivateKey(ec_key, NULL); 321280304Sjkim if (!eplen) { 322280304Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 323280304Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 324280304Sjkim return 0; 325280304Sjkim } 326280304Sjkim ep = (unsigned char *)OPENSSL_malloc(eplen); 327280304Sjkim if (!ep) { 328280304Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 329280304Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 330280304Sjkim return 0; 331280304Sjkim } 332280304Sjkim p = ep; 333280304Sjkim if (!i2d_ECPrivateKey(ec_key, &p)) { 334280304Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 335280304Sjkim OPENSSL_free(ep); 336280304Sjkim ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 337280304Sjkim return 0; 338280304Sjkim } 339280304Sjkim /* restore old encoding flags */ 340280304Sjkim EC_KEY_set_enc_flags(ec_key, old_flags); 341238384Sjkim 342280304Sjkim if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, 343280304Sjkim ptype, pval, ep, eplen)) 344280304Sjkim return 0; 345238384Sjkim 346280304Sjkim return 1; 347238384Sjkim} 348238384Sjkim 349238384Sjkimstatic int int_ec_size(const EVP_PKEY *pkey) 350280304Sjkim{ 351280304Sjkim return ECDSA_size(pkey->pkey.ec); 352280304Sjkim} 353238384Sjkim 354238384Sjkimstatic int ec_bits(const EVP_PKEY *pkey) 355280304Sjkim{ 356280304Sjkim BIGNUM *order = BN_new(); 357280304Sjkim const EC_GROUP *group; 358280304Sjkim int ret; 359238384Sjkim 360280304Sjkim if (!order) { 361280304Sjkim ERR_clear_error(); 362280304Sjkim return 0; 363280304Sjkim } 364280304Sjkim group = EC_KEY_get0_group(pkey->pkey.ec); 365280304Sjkim if (!EC_GROUP_get_order(group, order, NULL)) { 366280304Sjkim ERR_clear_error(); 367280304Sjkim return 0; 368280304Sjkim } 369238384Sjkim 370280304Sjkim ret = BN_num_bits(order); 371280304Sjkim BN_free(order); 372280304Sjkim return ret; 373280304Sjkim} 374238384Sjkim 375238384Sjkimstatic int ec_missing_parameters(const EVP_PKEY *pkey) 376280304Sjkim{ 377280304Sjkim if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) 378280304Sjkim return 1; 379280304Sjkim return 0; 380280304Sjkim} 381238384Sjkim 382238384Sjkimstatic int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 383280304Sjkim{ 384280304Sjkim EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); 385280304Sjkim if (group == NULL) 386280304Sjkim return 0; 387280304Sjkim if (EC_KEY_set_group(to->pkey.ec, group) == 0) 388280304Sjkim return 0; 389280304Sjkim EC_GROUP_free(group); 390280304Sjkim return 1; 391280304Sjkim} 392238384Sjkim 393238384Sjkimstatic int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 394280304Sjkim{ 395280304Sjkim const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), 396280304Sjkim *group_b = EC_KEY_get0_group(b->pkey.ec); 397280304Sjkim if (EC_GROUP_cmp(group_a, group_b, NULL)) 398280304Sjkim return 0; 399280304Sjkim else 400280304Sjkim return 1; 401280304Sjkim} 402238384Sjkim 403238384Sjkimstatic void int_ec_free(EVP_PKEY *pkey) 404280304Sjkim{ 405280304Sjkim EC_KEY_free(pkey->pkey.ec); 406280304Sjkim} 407238384Sjkim 408238384Sjkimstatic int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) 409280304Sjkim{ 410280304Sjkim unsigned char *buffer = NULL; 411280304Sjkim const char *ecstr; 412280304Sjkim size_t buf_len = 0, i; 413280304Sjkim int ret = 0, reason = ERR_R_BIO_LIB; 414280304Sjkim BIGNUM *pub_key = NULL, *order = NULL; 415280304Sjkim BN_CTX *ctx = NULL; 416280304Sjkim const EC_GROUP *group; 417280304Sjkim const EC_POINT *public_key; 418280304Sjkim const BIGNUM *priv_key; 419238384Sjkim 420280304Sjkim if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 421280304Sjkim reason = ERR_R_PASSED_NULL_PARAMETER; 422280304Sjkim goto err; 423280304Sjkim } 424238384Sjkim 425280304Sjkim ctx = BN_CTX_new(); 426280304Sjkim if (ctx == NULL) { 427280304Sjkim reason = ERR_R_MALLOC_FAILURE; 428280304Sjkim goto err; 429280304Sjkim } 430238384Sjkim 431280304Sjkim if (ktype > 0) { 432280304Sjkim public_key = EC_KEY_get0_public_key(x); 433280304Sjkim if (public_key != NULL) { 434280304Sjkim if ((pub_key = EC_POINT_point2bn(group, public_key, 435280304Sjkim EC_KEY_get_conv_form(x), NULL, 436280304Sjkim ctx)) == NULL) { 437280304Sjkim reason = ERR_R_EC_LIB; 438280304Sjkim goto err; 439280304Sjkim } 440280304Sjkim buf_len = (size_t)BN_num_bytes(pub_key); 441280304Sjkim } 442280304Sjkim } 443238384Sjkim 444280304Sjkim if (ktype == 2) { 445280304Sjkim priv_key = EC_KEY_get0_private_key(x); 446280304Sjkim if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) 447280304Sjkim buf_len = i; 448280304Sjkim } else 449280304Sjkim priv_key = NULL; 450238384Sjkim 451280304Sjkim if (ktype > 0) { 452280304Sjkim buf_len += 10; 453280304Sjkim if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { 454280304Sjkim reason = ERR_R_MALLOC_FAILURE; 455280304Sjkim goto err; 456280304Sjkim } 457280304Sjkim } 458280304Sjkim if (ktype == 2) 459280304Sjkim ecstr = "Private-Key"; 460280304Sjkim else if (ktype == 1) 461280304Sjkim ecstr = "Public-Key"; 462280304Sjkim else 463280304Sjkim ecstr = "ECDSA-Parameters"; 464238384Sjkim 465280304Sjkim if (!BIO_indent(bp, off, 128)) 466280304Sjkim goto err; 467280304Sjkim if ((order = BN_new()) == NULL) 468280304Sjkim goto err; 469280304Sjkim if (!EC_GROUP_get_order(group, order, NULL)) 470280304Sjkim goto err; 471280304Sjkim if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) 472280304Sjkim goto err; 473280304Sjkim 474280304Sjkim if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 475280304Sjkim buffer, off)) 476280304Sjkim goto err; 477280304Sjkim if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, 478280304Sjkim buffer, off)) 479280304Sjkim goto err; 480280304Sjkim if (!ECPKParameters_print(bp, group, off)) 481280304Sjkim goto err; 482280304Sjkim ret = 1; 483280304Sjkim err: 484280304Sjkim if (!ret) 485280304Sjkim ECerr(EC_F_DO_EC_KEY_PRINT, reason); 486280304Sjkim if (pub_key) 487280304Sjkim BN_free(pub_key); 488280304Sjkim if (order) 489280304Sjkim BN_free(order); 490280304Sjkim if (ctx) 491280304Sjkim BN_CTX_free(ctx); 492280304Sjkim if (buffer != NULL) 493280304Sjkim OPENSSL_free(buffer); 494280304Sjkim return (ret); 495280304Sjkim} 496280304Sjkim 497238384Sjkimstatic int eckey_param_decode(EVP_PKEY *pkey, 498280304Sjkim const unsigned char **pder, int derlen) 499280304Sjkim{ 500280304Sjkim EC_KEY *eckey; 501280304Sjkim if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { 502280304Sjkim ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); 503280304Sjkim return 0; 504280304Sjkim } 505280304Sjkim EVP_PKEY_assign_EC_KEY(pkey, eckey); 506280304Sjkim return 1; 507280304Sjkim} 508238384Sjkim 509238384Sjkimstatic int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 510280304Sjkim{ 511280304Sjkim return i2d_ECParameters(pkey->pkey.ec, pder); 512280304Sjkim} 513238384Sjkim 514238384Sjkimstatic int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 515280304Sjkim ASN1_PCTX *ctx) 516280304Sjkim{ 517280304Sjkim return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); 518280304Sjkim} 519238384Sjkim 520238384Sjkimstatic int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 521280304Sjkim ASN1_PCTX *ctx) 522280304Sjkim{ 523280304Sjkim return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); 524280304Sjkim} 525238384Sjkim 526238384Sjkimstatic int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 527280304Sjkim ASN1_PCTX *ctx) 528280304Sjkim{ 529280304Sjkim return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); 530280304Sjkim} 531238384Sjkim 532238384Sjkimstatic int old_ec_priv_decode(EVP_PKEY *pkey, 533280304Sjkim const unsigned char **pder, int derlen) 534280304Sjkim{ 535280304Sjkim EC_KEY *ec; 536280304Sjkim if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { 537280304Sjkim ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); 538280304Sjkim return 0; 539280304Sjkim } 540280304Sjkim EVP_PKEY_assign_EC_KEY(pkey, ec); 541280304Sjkim return 1; 542280304Sjkim} 543238384Sjkim 544238384Sjkimstatic int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 545280304Sjkim{ 546280304Sjkim return i2d_ECPrivateKey(pkey->pkey.ec, pder); 547280304Sjkim} 548238384Sjkim 549238384Sjkimstatic int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 550280304Sjkim{ 551280304Sjkim switch (op) { 552280304Sjkim case ASN1_PKEY_CTRL_PKCS7_SIGN: 553280304Sjkim if (arg1 == 0) { 554280304Sjkim int snid, hnid; 555280304Sjkim X509_ALGOR *alg1, *alg2; 556280304Sjkim PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 557280304Sjkim if (alg1 == NULL || alg1->algorithm == NULL) 558280304Sjkim return -1; 559280304Sjkim hnid = OBJ_obj2nid(alg1->algorithm); 560280304Sjkim if (hnid == NID_undef) 561280304Sjkim return -1; 562280304Sjkim if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 563280304Sjkim return -1; 564280304Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 565280304Sjkim } 566280304Sjkim return 1; 567238384Sjkim#ifndef OPENSSL_NO_CMS 568280304Sjkim case ASN1_PKEY_CTRL_CMS_SIGN: 569280304Sjkim if (arg1 == 0) { 570280304Sjkim int snid, hnid; 571280304Sjkim X509_ALGOR *alg1, *alg2; 572280304Sjkim CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 573280304Sjkim if (alg1 == NULL || alg1->algorithm == NULL) 574280304Sjkim return -1; 575280304Sjkim hnid = OBJ_obj2nid(alg1->algorithm); 576280304Sjkim if (hnid == NID_undef) 577280304Sjkim return -1; 578280304Sjkim if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 579280304Sjkim return -1; 580280304Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 581280304Sjkim } 582280304Sjkim return 1; 583238384Sjkim#endif 584238384Sjkim 585280304Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 586280304Sjkim *(int *)arg2 = NID_sha1; 587280304Sjkim return 2; 588238384Sjkim 589280304Sjkim default: 590280304Sjkim return -2; 591238384Sjkim 592280304Sjkim } 593238384Sjkim 594280304Sjkim} 595238384Sjkim 596280304Sjkimconst EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { 597280304Sjkim EVP_PKEY_EC, 598280304Sjkim EVP_PKEY_EC, 599280304Sjkim 0, 600280304Sjkim "EC", 601280304Sjkim "OpenSSL EC algorithm", 602238384Sjkim 603280304Sjkim eckey_pub_decode, 604280304Sjkim eckey_pub_encode, 605280304Sjkim eckey_pub_cmp, 606280304Sjkim eckey_pub_print, 607238384Sjkim 608280304Sjkim eckey_priv_decode, 609280304Sjkim eckey_priv_encode, 610280304Sjkim eckey_priv_print, 611238384Sjkim 612280304Sjkim int_ec_size, 613280304Sjkim ec_bits, 614238384Sjkim 615280304Sjkim eckey_param_decode, 616280304Sjkim eckey_param_encode, 617280304Sjkim ec_missing_parameters, 618280304Sjkim ec_copy_parameters, 619280304Sjkim ec_cmp_parameters, 620280304Sjkim eckey_param_print, 621280304Sjkim 0, 622238384Sjkim 623280304Sjkim int_ec_free, 624280304Sjkim ec_pkey_ctrl, 625280304Sjkim old_ec_priv_decode, 626280304Sjkim old_ec_priv_encode 627280304Sjkim}; 628