1238384Sjkim/********************************************************************** 2238384Sjkim * gost_ameth.c * 3238384Sjkim * Copyright (c) 2005-2006 Cryptocom LTD * 4238384Sjkim * This file is distributed under the same license as OpenSSL * 5238384Sjkim * * 6238384Sjkim * Implementation of RFC 4490/4491 ASN1 method * 7238384Sjkim * for OpenSSL * 8238384Sjkim * Requires OpenSSL 0.9.9 for compilation * 9238384Sjkim **********************************************************************/ 10238384Sjkim#include <string.h> 11238384Sjkim#include <openssl/crypto.h> 12238384Sjkim#include <openssl/err.h> 13238384Sjkim#include <openssl/engine.h> 14238384Sjkim#include <openssl/evp.h> 15238384Sjkim#include <openssl/asn1.h> 16238384Sjkim#ifndef OPENSSL_NO_CMS 17296341Sdelphij# include <openssl/cms.h> 18238384Sjkim#endif 19238384Sjkim#include "gost_params.h" 20238384Sjkim#include "gost_lcl.h" 21238384Sjkim#include "e_gost_err.h" 22238384Sjkim 23296341Sdelphijint gost94_nid_by_params(DSA *p) 24296341Sdelphij{ 25296341Sdelphij R3410_params *gost_params; 26296341Sdelphij BIGNUM *q = BN_new(); 27296341Sdelphij for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { 28296341Sdelphij BN_dec2bn(&q, gost_params->q); 29296341Sdelphij if (!BN_cmp(q, p->q)) { 30296341Sdelphij BN_free(q); 31296341Sdelphij return gost_params->nid; 32296341Sdelphij } 33296341Sdelphij } 34296341Sdelphij BN_free(q); 35296341Sdelphij return NID_undef; 36296341Sdelphij} 37238384Sjkim 38296341Sdelphijstatic ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) 39296341Sdelphij{ 40296341Sdelphij ASN1_STRING *params = ASN1_STRING_new(); 41296341Sdelphij GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 42296341Sdelphij int pkey_param_nid = NID_undef; 43238384Sjkim 44296341Sdelphij if (!params || !gkp) { 45296341Sdelphij GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 46296341Sdelphij ASN1_STRING_free(params); 47296341Sdelphij params = NULL; 48296341Sdelphij goto err; 49296341Sdelphij } 50296341Sdelphij switch (EVP_PKEY_base_id(key)) { 51296341Sdelphij case NID_id_GostR3410_2001: 52296341Sdelphij pkey_param_nid = 53296341Sdelphij EC_GROUP_get_curve_name(EC_KEY_get0_group 54296341Sdelphij (EVP_PKEY_get0((EVP_PKEY *)key))); 55296341Sdelphij break; 56296341Sdelphij case NID_id_GostR3410_94: 57296341Sdelphij pkey_param_nid = 58296341Sdelphij (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); 59296341Sdelphij if (pkey_param_nid == NID_undef) { 60296341Sdelphij GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 61296341Sdelphij GOST_R_INVALID_GOST94_PARMSET); 62296341Sdelphij ASN1_STRING_free(params); 63296341Sdelphij params = NULL; 64296341Sdelphij goto err; 65296341Sdelphij } 66296341Sdelphij break; 67296341Sdelphij } 68296341Sdelphij gkp->key_params = OBJ_nid2obj(pkey_param_nid); 69296341Sdelphij gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); 70296341Sdelphij /* 71296341Sdelphij * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); 72296341Sdelphij */ 73296341Sdelphij params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 74296341Sdelphij if (params->length <= 0) { 75296341Sdelphij GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 76296341Sdelphij ASN1_STRING_free(params); 77296341Sdelphij params = NULL; 78296341Sdelphij goto err; 79296341Sdelphij } 80296341Sdelphij params->type = V_ASN1_SEQUENCE; 81296341Sdelphij err: 82296341Sdelphij GOST_KEY_PARAMS_free(gkp); 83296341Sdelphij return params; 84296341Sdelphij} 85238384Sjkim 86296341Sdelphij/* 87296341Sdelphij * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting 88296341Sdelphij * NID and parameters 89238384Sjkim */ 90296341Sdelphijstatic int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 91296341Sdelphij{ 92296341Sdelphij ASN1_OBJECT *palg_obj = NULL; 93296341Sdelphij int ptype = V_ASN1_UNDEF; 94296341Sdelphij int pkey_nid = NID_undef, param_nid = NID_undef; 95296341Sdelphij void *_pval; 96296341Sdelphij ASN1_STRING *pval = NULL; 97296341Sdelphij const unsigned char *p; 98296341Sdelphij GOST_KEY_PARAMS *gkp = NULL; 99238384Sjkim 100296341Sdelphij X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); 101296341Sdelphij pval = _pval; 102296341Sdelphij if (ptype != V_ASN1_SEQUENCE) { 103296341Sdelphij GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 104296341Sdelphij GOST_R_BAD_KEY_PARAMETERS_FORMAT); 105296341Sdelphij return 0; 106296341Sdelphij } 107296341Sdelphij p = pval->data; 108296341Sdelphij pkey_nid = OBJ_obj2nid(palg_obj); 109238384Sjkim 110296341Sdelphij gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); 111296341Sdelphij if (!gkp) { 112296341Sdelphij GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 113296341Sdelphij GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 114296341Sdelphij return 0; 115296341Sdelphij } 116296341Sdelphij param_nid = OBJ_obj2nid(gkp->key_params); 117296341Sdelphij GOST_KEY_PARAMS_free(gkp); 118296341Sdelphij if(!EVP_PKEY_set_type(pkey, pkey_nid)) { 119296341Sdelphij GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); 120296341Sdelphij return 0; 121296341Sdelphij } 122296341Sdelphij switch (pkey_nid) { 123296341Sdelphij case NID_id_GostR3410_94: 124296341Sdelphij { 125296341Sdelphij DSA *dsa = EVP_PKEY_get0(pkey); 126296341Sdelphij if (!dsa) { 127296341Sdelphij dsa = DSA_new(); 128296341Sdelphij if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) 129296341Sdelphij return 0; 130296341Sdelphij } 131296341Sdelphij if (!fill_GOST94_params(dsa, param_nid)) 132296341Sdelphij return 0; 133296341Sdelphij break; 134296341Sdelphij } 135296341Sdelphij case NID_id_GostR3410_2001: 136296341Sdelphij { 137296341Sdelphij EC_KEY *ec = EVP_PKEY_get0(pkey); 138296341Sdelphij if (!ec) { 139296341Sdelphij ec = EC_KEY_new(); 140296341Sdelphij if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) 141296341Sdelphij return 0; 142296341Sdelphij } 143296341Sdelphij if (!fill_GOST2001_params(ec, param_nid)) 144296341Sdelphij return 0; 145296341Sdelphij } 146296341Sdelphij } 147238384Sjkim 148296341Sdelphij return 1; 149296341Sdelphij} 150238384Sjkim 151296341Sdelphijstatic int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) 152296341Sdelphij{ 153296341Sdelphij switch (EVP_PKEY_base_id(pkey)) { 154296341Sdelphij case NID_id_GostR3410_94: 155296341Sdelphij { 156296341Sdelphij DSA *dsa = EVP_PKEY_get0(pkey); 157296341Sdelphij if (!dsa) { 158296341Sdelphij dsa = DSA_new(); 159296341Sdelphij EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); 160296341Sdelphij } 161296341Sdelphij dsa->priv_key = BN_dup(priv); 162296341Sdelphij if (!EVP_PKEY_missing_parameters(pkey)) 163296341Sdelphij gost94_compute_public(dsa); 164296341Sdelphij break; 165296341Sdelphij } 166296341Sdelphij case NID_id_GostR3410_2001: 167296341Sdelphij { 168296341Sdelphij EC_KEY *ec = EVP_PKEY_get0(pkey); 169296341Sdelphij if (!ec) { 170296341Sdelphij ec = EC_KEY_new(); 171296341Sdelphij EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); 172296341Sdelphij } 173296341Sdelphij if (!EC_KEY_set_private_key(ec, priv)) 174296341Sdelphij return 0; 175296341Sdelphij if (!EVP_PKEY_missing_parameters(pkey)) 176296341Sdelphij gost2001_compute_public(ec); 177296341Sdelphij break; 178296341Sdelphij } 179296341Sdelphij } 180296341Sdelphij return 1; 181296341Sdelphij} 182238384Sjkim 183296341SdelphijBIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) 184296341Sdelphij{ 185296341Sdelphij switch (EVP_PKEY_base_id(pkey)) { 186296341Sdelphij case NID_id_GostR3410_94: 187296341Sdelphij { 188296341Sdelphij DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); 189296341Sdelphij if (!dsa) { 190296341Sdelphij return NULL; 191296341Sdelphij } 192296341Sdelphij if (!dsa->priv_key) 193296341Sdelphij return NULL; 194296341Sdelphij return dsa->priv_key; 195296341Sdelphij break; 196296341Sdelphij } 197296341Sdelphij case NID_id_GostR3410_2001: 198296341Sdelphij { 199296341Sdelphij EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); 200296341Sdelphij const BIGNUM *priv; 201296341Sdelphij if (!ec) { 202296341Sdelphij return NULL; 203296341Sdelphij } 204296341Sdelphij if (!(priv = EC_KEY_get0_private_key(ec))) 205296341Sdelphij return NULL; 206296341Sdelphij return (BIGNUM *)priv; 207296341Sdelphij break; 208296341Sdelphij } 209296341Sdelphij } 210296341Sdelphij return NULL; 211296341Sdelphij} 212296341Sdelphij 213296341Sdelphijstatic int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 214296341Sdelphij{ 215296341Sdelphij switch (op) { 216296341Sdelphij case ASN1_PKEY_CTRL_PKCS7_SIGN: 217296341Sdelphij if (arg1 == 0) { 218296341Sdelphij X509_ALGOR *alg1 = NULL, *alg2 = NULL; 219296341Sdelphij int nid = EVP_PKEY_base_id(pkey); 220296341Sdelphij PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, 221296341Sdelphij NULL, &alg1, &alg2); 222296341Sdelphij X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 223296341Sdelphij V_ASN1_NULL, 0); 224296341Sdelphij if (nid == NID_undef) { 225296341Sdelphij return (-1); 226296341Sdelphij } 227296341Sdelphij X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 228296341Sdelphij } 229296341Sdelphij return 1; 230238384Sjkim#ifndef OPENSSL_NO_CMS 231296341Sdelphij case ASN1_PKEY_CTRL_CMS_SIGN: 232296341Sdelphij if (arg1 == 0) { 233296341Sdelphij X509_ALGOR *alg1 = NULL, *alg2 = NULL; 234296341Sdelphij int nid = EVP_PKEY_base_id(pkey); 235296341Sdelphij CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 236296341Sdelphij NULL, NULL, &alg1, &alg2); 237296341Sdelphij X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 238296341Sdelphij V_ASN1_NULL, 0); 239296341Sdelphij if (nid == NID_undef) { 240296341Sdelphij return (-1); 241296341Sdelphij } 242296341Sdelphij X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 243296341Sdelphij } 244296341Sdelphij return 1; 245238384Sjkim#endif 246296341Sdelphij case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 247296341Sdelphij if (arg1 == 0) { 248296341Sdelphij X509_ALGOR *alg; 249296341Sdelphij ASN1_STRING *params = encode_gost_algor_params(pkey); 250296341Sdelphij if (!params) { 251296341Sdelphij return -1; 252296341Sdelphij } 253296341Sdelphij PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); 254296341Sdelphij X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 255296341Sdelphij V_ASN1_SEQUENCE, params); 256296341Sdelphij } 257296341Sdelphij return 1; 258238384Sjkim#ifndef OPENSSL_NO_CMS 259296341Sdelphij case ASN1_PKEY_CTRL_CMS_ENVELOPE: 260296341Sdelphij if (arg1 == 0) { 261296341Sdelphij X509_ALGOR *alg = NULL; 262296341Sdelphij ASN1_STRING *params = encode_gost_algor_params(pkey); 263296341Sdelphij if (!params) { 264296341Sdelphij return -1; 265296341Sdelphij } 266296341Sdelphij CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, 267296341Sdelphij NULL, &alg); 268296341Sdelphij X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, 269296341Sdelphij params); 270296341Sdelphij } 271296341Sdelphij return 1; 272238384Sjkim#endif 273296341Sdelphij case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 274296341Sdelphij *(int *)arg2 = NID_id_GostR3411_94; 275296341Sdelphij return 2; 276296341Sdelphij } 277238384Sjkim 278296341Sdelphij return -2; 279296341Sdelphij} 280238384Sjkim 281296341Sdelphij/* --------------------- free functions * ------------------------------*/ 282296341Sdelphijstatic void pkey_free_gost94(EVP_PKEY *key) 283296341Sdelphij{ 284296341Sdelphij if (key->pkey.dsa) { 285296341Sdelphij DSA_free(key->pkey.dsa); 286296341Sdelphij } 287296341Sdelphij} 288296341Sdelphij 289296341Sdelphijstatic void pkey_free_gost01(EVP_PKEY *key) 290296341Sdelphij{ 291296341Sdelphij if (key->pkey.ec) { 292296341Sdelphij EC_KEY_free(key->pkey.ec); 293296341Sdelphij } 294296341Sdelphij} 295296341Sdelphij 296238384Sjkim/* ------------------ private key functions -----------------------------*/ 297296341Sdelphijstatic int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 298296341Sdelphij{ 299296341Sdelphij const unsigned char *pkey_buf = NULL, *p = NULL; 300296341Sdelphij int priv_len = 0; 301296341Sdelphij BIGNUM *pk_num = NULL; 302296341Sdelphij int ret = 0; 303296341Sdelphij X509_ALGOR *palg = NULL; 304296341Sdelphij ASN1_OBJECT *palg_obj = NULL; 305296341Sdelphij ASN1_INTEGER *priv_key = NULL; 306238384Sjkim 307296341Sdelphij if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) 308296341Sdelphij return 0; 309296341Sdelphij p = pkey_buf; 310296341Sdelphij if (!decode_gost_algor_params(pk, palg)) { 311296341Sdelphij return 0; 312296341Sdelphij } 313296341Sdelphij if (V_ASN1_OCTET_STRING == *p) { 314296341Sdelphij /* New format - Little endian octet string */ 315296341Sdelphij unsigned char rev_buf[32]; 316296341Sdelphij int i; 317296341Sdelphij ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 318296341Sdelphij if (!s || s->length != 32) { 319296341Sdelphij GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 320296341Sdelphij return 0; 321296341Sdelphij } 322296341Sdelphij for (i = 0; i < 32; i++) { 323296341Sdelphij rev_buf[31 - i] = s->data[i]; 324296341Sdelphij } 325296341Sdelphij ASN1_STRING_free(s); 326296341Sdelphij pk_num = getbnfrombuf(rev_buf, 32); 327296341Sdelphij } else { 328296341Sdelphij priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 329296341Sdelphij if (!priv_key) 330296341Sdelphij return 0; 331296341Sdelphij ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 332296341Sdelphij ASN1_INTEGER_free(priv_key); 333296341Sdelphij if (!ret) { 334296341Sdelphij GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 335296341Sdelphij return 0; 336296341Sdelphij } 337296341Sdelphij } 338238384Sjkim 339296341Sdelphij ret = gost_set_priv_key(pk, pk_num); 340296341Sdelphij BN_free(pk_num); 341296341Sdelphij return ret; 342296341Sdelphij} 343238384Sjkim 344238384Sjkim/* ----------------------------------------------------------------------*/ 345238384Sjkimstatic int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 346296341Sdelphij{ 347296341Sdelphij ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 348296341Sdelphij ASN1_STRING *params = encode_gost_algor_params(pk); 349296341Sdelphij unsigned char *priv_buf = NULL; 350296341Sdelphij int priv_len; 351238384Sjkim 352296341Sdelphij ASN1_INTEGER *asn1key = NULL; 353296341Sdelphij if (!params) { 354296341Sdelphij return 0; 355296341Sdelphij } 356296341Sdelphij asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); 357296341Sdelphij priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 358296341Sdelphij ASN1_INTEGER_free(asn1key); 359296341Sdelphij return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, 360296341Sdelphij priv_buf, priv_len); 361296341Sdelphij} 362296341Sdelphij 363238384Sjkim/* --------- printing keys --------------------------------*/ 364238384Sjkimstatic int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, 365296341Sdelphij ASN1_PCTX *pctx, int type) 366296341Sdelphij{ 367296341Sdelphij int param_nid = NID_undef; 368238384Sjkim 369296341Sdelphij if (type == 2) { 370296341Sdelphij BIGNUM *key; 371238384Sjkim 372296341Sdelphij if (!BIO_indent(out, indent, 128)) 373296341Sdelphij return 0; 374296341Sdelphij BIO_printf(out, "Private key: "); 375296341Sdelphij key = gost_get0_priv_key(pkey); 376296341Sdelphij if (!key) 377296341Sdelphij BIO_printf(out, "<undefined>"); 378296341Sdelphij else 379296341Sdelphij BN_print(out, key); 380296341Sdelphij BIO_printf(out, "\n"); 381296341Sdelphij } 382296341Sdelphij if (type >= 1) { 383296341Sdelphij BIGNUM *pubkey; 384238384Sjkim 385296341Sdelphij pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; 386296341Sdelphij BIO_indent(out, indent, 128); 387296341Sdelphij BIO_printf(out, "Public key: "); 388296341Sdelphij BN_print(out, pubkey); 389296341Sdelphij BIO_printf(out, "\n"); 390296341Sdelphij } 391296341Sdelphij 392296341Sdelphij param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 393296341Sdelphij BIO_indent(out, indent, 128); 394296341Sdelphij BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 395296341Sdelphij return 1; 396238384Sjkim} 397238384Sjkim 398238384Sjkimstatic int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 399296341Sdelphij ASN1_PCTX *pctx) 400296341Sdelphij{ 401296341Sdelphij return print_gost_94(out, pkey, indent, pctx, 0); 402296341Sdelphij} 403238384Sjkim 404238384Sjkimstatic int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 405296341Sdelphij ASN1_PCTX *pctx) 406296341Sdelphij{ 407296341Sdelphij return print_gost_94(out, pkey, indent, pctx, 1); 408296341Sdelphij} 409238384Sjkim 410296341Sdelphijstatic int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 411296341Sdelphij ASN1_PCTX *pctx) 412296341Sdelphij{ 413296341Sdelphij return print_gost_94(out, pkey, indent, pctx, 2); 414296341Sdelphij} 415296341Sdelphij 416238384Sjkimstatic int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, 417296341Sdelphij ASN1_PCTX *pctx, int type) 418296341Sdelphij{ 419296341Sdelphij int param_nid = NID_undef; 420296341Sdelphij if (type == 2) { 421296341Sdelphij BIGNUM *key; 422238384Sjkim 423296341Sdelphij if (!BIO_indent(out, indent, 128)) 424296341Sdelphij return 0; 425296341Sdelphij BIO_printf(out, "Private key: "); 426296341Sdelphij key = gost_get0_priv_key(pkey); 427296341Sdelphij if (!key) 428296341Sdelphij BIO_printf(out, "<undefined)"); 429296341Sdelphij else 430296341Sdelphij BN_print(out, key); 431296341Sdelphij BIO_printf(out, "\n"); 432296341Sdelphij } 433296341Sdelphij if (type >= 1) { 434296341Sdelphij BN_CTX *ctx = BN_CTX_new(); 435296341Sdelphij BIGNUM *X, *Y; 436296341Sdelphij const EC_POINT *pubkey; 437296341Sdelphij const EC_GROUP *group; 438238384Sjkim 439296341Sdelphij if (!ctx) { 440296341Sdelphij GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); 441296341Sdelphij return 0; 442296341Sdelphij } 443296341Sdelphij BN_CTX_start(ctx); 444296341Sdelphij X = BN_CTX_get(ctx); 445296341Sdelphij Y = BN_CTX_get(ctx); 446296341Sdelphij pubkey = 447296341Sdelphij EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 448296341Sdelphij group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 449296341Sdelphij if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { 450296341Sdelphij GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); 451296341Sdelphij BN_CTX_free(ctx); 452296341Sdelphij return 0; 453296341Sdelphij } 454296341Sdelphij if (!BIO_indent(out, indent, 128)) 455296341Sdelphij return 0; 456296341Sdelphij BIO_printf(out, "Public key:\n"); 457296341Sdelphij if (!BIO_indent(out, indent + 3, 128)) 458296341Sdelphij return 0; 459296341Sdelphij BIO_printf(out, "X:"); 460296341Sdelphij BN_print(out, X); 461296341Sdelphij BIO_printf(out, "\n"); 462296341Sdelphij BIO_indent(out, indent + 3, 128); 463296341Sdelphij BIO_printf(out, "Y:"); 464296341Sdelphij BN_print(out, Y); 465296341Sdelphij BIO_printf(out, "\n"); 466296341Sdelphij BN_CTX_end(ctx); 467296341Sdelphij BN_CTX_free(ctx); 468296341Sdelphij } 469238384Sjkim 470296341Sdelphij param_nid = 471296341Sdelphij EC_GROUP_get_curve_name(EC_KEY_get0_group 472296341Sdelphij (EVP_PKEY_get0((EVP_PKEY *)pkey))); 473296341Sdelphij if (!BIO_indent(out, indent, 128)) 474296341Sdelphij return 0; 475296341Sdelphij BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 476296341Sdelphij return 1; 477238384Sjkim} 478296341Sdelphij 479238384Sjkimstatic int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 480296341Sdelphij ASN1_PCTX *pctx) 481296341Sdelphij{ 482296341Sdelphij return print_gost_01(out, pkey, indent, pctx, 0); 483296341Sdelphij} 484296341Sdelphij 485238384Sjkimstatic int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 486296341Sdelphij ASN1_PCTX *pctx) 487296341Sdelphij{ 488296341Sdelphij return print_gost_01(out, pkey, indent, pctx, 1); 489296341Sdelphij} 490296341Sdelphij 491296341Sdelphijstatic int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 492296341Sdelphij ASN1_PCTX *pctx) 493296341Sdelphij{ 494296341Sdelphij return print_gost_01(out, pkey, indent, pctx, 2); 495296341Sdelphij} 496296341Sdelphij 497238384Sjkim/* ---------------------------------------------------------------------*/ 498296341Sdelphijstatic int param_missing_gost94(const EVP_PKEY *pk) 499296341Sdelphij{ 500296341Sdelphij const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 501296341Sdelphij if (!dsa) 502296341Sdelphij return 1; 503296341Sdelphij if (!dsa->q) 504296341Sdelphij return 1; 505296341Sdelphij return 0; 506296341Sdelphij} 507238384Sjkim 508296341Sdelphijstatic int param_missing_gost01(const EVP_PKEY *pk) 509296341Sdelphij{ 510296341Sdelphij const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 511296341Sdelphij if (!ec) 512296341Sdelphij return 1; 513296341Sdelphij if (!EC_KEY_get0_group(ec)) 514296341Sdelphij return 1; 515296341Sdelphij return 0; 516296341Sdelphij} 517238384Sjkim 518296341Sdelphijstatic int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 519296341Sdelphij{ 520296341Sdelphij const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); 521296341Sdelphij DSA *dto = EVP_PKEY_get0(to); 522296341Sdelphij if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 523296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); 524296341Sdelphij return 0; 525296341Sdelphij } 526296341Sdelphij if (!dfrom) { 527296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); 528296341Sdelphij return 0; 529296341Sdelphij } 530296341Sdelphij if (!dto) { 531296341Sdelphij dto = DSA_new(); 532296341Sdelphij EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); 533296341Sdelphij } 534296341Sdelphij#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); 535296341Sdelphij COPYBIGNUM(dto, dfrom, p) 536296341Sdelphij COPYBIGNUM(dto, dfrom, q) 537296341Sdelphij COPYBIGNUM(dto, dfrom, g) 538238384Sjkim 539296341Sdelphij if (dto->priv_key) 540296341Sdelphij gost94_compute_public(dto); 541296341Sdelphij return 1; 542296341Sdelphij} 543238384Sjkim 544296341Sdelphijstatic int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 545296341Sdelphij{ 546296341Sdelphij EC_KEY *eto = EVP_PKEY_get0(to); 547296341Sdelphij const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); 548296341Sdelphij if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 549296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); 550296341Sdelphij return 0; 551296341Sdelphij } 552296341Sdelphij if (!efrom) { 553296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); 554296341Sdelphij return 0; 555296341Sdelphij } 556296341Sdelphij if (!eto) { 557296341Sdelphij eto = EC_KEY_new(); 558296341Sdelphij if(!eto) { 559296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); 560296341Sdelphij return 0; 561296341Sdelphij } 562296341Sdelphij if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { 563296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 564296341Sdelphij return 0; 565296341Sdelphij } 566296341Sdelphij } 567296341Sdelphij if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { 568296341Sdelphij GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 569296341Sdelphij return 0; 570296341Sdelphij } 571296341Sdelphij if (EC_KEY_get0_private_key(eto)) { 572296341Sdelphij gost2001_compute_public(eto); 573296341Sdelphij } 574296341Sdelphij return 1; 575296341Sdelphij} 576238384Sjkim 577296341Sdelphijstatic int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 578296341Sdelphij{ 579296341Sdelphij const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 580296341Sdelphij const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 581296341Sdelphij if (!BN_cmp(da->q, db->q)) 582296341Sdelphij return 1; 583296341Sdelphij return 0; 584296341Sdelphij} 585238384Sjkim 586296341Sdelphijstatic int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 587296341Sdelphij{ 588296341Sdelphij if (EC_GROUP_get_curve_name 589296341Sdelphij (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == 590296341Sdelphij EC_GROUP_get_curve_name(EC_KEY_get0_group 591296341Sdelphij (EVP_PKEY_get0((EVP_PKEY *)b)))) { 592296341Sdelphij return 1; 593296341Sdelphij } 594296341Sdelphij return 0; 595238384Sjkim 596296341Sdelphij} 597296341Sdelphij 598238384Sjkim/* ---------- Public key functions * --------------------------------------*/ 599238384Sjkimstatic int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) 600296341Sdelphij{ 601296341Sdelphij X509_ALGOR *palg = NULL; 602296341Sdelphij const unsigned char *pubkey_buf = NULL; 603296341Sdelphij unsigned char *databuf; 604296341Sdelphij ASN1_OBJECT *palgobj = NULL; 605296341Sdelphij int pub_len, i, j; 606296341Sdelphij DSA *dsa; 607296341Sdelphij ASN1_OCTET_STRING *octet = NULL; 608238384Sjkim 609296341Sdelphij if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 610296341Sdelphij return 0; 611296341Sdelphij EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 612296341Sdelphij if (!decode_gost_algor_params(pk, palg)) 613296341Sdelphij return 0; 614296341Sdelphij octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 615296341Sdelphij if (!octet) { 616296341Sdelphij GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); 617296341Sdelphij return 0; 618296341Sdelphij } 619296341Sdelphij databuf = OPENSSL_malloc(octet->length); 620296341Sdelphij for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 621296341Sdelphij databuf[j] = octet->data[i]; 622296341Sdelphij } 623296341Sdelphij dsa = EVP_PKEY_get0(pk); 624296341Sdelphij dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); 625296341Sdelphij ASN1_OCTET_STRING_free(octet); 626296341Sdelphij OPENSSL_free(databuf); 627296341Sdelphij return 1; 628238384Sjkim 629296341Sdelphij} 630238384Sjkim 631296341Sdelphijstatic int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) 632296341Sdelphij{ 633296341Sdelphij ASN1_OBJECT *algobj = NULL; 634296341Sdelphij ASN1_OCTET_STRING *octet = NULL; 635296341Sdelphij void *pval = NULL; 636296341Sdelphij unsigned char *buf = NULL, *databuf, *sptr; 637296341Sdelphij int i, j, data_len, ret = 0; 638238384Sjkim 639296341Sdelphij int ptype = V_ASN1_UNDEF; 640296341Sdelphij DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 641296341Sdelphij algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 642296341Sdelphij if (pk->save_parameters) { 643296341Sdelphij ASN1_STRING *params = encode_gost_algor_params(pk); 644296341Sdelphij pval = params; 645296341Sdelphij ptype = V_ASN1_SEQUENCE; 646296341Sdelphij } 647296341Sdelphij data_len = BN_num_bytes(dsa->pub_key); 648296341Sdelphij databuf = OPENSSL_malloc(data_len); 649296341Sdelphij BN_bn2bin(dsa->pub_key, databuf); 650296341Sdelphij octet = ASN1_OCTET_STRING_new(); 651296341Sdelphij ASN1_STRING_set(octet, NULL, data_len); 652296341Sdelphij sptr = ASN1_STRING_data(octet); 653296341Sdelphij for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 654296341Sdelphij sptr[i] = databuf[j]; 655296341Sdelphij } 656296341Sdelphij OPENSSL_free(databuf); 657296341Sdelphij ret = i2d_ASN1_OCTET_STRING(octet, &buf); 658296341Sdelphij ASN1_BIT_STRING_free(octet); 659296341Sdelphij if (ret < 0) 660296341Sdelphij return 0; 661296341Sdelphij return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 662296341Sdelphij} 663238384Sjkim 664296341Sdelphijstatic int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 665296341Sdelphij{ 666296341Sdelphij X509_ALGOR *palg = NULL; 667296341Sdelphij const unsigned char *pubkey_buf = NULL; 668296341Sdelphij unsigned char *databuf; 669296341Sdelphij ASN1_OBJECT *palgobj = NULL; 670296341Sdelphij int pub_len, i, j; 671296341Sdelphij EC_POINT *pub_key; 672296341Sdelphij BIGNUM *X, *Y; 673296341Sdelphij ASN1_OCTET_STRING *octet = NULL; 674296341Sdelphij int len; 675296341Sdelphij const EC_GROUP *group; 676238384Sjkim 677296341Sdelphij if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 678296341Sdelphij return 0; 679296341Sdelphij EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 680296341Sdelphij if (!decode_gost_algor_params(pk, palg)) 681296341Sdelphij return 0; 682296341Sdelphij group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); 683296341Sdelphij octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 684296341Sdelphij if (!octet) { 685296341Sdelphij GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 686296341Sdelphij return 0; 687296341Sdelphij } 688296341Sdelphij databuf = OPENSSL_malloc(octet->length); 689296341Sdelphij for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 690296341Sdelphij databuf[j] = octet->data[i]; 691296341Sdelphij } 692296341Sdelphij len = octet->length / 2; 693296341Sdelphij ASN1_OCTET_STRING_free(octet); 694238384Sjkim 695296341Sdelphij Y = getbnfrombuf(databuf, len); 696296341Sdelphij X = getbnfrombuf(databuf + len, len); 697296341Sdelphij OPENSSL_free(databuf); 698296341Sdelphij pub_key = EC_POINT_new(group); 699296341Sdelphij if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { 700296341Sdelphij GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 701296341Sdelphij EC_POINT_free(pub_key); 702296341Sdelphij BN_free(X); 703296341Sdelphij BN_free(Y); 704296341Sdelphij return 0; 705296341Sdelphij } 706296341Sdelphij BN_free(X); 707296341Sdelphij BN_free(Y); 708296341Sdelphij if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { 709296341Sdelphij GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 710296341Sdelphij EC_POINT_free(pub_key); 711296341Sdelphij return 0; 712296341Sdelphij } 713296341Sdelphij EC_POINT_free(pub_key); 714296341Sdelphij return 1; 715238384Sjkim 716296341Sdelphij} 717238384Sjkim 718296341Sdelphijstatic int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 719296341Sdelphij{ 720296341Sdelphij ASN1_OBJECT *algobj = NULL; 721296341Sdelphij ASN1_OCTET_STRING *octet = NULL; 722296341Sdelphij void *pval = NULL; 723296341Sdelphij unsigned char *buf = NULL, *databuf, *sptr; 724296341Sdelphij int i, j, data_len, ret = 0; 725296341Sdelphij const EC_POINT *pub_key; 726296341Sdelphij BIGNUM *X, *Y, *order; 727296341Sdelphij const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 728296341Sdelphij int ptype = V_ASN1_UNDEF; 729238384Sjkim 730296341Sdelphij algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 731296341Sdelphij if (pk->save_parameters) { 732296341Sdelphij ASN1_STRING *params = encode_gost_algor_params(pk); 733296341Sdelphij pval = params; 734296341Sdelphij ptype = V_ASN1_SEQUENCE; 735296341Sdelphij } 736296341Sdelphij order = BN_new(); 737296341Sdelphij EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); 738296341Sdelphij pub_key = EC_KEY_get0_public_key(ec); 739296341Sdelphij if (!pub_key) { 740296341Sdelphij GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); 741296341Sdelphij return 0; 742296341Sdelphij } 743296341Sdelphij X = BN_new(); 744296341Sdelphij Y = BN_new(); 745296341Sdelphij if(!X || !Y) { 746296341Sdelphij GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 747296341Sdelphij if(X) BN_free(X); 748296341Sdelphij if(Y) BN_free(Y); 749296341Sdelphij BN_free(order); 750296341Sdelphij return 0; 751296341Sdelphij } 752296341Sdelphij if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), 753296341Sdelphij pub_key, X, Y, NULL)) { 754296341Sdelphij GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); 755296341Sdelphij BN_free(X); 756296341Sdelphij BN_free(Y); 757296341Sdelphij BN_free(order); 758296341Sdelphij return 0; 759296341Sdelphij } 760296341Sdelphij data_len = 2 * BN_num_bytes(order); 761296341Sdelphij BN_free(order); 762296341Sdelphij databuf = OPENSSL_malloc(data_len); 763296341Sdelphij memset(databuf, 0, data_len); 764296341Sdelphij 765296341Sdelphij store_bignum(X, databuf + data_len / 2, data_len / 2); 766296341Sdelphij store_bignum(Y, databuf, data_len / 2); 767296341Sdelphij 768296341Sdelphij BN_free(X); 769296341Sdelphij BN_free(Y); 770296341Sdelphij octet = ASN1_OCTET_STRING_new(); 771296341Sdelphij ASN1_STRING_set(octet, NULL, data_len); 772296341Sdelphij sptr = ASN1_STRING_data(octet); 773296341Sdelphij for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 774296341Sdelphij sptr[i] = databuf[j]; 775296341Sdelphij } 776238384Sjkim OPENSSL_free(databuf); 777296341Sdelphij ret = i2d_ASN1_OCTET_STRING(octet, &buf); 778296341Sdelphij ASN1_BIT_STRING_free(octet); 779296341Sdelphij if (ret < 0) 780296341Sdelphij return 0; 781296341Sdelphij return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 782296341Sdelphij} 783238384Sjkim 784238384Sjkimstatic int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 785296341Sdelphij{ 786296341Sdelphij const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 787296341Sdelphij const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 788296341Sdelphij if (da && db && da->pub_key && db->pub_key 789296341Sdelphij && !BN_cmp(da->pub_key, db->pub_key)) { 790296341Sdelphij return 1; 791296341Sdelphij } 792296341Sdelphij return 0; 793296341Sdelphij} 794238384Sjkim 795296341Sdelphijstatic int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 796296341Sdelphij{ 797296341Sdelphij const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); 798296341Sdelphij const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); 799296341Sdelphij const EC_POINT *ka, *kb; 800296341Sdelphij int ret = 0; 801296341Sdelphij if (!ea || !eb) 802296341Sdelphij return 0; 803296341Sdelphij ka = EC_KEY_get0_public_key(ea); 804296341Sdelphij kb = EC_KEY_get0_public_key(eb); 805296341Sdelphij if (!ka || !kb) 806296341Sdelphij return 0; 807296341Sdelphij ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); 808296341Sdelphij return ret; 809296341Sdelphij} 810238384Sjkim 811238384Sjkimstatic int pkey_size_gost(const EVP_PKEY *pk) 812296341Sdelphij{ 813296341Sdelphij return 64; 814296341Sdelphij} 815238384Sjkim 816238384Sjkimstatic int pkey_bits_gost(const EVP_PKEY *pk) 817238384Sjkim{ 818296341Sdelphij return 256; 819296341Sdelphij} 820238384Sjkim 821296341Sdelphij/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ 822296341Sdelphijstatic void mackey_free_gost(EVP_PKEY *pk) 823238384Sjkim{ 824296341Sdelphij if (pk->pkey.ptr) { 825296341Sdelphij OPENSSL_free(pk->pkey.ptr); 826296341Sdelphij } 827238384Sjkim} 828296341Sdelphij 829296341Sdelphijstatic int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 830238384Sjkim{ 831296341Sdelphij switch (op) { 832296341Sdelphij case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 833296341Sdelphij *(int *)arg2 = NID_id_Gost28147_89_MAC; 834296341Sdelphij return 2; 835296341Sdelphij } 836296341Sdelphij return -2; 837238384Sjkim} 838238384Sjkim 839296341Sdelphijstatic int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 840238384Sjkim{ 841296341Sdelphij int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 842296341Sdelphij return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 843296341Sdelphij} 844238384Sjkim 845296341Sdelphijstatic int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 846296341Sdelphij{ 847296341Sdelphij int nid = 848296341Sdelphij EC_GROUP_get_curve_name(EC_KEY_get0_group 849296341Sdelphij (EVP_PKEY_get0((EVP_PKEY *)pkey))); 850296341Sdelphij return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 851296341Sdelphij} 852238384Sjkim 853296341Sdelphijstatic int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 854296341Sdelphij int derlen) 855296341Sdelphij{ 856296341Sdelphij ASN1_OBJECT *obj = NULL; 857296341Sdelphij DSA *dsa = EVP_PKEY_get0(pkey); 858296341Sdelphij int nid; 859296341Sdelphij if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 860296341Sdelphij return 0; 861296341Sdelphij } 862296341Sdelphij nid = OBJ_obj2nid(obj); 863296341Sdelphij ASN1_OBJECT_free(obj); 864296341Sdelphij if (!dsa) { 865296341Sdelphij dsa = DSA_new(); 866296341Sdelphij if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) 867296341Sdelphij return 0; 868296341Sdelphij } 869296341Sdelphij if (!fill_GOST94_params(dsa, nid)) 870296341Sdelphij return 0; 871296341Sdelphij return 1; 872296341Sdelphij} 873238384Sjkim 874296341Sdelphijstatic int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 875296341Sdelphij int derlen) 876296341Sdelphij{ 877296341Sdelphij ASN1_OBJECT *obj = NULL; 878296341Sdelphij int nid; 879296341Sdelphij EC_KEY *ec = EVP_PKEY_get0(pkey); 880296341Sdelphij if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 881296341Sdelphij return 0; 882296341Sdelphij } 883296341Sdelphij nid = OBJ_obj2nid(obj); 884296341Sdelphij ASN1_OBJECT_free(obj); 885296341Sdelphij if (!ec) { 886296341Sdelphij ec = EC_KEY_new(); 887296341Sdelphij if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) 888296341Sdelphij return 0; 889296341Sdelphij } 890296341Sdelphij if (!fill_GOST2001_params(ec, nid)) 891296341Sdelphij return 0; 892296341Sdelphij return 1; 893296341Sdelphij} 894238384Sjkim 895296341Sdelphij/* ----------------------------------------------------------------------*/ 896296341Sdelphijint register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, 897296341Sdelphij const char *pemstr, const char *info) 898296341Sdelphij{ 899296341Sdelphij *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 900296341Sdelphij if (!*ameth) 901296341Sdelphij return 0; 902296341Sdelphij switch (nid) { 903296341Sdelphij case NID_id_GostR3410_94: 904296341Sdelphij EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); 905296341Sdelphij EVP_PKEY_asn1_set_private(*ameth, 906296341Sdelphij priv_decode_gost, priv_encode_gost, 907296341Sdelphij priv_print_gost94); 908238384Sjkim 909296341Sdelphij EVP_PKEY_asn1_set_param(*ameth, 910296341Sdelphij gost94_param_decode, gost94_param_encode, 911296341Sdelphij param_missing_gost94, param_copy_gost94, 912296341Sdelphij param_cmp_gost94, param_print_gost94); 913296341Sdelphij EVP_PKEY_asn1_set_public(*ameth, 914296341Sdelphij pub_decode_gost94, pub_encode_gost94, 915296341Sdelphij pub_cmp_gost94, pub_print_gost94, 916296341Sdelphij pkey_size_gost, pkey_bits_gost); 917238384Sjkim 918296341Sdelphij EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 919296341Sdelphij break; 920296341Sdelphij case NID_id_GostR3410_2001: 921296341Sdelphij EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); 922296341Sdelphij EVP_PKEY_asn1_set_private(*ameth, 923296341Sdelphij priv_decode_gost, priv_encode_gost, 924296341Sdelphij priv_print_gost01); 925238384Sjkim 926296341Sdelphij EVP_PKEY_asn1_set_param(*ameth, 927296341Sdelphij gost2001_param_decode, gost2001_param_encode, 928296341Sdelphij param_missing_gost01, param_copy_gost01, 929296341Sdelphij param_cmp_gost01, param_print_gost01); 930296341Sdelphij EVP_PKEY_asn1_set_public(*ameth, 931296341Sdelphij pub_decode_gost01, pub_encode_gost01, 932296341Sdelphij pub_cmp_gost01, pub_print_gost01, 933296341Sdelphij pkey_size_gost, pkey_bits_gost); 934238384Sjkim 935296341Sdelphij EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 936296341Sdelphij break; 937296341Sdelphij case NID_id_Gost28147_89_MAC: 938296341Sdelphij EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); 939296341Sdelphij EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); 940296341Sdelphij break; 941296341Sdelphij } 942296341Sdelphij return 1; 943296341Sdelphij} 944