X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;ds=sidebyside;f=gost_ameth.c;h=2582d633c83a1114027622c0cd96c46e883238d5;hb=6da0c1cd9f85cfd01983cf1bf779320474bef57d;hp=92319e74c55ae3a85edde2484e30e0647d472e0e;hpb=5f76803c2582cccacd73cf285267418cb40d9a3d;p=openssl-gost%2Fengine.git diff --git a/gost_ameth.c b/gost_ameth.c index 92319e7..2582d63 100644 --- a/gost_ameth.c +++ b/gost_ameth.c @@ -224,7 +224,7 @@ BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) * GOST CMS processing functions */ /* FIXME reaarange declarations */ -static int pub_decode_gost_ec(EVP_PKEY *pk, X509_PUBKEY *pub); +static int pub_decode_gost_ec(EVP_PKEY *pk, const X509_PUBKEY *pub); static int gost_cms_set_kari_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) { @@ -340,6 +340,8 @@ static int gost_cms_set_ktri_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo * gctx->cipher_nid = NID_magma_ctr; break; + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001DH: case NID_id_GostR3410_2012_256: case NID_id_GostR3410_2012_512: gctx->cipher_nid = NID_id_Gost28147_89; @@ -367,6 +369,42 @@ static int gost_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) GOSTerr(GOST_F_GOST_CMS_SET_SHARED_INFO, GOST_R_UNSUPPORTED_RECIPIENT_INFO); return 0; } + +static ASN1_STRING *gost_encode_cms_params(int ka_nid) +{ + ASN1_STRING *ret = NULL; + ASN1_STRING *params = ASN1_STRING_new(); + + /* It's a hack. We have only one OID here, so we can use + * GOST_KEY_PARAMS which is a sequence of 3 OIDs, + * the 1st one is mandatory and the rest are optional */ + GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); + + if (params == NULL || gkp == NULL) { + GOSTerr(GOST_F_GOST_ENCODE_CMS_PARAMS, ERR_R_MALLOC_FAILURE); + goto end; + } + + gkp->key_params = OBJ_nid2obj(ka_nid); + params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); + + if (params->length < 0) { + GOSTerr(GOST_F_GOST_ENCODE_CMS_PARAMS, ERR_R_MALLOC_FAILURE); + goto end; + } + + params->type = V_ASN1_SEQUENCE; + ret = params; + +end: + GOST_KEY_PARAMS_free(gkp); + + if (ret == NULL) + ASN1_STRING_free(params); + + return ret; +} + /* * Control function */ @@ -423,14 +461,44 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_ENVELOPE: if (arg1 == 0) { - ASN1_STRING *params = encode_gost_algor_params(pkey); - if (!params) { - return -1; - } - CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, - NULL, &alg1); - X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_id(pkey)), - V_ASN1_SEQUENCE, params); + EVP_PKEY_CTX *pctx; + CMS_RecipientInfo *ri = arg2; + + struct gost_pmeth_data *gctx = NULL; + ASN1_STRING *params = NULL; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + + gctx = EVP_PKEY_CTX_get_data(pctx); + + switch (gctx->cipher_nid) { + case NID_magma_ctr: + case NID_kuznyechik_ctr: + { + int ka_nid; + + nid = (gctx->cipher_nid == NID_magma_ctr) ? NID_magma_kexp15 : + NID_kuznyechik_kexp15; + + ka_nid = (EVP_PKEY_base_id(pkey) == NID_id_GostR3410_2012_256) ? + NID_id_tc26_agreement_gost_3410_2012_256 : NID_id_tc26_agreement_gost_3410_2012_512; + + params = gost_encode_cms_params(ka_nid); + } + break; + default: + params = encode_gost_algor_params(pkey); + break; + } + + if (params == NULL) + return -1; + + CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, + NULL, &alg1); + X509_ALGOR_set0(alg1, OBJ_nid2obj(nid), V_ASN1_SEQUENCE, params); } else { EVP_PKEY_CTX *pctx; CMS_RecipientInfo *ri = arg2; @@ -445,10 +513,12 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) *(int *)arg2 = CMS_RECIPINFO_TRANS; return 1; case ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED: - if (arg1 == CMS_RECIPINFO_AGREE || arg1 == CMS_RECIPINFO_TRANS) - return 1; + if (arg1 == CMS_RECIPINFO_AGREE || arg1 == CMS_RECIPINFO_TRANS) { + *(int *)arg2 = 1; + return 1; + } else - return 0; + return 0; break; #endif #endif @@ -826,7 +896,7 @@ static int param_cmp_gost_ec(const EVP_PKEY *a, const EVP_PKEY *b) } /* ---------- Public key functions * --------------------------------------*/ -static int pub_decode_gost_ec(EVP_PKEY *pk, X509_PUBKEY *pub) +static int pub_decode_gost_ec(EVP_PKEY *pk, const X509_PUBKEY *pub) { X509_ALGOR *palg = NULL; const unsigned char *pubkey_buf = NULL; @@ -903,11 +973,14 @@ static int pub_encode_gost_ec(X509_PUBKEY *pub, const EVP_PKEY *pk) pval = params; order = BN_new(); - if (!order) { + if (order == NULL || EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL) == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE); goto err; } - EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); + if (EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL) == 0) { + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_INTERNAL_ERROR); + goto err; + } pub_key = EC_KEY_get0_public_key(ec); if (!pub_key) { GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, GOST_R_PUBLIC_KEY_UNDEFINED);