1 /* $OpenBSD: gostr341001_ameth.c,v 1.19 2021/12/26 15:38:49 tb 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 65 #include "asn1_locl.h" 66 #include "evp_locl.h" 67 #include "gost_locl.h" 68 #include "gost_asn1.h" 69 70 static void 71 pkey_free_gost01(EVP_PKEY *key) 72 { 73 GOST_KEY_free(key->pkey.gost); 74 } 75 76 /* 77 * Parses GOST algorithm parameters from X509_ALGOR and 78 * modifies pkey setting NID and parameters 79 */ 80 static int 81 decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len) 82 { 83 int param_nid = NID_undef, digest_nid = NID_undef; 84 GOST_KEY_PARAMS *gkp = NULL; 85 EC_GROUP *group; 86 GOST_KEY *ec; 87 88 gkp = d2i_GOST_KEY_PARAMS(NULL, p, len); 89 if (gkp == NULL) { 90 GOSTerror(GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 91 return 0; 92 } 93 param_nid = OBJ_obj2nid(gkp->key_params); 94 digest_nid = OBJ_obj2nid(gkp->hash_params); 95 GOST_KEY_PARAMS_free(gkp); 96 97 ec = pkey->pkey.gost; 98 if (ec == NULL) { 99 ec = GOST_KEY_new(); 100 if (ec == NULL) { 101 GOSTerror(ERR_R_MALLOC_FAILURE); 102 return 0; 103 } 104 if (EVP_PKEY_assign_GOST(pkey, ec) == 0) 105 return 0; 106 } 107 108 group = EC_GROUP_new_by_curve_name(param_nid); 109 if (group == NULL) { 110 GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 111 return 0; 112 } 113 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 114 if (GOST_KEY_set_group(ec, group) == 0) { 115 EC_GROUP_free(group); 116 return 0; 117 } 118 EC_GROUP_free(group); 119 if (GOST_KEY_set_digest(ec, digest_nid) == 0) 120 return 0; 121 return 1; 122 } 123 124 static ASN1_STRING * 125 encode_gost01_algor_params(const EVP_PKEY *key) 126 { 127 ASN1_STRING *params = ASN1_STRING_new(); 128 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 129 int pkey_param_nid = NID_undef; 130 131 if (params == NULL || gkp == NULL) { 132 GOSTerror(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 GOSTerror(ERR_R_MALLOC_FAILURE); 146 ASN1_STRING_free(params); 147 params = NULL; 148 goto err; 149 } 150 params->type = V_ASN1_SEQUENCE; 151 err: 152 GOST_KEY_PARAMS_free(gkp); 153 return params; 154 } 155 156 static int 157 pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 158 { 159 const GOST_KEY *ea = a->pkey.gost; 160 const GOST_KEY *eb = b->pkey.gost; 161 const EC_POINT *ka, *kb; 162 int ret = 0; 163 164 if (ea == NULL || eb == NULL) 165 return 0; 166 ka = GOST_KEY_get0_public_key(ea); 167 kb = GOST_KEY_get0_public_key(eb); 168 if (ka == NULL || kb == NULL) 169 return 0; 170 ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL)); 171 return ret; 172 } 173 174 static int 175 pkey_size_gost01(const EVP_PKEY *pk) 176 { 177 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) 178 return 128; 179 return 64; 180 } 181 182 static int 183 pkey_bits_gost01(const EVP_PKEY *pk) 184 { 185 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) 186 return 512; 187 return 256; 188 } 189 190 static int 191 pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 192 { 193 X509_ALGOR *palg = NULL; 194 const unsigned char *pubkey_buf = NULL; 195 const unsigned char *p; 196 ASN1_OBJECT *palgobj = NULL; 197 int pub_len; 198 BIGNUM *X, *Y; 199 ASN1_OCTET_STRING *octet = NULL; 200 int len; 201 int ret; 202 int ptype = V_ASN1_UNDEF; 203 ASN1_STRING *pval = NULL; 204 205 if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub) 206 == 0) 207 return 0; 208 (void)EVP_PKEY_assign_GOST(pk, NULL); 209 X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg); 210 if (ptype != V_ASN1_SEQUENCE) { 211 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 212 return 0; 213 } 214 p = pval->data; 215 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) { 216 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 217 return 0; 218 } 219 220 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 221 if (octet == NULL) { 222 GOSTerror(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 GOSTerror(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 GOSTerror(GOST_R_PUBLIC_KEY_UNDEFINED); 270 goto err; 271 } 272 273 octet = ASN1_OCTET_STRING_new(); 274 if (octet == NULL) { 275 GOSTerror(ERR_R_MALLOC_FAILURE); 276 goto err; 277 } 278 279 ret = ASN1_STRING_set(octet, NULL, 2 * key_size); 280 if (ret == 0) { 281 GOSTerror(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 GOSTerror(ERR_R_MALLOC_FAILURE); 291 goto err; 292 } 293 294 if (EC_POINT_get_affine_coordinates(GOST_KEY_get0_group(ec), 295 pub_key, X, Y, NULL) == 0) { 296 GOSTerror(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 GOSTerror(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(group, pubkey, X, Y, ctx) == 0) { 357 GOSTerror(ERR_R_EC_LIB); 358 goto err; 359 } 360 if (BIO_indent(out, indent, 128) == 0) 361 goto err; 362 BIO_printf(out, "Public key:\n"); 363 if (BIO_indent(out, indent + 3, 128) == 0) 364 goto err; 365 BIO_printf(out, "X:"); 366 BN_print(out, X); 367 BIO_printf(out, "\n"); 368 if (BIO_indent(out, indent + 3, 128) == 0) 369 goto err; 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, const 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 const X509_ALGOR *palg = NULL; 411 const 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 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 419 return 0; 420 } 421 (void)EVP_PKEY_assign_GOST(pk, NULL); 422 X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg); 423 if (ptype != V_ASN1_SEQUENCE) { 424 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 425 return 0; 426 } 427 p = pval->data; 428 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) { 429 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 430 return 0; 431 } 432 p = pkey_buf; 433 if (V_ASN1_OCTET_STRING == *p) { 434 /* New format - Little endian octet string */ 435 ASN1_OCTET_STRING *s = 436 d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 437 438 if (s == NULL) { 439 GOSTerror(EVP_R_DECODE_ERROR); 440 ASN1_STRING_free(s); 441 return 0; 442 } 443 444 pk_num = GOST_le2bn(s->data, s->length, NULL); 445 ASN1_STRING_free(s); 446 } else { 447 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 448 if (priv_key == NULL) 449 return 0; 450 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 451 ASN1_INTEGER_free(priv_key); 452 if (ret == 0) { 453 GOSTerror(EVP_R_DECODE_ERROR); 454 return 0; 455 } 456 } 457 458 ec = pk->pkey.gost; 459 if (ec == NULL) { 460 ec = GOST_KEY_new(); 461 if (ec == NULL) { 462 BN_free(pk_num); 463 return 0; 464 } 465 if (EVP_PKEY_assign_GOST(pk, ec) == 0) { 466 BN_free(pk_num); 467 GOST_KEY_free(ec); 468 return 0; 469 } 470 } 471 if (GOST_KEY_set_private_key(ec, pk_num) == 0) { 472 BN_free(pk_num); 473 return 0; 474 } 475 ret = 0; 476 if (EVP_PKEY_missing_parameters(pk) == 0) 477 ret = gost2001_compute_public(ec) != 0; 478 BN_free(pk_num); 479 480 return ret; 481 } 482 483 static int 484 priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 485 { 486 ASN1_OBJECT *algobj = 487 OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); 488 ASN1_STRING *params = encode_gost01_algor_params(pk); 489 unsigned char *priv_buf = NULL; 490 int priv_len; 491 ASN1_INTEGER *asn1key = NULL; 492 493 if (params == NULL) 494 return 0; 495 496 asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), 497 NULL); 498 if (asn1key == NULL) { 499 ASN1_STRING_free(params); 500 return 0; 501 } 502 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 503 ASN1_INTEGER_free(asn1key); 504 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, 505 priv_len); 506 } 507 508 static int 509 param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) 510 { 511 ASN1_STRING *params = encode_gost01_algor_params(pkey); 512 int len; 513 514 if (params == NULL) 515 return 0; 516 len = params->length; 517 if (pder != NULL) 518 memcpy(*pder, params->data, params->length); 519 ASN1_STRING_free(params); 520 return len; 521 } 522 523 static int 524 param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 525 { 526 ASN1_OBJECT *obj = NULL; 527 int nid; 528 GOST_KEY *ec; 529 EC_GROUP *group; 530 int ret; 531 532 /* New format */ 533 if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) 534 return decode_gost01_algor_params(pkey, pder, derlen); 535 536 /* Compatibility */ 537 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 538 GOSTerror(ERR_R_MALLOC_FAILURE); 539 return 0; 540 } 541 nid = OBJ_obj2nid(obj); 542 ASN1_OBJECT_free(obj); 543 544 ec = GOST_KEY_new(); 545 if (ec == NULL) { 546 GOSTerror(ERR_R_MALLOC_FAILURE); 547 return 0; 548 } 549 group = EC_GROUP_new_by_curve_name(nid); 550 if (group == NULL) { 551 GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 552 GOST_KEY_free(ec); 553 return 0; 554 } 555 556 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 557 if (GOST_KEY_set_group(ec, group) == 0) { 558 GOSTerror(ERR_R_EC_LIB); 559 EC_GROUP_free(group); 560 GOST_KEY_free(ec); 561 return 0; 562 } 563 EC_GROUP_free(group); 564 if (GOST_KEY_set_digest(ec, 565 NID_id_GostR3411_94_CryptoProParamSet) == 0) { 566 GOSTerror(GOST_R_INVALID_DIGEST_TYPE); 567 GOST_KEY_free(ec); 568 return 0; 569 } 570 ret = EVP_PKEY_assign_GOST(pkey, ec); 571 if (ret == 0) 572 GOST_KEY_free(ec); 573 return ret; 574 } 575 576 static int 577 param_missing_gost01(const EVP_PKEY *pk) 578 { 579 const GOST_KEY *ec = pk->pkey.gost; 580 581 if (ec == NULL) 582 return 1; 583 if (GOST_KEY_get0_group(ec) == NULL) 584 return 1; 585 if (GOST_KEY_get_digest(ec) == NID_undef) 586 return 1; 587 return 0; 588 } 589 590 static int 591 param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 592 { 593 GOST_KEY *eto = to->pkey.gost; 594 const GOST_KEY *efrom = from->pkey.gost; 595 int ret = 1; 596 597 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 598 GOSTerror(GOST_R_INCOMPATIBLE_ALGORITHMS); 599 return 0; 600 } 601 if (efrom == NULL) { 602 GOSTerror(GOST_R_KEY_PARAMETERS_MISSING); 603 return 0; 604 } 605 if (eto == NULL) { 606 eto = GOST_KEY_new(); 607 if (eto == NULL) { 608 GOSTerror(ERR_R_MALLOC_FAILURE); 609 return 0; 610 } 611 if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { 612 GOST_KEY_free(eto); 613 return 0; 614 } 615 } 616 GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); 617 GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); 618 if (GOST_KEY_get0_private_key(eto) != NULL) 619 ret = gost2001_compute_public(eto); 620 621 return ret; 622 } 623 624 static int 625 param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 626 { 627 if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != 628 EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) 629 return 0; 630 631 if (GOST_KEY_get_digest(a->pkey.gost) != 632 GOST_KEY_get_digest(b->pkey.gost)) 633 return 0; 634 635 return 1; 636 } 637 638 static int 639 pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) 640 { 641 X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; 642 int digest = GOST_KEY_get_digest(pkey->pkey.gost); 643 644 switch (op) { 645 case ASN1_PKEY_CTRL_PKCS7_SIGN: 646 if (arg1 == 0) 647 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 648 break; 649 650 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 651 if (arg1 == 0) 652 PKCS7_RECIP_INFO_get0_alg(arg2, &alg3); 653 break; 654 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 655 *(int *)arg2 = GostR3410_get_md_digest(digest); 656 return 2; 657 658 default: 659 return -2; 660 } 661 662 if (alg1) 663 X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0); 664 if (alg2) 665 X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0); 666 if (alg3) { 667 ASN1_STRING *params = encode_gost01_algor_params(pkey); 668 if (params == NULL) { 669 return -1; 670 } 671 X509_ALGOR_set0(alg3, 672 OBJ_nid2obj(GostR3410_get_pk_digest(digest)), 673 V_ASN1_SEQUENCE, params); 674 } 675 676 return 1; 677 } 678 679 const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[] = { 680 { 681 .pkey_id = EVP_PKEY_GOSTR01, 682 .pkey_base_id = EVP_PKEY_GOSTR01, 683 .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, 684 685 .pem_str = "GOST2001", 686 .info = "GOST R 34.10-2001", 687 688 .pkey_free = pkey_free_gost01, 689 .pkey_ctrl = pkey_ctrl_gost01, 690 691 .priv_decode = priv_decode_gost01, 692 .priv_encode = priv_encode_gost01, 693 .priv_print = priv_print_gost01, 694 695 .param_decode = param_decode_gost01, 696 .param_encode = param_encode_gost01, 697 .param_missing = param_missing_gost01, 698 .param_copy = param_copy_gost01, 699 .param_cmp = param_cmp_gost01, 700 .param_print = param_print_gost01, 701 702 .pub_decode = pub_decode_gost01, 703 .pub_encode = pub_encode_gost01, 704 .pub_cmp = pub_cmp_gost01, 705 .pub_print = pub_print_gost01, 706 .pkey_size = pkey_size_gost01, 707 .pkey_bits = pkey_bits_gost01, 708 }, 709 { 710 .pkey_id = EVP_PKEY_GOSTR12_256, 711 .pkey_base_id = EVP_PKEY_GOSTR01, 712 .pkey_flags = ASN1_PKEY_ALIAS 713 }, 714 { 715 .pkey_id = EVP_PKEY_GOSTR12_512, 716 .pkey_base_id = EVP_PKEY_GOSTR01, 717 .pkey_flags = ASN1_PKEY_ALIAS 718 }, 719 }; 720 721 #endif 722