+ /* Verify manually. */
+ const ASN1_BIT_STRING *signature;
+ X509_get0_signature(&signature, NULL, x);
+ unsigned char *tbs = NULL; /* signed part */
+ int tbs_len;
+ T((tbs_len = i2d_re_X509_tbs(x, &tbs)) > 0);
+ int algnid, hash_nid, pknid;
+ T(algnid = X509_get_signature_nid(x));
+ T(OBJ_find_sigid_algs(algnid, &hash_nid, &pknid));
+
+ printf(" EVP_Verify API\t\t");
+ EVP_MD_CTX *md_ctx;
+ T(md_ctx = EVP_MD_CTX_new());
+ const EVP_MD *mdtype;
+ T(mdtype = EVP_get_digestbynid(hash_nid));
+ T(EVP_VerifyInit(md_ctx, mdtype));
+ T(EVP_VerifyUpdate(md_ctx, tbs, tbs_len));
+ err = EVP_VerifyFinal(md_ctx, signature->data, signature->length, pk);
+ print_test_result(err);
+ EVP_MD_CTX_free(md_ctx);
+ ret |= err != 1;
+
+ X509_free(x);
+ OPENSSL_free(tbs);
+ return ret;
+}
+
+/* Generate EC_KEY with proper parameters using temporary PKEYs.
+ * This emulates fill_GOST_EC_params() call.
+ */
+static int EC_KEY_create(int type, int param_nid, EC_KEY *dst)
+{
+ EVP_PKEY *pkey;
+ T(pkey = EVP_PKEY_new());
+ T(EVP_PKEY_set_type(pkey, type));
+ EVP_PKEY_CTX *ctx;
+ T(ctx = EVP_PKEY_CTX_new(pkey, NULL));
+ T(EVP_PKEY_paramgen_init(ctx));
+ T(EVP_PKEY_CTX_ctrl(ctx, type, -1, EVP_PKEY_CTRL_GOST_PARAMSET, param_nid, NULL));
+ EVP_PKEY *pkey2 = NULL;
+ int err;
+ TE((err = EVP_PKEY_paramgen(ctx, &pkey2)) == 1);
+ T(EC_KEY_copy(dst, EVP_PKEY_get0(pkey2)));
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pkey2);
+ return err;