Ejemplo n.º 1
0
ATF_TC_BODY(isc_safe_memequal, tc) {
    UNUSED(tc);

    ATF_CHECK(isc_safe_memequal("test", "test", 4));
    ATF_CHECK(!isc_safe_memequal("test", "tesc", 4));
    ATF_CHECK(isc_safe_memequal("\x00\x00\x00\x00",
                                "\x00\x00\x00\x00", 4));
    ATF_CHECK(!isc_safe_memequal("\x00\x00\x00\x00",
                                 "\x00\x00\x00\x01", 4));
    ATF_CHECK(!isc_safe_memequal("\x00\x00\x00\x02",
                                 "\x00\x00\x00\x00", 4));
}
Ejemplo n.º 2
0
static isc_boolean_t
pkcs11ecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
	pk11_object_t *ec1, *ec2;
	CK_ATTRIBUTE *attr1, *attr2;

	ec1 = key1->keydata.pkey;
	ec2 = key2->keydata.pkey;

	if ((ec1 == NULL) && (ec2 == NULL))
		return (ISC_TRUE);
	else if ((ec1 == NULL) || (ec2 == NULL))
		return (ISC_FALSE);

	attr1 = pk11_attribute_bytype(ec1, CKA_EC_PARAMS);
	attr2 = pk11_attribute_bytype(ec2, CKA_EC_PARAMS);
	if ((attr1 == NULL) && (attr2 == NULL))
		return (ISC_TRUE);
	else if ((attr1 == NULL) || (attr2 == NULL) ||
		 (attr1->ulValueLen != attr2->ulValueLen) ||
		 !isc_safe_memequal(attr1->pValue, attr2->pValue,
				    attr1->ulValueLen))
		return (ISC_FALSE);

	attr1 = pk11_attribute_bytype(ec1, CKA_EC_POINT);
	attr2 = pk11_attribute_bytype(ec2, CKA_EC_POINT);
	if ((attr1 == NULL) && (attr2 == NULL))
		return (ISC_TRUE);
	else if ((attr1 == NULL) || (attr2 == NULL) ||
		 (attr1->ulValueLen != attr2->ulValueLen) ||
		 !isc_safe_memequal(attr1->pValue, attr2->pValue,
				    attr1->ulValueLen))
		return (ISC_FALSE);

	attr1 = pk11_attribute_bytype(ec1, CKA_VALUE);
	attr2 = pk11_attribute_bytype(ec2, CKA_VALUE);
	if (((attr1 != NULL) || (attr2 != NULL)) &&
	    ((attr1 == NULL) || (attr2 == NULL) ||
	     (attr1->ulValueLen != attr2->ulValueLen) ||
	     !isc_safe_memequal(attr1->pValue, attr2->pValue,
				attr1->ulValueLen)))
		return (ISC_FALSE);

	if (!ec1->ontoken && !ec2->ontoken)
		return (ISC_TRUE);
	else if (ec1->ontoken || ec2->ontoken ||
		 (ec1->object != ec2->object))
		return (ISC_FALSE);

	return (ISC_TRUE);
}
Ejemplo n.º 3
0
static isc_boolean_t
pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
	pk11_object_t *rsa1, *rsa2;
	CK_ATTRIBUTE *attr1, *attr2;

	rsa1 = key1->keydata.pkey;
	rsa2 = key2->keydata.pkey;

	if ((rsa1 == NULL) && (rsa2 == NULL))
		return (ISC_TRUE);
	else if ((rsa1 == NULL) || (rsa2 == NULL))
		return (ISC_FALSE);

	attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS);
	attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS);
	if ((attr1 == NULL) && (attr2 == NULL))
		return (ISC_TRUE);
	else if ((attr1 == NULL) || (attr2 == NULL) ||
		 (attr1->ulValueLen != attr2->ulValueLen) ||
		 !isc_safe_memequal(attr1->pValue, attr2->pValue,
				    attr1->ulValueLen))
		return (ISC_FALSE);

	attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT);
	attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT);
	if ((attr1 == NULL) && (attr2 == NULL))
		return (ISC_TRUE);
	else if ((attr1 == NULL) || (attr2 == NULL) ||
		 (attr1->ulValueLen != attr2->ulValueLen) ||
		 !isc_safe_memequal(attr1->pValue, attr2->pValue,
				    attr1->ulValueLen))
		return (ISC_FALSE);

	attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT);
	attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT);
	if (((attr1 != NULL) || (attr2 != NULL)) &&
	    ((attr1 == NULL) || (attr2 == NULL) ||
	     (attr1->ulValueLen != attr2->ulValueLen) ||
	     !isc_safe_memequal(attr1->pValue, attr2->pValue,
				attr1->ulValueLen)))
		return (ISC_FALSE);

	if (!rsa1->ontoken && !rsa2->ontoken)
		return (ISC_TRUE);
	else if (rsa1->ontoken || rsa2->ontoken ||
		 (rsa1->object != rsa2->object))
		return (ISC_FALSE);

	return (ISC_TRUE);
}
Ejemplo n.º 4
0
/*
 * Verify signature - finalize SHA224 operation and reapply SHA224, then
 * compare to the supplied digest.
 */
