1 /* $OpenBSD: gostr341001_ameth.c,v 1.8 2015/02/11 04:05:14 beck Exp $ */ 2 /* 3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 4 * Copyright (c) 2005-2006 Cryptocom LTD 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * 3. All advertising materials mentioning features or use of this 19 * software must display the following acknowledgment: 20 * "This product includes software developed by the OpenSSL Project 21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 22 * 23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 24 * endorse or promote products derived from this software without 25 * prior written permission. For written permission, please contact 26 * openssl-core@openssl.org. 27 * 28 * 5. Products derived from this software may not be called "OpenSSL" 29 * nor may "OpenSSL" appear in their names without prior written 30 * permission of the OpenSSL Project. 31 * 32 * 6. Redistributions of any form whatsoever must retain the following 33 * acknowledgment: 34 * "This product includes software developed by the OpenSSL Project 35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 48 * OF THE POSSIBILITY OF SUCH DAMAGE. 49 * ==================================================================== 50 */ 51 52 #include <string.h> 53 54 #include <openssl/opensslconf.h> 55 56 #ifndef OPENSSL_NO_GOST 57 #include <openssl/bn.h> 58 #include <openssl/evp.h> 59 #include <openssl/ec.h> 60 #include <openssl/err.h> 61 #include <openssl/x509.h> 62 #include <openssl/gost.h> 63 64 #ifndef OPENSSL_NO_CMS 65 #include <openssl/cms.h> 66 #endif 67 68 #include "asn1_locl.h" 69 #include "gost_locl.h" 70 #include "gost_asn1.h" 71 72 static void 73 pkey_free_gost01(EVP_PKEY *key) 74 { 75 GOST_KEY_free(key->pkey.gost); 76 } 77 78 /* 79 * Parses GOST algorithm parameters from X509_ALGOR and 80 * modifies pkey setting NID and parameters 81 */ 82 static int 83 decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len) 84 { 85 int param_nid = NID_undef, digest_nid = NID_undef; 86 GOST_KEY_PARAMS *gkp = NULL; 87 EC_GROUP *group; 88 GOST_KEY *ec; 89 90 gkp = d2i_GOST_KEY_PARAMS(NULL, p, len); 91 if (gkp == NULL) { 92 GOSTerr(GOST_F_DECODE_GOST01_ALGOR_PARAMS, 93 GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 94 return 0; 95 } 96 param_nid = OBJ_obj2nid(gkp->key_params); 97 digest_nid = OBJ_obj2nid(gkp->hash_params); 98 GOST_KEY_PARAMS_free(gkp); 99 100 ec = pkey->pkey.gost; 101 if (ec == NULL) { 102 ec = GOST_KEY_new(); 103 if (ec == NULL) 104 return 0; 105 if (EVP_PKEY_assign_GOST(pkey, ec) == 0) 106 return 0; 107 } 108 109 group = EC_GROUP_new_by_curve_name(param_nid); 110 if (group == NULL) 111 return 0; 112 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 113 if (GOST_KEY_set_group(ec, group) == 0) { 114 EC_GROUP_free(group); 115 return 0; 116 } 117 EC_GROUP_free(group); 118 if (GOST_KEY_set_digest(ec, digest_nid) == 0) 119 return 0; 120 return 1; 121 } 122 123 static ASN1_STRING * 124 encode_gost01_algor_params(const EVP_PKEY *key) 125 { 126 ASN1_STRING *params = ASN1_STRING_new(); 127 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 128 int pkey_param_nid = NID_undef; 129 130 if (params == NULL || gkp == NULL) { 131 GOSTerr(GOST_F_ENCODE_GOST01_ALGOR_PARAMS, 132 ERR_R_MALLOC_FAILURE); 133 ASN1_STRING_free(params); 134 params = NULL; 135 goto err; 136 } 137 138 pkey_param_nid = 139 EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost)); 140 gkp->key_params = OBJ_nid2obj(pkey_param_nid); 141 gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost)); 142 /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */ 143 params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 144 if (params->length <= 0) { 145 GOSTerr(GOST_F_ENCODE_GOST01_ALGOR_PARAMS, 146 ERR_R_MALLOC_FAILURE); 147 ASN1_STRING_free(params); 148 params = NULL; 149 goto err; 150 } 151 params->type = V_ASN1_SEQUENCE; 152 err: 153 GOST_KEY_PARAMS_free(gkp); 154 return params; 155 } 156 157 static int 158 pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 159 { 160 const GOST_KEY *ea = a->pkey.gost; 161 const GOST_KEY *eb = b->pkey.gost; 162 const EC_POINT *ka, *kb; 163 int ret = 0; 164 165 if (ea == NULL || eb == NULL) 166 return 0; 167 ka = GOST_KEY_get0_public_key(ea); 168 kb = GOST_KEY_get0_public_key(eb); 169 if (ka == NULL || kb == NULL) 170 return 0; 171 ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL)); 172 return ret; 173 } 174 175 static int 176 pkey_size_gost01(const EVP_PKEY *pk) 177 { 178 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) 179 return 128; 180 return 64; 181 } 182 183 static int 184 pkey_bits_gost01(const EVP_PKEY *pk) 185 { 186 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) 187 return 512; 188 return 256; 189 } 190 191 static int 192 pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 193 { 194 X509_ALGOR *palg = NULL; 195 const unsigned char *pubkey_buf = NULL; 196 const unsigned char *p; 197 ASN1_OBJECT *palgobj = NULL; 198 int pub_len; 199 BIGNUM *X, *Y; 200 ASN1_OCTET_STRING *octet = NULL; 201 int len; 202 int ret; 203 int ptype = V_ASN1_UNDEF; 204 ASN1_STRING *pval = NULL; 205 206 if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub) 207 == 0) 208 return 0; 209 (void)EVP_PKEY_assign_GOST(pk, NULL); 210 X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg); 211 if (ptype != V_ASN1_SEQUENCE) { 212 GOSTerr(GOST_F_PUB_DECODE_GOST01, 213 GOST_R_BAD_KEY_PARAMETERS_FORMAT); 214 return 0; 215 } 216 p = pval->data; 217 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) 218 return 0; 219 220 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 221 if (octet == NULL) { 222 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 223 return 0; 224 } 225 len = octet->length / 2; 226 227 X = GOST_le2bn(octet->data, len, NULL); 228 Y = GOST_le2bn(octet->data + len, len, NULL); 229 230 ASN1_OCTET_STRING_free(octet); 231 232 ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); 233 if (ret == 0) 234 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 235 236 BN_free(X); 237 BN_free(Y); 238 239 return ret; 240 } 241 242 static int 243 pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 244 { 245 ASN1_OBJECT *algobj = NULL; 246 ASN1_OCTET_STRING *octet = NULL; 247 ASN1_STRING *params = NULL; 248 void *pval = NULL; 249 unsigned char *buf = NULL, *sptr; 250 int key_size, ret = 0; 251 const EC_POINT *pub_key; 252 BIGNUM *X = NULL, *Y = NULL; 253 const GOST_KEY *ec = pk->pkey.gost; 254 int ptype = V_ASN1_UNDEF; 255 256 algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); 257 if (pk->save_parameters) { 258 params = encode_gost01_algor_params(pk); 259 if (params == NULL) 260 return 0; 261 pval = params; 262 ptype = V_ASN1_SEQUENCE; 263 } 264 265 key_size = GOST_KEY_get_size(ec); 266 267 pub_key = GOST_KEY_get0_public_key(ec); 268 if (pub_key == NULL) { 269 GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); 270 goto err; 271 } 272 273 octet = ASN1_OCTET_STRING_new(); 274 if (octet == NULL) { 275 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 276 goto err; 277 } 278 279 ret = ASN1_STRING_set(octet, NULL, 2 * key_size); 280 if (ret == 0) { 281 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); 282 goto err; 283 } 284 285 sptr = ASN1_STRING_data(octet); 286 287 X = BN_new(); 288 Y = BN_new(); 289 if (X == NULL || Y == NULL) { 290 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 291 goto err; 292 } 293 294 if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), 295 pub_key, X, Y, NULL) == 0) { 296 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); 297 goto err; 298 } 299 300 GOST_bn2le(X, sptr, key_size); 301 GOST_bn2le(Y, sptr + key_size, key_size); 302 303 BN_free(Y); 304 BN_free(X); 305 306 ret = i2d_ASN1_OCTET_STRING(octet, &buf); 307 ASN1_BIT_STRING_free(octet); 308 if (ret < 0) 309 return 0; 310 311 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 312 313 err: 314 BN_free(Y); 315 BN_free(X); 316 ASN1_BIT_STRING_free(octet); 317 ASN1_STRING_free(params); 318 return 0; 319 } 320 321 static int 322 param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) 323 { 324 int param_nid = 325 EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); 326 327 if (BIO_indent(out, indent, 128) == 0) 328 return 0; 329 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 330 if (BIO_indent(out, indent, 128) == 0) 331 return 0; 332 BIO_printf(out, "Digest Algorithm: %s\n", 333 OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); 334 return 1; 335 } 336 337 static int 338 pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) 339 { 340 BN_CTX *ctx = BN_CTX_new(); 341 BIGNUM *X, *Y; 342 const EC_POINT *pubkey; 343 const EC_GROUP *group; 344 345 if (ctx == NULL) { 346 GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE); 347 return 0; 348 } 349 BN_CTX_start(ctx); 350 if ((X = BN_CTX_get(ctx)) == NULL) 351 goto err; 352 if ((Y = BN_CTX_get(ctx)) == NULL) 353 goto err; 354 pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); 355 group = GOST_KEY_get0_group(pkey->pkey.gost); 356 if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, 357 ctx) == 0) { 358 GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB); 359 goto err; 360 } 361 if (BIO_indent(out, indent, 128) == 0) 362 goto err; 363 BIO_printf(out, "Public key:\n"); 364 if (BIO_indent(out, indent + 3, 128) == 0) 365 goto err; 366 BIO_printf(out, "X:"); 367 BN_print(out, X); 368 BIO_printf(out, "\n"); 369 BIO_indent(out, indent + 3, 128); 370 BIO_printf(out, "Y:"); 371 BN_print(out, Y); 372 BIO_printf(out, "\n"); 373 374 BN_CTX_end(ctx); 375 BN_CTX_free(ctx); 376 377 return param_print_gost01(out, pkey, indent, pctx); 378 379 err: 380 BN_CTX_end(ctx); 381 BN_CTX_free(ctx); 382 return 0; 383 } 384 385 static int 386 priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) 387 { 388 const BIGNUM *key; 389 390 if (BIO_indent(out, indent, 128) == 0) 391 return 0; 392 BIO_printf(out, "Private key: "); 393 key = GOST_KEY_get0_private_key(pkey->pkey.gost); 394 if (key == NULL) 395 BIO_printf(out, "<undefined)"); 396 else 397 BN_print(out, key); 398 BIO_printf(out, "\n"); 399 400 return pub_print_gost01(out, pkey, indent, pctx); 401 } 402 403 static int 404 priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 405 { 406 const unsigned char *pkey_buf = NULL, *p = NULL; 407 int priv_len = 0; 408 BIGNUM *pk_num = NULL; 409 int ret = 0; 410 X509_ALGOR *palg = NULL; 411 ASN1_OBJECT *palg_obj = NULL; 412 ASN1_INTEGER *priv_key = NULL; 413 GOST_KEY *ec; 414 int ptype = V_ASN1_UNDEF; 415 ASN1_STRING *pval = NULL; 416 417 if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) 418 return 0; 419 (void)EVP_PKEY_assign_GOST(pk, NULL); 420 X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg); 421 if (ptype != V_ASN1_SEQUENCE) { 422 GOSTerr(GOST_F_PUB_DECODE_GOST01, 423 GOST_R_BAD_KEY_PARAMETERS_FORMAT); 424 return 0; 425 } 426 p = pval->data; 427 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) 428 return 0; 429 p = pkey_buf; 430 if (V_ASN1_OCTET_STRING == *p) { 431 /* New format - Little endian octet string */ 432 unsigned char rev_buf[32]; 433 int i; 434 ASN1_OCTET_STRING *s = 435 d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 436 437 if (s == NULL || s->length != 32) { 438 GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); 439 ASN1_STRING_free(s); 440 return 0; 441 } 442 for (i = 0; i < 32; i++) { 443 rev_buf[31 - i] = s->data[i]; 444 } 445 ASN1_STRING_free(s); 446 pk_num = BN_bin2bn(rev_buf, 32, NULL); 447 } else { 448 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 449 if (priv_key == NULL) 450 return 0; 451 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 452 ASN1_INTEGER_free(priv_key); 453 if (ret == 0) { 454 GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); 455 return 0; 456 } 457 } 458 459 ec = pk->pkey.gost; 460 if (ec == NULL) { 461 ec = GOST_KEY_new(); 462 if (ec == NULL) { 463 BN_free(pk_num); 464 return 0; 465 } 466 if (EVP_PKEY_assign_GOST(pk, ec) == 0) { 467 BN_free(pk_num); 468 GOST_KEY_free(ec); 469 return 0; 470 } 471 } 472 if (GOST_KEY_set_private_key(ec, pk_num) == 0) { 473 BN_free(pk_num); 474 return 0; 475 } 476 ret = 0; 477 if (EVP_PKEY_missing_parameters(pk) == 0) 478 ret = gost2001_compute_public(ec) != 0; 479 BN_free(pk_num); 480 481 return ret; 482 } 483 484 static int 485 priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 486 { 487 ASN1_OBJECT *algobj = 488 OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); 489 ASN1_STRING *params = encode_gost01_algor_params(pk); 490 unsigned char *priv_buf = NULL; 491 int priv_len; 492 ASN1_INTEGER *asn1key = NULL; 493 494 if (params == NULL) 495 return 0; 496 497 asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), 498 NULL); 499 if (asn1key == NULL) { 500 ASN1_STRING_free(params); 501 return 0; 502 } 503 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 504 ASN1_INTEGER_free(asn1key); 505 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, 506 priv_len); 507 } 508 509 static int 510 param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) 511 { 512 ASN1_STRING *params = encode_gost01_algor_params(pkey); 513 int len; 514 515 if (params == NULL) 516 return 0; 517 len = params->length; 518 if (pder != NULL) 519 memcpy(*pder, params->data, params->length); 520 ASN1_STRING_free(params); 521 return len; 522 } 523 524 static int 525 param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 526 { 527 ASN1_OBJECT *obj = NULL; 528 int nid; 529 GOST_KEY *ec; 530 EC_GROUP *group; 531 int ret; 532 533 /* New format */ 534 if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) 535 return decode_gost01_algor_params(pkey, pder, derlen); 536 537 /* Compatibility */ 538 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 539 GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 540 return 0; 541 } 542 nid = OBJ_obj2nid(obj); 543 ASN1_OBJECT_free(obj); 544 545 ec = GOST_KEY_new(); 546 if (ec == NULL) { 547 GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 548 return 0; 549 } 550 group = EC_GROUP_new_by_curve_name(nid); 551 if (group == NULL) { 552 GOSTerr(GOST_F_PARAM_DECODE_GOST01, 553 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 554 GOST_KEY_free(ec); 555 return 0; 556 } 557 558 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 559 if (GOST_KEY_set_group(ec, group) == 0) { 560 GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_EC_LIB); 561 EC_GROUP_free(group); 562 GOST_KEY_free(ec); 563 return 0; 564 } 565 EC_GROUP_free(group); 566 if (GOST_KEY_set_digest(ec, 567 NID_id_GostR3411_94_CryptoProParamSet) == 0) { 568 GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE); 569 GOST_KEY_free(ec); 570 return 0; 571 } 572 ret = EVP_PKEY_assign_GOST(pkey, ec); 573 if (ret == 0) 574 GOST_KEY_free(ec); 575 return ret; 576 } 577 578 static int 579 param_missing_gost01(const EVP_PKEY *pk) 580 { 581 const GOST_KEY *ec = pk->pkey.gost; 582 583 if (ec == NULL) 584 return 1; 585 if (GOST_KEY_get0_group(ec) == NULL) 586 return 1; 587 if (GOST_KEY_get_digest(ec) == NID_undef) 588 return 1; 589 return 0; 590 } 591 592 static int 593 param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 594 { 595 GOST_KEY *eto = to->pkey.gost; 596 const GOST_KEY *efrom = from->pkey.gost; 597 int ret = 1; 598 599 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 600 GOSTerr(GOST_F_PARAM_COPY_GOST01, 601 GOST_R_INCOMPATIBLE_ALGORITHMS); 602 return 0; 603 } 604 if (efrom == NULL) { 605 GOSTerr(GOST_F_PARAM_COPY_GOST01, 606 GOST_R_KEY_PARAMETERS_MISSING); 607 return 0; 608 } 609 if (eto == NULL) { 610 eto = GOST_KEY_new(); 611 if (eto == NULL) { 612 GOSTerr(GOST_F_PARAM_COPY_GOST01, 613 ERR_R_MALLOC_FAILURE); 614 return 0; 615 } 616 if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { 617 GOST_KEY_free(eto); 618 return 0; 619 } 620 } 621 GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); 622 GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); 623 if (GOST_KEY_get0_private_key(eto) != NULL) 624 ret = gost2001_compute_public(eto); 625 626 return ret; 627 } 628 629 static int 630 param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 631 { 632 if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != 633 EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) 634 return 0; 635 636 if (GOST_KEY_get_digest(a->pkey.gost) != 637 GOST_KEY_get_digest(b->pkey.gost)) 638 return 0; 639 640 return 1; 641 } 642 643 static int 644 pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) 645 { 646 X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; 647 int digest = GOST_KEY_get_digest(pkey->pkey.gost); 648 649 switch (op) { 650 case ASN1_PKEY_CTRL_PKCS7_SIGN: 651 if (arg1 == 0) 652 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 653 break; 654 655 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 656 if (arg1 == 0) 657 PKCS7_RECIP_INFO_get0_alg(arg2, &alg3); 658 break; 659 #ifndef OPENSSL_NO_CMS 660 case ASN1_PKEY_CTRL_CMS_SIGN: 661 if (arg1 == 0) 662 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 663 break; 664 665 case ASN1_PKEY_CTRL_CMS_ENVELOPE: 666 if (arg1 == 0) 667 CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg3); 668 break; 669 #endif 670 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 671 *(int *)arg2 = GostR3410_get_md_digest(digest); 672 return 2; 673 674 default: 675 return -2; 676 } 677 678 if (alg1) 679 X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0); 680 if (alg2) 681 X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0); 682 if (alg3) { 683 ASN1_STRING *params = encode_gost01_algor_params(pkey); 684 if (params == NULL) { 685 return -1; 686 } 687 X509_ALGOR_set0(alg3, 688 OBJ_nid2obj(GostR3410_get_pk_digest(digest)), 689 V_ASN1_SEQUENCE, params); 690 } 691 692 return 1; 693 } 694 695 const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[] = { 696 { 697 .pkey_id = EVP_PKEY_GOSTR01, 698 .pkey_base_id = EVP_PKEY_GOSTR01, 699 .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, 700 701 .pem_str = "GOST2001", 702 .info = "GOST R 34.10-2001", 703 704 .pkey_free = pkey_free_gost01, 705 .pkey_ctrl = pkey_ctrl_gost01, 706 707 .priv_decode = priv_decode_gost01, 708 .priv_encode = priv_encode_gost01, 709 .priv_print = priv_print_gost01, 710 711 .param_decode = param_decode_gost01, 712 .param_encode = param_encode_gost01, 713 .param_missing = param_missing_gost01, 714 .param_copy = param_copy_gost01, 715 .param_cmp = param_cmp_gost01, 716 .param_print = param_print_gost01, 717 718 .pub_decode = pub_decode_gost01, 719 .pub_encode = pub_encode_gost01, 720 .pub_cmp = pub_cmp_gost01, 721 .pub_print = pub_print_gost01, 722 .pkey_size = pkey_size_gost01, 723 .pkey_bits = pkey_bits_gost01, 724 }, 725 { 726 .pkey_id = EVP_PKEY_GOSTR12_256, 727 .pkey_base_id = EVP_PKEY_GOSTR01, 728 .pkey_flags = ASN1_PKEY_ALIAS 729 }, 730 { 731 .pkey_id = EVP_PKEY_GOSTR12_512, 732 .pkey_base_id = EVP_PKEY_GOSTR01, 733 .pkey_flags = ASN1_PKEY_ALIAS 734 }, 735 }; 736 737 #endif 738