gost_ameth.c revision 284285
1/********************************************************************** 2 * gost_ameth.c * 3 * Copyright (c) 2005-2006 Cryptocom LTD * 4 * This file is distributed under the same license as OpenSSL * 5 * * 6 * Implementation of RFC 4490/4491 ASN1 method * 7 * for OpenSSL * 8 * Requires OpenSSL 0.9.9 for compilation * 9 **********************************************************************/ 10#include <string.h> 11#include <openssl/crypto.h> 12#include <openssl/err.h> 13#include <openssl/engine.h> 14#include <openssl/evp.h> 15#include <openssl/asn1.h> 16#ifndef OPENSSL_NO_CMS 17# include <openssl/cms.h> 18#endif 19#include "gost_params.h" 20#include "gost_lcl.h" 21#include "e_gost_err.h" 22 23int gost94_nid_by_params(DSA *p) 24{ 25 R3410_params *gost_params; 26 BIGNUM *q = BN_new(); 27 for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { 28 BN_dec2bn(&q, gost_params->q); 29 if (!BN_cmp(q, p->q)) { 30 BN_free(q); 31 return gost_params->nid; 32 } 33 } 34 BN_free(q); 35 return NID_undef; 36} 37 38static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) 39{ 40 ASN1_STRING *params = ASN1_STRING_new(); 41 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 42 int pkey_param_nid = NID_undef; 43 44 if (!params || !gkp) { 45 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 46 ASN1_STRING_free(params); 47 params = NULL; 48 goto err; 49 } 50 switch (EVP_PKEY_base_id(key)) { 51 case NID_id_GostR3410_2001: 52 pkey_param_nid = 53 EC_GROUP_get_curve_name(EC_KEY_get0_group 54 (EVP_PKEY_get0((EVP_PKEY *)key))); 55 break; 56 case NID_id_GostR3410_94: 57 pkey_param_nid = 58 (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); 59 if (pkey_param_nid == NID_undef) { 60 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 61 GOST_R_INVALID_GOST94_PARMSET); 62 ASN1_STRING_free(params); 63 params = NULL; 64 goto err; 65 } 66 break; 67 } 68 gkp->key_params = OBJ_nid2obj(pkey_param_nid); 69 gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); 70 /* 71 * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); 72 */ 73 params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 74 if (params->length <= 0) { 75 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 76 ASN1_STRING_free(params); 77 params = NULL; 78 goto err; 79 } 80 params->type = V_ASN1_SEQUENCE; 81 err: 82 GOST_KEY_PARAMS_free(gkp); 83 return params; 84} 85 86/* 87 * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting 88 * NID and parameters 89 */ 90static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 91{ 92 ASN1_OBJECT *palg_obj = NULL; 93 int ptype = V_ASN1_UNDEF; 94 int pkey_nid = NID_undef, param_nid = NID_undef; 95 void *_pval; 96 ASN1_STRING *pval = NULL; 97 const unsigned char *p; 98 GOST_KEY_PARAMS *gkp = NULL; 99 100 X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); 101 pval = _pval; 102 if (ptype != V_ASN1_SEQUENCE) { 103 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 104 GOST_R_BAD_KEY_PARAMETERS_FORMAT); 105 return 0; 106 } 107 p = pval->data; 108 pkey_nid = OBJ_obj2nid(palg_obj); 109 110 gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); 111 if (!gkp) { 112 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 113 GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 114 return 0; 115 } 116 param_nid = OBJ_obj2nid(gkp->key_params); 117 GOST_KEY_PARAMS_free(gkp); 118 if(!EVP_PKEY_set_type(pkey, pkey_nid)) { 119 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); 120 return 0; 121 } 122 switch (pkey_nid) { 123 case NID_id_GostR3410_94: 124 { 125 DSA *dsa = EVP_PKEY_get0(pkey); 126 if (!dsa) { 127 dsa = DSA_new(); 128 if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) 129 return 0; 130 } 131 if (!fill_GOST94_params(dsa, param_nid)) 132 return 0; 133 break; 134 } 135 case NID_id_GostR3410_2001: 136 { 137 EC_KEY *ec = EVP_PKEY_get0(pkey); 138 if (!ec) { 139 ec = EC_KEY_new(); 140 if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) 141 return 0; 142 } 143 if (!fill_GOST2001_params(ec, param_nid)) 144 return 0; 145 } 146 } 147 148 return 1; 149} 150 151static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) 152{ 153 switch (EVP_PKEY_base_id(pkey)) { 154 case NID_id_GostR3410_94: 155 { 156 DSA *dsa = EVP_PKEY_get0(pkey); 157 if (!dsa) { 158 dsa = DSA_new(); 159 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); 160 } 161 dsa->priv_key = BN_dup(priv); 162 if (!EVP_PKEY_missing_parameters(pkey)) 163 gost94_compute_public(dsa); 164 break; 165 } 166 case NID_id_GostR3410_2001: 167 { 168 EC_KEY *ec = EVP_PKEY_get0(pkey); 169 if (!ec) { 170 ec = EC_KEY_new(); 171 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); 172 } 173 if (!EC_KEY_set_private_key(ec, priv)) 174 return 0; 175 if (!EVP_PKEY_missing_parameters(pkey)) 176 gost2001_compute_public(ec); 177 break; 178 } 179 } 180 return 1; 181} 182 183BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) 184{ 185 switch (EVP_PKEY_base_id(pkey)) { 186 case NID_id_GostR3410_94: 187 { 188 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); 189 if (!dsa) { 190 return NULL; 191 } 192 if (!dsa->priv_key) 193 return NULL; 194 return dsa->priv_key; 195 break; 196 } 197 case NID_id_GostR3410_2001: 198 { 199 EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); 200 const BIGNUM *priv; 201 if (!ec) { 202 return NULL; 203 } 204 if (!(priv = EC_KEY_get0_private_key(ec))) 205 return NULL; 206 return (BIGNUM *)priv; 207 break; 208 } 209 } 210 return NULL; 211} 212 213static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 214{ 215 switch (op) { 216 case ASN1_PKEY_CTRL_PKCS7_SIGN: 217 if (arg1 == 0) { 218 X509_ALGOR *alg1 = NULL, *alg2 = NULL; 219 int nid = EVP_PKEY_base_id(pkey); 220 PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, 221 NULL, &alg1, &alg2); 222 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 223 V_ASN1_NULL, 0); 224 if (nid == NID_undef) { 225 return (-1); 226 } 227 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 228 } 229 return 1; 230#ifndef OPENSSL_NO_CMS 231 case ASN1_PKEY_CTRL_CMS_SIGN: 232 if (arg1 == 0) { 233 X509_ALGOR *alg1 = NULL, *alg2 = NULL; 234 int nid = EVP_PKEY_base_id(pkey); 235 CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 236 NULL, NULL, &alg1, &alg2); 237 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 238 V_ASN1_NULL, 0); 239 if (nid == NID_undef) { 240 return (-1); 241 } 242 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 243 } 244 return 1; 245#endif 246 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 247 if (arg1 == 0) { 248 X509_ALGOR *alg; 249 ASN1_STRING *params = encode_gost_algor_params(pkey); 250 if (!params) { 251 return -1; 252 } 253 PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); 254 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 255 V_ASN1_SEQUENCE, params); 256 } 257 return 1; 258#ifndef OPENSSL_NO_CMS 259 case ASN1_PKEY_CTRL_CMS_ENVELOPE: 260 if (arg1 == 0) { 261 X509_ALGOR *alg = NULL; 262 ASN1_STRING *params = encode_gost_algor_params(pkey); 263 if (!params) { 264 return -1; 265 } 266 CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, 267 NULL, &alg); 268 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, 269 params); 270 } 271 return 1; 272#endif 273 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 274 *(int *)arg2 = NID_id_GostR3411_94; 275 return 2; 276 } 277 278 return -2; 279} 280 281/* --------------------- free functions * ------------------------------*/ 282static void pkey_free_gost94(EVP_PKEY *key) 283{ 284 if (key->pkey.dsa) { 285 DSA_free(key->pkey.dsa); 286 } 287} 288 289static void pkey_free_gost01(EVP_PKEY *key) 290{ 291 if (key->pkey.ec) { 292 EC_KEY_free(key->pkey.ec); 293 } 294} 295 296/* ------------------ private key functions -----------------------------*/ 297static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 298{ 299 const unsigned char *pkey_buf = NULL, *p = NULL; 300 int priv_len = 0; 301 BIGNUM *pk_num = NULL; 302 int ret = 0; 303 X509_ALGOR *palg = NULL; 304 ASN1_OBJECT *palg_obj = NULL; 305 ASN1_INTEGER *priv_key = NULL; 306 307 if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) 308 return 0; 309 p = pkey_buf; 310 if (!decode_gost_algor_params(pk, palg)) { 311 return 0; 312 } 313 if (V_ASN1_OCTET_STRING == *p) { 314 /* New format - Little endian octet string */ 315 unsigned char rev_buf[32]; 316 int i; 317 ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 318 if (!s || s->length != 32) { 319 GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 320 return 0; 321 } 322 for (i = 0; i < 32; i++) { 323 rev_buf[31 - i] = s->data[i]; 324 } 325 ASN1_STRING_free(s); 326 pk_num = getbnfrombuf(rev_buf, 32); 327 } else { 328 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 329 if (!priv_key) 330 return 0; 331 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 332 ASN1_INTEGER_free(priv_key); 333 if (!ret) { 334 GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 335 return 0; 336 } 337 } 338 339 ret = gost_set_priv_key(pk, pk_num); 340 BN_free(pk_num); 341 return ret; 342} 343 344/* ----------------------------------------------------------------------*/ 345static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 346{ 347 ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 348 ASN1_STRING *params = encode_gost_algor_params(pk); 349 unsigned char *priv_buf = NULL; 350 int priv_len; 351 352 ASN1_INTEGER *asn1key = NULL; 353 if (!params) { 354 return 0; 355 } 356 asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); 357 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 358 ASN1_INTEGER_free(asn1key); 359 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, 360 priv_buf, priv_len); 361} 362 363/* --------- printing keys --------------------------------*/ 364static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, 365 ASN1_PCTX *pctx, int type) 366{ 367 int param_nid = NID_undef; 368 369 if (type == 2) { 370 BIGNUM *key; 371 372 if (!BIO_indent(out, indent, 128)) 373 return 0; 374 BIO_printf(out, "Private key: "); 375 key = gost_get0_priv_key(pkey); 376 if (!key) 377 BIO_printf(out, "<undefined>"); 378 else 379 BN_print(out, key); 380 BIO_printf(out, "\n"); 381 } 382 if (type >= 1) { 383 BIGNUM *pubkey; 384 385 pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; 386 BIO_indent(out, indent, 128); 387 BIO_printf(out, "Public key: "); 388 BN_print(out, pubkey); 389 BIO_printf(out, "\n"); 390 } 391 392 param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 393 BIO_indent(out, indent, 128); 394 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 395 return 1; 396} 397 398static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 399 ASN1_PCTX *pctx) 400{ 401 return print_gost_94(out, pkey, indent, pctx, 0); 402} 403 404static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 405 ASN1_PCTX *pctx) 406{ 407 return print_gost_94(out, pkey, indent, pctx, 1); 408} 409 410static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 411 ASN1_PCTX *pctx) 412{ 413 return print_gost_94(out, pkey, indent, pctx, 2); 414} 415 416static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, 417 ASN1_PCTX *pctx, int type) 418{ 419 int param_nid = NID_undef; 420 if (type == 2) { 421 BIGNUM *key; 422 423 if (!BIO_indent(out, indent, 128)) 424 return 0; 425 BIO_printf(out, "Private key: "); 426 key = gost_get0_priv_key(pkey); 427 if (!key) 428 BIO_printf(out, "<undefined)"); 429 else 430 BN_print(out, key); 431 BIO_printf(out, "\n"); 432 } 433 if (type >= 1) { 434 BN_CTX *ctx = BN_CTX_new(); 435 BIGNUM *X, *Y; 436 const EC_POINT *pubkey; 437 const EC_GROUP *group; 438 439 if (!ctx) { 440 GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); 441 return 0; 442 } 443 BN_CTX_start(ctx); 444 X = BN_CTX_get(ctx); 445 Y = BN_CTX_get(ctx); 446 pubkey = 447 EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 448 group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 449 if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { 450 GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); 451 BN_CTX_free(ctx); 452 return 0; 453 } 454 if (!BIO_indent(out, indent, 128)) 455 return 0; 456 BIO_printf(out, "Public key:\n"); 457 if (!BIO_indent(out, indent + 3, 128)) 458 return 0; 459 BIO_printf(out, "X:"); 460 BN_print(out, X); 461 BIO_printf(out, "\n"); 462 BIO_indent(out, indent + 3, 128); 463 BIO_printf(out, "Y:"); 464 BN_print(out, Y); 465 BIO_printf(out, "\n"); 466 BN_CTX_end(ctx); 467 BN_CTX_free(ctx); 468 } 469 470 param_nid = 471 EC_GROUP_get_curve_name(EC_KEY_get0_group 472 (EVP_PKEY_get0((EVP_PKEY *)pkey))); 473 if (!BIO_indent(out, indent, 128)) 474 return 0; 475 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 476 return 1; 477} 478 479static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 480 ASN1_PCTX *pctx) 481{ 482 return print_gost_01(out, pkey, indent, pctx, 0); 483} 484 485static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 486 ASN1_PCTX *pctx) 487{ 488 return print_gost_01(out, pkey, indent, pctx, 1); 489} 490 491static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 492 ASN1_PCTX *pctx) 493{ 494 return print_gost_01(out, pkey, indent, pctx, 2); 495} 496 497/* ---------------------------------------------------------------------*/ 498static int param_missing_gost94(const EVP_PKEY *pk) 499{ 500 const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 501 if (!dsa) 502 return 1; 503 if (!dsa->q) 504 return 1; 505 return 0; 506} 507 508static int param_missing_gost01(const EVP_PKEY *pk) 509{ 510 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 511 if (!ec) 512 return 1; 513 if (!EC_KEY_get0_group(ec)) 514 return 1; 515 return 0; 516} 517 518static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 519{ 520 const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); 521 DSA *dto = EVP_PKEY_get0(to); 522 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 523 GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); 524 return 0; 525 } 526 if (!dfrom) { 527 GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); 528 return 0; 529 } 530 if (!dto) { 531 dto = DSA_new(); 532 EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); 533 } 534#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); 535 COPYBIGNUM(dto, dfrom, p) 536 COPYBIGNUM(dto, dfrom, q) 537 COPYBIGNUM(dto, dfrom, g) 538 539 if (dto->priv_key) 540 gost94_compute_public(dto); 541 return 1; 542} 543 544static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 545{ 546 EC_KEY *eto = EVP_PKEY_get0(to); 547 const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); 548 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 549 GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); 550 return 0; 551 } 552 if (!efrom) { 553 GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); 554 return 0; 555 } 556 if (!eto) { 557 eto = EC_KEY_new(); 558 if(!eto) { 559 GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); 560 return 0; 561 } 562 if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { 563 GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 564 return 0; 565 } 566 } 567 if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { 568 GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 569 return 0; 570 } 571 if (EC_KEY_get0_private_key(eto)) { 572 gost2001_compute_public(eto); 573 } 574 return 1; 575} 576 577static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 578{ 579 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 580 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 581 if (!BN_cmp(da->q, db->q)) 582 return 1; 583 return 0; 584} 585 586static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 587{ 588 if (EC_GROUP_get_curve_name 589 (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == 590 EC_GROUP_get_curve_name(EC_KEY_get0_group 591 (EVP_PKEY_get0((EVP_PKEY *)b)))) { 592 return 1; 593 } 594 return 0; 595 596} 597 598/* ---------- Public key functions * --------------------------------------*/ 599static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) 600{ 601 X509_ALGOR *palg = NULL; 602 const unsigned char *pubkey_buf = NULL; 603 unsigned char *databuf; 604 ASN1_OBJECT *palgobj = NULL; 605 int pub_len, i, j; 606 DSA *dsa; 607 ASN1_OCTET_STRING *octet = NULL; 608 609 if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 610 return 0; 611 EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 612 if (!decode_gost_algor_params(pk, palg)) 613 return 0; 614 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 615 if (!octet) { 616 GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); 617 return 0; 618 } 619 databuf = OPENSSL_malloc(octet->length); 620 for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 621 databuf[j] = octet->data[i]; 622 } 623 dsa = EVP_PKEY_get0(pk); 624 dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); 625 ASN1_OCTET_STRING_free(octet); 626 OPENSSL_free(databuf); 627 return 1; 628 629} 630 631static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) 632{ 633 ASN1_OBJECT *algobj = NULL; 634 ASN1_OCTET_STRING *octet = NULL; 635 void *pval = NULL; 636 unsigned char *buf = NULL, *databuf, *sptr; 637 int i, j, data_len, ret = 0; 638 639 int ptype = V_ASN1_UNDEF; 640 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 641 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 642 if (pk->save_parameters) { 643 ASN1_STRING *params = encode_gost_algor_params(pk); 644 pval = params; 645 ptype = V_ASN1_SEQUENCE; 646 } 647 data_len = BN_num_bytes(dsa->pub_key); 648 databuf = OPENSSL_malloc(data_len); 649 BN_bn2bin(dsa->pub_key, databuf); 650 octet = ASN1_OCTET_STRING_new(); 651 ASN1_STRING_set(octet, NULL, data_len); 652 sptr = ASN1_STRING_data(octet); 653 for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 654 sptr[i] = databuf[j]; 655 } 656 OPENSSL_free(databuf); 657 ret = i2d_ASN1_OCTET_STRING(octet, &buf); 658 ASN1_BIT_STRING_free(octet); 659 if (ret < 0) 660 return 0; 661 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 662} 663 664static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 665{ 666 X509_ALGOR *palg = NULL; 667 const unsigned char *pubkey_buf = NULL; 668 unsigned char *databuf; 669 ASN1_OBJECT *palgobj = NULL; 670 int pub_len, i, j; 671 EC_POINT *pub_key; 672 BIGNUM *X, *Y; 673 ASN1_OCTET_STRING *octet = NULL; 674 int len; 675 const EC_GROUP *group; 676 677 if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 678 return 0; 679 EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 680 if (!decode_gost_algor_params(pk, palg)) 681 return 0; 682 group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); 683 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 684 if (!octet) { 685 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 686 return 0; 687 } 688 databuf = OPENSSL_malloc(octet->length); 689 for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 690 databuf[j] = octet->data[i]; 691 } 692 len = octet->length / 2; 693 ASN1_OCTET_STRING_free(octet); 694 695 Y = getbnfrombuf(databuf, len); 696 X = getbnfrombuf(databuf + len, len); 697 OPENSSL_free(databuf); 698 pub_key = EC_POINT_new(group); 699 if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { 700 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 701 EC_POINT_free(pub_key); 702 BN_free(X); 703 BN_free(Y); 704 return 0; 705 } 706 BN_free(X); 707 BN_free(Y); 708 if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { 709 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 710 EC_POINT_free(pub_key); 711 return 0; 712 } 713 EC_POINT_free(pub_key); 714 return 1; 715 716} 717 718static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 719{ 720 ASN1_OBJECT *algobj = NULL; 721 ASN1_OCTET_STRING *octet = NULL; 722 void *pval = NULL; 723 unsigned char *buf = NULL, *databuf, *sptr; 724 int i, j, data_len, ret = 0; 725 const EC_POINT *pub_key; 726 BIGNUM *X, *Y, *order; 727 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 728 int ptype = V_ASN1_UNDEF; 729 730 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 731 if (pk->save_parameters) { 732 ASN1_STRING *params = encode_gost_algor_params(pk); 733 pval = params; 734 ptype = V_ASN1_SEQUENCE; 735 } 736 order = BN_new(); 737 EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); 738 pub_key = EC_KEY_get0_public_key(ec); 739 if (!pub_key) { 740 GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); 741 return 0; 742 } 743 X = BN_new(); 744 Y = BN_new(); 745 if(!X || !Y) { 746 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 747 if(X) BN_free(X); 748 if(Y) BN_free(Y); 749 BN_free(order); 750 return 0; 751 } 752 if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), 753 pub_key, X, Y, NULL)) { 754 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); 755 BN_free(X); 756 BN_free(Y); 757 BN_free(order); 758 return 0; 759 } 760 data_len = 2 * BN_num_bytes(order); 761 BN_free(order); 762 databuf = OPENSSL_malloc(data_len); 763 memset(databuf, 0, data_len); 764 765 store_bignum(X, databuf + data_len / 2, data_len / 2); 766 store_bignum(Y, databuf, data_len / 2); 767 768 BN_free(X); 769 BN_free(Y); 770 octet = ASN1_OCTET_STRING_new(); 771 ASN1_STRING_set(octet, NULL, data_len); 772 sptr = ASN1_STRING_data(octet); 773 for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 774 sptr[i] = databuf[j]; 775 } 776 OPENSSL_free(databuf); 777 ret = i2d_ASN1_OCTET_STRING(octet, &buf); 778 ASN1_BIT_STRING_free(octet); 779 if (ret < 0) 780 return 0; 781 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 782} 783 784static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 785{ 786 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 787 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 788 if (da && db && da->pub_key && db->pub_key 789 && !BN_cmp(da->pub_key, db->pub_key)) { 790 return 1; 791 } 792 return 0; 793} 794 795static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 796{ 797 const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); 798 const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); 799 const EC_POINT *ka, *kb; 800 int ret = 0; 801 if (!ea || !eb) 802 return 0; 803 ka = EC_KEY_get0_public_key(ea); 804 kb = EC_KEY_get0_public_key(eb); 805 if (!ka || !kb) 806 return 0; 807 ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); 808 return ret; 809} 810 811static int pkey_size_gost(const EVP_PKEY *pk) 812{ 813 return 64; 814} 815 816static int pkey_bits_gost(const EVP_PKEY *pk) 817{ 818 return 256; 819} 820 821/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ 822static void mackey_free_gost(EVP_PKEY *pk) 823{ 824 if (pk->pkey.ptr) { 825 OPENSSL_free(pk->pkey.ptr); 826 } 827} 828 829static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 830{ 831 switch (op) { 832 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 833 *(int *)arg2 = NID_id_Gost28147_89_MAC; 834 return 2; 835 } 836 return -2; 837} 838 839static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 840{ 841 int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 842 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 843} 844 845static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 846{ 847 int nid = 848 EC_GROUP_get_curve_name(EC_KEY_get0_group 849 (EVP_PKEY_get0((EVP_PKEY *)pkey))); 850 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 851} 852 853static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 854 int derlen) 855{ 856 ASN1_OBJECT *obj = NULL; 857 DSA *dsa = EVP_PKEY_get0(pkey); 858 int nid; 859 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 860 return 0; 861 } 862 nid = OBJ_obj2nid(obj); 863 ASN1_OBJECT_free(obj); 864 if (!dsa) { 865 dsa = DSA_new(); 866 if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) 867 return 0; 868 } 869 if (!fill_GOST94_params(dsa, nid)) 870 return 0; 871 return 1; 872} 873 874static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 875 int derlen) 876{ 877 ASN1_OBJECT *obj = NULL; 878 int nid; 879 EC_KEY *ec = EVP_PKEY_get0(pkey); 880 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 881 return 0; 882 } 883 nid = OBJ_obj2nid(obj); 884 ASN1_OBJECT_free(obj); 885 if (!ec) { 886 ec = EC_KEY_new(); 887 if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) 888 return 0; 889 } 890 if (!fill_GOST2001_params(ec, nid)) 891 return 0; 892 return 1; 893} 894 895/* ----------------------------------------------------------------------*/ 896int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, 897 const char *pemstr, const char *info) 898{ 899 *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 900 if (!*ameth) 901 return 0; 902 switch (nid) { 903 case NID_id_GostR3410_94: 904 EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); 905 EVP_PKEY_asn1_set_private(*ameth, 906 priv_decode_gost, priv_encode_gost, 907 priv_print_gost94); 908 909 EVP_PKEY_asn1_set_param(*ameth, 910 gost94_param_decode, gost94_param_encode, 911 param_missing_gost94, param_copy_gost94, 912 param_cmp_gost94, param_print_gost94); 913 EVP_PKEY_asn1_set_public(*ameth, 914 pub_decode_gost94, pub_encode_gost94, 915 pub_cmp_gost94, pub_print_gost94, 916 pkey_size_gost, pkey_bits_gost); 917 918 EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 919 break; 920 case NID_id_GostR3410_2001: 921 EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); 922 EVP_PKEY_asn1_set_private(*ameth, 923 priv_decode_gost, priv_encode_gost, 924 priv_print_gost01); 925 926 EVP_PKEY_asn1_set_param(*ameth, 927 gost2001_param_decode, gost2001_param_encode, 928 param_missing_gost01, param_copy_gost01, 929 param_cmp_gost01, param_print_gost01); 930 EVP_PKEY_asn1_set_public(*ameth, 931 pub_decode_gost01, pub_encode_gost01, 932 pub_cmp_gost01, pub_print_gost01, 933 pkey_size_gost, pkey_bits_gost); 934 935 EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 936 break; 937 case NID_id_Gost28147_89_MAC: 938 EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); 939 EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); 940 break; 941 } 942 return 1; 943} 944