isc_boolean_t
isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];

	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
	isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
	return (isc_safe_memequal(digest, newdigest, len));
}
Ejemplo n.º 5
0
static isc_boolean_t
pkcs11gost_compare(const dst_key_t *key1, const dst_key_t *key2) {
    pk11_object_t *gost1, *gost2;
    CK_ATTRIBUTE *attr1, *attr2;

    gost1 = key1->keydata.pkey;
    gost2 = key2->keydata.pkey;

    if ((gost1 == NULL) && (gost2 == NULL))
        return (ISC_TRUE);
    else if ((gost1 == NULL) || (gost2 == NULL))
        return (ISC_FALSE);

    attr1 = pk11_attribute_bytype(gost1, CKA_VALUE);
    attr2 = pk11_attribute_bytype(gost2, CKA_VALUE);
    if ((attr1 == NULL) && (attr2 == NULL))
        return (ISC_TRUE);
    else if ((attr1 == NULL) || (attr2 == NULL) ||
             (attr1->ulValueLen != attr2->ulValueLen) ||
             !isc_safe_memequal(attr1->pValue, attr2->pValue,
                                attr1->ulValueLen))
        return (ISC_FALSE);

    attr1 = pk11_attribute_bytype(gost1, CKA_VALUE2);
    attr2 = pk11_attribute_bytype(gost2, CKA_VALUE2);
    if (((attr1 != NULL) || (attr2 != NULL)) &&
            ((attr1 == NULL) || (attr2 == NULL) ||
             (attr1->ulValueLen != attr2->ulValueLen) ||
             !isc_safe_memequal(attr1->pValue, attr2->pValue,
                                attr1->ulValueLen)))
        return (ISC_FALSE);

    if (!gost1->ontoken && !gost2->ontoken)
        return (ISC_TRUE);
    else if (gost1->ontoken || gost2->ontoken ||
             (gost1->object != gost2->object))
        return (ISC_FALSE);

    return (ISC_TRUE);
}
Ejemplo n.º 6
0
static isc_result_t
pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
    dst_private_t priv;
    isc_result_t ret;
    pk11_object_t *gost = NULL;
    CK_ATTRIBUTE *attr, *pattr;
    isc_mem_t *mctx = key->mctx;

    if ((pub == NULL) || (pub->keydata.pkey == NULL))
        DST_RET(DST_R_INVALIDPRIVATEKEY);

    /* read private key file */
    ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
    if (ret != ISC_R_SUCCESS)
        return (ret);

    if (key->external) {
        if (priv.nelements != 0)
            DST_RET(DST_R_INVALIDPRIVATEKEY);

        key->keydata.pkey = pub->keydata.pkey;
        pub->keydata.pkey = NULL;
        key->key_size = pub->key_size;

        dst__privstruct_free(&priv, mctx);
        memset(&priv, 0, sizeof(priv));

        return (ISC_R_SUCCESS);
    }

    if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
        int adj = (int) priv.elements[0].length - (39 + 32);
        unsigned char buf[39];

        if ((adj > 0) || (adj < -31))
            DST_RET(DST_R_INVALIDPRIVATEKEY);
        memmove(buf, gost_private_der, 39);
        if (adj != 0) {
            buf[1] += adj;
            buf[36] += adj;
            buf[38] += adj;
        }
        if (!isc_safe_memequal(priv.elements[0].data, buf, 39))
            DST_RET(DST_R_INVALIDPRIVATEKEY);
        priv.elements[0].tag = TAG_GOST_PRIVRAW;
        priv.elements[0].length -= 39;
        memmove(priv.elements[0].data,
                priv.elements[0].data + 39,
                32 + adj);
    }

    gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost));
    if (gost == NULL)
        DST_RET(ISC_R_NOMEMORY);
    memset(gost, 0, sizeof(*gost));
    key->keydata.pkey = gost;
    key->key_size = ISC_GOST_KEYSIZE;

    gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx,
                 sizeof(*attr) * 2);
    if (gost->repr == NULL)
        DST_RET(ISC_R_NOMEMORY);
    memset(gost->repr, 0, sizeof(*attr) * 2);
    gost->attrcnt = 2;

    attr = gost->repr;
    attr->type = CKA_VALUE;
    pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE);
    INSIST(pattr != NULL);
    attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen);
    if (attr->pValue == NULL)
        DST_RET(ISC_R_NOMEMORY);
    memmove(attr->pValue, pattr->pValue, pattr->ulValueLen);
    attr->ulValueLen = pattr->ulValueLen;

    attr++;
    attr->type = CKA_VALUE2;
    attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length);
    if (attr->pValue == NULL)
        DST_RET(ISC_R_NOMEMORY);
    memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length);
    attr->ulValueLen = priv.elements[0].length;

    dst__privstruct_free(&priv, mctx);
    memset(&priv, 0, sizeof(priv));

    return (ISC_R_SUCCESS);

