static isc_result_t opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; RSA *rsa = key->opaque; /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */ unsigned char digest[ISC_SHA1_DIGESTLENGTH]; int status = 0; int type; unsigned int digestlen; REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1); if (dctx->key->key_alg == DST_ALG_RSAMD5) { isc_md5_t *md5ctx = dctx->opaque; isc_md5_final(md5ctx, digest); type = NID_md5; digestlen = ISC_MD5_DIGESTLENGTH; } else { isc_sha1_t *sha1ctx = dctx->opaque; isc_sha1_final(sha1ctx, digest); type = NID_sha1; digestlen = ISC_SHA1_DIGESTLENGTH; } if (sig->length < (unsigned int) RSA_size(rsa)) return (DST_R_VERIFYFAILURE); status = RSA_verify(type, digest, digestlen, sig->base, RSA_size(rsa), rsa); if (status == 0) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); }
/* given a reader and a reader arg, calculate and validate the the hash * signature of a NIST leap second file. */ int leapsec_validate( leapsec_reader func, void * farg) { isc_sha1_t mdctx; sha1_digest rdig, ldig; /* remote / local digests */ char line[50]; int hlseen = -1; isc_sha1_init(&mdctx); while (get_line(func, farg, line, sizeof(line))) { if (!strncmp(line, "#h", 2)) hlseen = do_leap_hash(&rdig, line+2); else if (!strncmp(line, "#@", 2)) do_hash_data(&mdctx, line+2); else if (!strncmp(line, "#$", 2)) do_hash_data(&mdctx, line+2); else if (isdigit((unsigned char)line[0])) do_hash_data(&mdctx, line); } isc_sha1_final(&mdctx, ldig.hv); isc_sha1_invalidate(&mdctx); if (0 > hlseen) return LSVALID_NOHASH; if (0 == hlseen) return LSVALID_BADFORMAT; if (0 != memcmp(&rdig, &ldig, sizeof(sha1_digest))) return LSVALID_BADHASH; return LSVALID_GOODHASH; }
static isc_result_t openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_sha1_t *sha1ctx = dctx->opaque; dst_key_t *key = dctx->key; DSA *dsa = key->opaque; DSA_SIG *dsasig; isc_region_t r; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); return (ISC_R_SUCCESS); }
static isc_result_t openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_sha1_t *sha1ctx = dctx->opaque; dst_key_t *key = dctx->key; DSA *dsa = key->opaque; DSA_SIG *dsasig; int status = 0; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; unsigned char *cp = sig->base; isc_sha1_final(sha1ctx, digest); if (sig->length < 2 * ISC_SHA1_DIGESTLENGTH + 1) return (DST_R_VERIFYFAILURE); cp++; /*%< Skip T */ dsasig = DSA_SIG_new(); dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); DSA_SIG_free(dsasig); if (status <= 0) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); }
/* * Compute signature - finalize SHA1 operation and reapply SHA1. */ void isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { unsigned char opad[ISC_SHA1_BLOCK_LENGTH]; unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; unsigned int i; REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); isc_sha1_final(&ctx->sha1ctx, newdigest); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) opad[i] ^= ctx->key[i]; isc_sha1_init(&ctx->sha1ctx); isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad)); isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH); isc_sha1_final(&ctx->sha1ctx, newdigest); isc_hmacsha1_invalidate(ctx); memcpy(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); }
static isc_result_t opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; RSA *rsa = key->opaque; isc_region_t r; /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */ unsigned char digest[ISC_SHA1_DIGESTLENGTH]; unsigned int siglen = 0; int status; int type; unsigned int digestlen; char *message; unsigned long err; const char* file; int line; REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1); isc_buffer_availableregion(sig, &r); if (r.length < (unsigned int) RSA_size(rsa)) return (ISC_R_NOSPACE); if (dctx->key->key_alg == DST_ALG_RSAMD5) { isc_md5_t *md5ctx = dctx->opaque; isc_md5_final(md5ctx, digest); type = NID_md5; digestlen = ISC_MD5_DIGESTLENGTH; } else { isc_sha1_t *sha1ctx = dctx->opaque; isc_sha1_final(sha1ctx, digest); type = NID_sha1; digestlen = ISC_SHA1_DIGESTLENGTH; } status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); if (status == 0) { err = ERR_peek_error_line(&file, &line); if (err != 0U) { message = ERR_error_string(err, NULL); fprintf(stderr, "%s:%s:%d\n", message, file ? file : "", line); } return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } isc_buffer_add(sig, siglen); return (ISC_R_SUCCESS); }
/* * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key. */ void isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[ISC_SHA1_BLOCK_LENGTH]; unsigned int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_sha1_t sha1ctx; isc_sha1_init(&sha1ctx); isc_sha1_update(&sha1ctx, key, len); isc_sha1_final(&sha1ctx, ctx->key); } else memcpy(ctx->key, key, len); isc_sha1_init(&ctx->sha1ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) ipad[i] ^= ctx->key[i]; isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad)); }
int isc_iterated_hash(unsigned char out[ISC_SHA1_DIGESTLENGTH], unsigned int hashalg, int iterations, const unsigned char *salt, int saltlength, const unsigned char *in, int inlength) { isc_sha1_t ctx; int n = 0; if (hashalg != 1) return (0); do { isc_sha1_init(&ctx); isc_sha1_update(&ctx, in, inlength); isc_sha1_update(&ctx, salt, saltlength); isc_sha1_final(&ctx, out); in = out; inlength = ISC_SHA1_DIGESTLENGTH; } while (n++ < iterations); return (ISC_SHA1_DIGESTLENGTH); }
isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { dns_fixedname_t fname; dns_name_t *name; unsigned char digest[ISC_SHA256_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; isc_sha1_t sha1; isc_sha256_t sha256; #ifdef HAVE_OPENSSL_GOST EVP_MD_CTX ctx; const EVP_MD *md; #endif REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); if (!dns_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); (void)dns_name_downcase(owner, name, NULL); memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); switch (digest_type) { case DNS_DSDIGEST_SHA1: isc_sha1_init(&sha1); dns_name_toregion(name, &r); isc_sha1_update(&sha1, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); break; #ifdef HAVE_OPENSSL_GOST #define CHECK(x) \ if ((x) != 1) { \ EVP_MD_CTX_cleanup(&ctx); \ return (DST_R_OPENSSLFAILURE); \ } case DNS_DSDIGEST_GOST: md = EVP_gost(); if (md == NULL) return (DST_R_OPENSSLFAILURE); EVP_MD_CTX_init(&ctx); CHECK(EVP_DigestInit(&ctx, md)); dns_name_toregion(name, &r); CHECK(EVP_DigestUpdate(&ctx, (const void *) r.base, (size_t) r.length)); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); CHECK(EVP_DigestUpdate(&ctx, (const void *) r.base, (size_t) r.length)); CHECK(EVP_DigestFinal(&ctx, digest, NULL)); break; #endif default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); isc_sha256_update(&sha256, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha256_update(&sha256, r.base, r.length); isc_sha256_final(digest, &sha256); break; } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); ds.digest_type = digest_type; switch (digest_type) { case DNS_DSDIGEST_SHA1: ds.length = ISC_SHA1_DIGESTLENGTH; break; #ifdef HAVE_OPENSSL_GOST case DNS_DSDIGEST_GOST: ds.length = ISC_GOST_DIGESTLENGTH; break; #endif default: ds.length = ISC_SHA256_DIGESTLENGTH; break; } ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, &ds, &b)); }
static isc_result_t opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; int status = 0; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; #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 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); #if USE_EVP status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; isc_md5_final(md5ctx, digest); type = NID_md5; digestlen = ISC_MD5_DIGESTLENGTH; } break; 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) { case DST_ALG_RSAMD5: 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_toresult2( "RSA_public_decrypt", DST_R_VERIFYFAILURE)); if (status != (int)(prefixlen + digestlen)) return (DST_R_VERIFYFAILURE); if (memcmp(original, prefix, prefixlen)) return (DST_R_VERIFYFAILURE); if (memcmp(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 #endif if (status != 1) return (dst__openssl_toresult2("RSA_verify", DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); }
static isc_result_t opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; isc_region_t r; unsigned int siglen = 0; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; #else RSA *rsa = key->keydata.rsa; /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH]; int status; int type = 0; unsigned int digestlen = 0; #if OPENSSL_VERSION_NUMBER < 0x00908000L unsigned int prefixlen = 0; const unsigned char *prefix = NULL; #endif #endif 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); isc_buffer_availableregion(sig, &r); #if USE_EVP if (r.length < (unsigned int) EVP_PKEY_size(pkey)) return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { return (dst__openssl_toresult2("EVP_SignFinal", ISC_R_FAILURE)); } #else if (r.length < (unsigned int) RSA_size(rsa)) return (ISC_R_NOSPACE); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; isc_md5_final(md5ctx, digest); type = NID_md5; digestlen = ISC_MD5_DIGESTLENGTH; } break; 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 OPENSSL_VERSION_NUMBER < 0x00908000L switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); break; case DST_ALG_RSASHA256: case DST_ALG_RSASHA512: INSIST(prefix != NULL); INSIST(prefixlen != 0); INSIST(prefixlen + digestlen <= sizeof(digest)); memmove(digest + prefixlen, digest, digestlen); memcpy(digest, prefix, prefixlen); status = RSA_private_encrypt(digestlen + prefixlen, digest, r.base, rsa, RSA_PKCS1_PADDING); if (status < 0) status = 0; else siglen = status; break; default: INSIST(0); } #else INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); #endif if (status == 0) return (dst__openssl_toresult2("RSA_sign", DST_R_OPENSSLFAILURE)); #endif isc_buffer_add(sig, siglen); return (ISC_R_SUCCESS); }
isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { dns_fixedname_t fname; dns_name_t *name; unsigned char digest[ISC_SHA384_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; isc_sha1_t sha1; isc_sha256_t sha256; isc_sha384_t sha384; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) isc_gost_t gost; #endif REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); if (!dst_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); (void)dns_name_downcase(owner, name, NULL); memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); switch (digest_type) { case DNS_DSDIGEST_SHA1: isc_sha1_init(&sha1); dns_name_toregion(name, &r); isc_sha1_update(&sha1, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); break; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) #define RETERR(x) do { \ isc_result_t ret = (x); \ if (ret != ISC_R_SUCCESS) { \ isc_gost_invalidate(&gost); \ return (ret); \ } \ } while (/*CONSTCOND*/0) case DNS_DSDIGEST_GOST: RETERR(isc_gost_init(&gost)); dns_name_toregion(name, &r); RETERR(isc_gost_update(&gost, r.base, r.length)); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); RETERR(isc_gost_update(&gost, r.base, r.length)); RETERR(isc_gost_final(&gost, digest)); break; #endif case DNS_DSDIGEST_SHA384: isc_sha384_init(&sha384); dns_name_toregion(name, &r); isc_sha384_update(&sha384, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha384_update(&sha384, r.base, r.length); isc_sha384_final(digest, &sha384); break; case DNS_DSDIGEST_SHA256: default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); isc_sha256_update(&sha256, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha256_update(&sha256, r.base, r.length); isc_sha256_final(digest, &sha256); break; } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); ds.digest_type = digest_type; switch (digest_type) { case DNS_DSDIGEST_SHA1: ds.length = ISC_SHA1_DIGESTLENGTH; break; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) case DNS_DSDIGEST_GOST: ds.length = ISC_GOST_DIGESTLENGTH; break; #endif case DNS_DSDIGEST_SHA384: ds.length = ISC_SHA384_DIGESTLENGTH; break; case DNS_DSDIGEST_SHA256: default: ds.length = ISC_SHA256_DIGESTLENGTH; break; } ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, &ds, &b)); }
static isc_result_t openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; int status = 0; unsigned char *cp = sig->base; DSA_SIG *dsasig; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #if 0 EVP_PKEY *pkey; unsigned char *sigbuf; #endif unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; #endif unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #if USE_EVP #if 1 /* Only use EVP for the digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (ISC_R_FAILURE); } #endif #else isc_sha1_final(sha1ctx, digest); #endif if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) { return (DST_R_VERIFYFAILURE); } cp++; /*%< Skip T */ dsasig = DSA_SIG_new(); if (dsasig == NULL) return (ISC_R_NOMEMORY); dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); #if 0 pkey = EVP_PKEY_new(); if (pkey == NULL) return (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); return (ISC_R_FAILURE); } /* Convert to Dss-Sig-Value (RFC2459). */ sigbuf = malloc(EVP_PKEY_size(pkey) + 50); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf); INSIST(EVP_PKEY_size(pkey) >= (int) siglen); status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey); EVP_PKEY_free(pkey); free(sigbuf); #else status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); #endif DSA_SIG_free(dsasig); if (status != 1) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); }
static isc_result_t openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; isc_region_t r; DSA_SIG *dsasig; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey; unsigned char *sigbuf; const unsigned char *sb; unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #endif isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) return (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); return (ISC_R_FAILURE); } sigbuf = malloc(EVP_PKEY_size(pkey)); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); return (ISC_R_FAILURE); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); EVP_PKEY_free(pkey); /* Convert from Dss-Sig-Value (RFC2459). */ dsasig = DSA_SIG_new(); if (dsasig == NULL) { free(sigbuf); return (ISC_R_NOMEMORY); } sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); return (ISC_R_FAILURE); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (ISC_R_FAILURE); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); return (ISC_R_SUCCESS); }
int main(int argc, char **argv) { isc_buffer_t buf; unsigned char key[1024]; char secret[1024]; char base64[(1024*4)/3]; isc_region_t r; isc_result_t result; if (argc != 3) { fprintf(stderr, "Usage:\t%s algorithm secret\n", argv[0]); fprintf(stderr, "\talgorithm: (MD5 | SHA1 | SHA224 | " "SHA256 | SHA384 | SHA512)\n"); return (1); } isc_buffer_init(&buf, secret, sizeof(secret)); result = isc_base64_decodestring(argv[2], &buf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "error: %s\n", isc_result_totext(result)); return (1); } isc__buffer_usedregion(&buf, &r); if (!strcasecmp(argv[1], "md5") || !strcasecmp(argv[1], "hmac-md5")) { if (r.length > HMAC_LEN) { isc_md5_t md5ctx; isc_md5_init(&md5ctx); isc_md5_update(&md5ctx, r.base, r.length); isc_md5_final(&md5ctx, key); r.base = key; r.length = ISC_MD5_DIGESTLENGTH; } } else if (!strcasecmp(argv[1], "sha1") || !strcasecmp(argv[1], "hmac-sha1")) { if (r.length > ISC_SHA1_DIGESTLENGTH) { isc_sha1_t sha1ctx; isc_sha1_init(&sha1ctx); isc_sha1_update(&sha1ctx, r.base, r.length); isc_sha1_final(&sha1ctx, key); r.base = key; r.length = ISC_SHA1_DIGESTLENGTH; } } else if (!strcasecmp(argv[1], "sha224") || !strcasecmp(argv[1], "hmac-sha224")) { if (r.length > ISC_SHA224_DIGESTLENGTH) { isc_sha224_t sha224ctx; isc_sha224_init(&sha224ctx); isc_sha224_update(&sha224ctx, r.base, r.length); isc_sha224_final(key, &sha224ctx); r.base = key; r.length = ISC_SHA224_DIGESTLENGTH; } } else if (!strcasecmp(argv[1], "sha256") || !strcasecmp(argv[1], "hmac-sha256")) { if (r.length > ISC_SHA256_DIGESTLENGTH) { isc_sha256_t sha256ctx; isc_sha256_init(&sha256ctx); isc_sha256_update(&sha256ctx, r.base, r.length); isc_sha256_final(key, &sha256ctx); r.base = key; r.length = ISC_SHA256_DIGESTLENGTH; } } else if (!strcasecmp(argv[1], "sha384") || !strcasecmp(argv[1], "hmac-sha384")) { if (r.length > ISC_SHA384_DIGESTLENGTH) { isc_sha384_t sha384ctx; isc_sha384_init(&sha384ctx); isc_sha384_update(&sha384ctx, r.base, r.length); isc_sha384_final(key, &sha384ctx); r.base = key; r.length = ISC_SHA384_DIGESTLENGTH; } } else if (!strcasecmp(argv[1], "sha512") || !strcasecmp(argv[1], "hmac-sha512")) { if (r.length > ISC_SHA512_DIGESTLENGTH) { isc_sha512_t sha512ctx; isc_sha512_init(&sha512ctx); isc_sha512_update(&sha512ctx, r.base, r.length); isc_sha512_final(key, &sha512ctx); r.base = key; r.length = ISC_SHA512_DIGESTLENGTH; } } else { fprintf(stderr, "unknown hmac/digest algorithm: %s\n", argv[1]); return (1); } isc_buffer_init(&buf, base64, sizeof(base64)); result = isc_base64_totext(&r, 0, "", &buf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "error: %s\n", isc_result_totext(result)); return (1); } fprintf(stdout, "%.*s\n", (int)isc_buffer_usedlength(&buf), base64); return (0); }
int main(int argc, char **argv) { isc_sha1_t sha1; isc_sha224_t sha224; isc_md5_t md5; isc_hmacmd5_t hmacmd5; isc_hmacsha1_t hmacsha1; isc_hmacsha224_t hmacsha224; isc_hmacsha256_t hmacsha256; isc_hmacsha384_t hmacsha384; isc_hmacsha512_t hmacsha512; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char buffer[1024]; const char *s; unsigned char key[20]; UNUSED(argc); UNUSED(argv); s = "abc"; isc_sha1_init(&sha1); memcpy(buffer, s, strlen(s)); isc_sha1_update(&sha1, buffer, strlen(s)); isc_sha1_final(&sha1, digest); print_digest(s, "sha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; isc_sha1_init(&sha1); memcpy(buffer, s, strlen(s)); isc_sha1_update(&sha1, buffer, strlen(s)); isc_sha1_final(&sha1, digest); print_digest(s, "sha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "abc"; isc_sha224_init(&sha224); memcpy(buffer, s, strlen(s)); isc_sha224_update(&sha224, buffer, strlen(s)); isc_sha224_final(digest, &sha224); print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; isc_sha224_init(&sha224); memcpy(buffer, s, strlen(s)); isc_sha224_update(&sha224, buffer, strlen(s)); isc_sha224_final(digest, &sha224); print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "abc"; isc_md5_init(&md5); memcpy(buffer, s, strlen(s)); isc_md5_update(&md5, buffer, strlen(s)); isc_md5_final(&md5, digest); print_digest(s, "md5", digest, 4); /* * The 3 HMAC-MD5 examples from RFC2104 */ s = "Hi There"; memset(key, 0x0b, 16); isc_hmacmd5_init(&hmacmd5, key, 16); memcpy(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacmd5_init(&hmacmd5, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 16); isc_hmacmd5_init(&hmacmd5, key, 16); memcpy(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); /* * The 3 HMAC-SHA1 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha1_init(&hmacsha1, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha1_init(&hmacsha1, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha1_init(&hmacsha1, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); /* * The 3 HMAC-SHA224 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha224_init(&hmacsha224, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha224_init(&hmacsha224, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha224_init(&hmacsha224, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); /* * The 3 HMAC-SHA256 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha256_init(&hmacsha256, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha256_init(&hmacsha256, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha256_init(&hmacsha256, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); /* * The 3 HMAC-SHA384 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha384_init(&hmacsha384, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha384_init(&hmacsha384, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha384_init(&hmacsha384, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); /* * The 3 HMAC-SHA512 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha512_init(&hmacsha512, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha512_init(&hmacsha512, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha512_init(&hmacsha512, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); return (0); }