int TS_CONF_set_digests(CONF *conf, const char *section,
			TS_RESP_CTX *ctx)
	{
	int ret = 0;
	int i;
	STACK_OF(CONF_VALUE) *list = NULL;
	char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
	if (!digests)
		{
		TS_CONF_lookup_fail(section, ENV_DIGESTS);
		goto err;
		}
	if (!(list = X509V3_parse_list(digests)))
		{
		TS_CONF_invalid(section, ENV_DIGESTS);
		goto err;
		}
	if (sk_CONF_VALUE_num(list) == 0)
		{
		TS_CONF_invalid(section, ENV_DIGESTS);
		goto err;
		}
	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
		{
		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
		const char *extval = val->value ? val->value : val->name;
		const EVP_MD *md;
		if (!(md = EVP_get_digestbyname(extval)))
			{
			TS_CONF_invalid(section, ENV_DIGESTS);
			goto err;
			}
		if (!TS_RESP_CTX_add_md(ctx, md))
			goto err;
		}

	ret = 1;
 err:
	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
	return ret;
	}
int TS_CONF_set_digests(CONF *conf, const char *section,
			TS_RESP_CTX *ctx)
	{
	int ret = 0;
	int i;
	STACK_OF(CONF_VALUE) *list = NULL;
	char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
	if (!digests)
		{
		TS_CONF_lookup_fail(section, ENV_DIGESTS);
		goto err;
		}
	if (!(list = X509V3_parse_list(digests)))
		{
		TS_CONF_invalid(section, ENV_DIGESTS);
		goto err;
		}
	if (sk_CONF_VALUE_num(list) == 0)
		{
		TS_CONF_invalid(section, ENV_DIGESTS);
		goto err;
		}
	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
		{
		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
		const char *extval = val->value ? val->value : val->name;
		const EVP_MD *md;
		if (!(md = EVP_get_digestbyname(extval)))
			{
			TS_CONF_invalid(section, ENV_DIGESTS);
			goto err;
			}
		if (!TS_RESP_CTX_add_md(ctx, md))
			goto err;
		}

	ret = 1;
 err:
	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
	return ret;
	}