err:
    pkcs11gost_destroy(key);
    dst__privstruct_free(&priv, mctx);
    memset(&priv, 0, sizeof(priv));
    return (ret);
}
Ejemplo n.º 7
0
static isc_result_t
rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) {
	CK_ATTRIBUTE *pubattr, *privattr;
	CK_BYTE *priv_exp = NULL, *priv_mod = NULL;
	CK_BYTE *pub_exp = NULL, *pub_mod = NULL;
	unsigned int priv_explen = 0, priv_modlen = 0;
	unsigned int pub_explen = 0, pub_modlen = 0;

	REQUIRE(rsa != NULL && pubrsa != NULL);

	privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
	INSIST(privattr != NULL);
	priv_exp = privattr->pValue;
	priv_explen = privattr->ulValueLen;

	pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
	INSIST(pubattr != NULL);
	pub_exp = pubattr->pValue;
	pub_explen = pubattr->ulValueLen;

	if (priv_exp != NULL) {
		if (priv_explen != pub_explen)
			return (DST_R_INVALIDPRIVATEKEY);
		if (!isc_safe_memequal(priv_exp, pub_exp, pub_explen))
			return (DST_R_INVALIDPRIVATEKEY);
	} else {
		privattr->pValue = pub_exp;
		privattr->ulValueLen = pub_explen;
		pubattr->pValue = NULL;
		pubattr->ulValueLen = 0;
	}

	if (privattr->pValue == NULL)
		return (DST_R_INVALIDPRIVATEKEY);

	privattr = pk11_attribute_bytype(rsa, CKA_MODULUS);
	INSIST(privattr != NULL);
	priv_mod = privattr->pValue;
	priv_modlen = privattr->ulValueLen;

	pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
	INSIST(pubattr != NULL);
	pub_mod = pubattr->pValue;
	pub_modlen = pubattr->ulValueLen;

	if (priv_mod != NULL) {
		if (priv_modlen != pub_modlen)
			return (DST_R_INVALIDPRIVATEKEY);
		if (!isc_safe_memequal(priv_mod, pub_mod, pub_modlen))
			return (DST_R_INVALIDPRIVATEKEY);
	} else {
		privattr->pValue = pub_mod;
		privattr->ulValueLen = pub_modlen;
		pubattr->pValue = NULL;
		pubattr->ulValueLen = 0;
	}

	if (privattr->pValue == NULL)
		return (DST_R_INVALIDPRIVATEKEY);

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 8
0
static isc_result_t
verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
       isc_uint32_t algorithm, isccc_region_t *secret)
{
	union {
		isc_hmacmd5_t hmd5;
		isc_hmacsha1_t hsha;
		isc_hmacsha224_t h224;
		isc_hmacsha256_t h256;
		isc_hmacsha384_t h384;
		isc_hmacsha512_t h512;
	} ctx;
	isccc_region_t source;
	isccc_region_t target;
	isc_result_t result;
	isccc_sexpr_t *_auth, *hmac;
	unsigned char digest[ISC_SHA512_DIGESTLENGTH];
	unsigned char digestb64[HSHA_LENGTH * 4];

	/*
	 * Extract digest.
	 */
	_auth = isccc_alist_lookup(alist, "_auth");
	if (!isccc_alist_alistp(_auth))
		return (ISC_R_FAILURE);
	if (algorithm == ISCCC_ALG_HMACMD5)
		hmac = isccc_alist_lookup(_auth, "hmd5");
	else
		hmac = isccc_alist_lookup(_auth, "hsha");
	if (!isccc_sexpr_binaryp(hmac))
		return (ISC_R_FAILURE);
	/*
	 * Compute digest.
	 */
	source.rstart = digest;
	target.rstart = digestb64;
	switch (algorithm) {
	case ISCCC_ALG_HMACMD5:
		isc_hmacmd5_init(&ctx.hmd5, secret->rstart,
				 REGION_SIZE(*secret));
		isc_hmacmd5_update(&ctx.hmd5, data, length);
		isc_hmacmd5_sign(&ctx.hmd5, digest);
		source.rend = digest + ISC_MD5_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA1:
		isc_hmacsha1_init(&ctx.hsha, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha1_update(&ctx.hsha, data, length);
		isc_hmacsha1_sign(&ctx.hsha, digest,
				    ISC_SHA1_DIGESTLENGTH);
		source.rend = digest + ISC_SHA1_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA224:
		isc_hmacsha224_init(&ctx.h224, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha224_update(&ctx.h224, data, length);
		isc_hmacsha224_sign(&ctx.h224, digest,
				    ISC_SHA224_DIGESTLENGTH);
		source.rend = digest + ISC_SHA224_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA256:
		isc_hmacsha256_init(&ctx.h256, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha256_update(&ctx.h256, data, length);
		isc_hmacsha256_sign(&ctx.h256, digest,
				    ISC_SHA256_DIGESTLENGTH);
		source.rend = digest + ISC_SHA256_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA384:
		isc_hmacsha384_init(&ctx.h384, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha384_update(&ctx.h384, data, length);
		isc_hmacsha384_sign(&ctx.h384, digest,
				    ISC_SHA384_DIGESTLENGTH);
		source.rend = digest + ISC_SHA384_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA512:
		isc_hmacsha512_init(&ctx.h512, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha512_update(&ctx.h512, data, length);
		isc_hmacsha512_sign(&ctx.h512, digest,
				    ISC_SHA512_DIGESTLENGTH);
		source.rend = digest + ISC_SHA512_DIGESTLENGTH;
		break;

	default:
		return (ISC_R_FAILURE);
	}
	target.rstart = digestb64;
	target.rend = digestb64 + sizeof(digestb64);
	memset(digestb64, 0, sizeof(digestb64));
	result = isccc_base64_encode(&source, 64, "", &target);
	if (result != ISC_R_SUCCESS)
		return (result);

	/*
	 * Verify.
	 */
	if (algorithm == ISCCC_ALG_HMACMD5) {
		unsigned char *value;

		value = (unsigned char *) isccc_sexpr_tostring(hmac);
		if (!isc_safe_memequal(value, digestb64, HMD5_LENGTH))
			return (ISCCC_R_BADAUTH);
	} else {
		unsigned char *value;
		isc_uint32_t valalg;

		value = (unsigned char *) isccc_sexpr_tostring(hmac);
		GET8(valalg, value);
		if ((valalg != algorithm) ||
		    !isc_safe_memequal(value, digestb64, HSHA_LENGTH))
			return (ISCCC_R_BADAUTH);
	}

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 9
0
static isc_result_t
opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) {
	dst_key_t *key = dctx->key;
	int status = 0;
	const BIGNUM *e = NULL;
#if USE_EVP
	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
	EVP_PKEY *pkey = key->keydata.pkey;
	RSA *rsa;
	int bits;
#else
	/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
	unsigned char digest[ISC_SHA512_DIGESTLENGTH];
	int type = 0;
	unsigned int digestlen = 0;
	RSA *rsa = key->keydata.rsa;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
	unsigned int prefixlen = 0;
	const unsigned char *prefix = NULL;
#endif
#endif

#ifndef PK11_MD5_DISABLE
	REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
		dctx->key->key_alg == DST_ALG_RSASHA1 ||
		dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		dctx->key->key_alg == DST_ALG_RSASHA256 ||
		dctx->key->key_alg == DST_ALG_RSASHA512);
#else
	REQUIRE(dctx->key->key_alg == DST_ALG_RSASHA1 ||
		dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		dctx->key->key_alg == DST_ALG_RSASHA256 ||
		dctx->key->key_alg == DST_ALG_RSASHA512);
#endif

#if USE_EVP
	rsa = EVP_PKEY_get1_RSA(pkey);
	if (rsa == NULL)
		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
	RSA_get0_key(rsa, NULL, &e, NULL);
	bits = BN_num_bits(e);
	RSA_free(rsa);
	if (bits > maxbits && maxbits != 0)
		return (DST_R_VERIFYFAILURE);

	status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
	switch (status) {
	case 1:
		return (ISC_R_SUCCESS);
	case 0:
		return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
	default:
		return (dst__openssl_toresult3(dctx->category,
					       "EVP_VerifyFinal",
					       DST_R_VERIFYFAILURE));
	}
#else
	RSA_get0_key(rsa, NULL, &e, NULL);
	if (BN_num_bits(e) > maxbits && maxbits != 0)
		return (DST_R_VERIFYFAILURE);

	switch (dctx->key->key_alg) {
#ifndef PK11_MD5_DISABLE
	case DST_ALG_RSAMD5:
		{
			isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;

			isc_md5_final(md5ctx, digest);
			type = NID_md5;
			digestlen = ISC_MD5_DIGESTLENGTH;
		}
		break;
#endif
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		{
			isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;

			isc_sha1_final(sha1ctx, digest);
			type = NID_sha1;
			digestlen = ISC_SHA1_DIGESTLENGTH;
		}
		break;
	case DST_ALG_RSASHA256:
		{
			isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;

			isc_sha256_final(digest, sha256ctx);
			digestlen = ISC_SHA256_DIGESTLENGTH;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
			prefix = sha256_prefix;
			prefixlen = sizeof(sha256_prefix);
#else
			type = NID_sha256;
#endif
		}
		break;
	case DST_ALG_RSASHA512:
		{
			isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;

			isc_sha512_final(digest, sha512ctx);
			digestlen = ISC_SHA512_DIGESTLENGTH;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
			prefix = sha512_prefix;
			prefixlen = sizeof(sha512_prefix);
#else
			type = NID_sha512;
#endif
		}
		break;
	default:
		INSIST(0);
	}

	if (sig->length != (unsigned int) RSA_size(rsa))
		return (DST_R_VERIFYFAILURE);

#if OPENSSL_VERSION_NUMBER < 0x00908000L
	switch (dctx->key->key_alg) {
#ifndef PK11_MD5_DISABLE
	case DST_ALG_RSAMD5:
#endif
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		INSIST(type != 0);
		status = RSA_verify(type, digest, digestlen, sig->base,
				    RSA_size(rsa), rsa);
		break;

	case DST_ALG_RSASHA256:
	case DST_ALG_RSASHA512:
		{
			/*
			 * 1024 is big enough for all valid RSA bit sizes
			 * for use with DNSSEC.
			 */
			unsigned char original[PREFIXLEN + 1024];

			INSIST(prefix != NULL);
			INSIST(prefixlen != 0U);

			if (RSA_size(rsa) > (int)sizeof(original))
				return (DST_R_VERIFYFAILURE);

			status = RSA_public_decrypt(sig->length, sig->base,
						    original, rsa,
						    RSA_PKCS1_PADDING);
			if (status <= 0)
				return (dst__openssl_toresult3(
						dctx->category,
						"RSA_public_decrypt",
						DST_R_VERIFYFAILURE));
			if (status != (int)(prefixlen + digestlen))
				return (DST_R_VERIFYFAILURE);
			if (!isc_safe_memequal(original, prefix, prefixlen))
				return (DST_R_VERIFYFAILURE);
			if (!isc_safe_memequal(original + prefixlen,
					    digest, digestlen))
				return (DST_R_VERIFYFAILURE);
			status = 1;
		}
		break;

	default:
		INSIST(0);
	}
#else
	INSIST(type != 0);
	status = RSA_verify(type, digest, digestlen, sig->base,
			     RSA_size(rsa), rsa);
#endif
	if (status != 1)
		return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
	return (ISC_R_SUCCESS);
#endif
}