1 /* $OpenBSD: gostr341001_ameth.c,v 1.16 2020/06/05 17:17:22 jsing 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 "gost_locl.h" 67 #include "gost_asn1.h" 68 69 static void 70 pkey_free_gost01(EVP_PKEY *key) 71 { 72 GOST_KEY_free(key->pkey.gost); 73 } 74 75 /* 76 * Parses GOST algorithm parameters from X509_ALGOR and 77 * modifies pkey setting NID and parameters 78 */ 79 static int 80 decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len) 81 { 82 int param_nid = NID_undef, digest_nid = NID_undef; 83 GOST_KEY_PARAMS *gkp = NULL; 84 EC_GROUP *group; 85 GOST_KEY *ec; 86 87 gkp = d2i_GOST_KEY_PARAMS(NULL, p, len); 88 if (gkp == NULL) { 89 GOSTerror(GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 90 return 0; 91 } 92 param_nid = OBJ_obj2nid(gkp->key_params); 93 digest_nid = OBJ_obj2nid(gkp->hash_params); 94 GOST_KEY_PARAMS_free(gkp); 95 96 ec = pkey->pkey.gost; 97 if (ec == NULL) { 98 ec = GOST_KEY_new(); 99 if (ec == NULL) { 100 GOSTerror(ERR_R_MALLOC_FAILURE); 101 return 0; 102 } 103 if (EVP_PKEY_assign_GOST(pkey, ec) == 0) 104 return 0; 105 } 106 107 group = EC_GROUP_new_by_curve_name(param_nid); 108 if (group == NULL) { 109 GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 110 return 0; 111 } 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 GOSTerror(ERR_R_MALLOC_FAILURE); 132 ASN1_STRING_free(params); 133 params = NULL; 134 goto err; 135 } 136 137 pkey_param_nid = 138 EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost)); 139 gkp->key_params = OBJ_nid2obj(pkey_param_nid); 140 gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost)); 141 /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */ 142 params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 143 if (params->length <= 0) { 144 GOSTerror(ERR_R_MALLOC_FAILURE); 145 ASN1_STRING_free(params); 146 params = NULL; 147 goto err; 148 } 149 params->type = V_ASN1_SEQUENCE; 150 err: 151 GOST_KEY_PARAMS_free(gkp); 152 return params; 153 } 154 155 static int 156 pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 157 { 158 const GOST_KEY *ea = a->pkey.gost; 159 const GOST_KEY *eb = b->pkey.gost; 160 const EC_POINT *ka, *kb; 161 int ret = 0; 162 163 if (ea == NULL || eb == NULL) 164 return 0; 165 ka = GOST_KEY_get0_public_key(ea); 166 kb = GOST_KEY_get0_public_key(eb); 167 if (ka == NULL || kb == NULL) 168 return 0; 169 ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL)); 170 return ret; 171 } 172 173 static int 174 pkey_size_gost01(const EVP_PKEY *pk) 175 { 176 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) 177 return 128; 178 return 64; 179 } 180 181 static int 182 pkey_bits_gost01(const EVP_PKEY *pk) 183 { 184 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512) 185 return 512; 186 return 256; 187 } 188 189 static int 190 pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 191 { 192 X509_ALGOR *palg = NULL; 193 const unsigned char *pubkey_buf = NULL; 194 const unsigned char *p; 195 ASN1_OBJECT *palgobj = NULL; 196 int pub_len; 197 BIGNUM *X, *Y; 198 ASN1_OCTET_STRING *octet = NULL; 199 int len; 200 int ret; 201 int ptype = V_ASN1_UNDEF; 202 ASN1_STRING *pval = NULL; 203 204 if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub) 205 == 0) 206 return 0; 207 (void)EVP_PKEY_assign_GOST(pk, NULL); 208 X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg); 209 if (ptype != V_ASN1_SEQUENCE) { 210 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 211 return 0; 212 } 213 p = pval->data; 214 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) { 215 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 216 return 0; 217 } 218 219 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 220 if (octet == NULL) { 221 GOSTerror(ERR_R_MALLOC_FAILURE); 222 return 0; 223 } 224 len = octet->length / 2; 225 226 X = GOST_le2bn(octet->data, len, NULL); 227 Y = GOST_le2bn(octet->data + len, len, NULL); 228 229 ASN1_OCTET_STRING_free(octet); 230 231 ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); 232 if (ret == 0) 233 GOSTerror(ERR_R_EC_LIB); 234 235 BN_free(X); 236 BN_free(Y); 237 238 return ret; 239 } 240 241 static int 242 pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 243 { 244 ASN1_OBJECT *algobj = NULL; 245 ASN1_OCTET_STRING *octet = NULL; 246 ASN1_STRING *params = NULL; 247 void *pval = NULL; 248 unsigned char *buf = NULL, *sptr; 249 int key_size, ret = 0; 250 const EC_POINT *pub_key; 251 BIGNUM *X = NULL, *Y = NULL; 252 const GOST_KEY *ec = pk->pkey.gost; 253 int ptype = V_ASN1_UNDEF; 254 255 algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); 256 if (pk->save_parameters) { 257 params = encode_gost01_algor_params(pk); 258 if (params == NULL) 259 return 0; 260 pval = params; 261 ptype = V_ASN1_SEQUENCE; 262 } 263 264 key_size = GOST_KEY_get_size(ec); 265 266 pub_key = GOST_KEY_get0_public_key(ec); 267 if (pub_key == NULL) { 268 GOSTerror(GOST_R_PUBLIC_KEY_UNDEFINED); 269 goto err; 270 } 271 272 octet = ASN1_OCTET_STRING_new(); 273 if (octet == NULL) { 274 GOSTerror(ERR_R_MALLOC_FAILURE); 275 goto err; 276 } 277 278 ret = ASN1_STRING_set(octet, NULL, 2 * key_size); 279 if (ret == 0) { 280 GOSTerror(ERR_R_INTERNAL_ERROR); 281 goto err; 282 } 283 284 sptr = ASN1_STRING_data(octet); 285 286 X = BN_new(); 287 Y = BN_new(); 288 if (X == NULL || Y == NULL) { 289 GOSTerror(ERR_R_MALLOC_FAILURE); 290 goto err; 291 } 292 293 if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), 294 pub_key, X, Y, NULL) == 0) { 295 GOSTerror(ERR_R_EC_LIB); 296 goto err; 297 } 298 299 GOST_bn2le(X, sptr, key_size); 300 GOST_bn2le(Y, sptr + key_size, key_size); 301 302 BN_free(Y); 303 BN_free(X); 304 305 ret = i2d_ASN1_OCTET_STRING(octet, &buf); 306 ASN1_BIT_STRING_free(octet); 307 if (ret < 0) 308 return 0; 309 310 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 311 312 err: 313 BN_free(Y); 314 BN_free(X); 315 ASN1_BIT_STRING_free(octet); 316 ASN1_STRING_free(params); 317 return 0; 318 } 319 320 static int 321 param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) 322 { 323 int param_nid = 324 EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); 325 326 if (BIO_indent(out, indent, 128) == 0) 327 return 0; 328 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 329 if (BIO_indent(out, indent, 128) == 0) 330 return 0; 331 BIO_printf(out, "Digest Algorithm: %s\n", 332 OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); 333 return 1; 334 } 335 336 static int 337 pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) 338 { 339 BN_CTX *ctx = BN_CTX_new(); 340 BIGNUM *X, *Y; 341 const EC_POINT *pubkey; 342 const EC_GROUP *group; 343 344 if (ctx == NULL) { 345 GOSTerror(ERR_R_MALLOC_FAILURE); 346 return 0; 347 } 348 BN_CTX_start(ctx); 349 if ((X = BN_CTX_get(ctx)) == NULL) 350 goto err; 351 if ((Y = BN_CTX_get(ctx)) == NULL) 352 goto err; 353 pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); 354 group = GOST_KEY_get0_group(pkey->pkey.gost); 355 if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, 356 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 BIO_indent(out, indent + 3, 128); 369 BIO_printf(out, "Y:"); 370 BN_print(out, Y); 371 BIO_printf(out, "\n"); 372 373 BN_CTX_end(ctx); 374 BN_CTX_free(ctx); 375 376 return param_print_gost01(out, pkey, indent, pctx); 377 378 err: 379 BN_CTX_end(ctx); 380 BN_CTX_free(ctx); 381 return 0; 382 } 383 384 static int 385 priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) 386 { 387 const BIGNUM *key; 388 389 if (BIO_indent(out, indent, 128) == 0) 390 return 0; 391 BIO_printf(out, "Private key: "); 392 key = GOST_KEY_get0_private_key(pkey->pkey.gost); 393 if (key == NULL) 394 BIO_printf(out, "<undefined)"); 395 else 396 BN_print(out, key); 397 BIO_printf(out, "\n"); 398 399 return pub_print_gost01(out, pkey, indent, pctx); 400 } 401 402 static int 403 priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf) 404 { 405 const unsigned char *pkey_buf = NULL, *p = NULL; 406 int priv_len = 0; 407 BIGNUM *pk_num = NULL; 408 int ret = 0; 409 const X509_ALGOR *palg = NULL; 410 const ASN1_OBJECT *palg_obj = NULL; 411 ASN1_INTEGER *priv_key = NULL; 412 GOST_KEY *ec; 413 int ptype = V_ASN1_UNDEF; 414 ASN1_STRING *pval = NULL; 415 416 if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) { 417 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 418 return 0; 419 } 420 (void)EVP_PKEY_assign_GOST(pk, NULL); 421 X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg); 422 if (ptype != V_ASN1_SEQUENCE) { 423 GOSTerror(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 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT); 429 return 0; 430 } 431 p = pkey_buf; 432 if (V_ASN1_OCTET_STRING == *p) { 433 /* New format - Little endian octet string */ 434 ASN1_OCTET_STRING *s = 435 d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 436 437 if (s == NULL) { 438 GOSTerror(EVP_R_DECODE_ERROR); 439 ASN1_STRING_free(s); 440 return 0; 441 } 442 443 pk_num = GOST_le2bn(s->data, s->length, NULL); 444 ASN1_STRING_free(s); 445 } else { 446 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 447 if (priv_key == NULL) 448 return 0; 449 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 450 ASN1_INTEGER_free(priv_key); 451 if (ret == 0) { 452 GOSTerror(EVP_R_DECODE_ERROR); 453 return 0; 454 } 455 } 456 457 ec = pk->pkey.gost; 458 if (ec == NULL) { 459 ec = GOST_KEY_new(); 460 if (ec == NULL) { 461 BN_free(pk_num); 462 return 0; 463 } 464 if (EVP_PKEY_assign_GOST(pk, ec) == 0) { 465 BN_free(pk_num); 466 GOST_KEY_free(ec); 467 return 0; 468 } 469 } 470 if (GOST_KEY_set_private_key(ec, pk_num) == 0) { 471 BN_free(pk_num); 472 return 0; 473 } 474 ret = 0; 475 if (EVP_PKEY_missing_parameters(pk) == 0) 476 ret = gost2001_compute_public(ec) != 0; 477 BN_free(pk_num); 478 479 return ret; 480 } 481 482 static int 483 priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 484 { 485 ASN1_OBJECT *algobj = 486 OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); 487 ASN1_STRING *params = encode_gost01_algor_params(pk); 488 unsigned char *priv_buf = NULL; 489 int priv_len; 490 ASN1_INTEGER *asn1key = NULL; 491 492 if (params == NULL) 493 return 0; 494 495 asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), 496 NULL); 497 if (asn1key == NULL) { 498 ASN1_STRING_free(params); 499 return 0; 500 } 501 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 502 ASN1_INTEGER_free(asn1key); 503 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, 504 priv_len); 505 } 506 507 static int 508 param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) 509 { 510 ASN1_STRING *params = encode_gost01_algor_params(pkey); 511 int len; 512 513 if (params == NULL) 514 return 0; 515 len = params->length; 516 if (pder != NULL) 517 memcpy(*pder, params->data, params->length); 518 ASN1_STRING_free(params); 519 return len; 520 } 521 522 static int 523 param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 524 { 525 ASN1_OBJECT *obj = NULL; 526 int nid; 527 GOST_KEY *ec; 528 EC_GROUP *group; 529 int ret; 530 531 /* New format */ 532 if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) 533 return decode_gost01_algor_params(pkey, pder, derlen); 534 535 /* Compatibility */ 536 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 537 GOSTerror(ERR_R_MALLOC_FAILURE); 538 return 0; 539 } 540 nid = OBJ_obj2nid(obj); 541 ASN1_OBJECT_free(obj); 542 543 ec = GOST_KEY_new(); 544 if (ec == NULL) { 545 GOSTerror(ERR_R_MALLOC_FAILURE); 546 return 0; 547 } 548 group = EC_GROUP_new_by_curve_name(nid); 549 if (group == NULL) { 550 GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 551 GOST_KEY_free(ec); 552 return 0; 553 } 554 555 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 556 if (GOST_KEY_set_group(ec, group) == 0) { 557 GOSTerror(ERR_R_EC_LIB); 558 EC_GROUP_free(group); 559 GOST_KEY_free(ec); 560 return 0; 561 } 562 EC_GROUP_free(group); 563 if (GOST_KEY_set_digest(ec, 564 NID_id_GostR3411_94_CryptoProParamSet) == 0) { 565 GOSTerror(GOST_R_INVALID_DIGEST_TYPE); 566 GOST_KEY_free(ec); 567 return 0; 568 } 569 ret = EVP_PKEY_assign_GOST(pkey, ec); 570 if (ret == 0) 571 GOST_KEY_free(ec); 572 return ret; 573 } 574 575 static int 576 param_missing_gost01(const EVP_PKEY *pk) 577 { 578 const GOST_KEY *ec = pk->pkey.gost; 579 580 if (ec == NULL) 581 return 1; 582 if (GOST_KEY_get0_group(ec) == NULL) 583 return 1; 584 if (GOST_KEY_get_digest(ec) == NID_undef) 585 return 1; 586 return 0; 587 } 588 589 static int 590 param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 591 { 592 GOST_KEY *eto = to->pkey.gost; 593 const GOST_KEY *efrom = from->pkey.gost; 594 int ret = 1; 595 596 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 597 GOSTerror(GOST_R_INCOMPATIBLE_ALGORITHMS); 598 return 0; 599 } 600 if (efrom == NULL) { 601 GOSTerror(GOST_R_KEY_PARAMETERS_MISSING); 602 return 0; 603 } 604 if (eto == NULL) { 605 eto = GOST_KEY_new(); 606 if (eto == NULL) { 607 GOSTerror(ERR_R_MALLOC_FAILURE); 608 return 0; 609 } 610 if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { 611 GOST_KEY_free(eto); 612 return 0; 613 } 614 } 615 GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); 616 GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); 617 if (GOST_KEY_get0_private_key(eto) != NULL) 618 ret = gost2001_compute_public(eto); 619 620 return ret; 621 } 622 623 static int 624 param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 625 { 626 if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != 627 EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) 628 return 0; 629 630 if (GOST_KEY_get_digest(a->pkey.gost) != 631 GOST_KEY_get_digest(b->pkey.gost)) 632 return 0; 633 634 return 1; 635 } 636 637 static int 638 pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) 639 { 640 X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; 641 int digest = GOST_KEY_get_digest(pkey->pkey.gost); 642 643 switch (op) { 644 case ASN1_PKEY_CTRL_PKCS7_SIGN: 645 if (arg1 == 0) 646 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 647 break; 648 649 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 650 if (arg1 == 0) 651 PKCS7_RECIP_INFO_get0_alg(arg2, &alg3); 652 break; 653 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 654 *(int *)arg2 = GostR3410_get_md_digest(digest); 655 return 2; 656 657 default: 658 return -2; 659 } 660 661 if (alg1) 662 X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0); 663 if (alg2) 664 X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0); 665 if (alg3) { 666 ASN1_STRING *params = encode_gost01_algor_params(pkey); 667 if (params == NULL) { 668 return -1; 669 } 670 X509_ALGOR_set0(alg3, 671 OBJ_nid2obj(GostR3410_get_pk_digest(digest)), 672 V_ASN1_SEQUENCE, params); 673 } 674 675 return 1; 676 } 677 678 const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[] = { 679 { 680 .pkey_id = EVP_PKEY_GOSTR01, 681 .pkey_base_id = EVP_PKEY_GOSTR01, 682 .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, 683 684 .pem_str = "GOST2001", 685 .info = "GOST R 34.10-2001", 686 687 .pkey_free = pkey_free_gost01, 688 .pkey_ctrl = pkey_ctrl_gost01, 689 690 .priv_decode = priv_decode_gost01, 691 .priv_encode = priv_encode_gost01, 692 .priv_print = priv_print_gost01, 693 694 .param_decode = param_decode_gost01, 695 .param_encode = param_encode_gost01, 696 .param_missing = param_missing_gost01, 697 .param_copy = param_copy_gost01, 698 .param_cmp = param_cmp_gost01, 699 .param_print = param_print_gost01, 700 701 .pub_decode = pub_decode_gost01, 702 .pub_encode = pub_encode_gost01, 703 .pub_cmp = pub_cmp_gost01, 704 .pub_print = pub_print_gost01, 705 .pkey_size = pkey_size_gost01, 706 .pkey_bits = pkey_bits_gost01, 707 }, 708 { 709 .pkey_id = EVP_PKEY_GOSTR12_256, 710 .pkey_base_id = EVP_PKEY_GOSTR01, 711 .pkey_flags = ASN1_PKEY_ALIAS 712 }, 713 { 714 .pkey_id = EVP_PKEY_GOSTR12_512, 715 .pkey_base_id = EVP_PKEY_GOSTR01, 716 .pkey_flags = ASN1_PKEY_ALIAS 717 }, 718 }; 719 720 #endif 721