X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=engines%2Fccgost%2Fgost_ameth.c;h=7b3ba5048b4b2667374c5044eb481d79e2244556;hp=39a175f52cf057bd1f2debed2b2d863443520266;hb=b6af2c7e3e77e3dc9e295027e8921c9566d523e8;hpb=ec06417d52e53cc66fbc2ffe3e45520514098cba diff --git a/engines/ccgost/gost_ameth.c b/engines/ccgost/gost_ameth.c index 39a175f52c..7b3ba5048b 100644 --- a/engines/ccgost/gost_ameth.c +++ b/engines/ccgost/gost_ameth.c @@ -7,10 +7,12 @@ * for OpenSSL * * Requires OpenSSL 0.9.9 for compilation * **********************************************************************/ +#include +#include +#include #include #include #include -#include #include "gost_params.h" #include "gost_lcl.h" #include "e_gost_err.h" @@ -48,14 +50,6 @@ static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) } switch (EVP_PKEY_base_id(key)) { - case NID_id_GostR3410_2001_cc: - pkey_param_nid = NID_id_GostR3410_2001_ParamSet_cc; - cipher_param_nid = NID_id_Gost28147_89_cc; - break; - case NID_id_GostR3410_94_cc: - pkey_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - cipher_param_nid = NID_id_Gost28147_89_cc; - break; case NID_id_GostR3410_2001: pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key))); cipher_param_nid = get_encryption_params(NULL)->nid; @@ -128,7 +122,6 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) switch (pkey_nid) { case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: { DSA *dsa= EVP_PKEY_get0(pkey); if (!dsa) @@ -140,7 +133,6 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) break; } case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: { EC_KEY *ec = EVP_PKEY_get0(pkey); if (!ec) @@ -160,7 +152,6 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) switch (EVP_PKEY_base_id(pkey)) { case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: { DSA *dsa = EVP_PKEY_get0(pkey); if (!dsa) @@ -174,7 +165,6 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) break; } case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: { EC_KEY *ec = EVP_PKEY_get0(pkey); if (!ec) @@ -190,12 +180,11 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) } return 1; } -BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) +BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) { switch (EVP_PKEY_base_id(pkey)) { case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: { DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); if (!dsa) @@ -203,11 +192,10 @@ BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) return NULL; } if (!dsa->priv_key) return NULL; - return BN_dup(dsa->priv_key); + return dsa->priv_key; break; } case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: { EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); const BIGNUM* priv; @@ -216,7 +204,7 @@ BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) return NULL; } if (!(priv=EC_KEY_get0_private_key(ec))) return NULL; - return BN_dup(priv); + return (BIGNUM *)priv; break; } } @@ -308,7 +296,7 @@ static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len); if (!s||s->length !=32) { - GOSTerr(GOST_F_PRIV_DECODE_GOST_94, + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } @@ -322,9 +310,12 @@ static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) else { priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len); - if (!priv_key || !(pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))) + if (!priv_key) return 0; + ret= ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ; + ASN1_INTEGER_free(priv_key); + if (!ret) { - GOSTerr(GOST_F_PRIV_DECODE_GOST_94, + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } @@ -342,34 +333,145 @@ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) ASN1_STRING *params = encode_gost_algor_params(pk); unsigned char *priv_buf = NULL; int priv_len; - BIGNUM *key; ASN1_INTEGER *asn1key=NULL; if (!params) { return 0; } - key = gost_get_priv_key(pk); - asn1key = BN_to_ASN1_INTEGER(key,NULL); - BN_free(key); + asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL); priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf); ASN1_INTEGER_free(asn1key); return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params, priv_buf,priv_len); } +/* --------- printing keys --------------------------------*/ +static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) + { + int param_nid = NID_undef; + + if (type == 2) + { + BIGNUM *key; + + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Private key: "); + key = gost_get0_priv_key(pkey); + if (!key) + BIO_printf(out,""); + else + BN_print(out,key); + BIO_printf(out,"\n"); + } + if (type >= 1) + { + BIGNUM *pubkey; + + pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; + BIO_indent(out,indent,128); + BIO_printf(out,"Public key: "); + BN_print(out,pubkey); + BIO_printf(out,"\n"); + } + + param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); + BIO_indent(out,indent,128); + BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid)); + return 1; +} -static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent, +static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - BIGNUM *key; + return print_gost_94(out, pkey, indent, pctx,0); + } + +static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_94(out,pkey, indent, pctx,1); + } +static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_94(out,pkey,indent,pctx,2); + } + +static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) + { + int param_nid = NID_undef; + if (type == 2) + { + BIGNUM *key; + + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Private key: "); + key = gost_get0_priv_key(pkey); + if (!key) + BIO_printf(out,"= 1) + { + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *X,*Y; + const EC_POINT *pubkey; + const EC_GROUP *group; + + if (!ctx) + { + GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); + group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); + if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) + { + GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB); + BN_CTX_free(ctx); + return 0; + } + if (!BIO_indent(out,indent,128)) return 0; + BIO_printf(out,"Public key:\n"); + if (!BIO_indent(out,indent+3,128)) return 0; + BIO_printf(out,"X:"); + BN_print(out,X); + BIO_printf(out,"\n"); + BIO_indent(out,indent+3,128); + BIO_printf(out,"Y:"); + BN_print(out,Y); + BIO_printf(out,"\n"); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); if (!BIO_indent(out,indent,128)) return 0; - key = gost_get_priv_key(pkey); - if (!key) return 0; - BN_print(out,key); - BN_free(key); + BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid)); return 1; +} +static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_01(out,pkey,indent,pctx,0); + } +static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_01(out,pkey, indent, pctx,1); + } +static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + return print_gost_01(out,pkey,indent,pctx,2); } - /* ---------------------------------------------------------------------*/ static int param_missing_gost94(const EVP_PKEY *pk) { @@ -429,7 +531,7 @@ static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) } if (!efrom) { - GOSTerr(GOST_F_PARAM_COPY_GOST94, + GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); return 0; } @@ -438,7 +540,7 @@ static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) eto = EC_KEY_new(); EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto); } - EC_KEY_set_group(eto,EC_GROUP_dup(EC_KEY_get0_group(efrom))); + EC_KEY_set_group(eto,EC_KEY_get0_group(efrom)); if (EC_KEY_get0_private_key(eto)) { gost2001_compute_public(eto); @@ -543,6 +645,7 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) EC_POINT *pub_key; BIGNUM *X,*Y; ASN1_OCTET_STRING *octet= NULL; + int len; const EC_GROUP *group; if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, @@ -553,7 +656,7 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len); if (!octet) { - GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE); + GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE); return 0; } databuf = OPENSSL_malloc(octet->length); @@ -561,16 +664,11 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) { databuf[j]=octet->data[i]; } - if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) - { - X= getbnfrombuf(databuf,octet->length/2); - Y= getbnfrombuf(databuf+(octet->length/2),octet->length/2); - } - else - { - Y= getbnfrombuf(databuf,octet->length/2); - X= getbnfrombuf(databuf+(octet->length/2),octet->length/2); - } + len=octet->length/2; + ASN1_OCTET_STRING_free(octet); + + Y= getbnfrombuf(databuf,len); + X= getbnfrombuf(databuf+len,len); OPENSSL_free(databuf); pub_key = EC_POINT_new(group); if (!EC_POINT_set_affine_coordinates_GFp(group @@ -578,6 +676,9 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) { GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); + EC_POINT_free(pub_key); + BN_free(X); + BN_free(Y); return 0; } BN_free(X); @@ -586,9 +687,10 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) { GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); + EC_POINT_free(pub_key); return 0; } - /*EC_POINT_free(pub_key);*/ + EC_POINT_free(pub_key); return 1; } @@ -629,16 +731,10 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) BN_free(order); databuf = OPENSSL_malloc(data_len); memset(databuf,0,data_len); - if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) - { - store_bignum(X,databuf,data_len/2); - store_bignum(Y,databuf+data_len/2,data_len/2); - } - else - { - store_bignum(X,databuf+data_len/2,data_len/2); - store_bignum(Y,databuf,data_len/2); - } + + store_bignum(X,databuf+data_len/2,data_len/2); + store_bignum(Y,databuf,data_len/2); + BN_free(X); BN_free(Y); octet = ASN1_OCTET_STRING_new(); @@ -681,22 +777,8 @@ static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b) return ret; } -static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) - { - const BIGNUM *key; - if (!BIO_indent(out,indent,128)) return 0; - key = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; - if (!key) return 0; - BN_print(out,key); - return 1; - } -static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) - { - return 0; - } + static int pkey_size_gost(const EVP_PKEY *pk) { @@ -724,6 +806,59 @@ static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) } return -2; } + +int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); + return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder); +} +int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); + return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder); +} + +int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) +{ + ASN1_OBJECT *obj=NULL; + DSA *dsa = EVP_PKEY_get0(pkey); + int nid; + if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) { + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + if (!dsa) + { + dsa=DSA_new(); + if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0; + } + if (!fill_GOST94_params(dsa,nid)) return 0; + return 1; +} + +int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { + ASN1_OBJECT *obj=NULL; + int nid; + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) { + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + if (!ec) + { + ec = EC_KEY_new(); + if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0; + } + if (!fill_GOST2001_params(ec, nid)) return 0; + return 1; +} + + + + + /* ----------------------------------------------------------------------*/ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) { @@ -732,16 +867,16 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems if (!*ameth) return 0; switch (nid) { - case NID_id_GostR3410_94_cc: case NID_id_GostR3410_94: EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94); EVP_PKEY_asn1_set_private (*ameth, priv_decode_gost, priv_encode_gost, - priv_print_gost); + priv_print_gost94); - EVP_PKEY_asn1_set_param (*ameth, 0, 0, + EVP_PKEY_asn1_set_param (*ameth, + gost94_param_decode, gost94_param_encode, param_missing_gost94, param_copy_gost94, - param_cmp_gost94,0 ); + param_cmp_gost94,param_print_gost94 ); EVP_PKEY_asn1_set_public (*ameth, pub_decode_gost94, pub_encode_gost94, pub_cmp_gost94, pub_print_gost94, @@ -749,16 +884,16 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); break; - case NID_id_GostR3410_2001_cc: case NID_id_GostR3410_2001: EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01); EVP_PKEY_asn1_set_private (*ameth, priv_decode_gost, priv_encode_gost, - priv_print_gost); + priv_print_gost01); - EVP_PKEY_asn1_set_param (*ameth, 0, 0, + EVP_PKEY_asn1_set_param (*ameth, + gost2001_param_decode, gost2001_param_encode, param_missing_gost01, param_copy_gost01, - param_cmp_gost01, 0); + param_cmp_gost01, param_print_gost01); EVP_PKEY_asn1_set_public (*ameth, pub_decode_gost01, pub_encode_gost01, pub_cmp_gost01, pub_print_gost01,