1/* $OpenBSD: ec_asn1.c,v 1.53 2024/04/17 23:24:18 tb Exp $ */ 2/* 3 * Written by Nils Larsch for the OpenSSL project. 4 */ 5/* ==================================================================== 6 * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59#include <string.h> 60 61#include <openssl/opensslconf.h> 62 63#include <openssl/err.h> 64#include <openssl/asn1t.h> 65#include <openssl/objects.h> 66 67#include "asn1_local.h" 68#include "ec_local.h" 69 70int 71EC_GROUP_get_basis_type(const EC_GROUP *group) 72{ 73 return 0; 74} 75LCRYPTO_ALIAS(EC_GROUP_get_basis_type); 76 77typedef struct x9_62_pentanomial_st { 78 long k1; 79 long k2; 80 long k3; 81} X9_62_PENTANOMIAL; 82 83typedef struct x9_62_characteristic_two_st { 84 long m; 85 ASN1_OBJECT *type; 86 union { 87 char *ptr; 88 /* NID_X9_62_onBasis */ 89 ASN1_NULL *onBasis; 90 /* NID_X9_62_tpBasis */ 91 ASN1_INTEGER *tpBasis; 92 /* NID_X9_62_ppBasis */ 93 X9_62_PENTANOMIAL *ppBasis; 94 /* anything else */ 95 ASN1_TYPE *other; 96 } p; 97} X9_62_CHARACTERISTIC_TWO; 98 99typedef struct x9_62_fieldid_st { 100 ASN1_OBJECT *fieldType; 101 union { 102 char *ptr; 103 /* NID_X9_62_prime_field */ 104 ASN1_INTEGER *prime; 105 /* NID_X9_62_characteristic_two_field */ 106 X9_62_CHARACTERISTIC_TWO *char_two; 107 /* anything else */ 108 ASN1_TYPE *other; 109 } p; 110} X9_62_FIELDID; 111 112typedef struct x9_62_curve_st { 113 ASN1_OCTET_STRING *a; 114 ASN1_OCTET_STRING *b; 115 ASN1_BIT_STRING *seed; 116} X9_62_CURVE; 117 118typedef struct ec_parameters_st { 119 long version; 120 X9_62_FIELDID *fieldID; 121 X9_62_CURVE *curve; 122 ASN1_OCTET_STRING *base; 123 ASN1_INTEGER *order; 124 ASN1_INTEGER *cofactor; 125} ECPARAMETERS; 126 127typedef struct ecpk_parameters_st { 128 int type; 129 union { 130 ASN1_OBJECT *named_curve; 131 ECPARAMETERS *parameters; 132 ASN1_NULL *implicitlyCA; 133 } value; 134} ECPKPARAMETERS; 135 136typedef struct ec_privatekey_st { 137 long version; 138 ASN1_OCTET_STRING *privateKey; 139 ECPKPARAMETERS *parameters; 140 ASN1_BIT_STRING *publicKey; 141} EC_PRIVATEKEY; 142 143static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = { 144 { 145 .flags = 0, 146 .tag = 0, 147 .offset = offsetof(X9_62_PENTANOMIAL, k1), 148 .field_name = "k1", 149 .item = &LONG_it, 150 }, 151 { 152 .flags = 0, 153 .tag = 0, 154 .offset = offsetof(X9_62_PENTANOMIAL, k2), 155 .field_name = "k2", 156 .item = &LONG_it, 157 }, 158 { 159 .flags = 0, 160 .tag = 0, 161 .offset = offsetof(X9_62_PENTANOMIAL, k3), 162 .field_name = "k3", 163 .item = &LONG_it, 164 }, 165}; 166 167static const ASN1_ITEM X9_62_PENTANOMIAL_it = { 168 .itype = ASN1_ITYPE_SEQUENCE, 169 .utype = V_ASN1_SEQUENCE, 170 .templates = X9_62_PENTANOMIAL_seq_tt, 171 .tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE), 172 .funcs = NULL, 173 .size = sizeof(X9_62_PENTANOMIAL), 174 .sname = "X9_62_PENTANOMIAL", 175}; 176 177static const ASN1_TEMPLATE char_two_def_tt = { 178 .flags = 0, 179 .tag = 0, 180 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other), 181 .field_name = "p.other", 182 .item = &ASN1_ANY_it, 183}; 184 185static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = { 186 { 187 .value = NID_X9_62_onBasis, 188 .tt = { 189 .flags = 0, 190 .tag = 0, 191 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis), 192 .field_name = "p.onBasis", 193 .item = &ASN1_NULL_it, 194 }, 195 }, 196 { 197 .value = NID_X9_62_tpBasis, 198 .tt = { 199 .flags = 0, 200 .tag = 0, 201 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis), 202 .field_name = "p.tpBasis", 203 .item = &ASN1_INTEGER_it, 204 }, 205 }, 206 { 207 .value = NID_X9_62_ppBasis, 208 .tt = { 209 .flags = 0, 210 .tag = 0, 211 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis), 212 .field_name = "p.ppBasis", 213 .item = &X9_62_PENTANOMIAL_it, 214 }, 215 216 }, 217}; 218 219static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = { 220 .flags = 0, 221 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type), 222 .tbl = X9_62_CHARACTERISTIC_TWO_adbtbl, 223 .tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE), 224 .default_tt = &char_two_def_tt, 225 .null_tt = NULL, 226}; 227 228static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = { 229 { 230 .flags = 0, 231 .tag = 0, 232 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, m), 233 .field_name = "m", 234 .item = &LONG_it, 235 }, 236 { 237 .flags = 0, 238 .tag = 0, 239 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type), 240 .field_name = "type", 241 .item = &ASN1_OBJECT_it, 242 }, 243 { 244 .flags = ASN1_TFLG_ADB_OID, 245 .tag = -1, 246 .offset = 0, 247 .field_name = "X9_62_CHARACTERISTIC_TWO", 248 .item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb, 249 }, 250}; 251 252static const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = { 253 .itype = ASN1_ITYPE_SEQUENCE, 254 .utype = V_ASN1_SEQUENCE, 255 .templates = X9_62_CHARACTERISTIC_TWO_seq_tt, 256 .tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE), 257 .funcs = NULL, 258 .size = sizeof(X9_62_CHARACTERISTIC_TWO), 259 .sname = "X9_62_CHARACTERISTIC_TWO", 260}; 261 262static const ASN1_TEMPLATE fieldID_def_tt = { 263 .flags = 0, 264 .tag = 0, 265 .offset = offsetof(X9_62_FIELDID, p.other), 266 .field_name = "p.other", 267 .item = &ASN1_ANY_it, 268}; 269 270static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = { 271 { 272 .value = NID_X9_62_prime_field, 273 .tt = { 274 .flags = 0, 275 .tag = 0, 276 .offset = offsetof(X9_62_FIELDID, p.prime), 277 .field_name = "p.prime", 278 .item = &ASN1_INTEGER_it, 279 }, 280 }, 281 { 282 .value = NID_X9_62_characteristic_two_field, 283 .tt = { 284 .flags = 0, 285 .tag = 0, 286 .offset = offsetof(X9_62_FIELDID, p.char_two), 287 .field_name = "p.char_two", 288 .item = &X9_62_CHARACTERISTIC_TWO_it, 289 }, 290 }, 291}; 292 293static const ASN1_ADB X9_62_FIELDID_adb = { 294 .flags = 0, 295 .offset = offsetof(X9_62_FIELDID, fieldType), 296 .tbl = X9_62_FIELDID_adbtbl, 297 .tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE), 298 .default_tt = &fieldID_def_tt, 299 .null_tt = NULL, 300}; 301 302static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = { 303 { 304 .flags = 0, 305 .tag = 0, 306 .offset = offsetof(X9_62_FIELDID, fieldType), 307 .field_name = "fieldType", 308 .item = &ASN1_OBJECT_it, 309 }, 310 { 311 .flags = ASN1_TFLG_ADB_OID, 312 .tag = -1, 313 .offset = 0, 314 .field_name = "X9_62_FIELDID", 315 .item = (const ASN1_ITEM *)&X9_62_FIELDID_adb, 316 }, 317}; 318 319static const ASN1_ITEM X9_62_FIELDID_it = { 320 .itype = ASN1_ITYPE_SEQUENCE, 321 .utype = V_ASN1_SEQUENCE, 322 .templates = X9_62_FIELDID_seq_tt, 323 .tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE), 324 .funcs = NULL, 325 .size = sizeof(X9_62_FIELDID), 326 .sname = "X9_62_FIELDID", 327}; 328 329static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = { 330 { 331 .flags = 0, 332 .tag = 0, 333 .offset = offsetof(X9_62_CURVE, a), 334 .field_name = "a", 335 .item = &ASN1_OCTET_STRING_it, 336 }, 337 { 338 .flags = 0, 339 .tag = 0, 340 .offset = offsetof(X9_62_CURVE, b), 341 .field_name = "b", 342 .item = &ASN1_OCTET_STRING_it, 343 }, 344 { 345 .flags = ASN1_TFLG_OPTIONAL, 346 .tag = 0, 347 .offset = offsetof(X9_62_CURVE, seed), 348 .field_name = "seed", 349 .item = &ASN1_BIT_STRING_it, 350 }, 351}; 352 353static const ASN1_ITEM X9_62_CURVE_it = { 354 .itype = ASN1_ITYPE_SEQUENCE, 355 .utype = V_ASN1_SEQUENCE, 356 .templates = X9_62_CURVE_seq_tt, 357 .tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE), 358 .funcs = NULL, 359 .size = sizeof(X9_62_CURVE), 360 .sname = "X9_62_CURVE", 361}; 362 363static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = { 364 { 365 .flags = 0, 366 .tag = 0, 367 .offset = offsetof(ECPARAMETERS, version), 368 .field_name = "version", 369 .item = &LONG_it, 370 }, 371 { 372 .flags = 0, 373 .tag = 0, 374 .offset = offsetof(ECPARAMETERS, fieldID), 375 .field_name = "fieldID", 376 .item = &X9_62_FIELDID_it, 377 }, 378 { 379 .flags = 0, 380 .tag = 0, 381 .offset = offsetof(ECPARAMETERS, curve), 382 .field_name = "curve", 383 .item = &X9_62_CURVE_it, 384 }, 385 { 386 .flags = 0, 387 .tag = 0, 388 .offset = offsetof(ECPARAMETERS, base), 389 .field_name = "base", 390 .item = &ASN1_OCTET_STRING_it, 391 }, 392 { 393 .flags = 0, 394 .tag = 0, 395 .offset = offsetof(ECPARAMETERS, order), 396 .field_name = "order", 397 .item = &ASN1_INTEGER_it, 398 }, 399 { 400 .flags = ASN1_TFLG_OPTIONAL, 401 .tag = 0, 402 .offset = offsetof(ECPARAMETERS, cofactor), 403 .field_name = "cofactor", 404 .item = &ASN1_INTEGER_it, 405 }, 406}; 407 408const ASN1_ITEM ECPARAMETERS_it = { 409 .itype = ASN1_ITYPE_SEQUENCE, 410 .utype = V_ASN1_SEQUENCE, 411 .templates = ECPARAMETERS_seq_tt, 412 .tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE), 413 .funcs = NULL, 414 .size = sizeof(ECPARAMETERS), 415 .sname = "ECPARAMETERS", 416}; 417 418static ECPARAMETERS * 419ECPARAMETERS_new(void) 420{ 421 return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it); 422} 423 424static void 425ECPARAMETERS_free(ECPARAMETERS *a) 426{ 427 ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it); 428} 429 430static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = { 431 { 432 .flags = 0, 433 .tag = 0, 434 .offset = offsetof(ECPKPARAMETERS, value.named_curve), 435 .field_name = "value.named_curve", 436 .item = &ASN1_OBJECT_it, 437 }, 438 { 439 .flags = 0, 440 .tag = 0, 441 .offset = offsetof(ECPKPARAMETERS, value.parameters), 442 .field_name = "value.parameters", 443 .item = &ECPARAMETERS_it, 444 }, 445 { 446 .flags = 0, 447 .tag = 0, 448 .offset = offsetof(ECPKPARAMETERS, value.implicitlyCA), 449 .field_name = "value.implicitlyCA", 450 .item = &ASN1_NULL_it, 451 }, 452}; 453 454const ASN1_ITEM ECPKPARAMETERS_it = { 455 .itype = ASN1_ITYPE_CHOICE, 456 .utype = offsetof(ECPKPARAMETERS, type), 457 .templates = ECPKPARAMETERS_ch_tt, 458 .tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE), 459 .funcs = NULL, 460 .size = sizeof(ECPKPARAMETERS), 461 .sname = "ECPKPARAMETERS", 462}; 463 464static ECPKPARAMETERS * 465d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len) 466{ 467 return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 468 &ECPKPARAMETERS_it); 469} 470 471static int 472i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out) 473{ 474 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it); 475} 476 477static ECPKPARAMETERS * 478ECPKPARAMETERS_new(void) 479{ 480 return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it); 481} 482 483static void 484ECPKPARAMETERS_free(ECPKPARAMETERS *a) 485{ 486 ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it); 487} 488 489static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = { 490 { 491 .flags = 0, 492 .tag = 0, 493 .offset = offsetof(EC_PRIVATEKEY, version), 494 .field_name = "version", 495 .item = &LONG_it, 496 }, 497 { 498 .flags = 0, 499 .tag = 0, 500 .offset = offsetof(EC_PRIVATEKEY, privateKey), 501 .field_name = "privateKey", 502 .item = &ASN1_OCTET_STRING_it, 503 }, 504 { 505 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, 506 .tag = 0, 507 .offset = offsetof(EC_PRIVATEKEY, parameters), 508 .field_name = "parameters", 509 .item = &ECPKPARAMETERS_it, 510 }, 511 { 512 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, 513 .tag = 1, 514 .offset = offsetof(EC_PRIVATEKEY, publicKey), 515 .field_name = "publicKey", 516 .item = &ASN1_BIT_STRING_it, 517 }, 518}; 519 520static const ASN1_ITEM EC_PRIVATEKEY_it = { 521 .itype = ASN1_ITYPE_SEQUENCE, 522 .utype = V_ASN1_SEQUENCE, 523 .templates = EC_PRIVATEKEY_seq_tt, 524 .tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE), 525 .funcs = NULL, 526 .size = sizeof(EC_PRIVATEKEY), 527 .sname = "EC_PRIVATEKEY", 528}; 529 530static EC_PRIVATEKEY * 531d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len) 532{ 533 return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 534 &EC_PRIVATEKEY_it); 535} 536 537static int 538i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out) 539{ 540 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it); 541} 542 543static EC_PRIVATEKEY * 544EC_PRIVATEKEY_new(void) 545{ 546 return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it); 547} 548 549static void 550EC_PRIVATEKEY_free(EC_PRIVATEKEY *a) 551{ 552 ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it); 553} 554 555static int 556ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) 557{ 558 int ok = 0, nid; 559 BIGNUM *tmp = NULL; 560 561 if (group == NULL || field == NULL) 562 return 0; 563 564 /* clear the old values (if necessary) */ 565 if (field->fieldType != NULL) 566 ASN1_OBJECT_free(field->fieldType); 567 if (field->p.other != NULL) 568 ASN1_TYPE_free(field->p.other); 569 570 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 571 /* set OID for the field */ 572 if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { 573 ECerror(ERR_R_OBJ_LIB); 574 goto err; 575 } 576 if (nid == NID_X9_62_prime_field) { 577 if ((tmp = BN_new()) == NULL) { 578 ECerror(ERR_R_MALLOC_FAILURE); 579 goto err; 580 } 581 /* the parameters are specified by the prime number p */ 582 if (!EC_GROUP_get_curve(group, tmp, NULL, NULL, NULL)) { 583 ECerror(ERR_R_EC_LIB); 584 goto err; 585 } 586 /* set the prime number */ 587 field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); 588 if (field->p.prime == NULL) { 589 ECerror(ERR_R_ASN1_LIB); 590 goto err; 591 } 592 } else { 593 ECerror(EC_R_GF2M_NOT_SUPPORTED); 594 goto err; 595 } 596 597 ok = 1; 598 599 err: 600 BN_free(tmp); 601 return (ok); 602} 603 604static int 605ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 606{ 607 BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; 608 unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL, 609 *b_buf = NULL; 610 size_t len_1, len_2; 611 unsigned char char_zero = 0; 612 int ok = 0; 613 614 if (!group || !curve || !curve->a || !curve->b) 615 return 0; 616 617 if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { 618 ECerror(ERR_R_MALLOC_FAILURE); 619 goto err; 620 } 621 622 /* get a and b */ 623 if (!EC_GROUP_get_curve(group, NULL, tmp_1, tmp_2, NULL)) { 624 ECerror(ERR_R_EC_LIB); 625 goto err; 626 } 627 len_1 = (size_t) BN_num_bytes(tmp_1); 628 len_2 = (size_t) BN_num_bytes(tmp_2); 629 630 if (len_1 == 0) { 631 /* len_1 == 0 => a == 0 */ 632 a_buf = &char_zero; 633 len_1 = 1; 634 } else { 635 if ((buffer_1 = malloc(len_1)) == NULL) { 636 ECerror(ERR_R_MALLOC_FAILURE); 637 goto err; 638 } 639 if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { 640 ECerror(ERR_R_BN_LIB); 641 goto err; 642 } 643 a_buf = buffer_1; 644 } 645 646 if (len_2 == 0) { 647 /* len_2 == 0 => b == 0 */ 648 b_buf = &char_zero; 649 len_2 = 1; 650 } else { 651 if ((buffer_2 = malloc(len_2)) == NULL) { 652 ECerror(ERR_R_MALLOC_FAILURE); 653 goto err; 654 } 655 if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { 656 ECerror(ERR_R_BN_LIB); 657 goto err; 658 } 659 b_buf = buffer_2; 660 } 661 662 /* set a and b */ 663 if (!ASN1_STRING_set(curve->a, a_buf, len_1) || 664 !ASN1_STRING_set(curve->b, b_buf, len_2)) { 665 ECerror(ERR_R_ASN1_LIB); 666 goto err; 667 } 668 669 ASN1_BIT_STRING_free(curve->seed); 670 curve->seed = NULL; 671 672 /* set the seed (optional) */ 673 if (group->seed != NULL) { 674 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { 675 ECerror(ERR_R_MALLOC_FAILURE); 676 goto err; 677 } 678 if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 679 (int) group->seed_len)) { 680 ECerror(ERR_R_ASN1_LIB); 681 goto err; 682 } 683 if (!asn1_abs_set_unused_bits(curve->seed, 0)) { 684 ECerror(ERR_R_ASN1_LIB); 685 goto err; 686 } 687 } 688 689 ok = 1; 690 691 err: 692 free(buffer_1); 693 free(buffer_2); 694 BN_free(tmp_1); 695 BN_free(tmp_2); 696 return (ok); 697} 698 699static ECPARAMETERS * 700ec_asn1_group2parameters(const EC_GROUP *group, ECPARAMETERS *param) 701{ 702 int ok = 0; 703 size_t len = 0; 704 ECPARAMETERS *ret = NULL; 705 BIGNUM *tmp = NULL; 706 unsigned char *buffer = NULL; 707 const EC_POINT *point = NULL; 708 point_conversion_form_t form; 709 710 if ((tmp = BN_new()) == NULL) { 711 ECerror(ERR_R_MALLOC_FAILURE); 712 goto err; 713 } 714 if (param == NULL) { 715 if ((ret = ECPARAMETERS_new()) == NULL) { 716 ECerror(ERR_R_MALLOC_FAILURE); 717 goto err; 718 } 719 } else 720 ret = param; 721 722 /* set the version (always one) */ 723 ret->version = (long) 0x1; 724 725 /* set the fieldID */ 726 if (!ec_asn1_group2fieldid(group, ret->fieldID)) { 727 ECerror(ERR_R_EC_LIB); 728 goto err; 729 } 730 /* set the curve */ 731 if (!ec_asn1_group2curve(group, ret->curve)) { 732 ECerror(ERR_R_EC_LIB); 733 goto err; 734 } 735 /* set the base point */ 736 if ((point = EC_GROUP_get0_generator(group)) == NULL) { 737 ECerror(EC_R_UNDEFINED_GENERATOR); 738 goto err; 739 } 740 form = EC_GROUP_get_point_conversion_form(group); 741 742 len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); 743 if (len == 0) { 744 ECerror(ERR_R_EC_LIB); 745 goto err; 746 } 747 if ((buffer = malloc(len)) == NULL) { 748 ECerror(ERR_R_MALLOC_FAILURE); 749 goto err; 750 } 751 if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { 752 ECerror(ERR_R_EC_LIB); 753 goto err; 754 } 755 if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { 756 ECerror(ERR_R_MALLOC_FAILURE); 757 goto err; 758 } 759 if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { 760 ECerror(ERR_R_ASN1_LIB); 761 goto err; 762 } 763 /* set the order */ 764 if (!EC_GROUP_get_order(group, tmp, NULL)) { 765 ECerror(ERR_R_EC_LIB); 766 goto err; 767 } 768 ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); 769 if (ret->order == NULL) { 770 ECerror(ERR_R_ASN1_LIB); 771 goto err; 772 } 773 /* set the cofactor (optional) */ 774 if (EC_GROUP_get_cofactor(group, tmp, NULL)) { 775 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); 776 if (ret->cofactor == NULL) { 777 ECerror(ERR_R_ASN1_LIB); 778 goto err; 779 } 780 } 781 ok = 1; 782 783 err: 784 if (!ok) { 785 if (ret && !param) 786 ECPARAMETERS_free(ret); 787 ret = NULL; 788 } 789 BN_free(tmp); 790 free(buffer); 791 return (ret); 792} 793 794ECPKPARAMETERS * 795ec_asn1_group2pkparameters(const EC_GROUP *group, ECPKPARAMETERS *params) 796{ 797 int ok = 1, tmp; 798 ECPKPARAMETERS *ret = params; 799 800 if (ret == NULL) { 801 if ((ret = ECPKPARAMETERS_new()) == NULL) { 802 ECerror(ERR_R_MALLOC_FAILURE); 803 return NULL; 804 } 805 } else { 806 if (ret->type == 0 && ret->value.named_curve) 807 ASN1_OBJECT_free(ret->value.named_curve); 808 else if (ret->type == 1 && ret->value.parameters) 809 ECPARAMETERS_free(ret->value.parameters); 810 } 811 812 if (EC_GROUP_get_asn1_flag(group)) { 813 /* 814 * use the asn1 OID to describe the elliptic curve 815 * parameters 816 */ 817 tmp = EC_GROUP_get_curve_name(group); 818 if (tmp) { 819 ret->type = 0; 820 if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) 821 ok = 0; 822 } else 823 /* we don't know the group => ERROR */ 824 ok = 0; 825 } else { 826 /* use the ECPARAMETERS structure */ 827 ret->type = 1; 828 if ((ret->value.parameters = ec_asn1_group2parameters(group, 829 NULL)) == NULL) 830 ok = 0; 831 } 832 833 if (!ok) { 834 ECPKPARAMETERS_free(ret); 835 return NULL; 836 } 837 return ret; 838} 839 840static EC_GROUP * 841ec_asn1_parameters2group(const ECPARAMETERS *params) 842{ 843 int ok = 0, tmp; 844 EC_GROUP *ret = NULL; 845 BIGNUM *p = NULL, *a = NULL, *b = NULL; 846 EC_POINT *point = NULL; 847 long field_bits; 848 849 if (!params->fieldID || !params->fieldID->fieldType || 850 !params->fieldID->p.ptr) { 851 ECerror(EC_R_ASN1_ERROR); 852 goto err; 853 } 854 /* now extract the curve parameters a and b */ 855 if (!params->curve || !params->curve->a || 856 !params->curve->a->data || !params->curve->b || 857 !params->curve->b->data) { 858 ECerror(EC_R_ASN1_ERROR); 859 goto err; 860 } 861 a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); 862 if (a == NULL) { 863 ECerror(ERR_R_BN_LIB); 864 goto err; 865 } 866 b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); 867 if (b == NULL) { 868 ECerror(ERR_R_BN_LIB); 869 goto err; 870 } 871 /* get the field parameters */ 872 tmp = OBJ_obj2nid(params->fieldID->fieldType); 873 if (tmp == NID_X9_62_characteristic_two_field) { 874 ECerror(EC_R_GF2M_NOT_SUPPORTED); 875 goto err; 876 } else if (tmp == NID_X9_62_prime_field) { 877 /* we have a curve over a prime field */ 878 /* extract the prime number */ 879 if (!params->fieldID->p.prime) { 880 ECerror(EC_R_ASN1_ERROR); 881 goto err; 882 } 883 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); 884 if (p == NULL) { 885 ECerror(ERR_R_ASN1_LIB); 886 goto err; 887 } 888 if (BN_is_negative(p) || BN_is_zero(p)) { 889 ECerror(EC_R_INVALID_FIELD); 890 goto err; 891 } 892 field_bits = BN_num_bits(p); 893 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 894 ECerror(EC_R_FIELD_TOO_LARGE); 895 goto err; 896 } 897 /* create the EC_GROUP structure */ 898 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); 899 } else { 900 ECerror(EC_R_INVALID_FIELD); 901 goto err; 902 } 903 904 if (ret == NULL) { 905 ECerror(ERR_R_EC_LIB); 906 goto err; 907 } 908 /* extract seed (optional) */ 909 if (params->curve->seed != NULL) { 910 free(ret->seed); 911 if (!(ret->seed = malloc(params->curve->seed->length))) { 912 ECerror(ERR_R_MALLOC_FAILURE); 913 goto err; 914 } 915 memcpy(ret->seed, params->curve->seed->data, 916 params->curve->seed->length); 917 ret->seed_len = params->curve->seed->length; 918 } 919 if (!params->order || !params->base || !params->base->data) { 920 ECerror(EC_R_ASN1_ERROR); 921 goto err; 922 } 923 if ((point = EC_POINT_new(ret)) == NULL) 924 goto err; 925 926 /* set the point conversion form */ 927 EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) 928 (params->base->data[0] & ~0x01)); 929 930 /* extract the ec point */ 931 if (!EC_POINT_oct2point(ret, point, params->base->data, 932 params->base->length, NULL)) { 933 ECerror(ERR_R_EC_LIB); 934 goto err; 935 } 936 /* extract the order */ 937 if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { 938 ECerror(ERR_R_ASN1_LIB); 939 goto err; 940 } 941 if (BN_is_negative(a) || BN_is_zero(a)) { 942 ECerror(EC_R_INVALID_GROUP_ORDER); 943 goto err; 944 } 945 if (BN_num_bits(a) > (int) field_bits + 1) { /* Hasse bound */ 946 ECerror(EC_R_INVALID_GROUP_ORDER); 947 goto err; 948 } 949 /* extract the cofactor (optional) */ 950 if (params->cofactor == NULL) { 951 BN_free(b); 952 b = NULL; 953 } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { 954 ECerror(ERR_R_ASN1_LIB); 955 goto err; 956 } 957 /* set the generator, order and cofactor (if present) */ 958 if (!EC_GROUP_set_generator(ret, point, a, b)) { 959 ECerror(ERR_R_EC_LIB); 960 goto err; 961 } 962 ok = 1; 963 964 err: 965 if (!ok) { 966 EC_GROUP_free(ret); 967 ret = NULL; 968 } 969 BN_free(p); 970 BN_free(a); 971 BN_free(b); 972 EC_POINT_free(point); 973 return (ret); 974} 975 976EC_GROUP * 977ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) 978{ 979 EC_GROUP *ret = NULL; 980 int tmp = 0; 981 982 if (params == NULL) { 983 ECerror(EC_R_MISSING_PARAMETERS); 984 return NULL; 985 } 986 if (params->type == 0) {/* the curve is given by an OID */ 987 tmp = OBJ_obj2nid(params->value.named_curve); 988 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { 989 ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 990 return NULL; 991 } 992 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); 993 } else if (params->type == 1) { /* the parameters are given by a 994 * ECPARAMETERS structure */ 995 ret = ec_asn1_parameters2group(params->value.parameters); 996 if (!ret) { 997 ECerror(ERR_R_EC_LIB); 998 return NULL; 999 } 1000 EC_GROUP_set_asn1_flag(ret, 0x0); 1001 } else if (params->type == 2) { /* implicitlyCA */ 1002 return NULL; 1003 } else { 1004 ECerror(EC_R_ASN1_ERROR); 1005 return NULL; 1006 } 1007 1008 return ret; 1009} 1010 1011EC_GROUP * 1012d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) 1013{ 1014 EC_GROUP *group = NULL; 1015 ECPKPARAMETERS *params; 1016 1017 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) { 1018 ECerror(EC_R_D2I_ECPKPARAMETERS_FAILURE); 1019 goto err; 1020 } 1021 if ((group = ec_asn1_pkparameters2group(params)) == NULL) { 1022 ECerror(EC_R_PKPARAMETERS2GROUP_FAILURE); 1023 goto err; 1024 } 1025 1026 if (a != NULL) { 1027 EC_GROUP_free(*a); 1028 *a = group; 1029 } 1030 1031 err: 1032 ECPKPARAMETERS_free(params); 1033 return (group); 1034} 1035LCRYPTO_ALIAS(d2i_ECPKParameters); 1036 1037int 1038i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) 1039{ 1040 int ret = 0; 1041 ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); 1042 if (tmp == NULL) { 1043 ECerror(EC_R_GROUP2PKPARAMETERS_FAILURE); 1044 return 0; 1045 } 1046 if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { 1047 ECerror(EC_R_I2D_ECPKPARAMETERS_FAILURE); 1048 ECPKPARAMETERS_free(tmp); 1049 return 0; 1050 } 1051 ECPKPARAMETERS_free(tmp); 1052 return (ret); 1053} 1054LCRYPTO_ALIAS(i2d_ECPKParameters); 1055 1056EC_KEY * 1057d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) 1058{ 1059 EC_KEY *ret = NULL; 1060 EC_PRIVATEKEY *priv_key = NULL; 1061 1062 if ((priv_key = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) { 1063 ECerror(ERR_R_EC_LIB); 1064 return NULL; 1065 } 1066 if (a == NULL || *a == NULL) { 1067 if ((ret = EC_KEY_new()) == NULL) { 1068 ECerror(ERR_R_MALLOC_FAILURE); 1069 goto err; 1070 } 1071 } else 1072 ret = *a; 1073 1074 if (priv_key->parameters) { 1075 EC_GROUP_free(ret->group); 1076 ret->group = ec_asn1_pkparameters2group(priv_key->parameters); 1077 } 1078 if (ret->group == NULL) { 1079 ECerror(ERR_R_EC_LIB); 1080 goto err; 1081 } 1082 ret->version = priv_key->version; 1083 1084 if (priv_key->privateKey) { 1085 ret->priv_key = BN_bin2bn( 1086 ASN1_STRING_data(priv_key->privateKey), 1087 ASN1_STRING_length(priv_key->privateKey), 1088 ret->priv_key); 1089 if (ret->priv_key == NULL) { 1090 ECerror(ERR_R_BN_LIB); 1091 goto err; 1092 } 1093 } else { 1094 ECerror(EC_R_MISSING_PRIVATE_KEY); 1095 goto err; 1096 } 1097 1098 if (ret->pub_key) 1099 EC_POINT_free(ret->pub_key); 1100 ret->pub_key = EC_POINT_new(ret->group); 1101 if (ret->pub_key == NULL) { 1102 ECerror(ERR_R_EC_LIB); 1103 goto err; 1104 } 1105 1106 if (priv_key->publicKey) { 1107 const unsigned char *pub_oct; 1108 size_t pub_oct_len; 1109 1110 pub_oct = ASN1_STRING_data(priv_key->publicKey); 1111 pub_oct_len = ASN1_STRING_length(priv_key->publicKey); 1112 if (pub_oct == NULL || pub_oct_len <= 0) { 1113 ECerror(EC_R_BUFFER_TOO_SMALL); 1114 goto err; 1115 } 1116 1117 /* save the point conversion form */ 1118 ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); 1119 if (!EC_POINT_oct2point(ret->group, ret->pub_key, 1120 pub_oct, pub_oct_len, NULL)) { 1121 ECerror(ERR_R_EC_LIB); 1122 goto err; 1123 } 1124 } else { 1125 if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, 1126 NULL, NULL, NULL)) { 1127 ECerror(ERR_R_EC_LIB); 1128 goto err; 1129 } 1130 /* Remember the original private-key-only encoding. */ 1131 ret->enc_flag |= EC_PKEY_NO_PUBKEY; 1132 } 1133 1134 EC_PRIVATEKEY_free(priv_key); 1135 if (a != NULL) 1136 *a = ret; 1137 return (ret); 1138 1139 err: 1140 if (a == NULL || *a != ret) 1141 EC_KEY_free(ret); 1142 if (priv_key) 1143 EC_PRIVATEKEY_free(priv_key); 1144 1145 return (NULL); 1146} 1147LCRYPTO_ALIAS(d2i_ECPrivateKey); 1148 1149int 1150i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) 1151{ 1152 int ret = 0, ok = 0; 1153 unsigned char *buffer = NULL; 1154 size_t buf_len = 0, tmp_len; 1155 EC_PRIVATEKEY *priv_key = NULL; 1156 1157 if (a == NULL || a->group == NULL || a->priv_key == NULL || 1158 (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { 1159 ECerror(ERR_R_PASSED_NULL_PARAMETER); 1160 goto err; 1161 } 1162 if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { 1163 ECerror(ERR_R_MALLOC_FAILURE); 1164 goto err; 1165 } 1166 priv_key->version = a->version; 1167 1168 buf_len = (size_t) BN_num_bytes(a->priv_key); 1169 buffer = malloc(buf_len); 1170 if (buffer == NULL) { 1171 ECerror(ERR_R_MALLOC_FAILURE); 1172 goto err; 1173 } 1174 if (!BN_bn2bin(a->priv_key, buffer)) { 1175 ECerror(ERR_R_BN_LIB); 1176 goto err; 1177 } 1178 if (!ASN1_STRING_set(priv_key->privateKey, buffer, buf_len)) { 1179 ECerror(ERR_R_ASN1_LIB); 1180 goto err; 1181 } 1182 if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { 1183 if ((priv_key->parameters = ec_asn1_group2pkparameters( 1184 a->group, priv_key->parameters)) == NULL) { 1185 ECerror(ERR_R_EC_LIB); 1186 goto err; 1187 } 1188 } 1189 if (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key != NULL) { 1190 priv_key->publicKey = ASN1_BIT_STRING_new(); 1191 if (priv_key->publicKey == NULL) { 1192 ECerror(ERR_R_MALLOC_FAILURE); 1193 goto err; 1194 } 1195 tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 1196 a->conv_form, NULL, 0, NULL); 1197 1198 if (tmp_len > buf_len) { 1199 unsigned char *tmp_buffer = realloc(buffer, tmp_len); 1200 if (!tmp_buffer) { 1201 ECerror(ERR_R_MALLOC_FAILURE); 1202 goto err; 1203 } 1204 buffer = tmp_buffer; 1205 buf_len = tmp_len; 1206 } 1207 if (!EC_POINT_point2oct(a->group, a->pub_key, 1208 a->conv_form, buffer, buf_len, NULL)) { 1209 ECerror(ERR_R_EC_LIB); 1210 goto err; 1211 } 1212 if (!ASN1_STRING_set(priv_key->publicKey, buffer, buf_len)) { 1213 ECerror(ERR_R_ASN1_LIB); 1214 goto err; 1215 } 1216 if (!asn1_abs_set_unused_bits(priv_key->publicKey, 0)) { 1217 ECerror(ERR_R_ASN1_LIB); 1218 goto err; 1219 } 1220 } 1221 if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { 1222 ECerror(ERR_R_EC_LIB); 1223 goto err; 1224 } 1225 ok = 1; 1226 err: 1227 free(buffer); 1228 if (priv_key) 1229 EC_PRIVATEKEY_free(priv_key); 1230 return (ok ? ret : 0); 1231} 1232LCRYPTO_ALIAS(i2d_ECPrivateKey); 1233 1234int 1235i2d_ECParameters(EC_KEY *a, unsigned char **out) 1236{ 1237 if (a == NULL) { 1238 ECerror(ERR_R_PASSED_NULL_PARAMETER); 1239 return 0; 1240 } 1241 return i2d_ECPKParameters(a->group, out); 1242} 1243LCRYPTO_ALIAS(i2d_ECParameters); 1244 1245EC_KEY * 1246d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) 1247{ 1248 EC_KEY *ret; 1249 1250 if (in == NULL || *in == NULL) { 1251 ECerror(ERR_R_PASSED_NULL_PARAMETER); 1252 return NULL; 1253 } 1254 if (a == NULL || *a == NULL) { 1255 if ((ret = EC_KEY_new()) == NULL) { 1256 ECerror(ERR_R_MALLOC_FAILURE); 1257 return NULL; 1258 } 1259 } else 1260 ret = *a; 1261 1262 if (!d2i_ECPKParameters(&ret->group, in, len)) { 1263 ECerror(ERR_R_EC_LIB); 1264 if (a == NULL || *a != ret) 1265 EC_KEY_free(ret); 1266 return NULL; 1267 } 1268 1269 if (a != NULL) 1270 *a = ret; 1271 return ret; 1272} 1273LCRYPTO_ALIAS(d2i_ECParameters); 1274 1275EC_KEY * 1276o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) 1277{ 1278 EC_KEY *ret = NULL; 1279 1280 if (a == NULL || (*a) == NULL || (*a)->group == NULL) { 1281 /* An EC_GROUP structure is necessary to set the public key. */ 1282 ECerror(ERR_R_PASSED_NULL_PARAMETER); 1283 return 0; 1284 } 1285 ret = *a; 1286 if (ret->pub_key == NULL && 1287 (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { 1288 ECerror(ERR_R_MALLOC_FAILURE); 1289 return 0; 1290 } 1291 if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { 1292 ECerror(ERR_R_EC_LIB); 1293 return 0; 1294 } 1295 /* save the point conversion form */ 1296 ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); 1297 *in += len; 1298 return ret; 1299} 1300LCRYPTO_ALIAS(o2i_ECPublicKey); 1301 1302int 1303i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) 1304{ 1305 size_t buf_len = 0; 1306 int new_buffer = 0; 1307 1308 if (a == NULL) { 1309 ECerror(ERR_R_PASSED_NULL_PARAMETER); 1310 return 0; 1311 } 1312 buf_len = EC_POINT_point2oct(a->group, a->pub_key, 1313 a->conv_form, NULL, 0, NULL); 1314 1315 if (out == NULL || buf_len == 0) 1316 /* out == NULL => just return the length of the octet string */ 1317 return buf_len; 1318 1319 if (*out == NULL) { 1320 if ((*out = malloc(buf_len)) == NULL) { 1321 ECerror(ERR_R_MALLOC_FAILURE); 1322 return 0; 1323 } 1324 new_buffer = 1; 1325 } 1326 if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, 1327 *out, buf_len, NULL)) { 1328 ECerror(ERR_R_EC_LIB); 1329 if (new_buffer) { 1330 free(*out); 1331 *out = NULL; 1332 } 1333 return 0; 1334 } 1335 if (!new_buffer) 1336 *out += buf_len; 1337 return buf_len; 1338} 1339LCRYPTO_ALIAS(i2o_ECPublicKey); 1340