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)); }
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); }
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); }
/* * 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)); }
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); }
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); }
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); }
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); }
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 }