static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
			  const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
			  int ver)
	{
	if (ctx->pctx == NULL)
		ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
	if (ctx->pctx == NULL)
		return 0;

	if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM))
		{

		if (type == NULL)
			{
			int def_nid;
			if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
				type = EVP_get_digestbynid(def_nid);
			}

		if (type == NULL)
			{
			EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
			return 0;
			}
		}

	if (ver)
		{
		if (ctx->pctx->pmeth->verifyctx_init)
			{
			if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0)
				return 0;
			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
			}
		else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
			return 0;
		}
	else
		{
		if (ctx->pctx->pmeth->signctx_init)
			{
			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
				return 0;
			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
			}
		else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
			return 0;
		}
	if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
		return 0;
	if (pctx)
		*pctx = ctx->pctx;
	if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
		return 1;
	if (!EVP_DigestInit_ex(ctx, type, e))
		return 0;
	return 1;
	}