2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

2726. [func] Added support for SHA-2 DNSSEC algorithms,

RSASHA256 and RSASHA512. [RT #20023]
This commit is contained in:
Evan Hunt
2009-10-22 02:21:31 +00:00
parent 8d307467b7
commit cc6cddfd94
15 changed files with 520 additions and 172 deletions

View File

@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
* $Id: opensslrsa_link.c,v 1.30 2009/10/20 02:59:19 marka Exp $
* $Id: opensslrsa_link.c,v 1.31 2009/10/22 02:21:30 each Exp $
*/
#ifdef OPENSSL
#ifndef USE_EVP
@@ -29,6 +29,7 @@
#include <isc/entropy.h>
#include <isc/md5.h>
#include <isc/sha1.h>
#include <isc/sha2.h>
#include <isc/mem.h>
#include <isc/string.h>
#include <isc/util.h>
@@ -105,27 +106,122 @@
static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data);
#if defined(USE_EVP) && OPENSSL_VERSION_NUMBER < 0x00908000L
/*
* OpenSSL 0.9.7 doesn't support SHA2.
* Provide the method functions we need.
*/
/*
* Use our namespace, not OpenSSL's.
*/
#define EVP_sha256 ISC_EVP_sha256
#define EVP_sha512 ISC_EVP_sha512
/*
* OpensSSL 0.9.8 defines these.
*/
#if 0
#define NID_sha256WithRSAEncryption 668
#define NID_sha256 672
#define NID_sha512WithRSAEncryption 670
#define NID_sha512 674
#else
#define NID_sha256WithRSAEncryption 0
#define NID_sha256 0
#define NID_sha512WithRSAEncryption 0
#define NID_sha512 0
#endif
static int init256(EVP_MD_CTX *ctx)
{ isc_sha256_init(ctx->md_data); return 1; }
static int update256(EVP_MD_CTX *ctx,const void *data, unsigned long count)
{ isc_sha256_update(ctx->md_data,data,count); return 1; }
static int final256(EVP_MD_CTX *ctx,unsigned char *md)
{ isc_sha256_final(md,ctx->md_data); return 1; }
static const EVP_MD sha256_md=
{
NID_sha256,
NID_sha256WithRSAEncryption,
ISC_SHA256_DIGESTLENGTH,
0,
init256,
update256,
final256,
NULL,
NULL,
EVP_PKEY_RSA_method,
ISC_SHA256_BLOCK_LENGTH,
sizeof(EVP_MD *)+sizeof(isc_sha256_t),
};
static const EVP_MD *EVP_sha256(void)
{ return(&sha256_md); }
static int init512(EVP_MD_CTX *ctx)
{ isc_sha512_init(ctx->md_data); return 1; }
static int update512(EVP_MD_CTX *ctx,const void *data,unsigned long count)
{ isc_sha512_update(ctx->md_data,data,count); return 1; }
static int final512(EVP_MD_CTX *ctx,unsigned char *md)
{ isc_sha512_final(md,ctx->md_data); return 1; }
static const EVP_MD sha512_md=
{
NID_sha512,
NID_sha512WithRSAEncryption,
ISC_SHA512_DIGESTLENGTH,
0,
init512,
update512,
final512,
NULL,
NULL,
EVP_PKEY_RSA_method,
ISC_SHA512_BLOCK_LENGTH,
sizeof(EVP_MD *)+sizeof(isc_sha512_t),
};
static const EVP_MD *EVP_sha512(void)
{ return(&sha512_md); }
#endif
static isc_result_t
opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
#if USE_EVP
EVP_MD_CTX *evp_md_ctx;
const EVP_MD *type;
const EVP_MD *type = NULL;
#endif
UNUSED(key);
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_NSEC3RSASHA1 ||
dctx->key->key_alg == DST_ALG_RSASHA256 ||
dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
evp_md_ctx = EVP_MD_CTX_create();
if (evp_md_ctx == NULL)
return (ISC_R_NOMEMORY);
if (dctx->key->key_alg == DST_ALG_RSAMD5)
switch (dctx->key->key_alg) {
case DST_ALG_RSAMD5:
type = EVP_md5(); /* MD5 + RSA */
else
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
type = EVP_sha1(); /* SHA1 + RSA */
break;
case DST_ALG_RSASHA256:
type = EVP_sha256(); /* SHA256 + RSA */
break;
case DST_ALG_RSASHA512:
type = EVP_sha512();
break;
default:
INSIST(0);
}
if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
EVP_MD_CTX_destroy(evp_md_ctx);
@@ -133,22 +229,56 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
}
dctx->ctxdata.evp_md_ctx = evp_md_ctx;
#else
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx;
switch (dctx->key->key_alg) {
case DST_ALG_RSAMD5:
{
isc_md5_t *md5ctx;
md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
if (md5ctx == NULL)
return (ISC_R_NOMEMORY);
isc_md5_init(md5ctx);
dctx->ctxdata.md5ctx = md5ctx;
} else {
isc_sha1_t *sha1ctx;
md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
if (md5ctx == NULL)
return (ISC_R_NOMEMORY);
isc_md5_init(md5ctx);
dctx->ctxdata.md5ctx = md5ctx;
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
isc_sha1_t *sha1ctx;
sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
if (sha1ctx == NULL)
return (ISC_R_NOMEMORY);
isc_sha1_init(sha1ctx);
dctx->ctxdata.sha1ctx = sha1ctx;
sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
if (sha1ctx == NULL)
return (ISC_R_NOMEMORY);
isc_sha1_init(sha1ctx);
dctx->ctxdata.sha1ctx = sha1ctx;
}
break;
case DST_ALG_RSASHA256:
{
isc_sha256_t *sha256ctx;
sha256ctx = isc_mem_get(dctx->mctx,
sizeof(isc_sha256_t));
if (sha256ctx == NULL)
return (ISC_R_NOMEMORY);
isc_sha256_init(sha256ctx);
dctx->ctxdata.sha256ctx = sha256ctx;
}
break;
case DST_ALG_RSASHA512:
{
isc_sha512_t *sha512ctx;
sha512ctx = isc_mem_get(dctx->mctx,
sizeof(isc_sha512_t));
if (sha512ctx == NULL)
return (ISC_R_NOMEMORY);
isc_sha512_init(sha512ctx);
dctx->ctxdata.sha512ctx = sha512ctx;
}
break;
default:
INSIST(0);
}
#endif
@@ -163,7 +293,9 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
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_NSEC3RSASHA1 ||
dctx->key->key_alg == DST_ALG_RSASHA256 ||
dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
if (evp_md_ctx != NULL) {
@@ -171,22 +303,58 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
dctx->ctxdata.evp_md_ctx = NULL;
}
#else
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
switch (dctx->key->key_alg) {
case DST_ALG_RSAMD5:
{
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
if (md5ctx != NULL) {
isc_md5_invalidate(md5ctx);
isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
dctx->ctxdata.md5ctx = NULL;
if (md5ctx != NULL) {
isc_md5_invalidate(md5ctx);
isc_mem_put(dctx->mctx, md5ctx,
sizeof(isc_md5_t));
dctx->ctxdata.md5ctx = NULL;
}
}
} else {
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
if (sha1ctx != NULL) {
isc_sha1_invalidate(sha1ctx);
isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
dctx->ctxdata.sha1ctx = NULL;
if (sha1ctx != NULL) {
isc_sha1_invalidate(sha1ctx);
isc_mem_put(dctx->mctx, sha1ctx,
sizeof(isc_sha1_t));
dctx->ctxdata.sha1ctx = NULL;
}
}
break;
case DST_ALG_RSASHA256:
{
isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
if (sha256ctx != NULL) {
isc_sha256_invalidate(sha256ctx);
isc_mem_put(dctx->mctx, sha256ctx,
sizeof(isc_sha256_t));
dctx->ctxdata.sha256ctx = NULL;
}
}
break;
case DST_ALG_RSASHA512:
{
isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
if (sha512ctx != NULL) {
isc_sha512_invalidate(sha512ctx);
isc_mem_put(dctx->mctx, sha512ctx,
sizeof(isc_sha512_t));
dctx->ctxdata.sha512ctx = NULL;
}
}
break;
default:
INSIST(0);
}
#endif
}
@@ -199,19 +367,47 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
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_NSEC3RSASHA1 ||
dctx->key->key_alg == DST_ALG_RSASHA256 ||
dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
return (ISC_R_FAILURE);
}
#else
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
isc_md5_update(md5ctx, data->base, data->length);
} else {
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_update(sha1ctx, data->base, data->length);
switch (dctx->key->key_alg) {
case DST_ALG_RSAMD5:
{
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
isc_md5_update(md5ctx, data->base, data->length);
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_update(sha1ctx, data->base, data->length);
}
break;
case DST_ALG_RSASHA256:
{
isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
isc_sha256_update(sha256ctx, data->base, data->length);
}
break;
case DST_ALG_RSASHA512:
{
isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
isc_sha512_update(sha512ctx, data->base, data->length);
}
break;
default:
INSIST(0);
}
#endif
return (ISC_R_SUCCESS);
@@ -227,11 +423,11 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
EVP_PKEY *pkey = key->keydata.pkey;
#else
RSA *rsa = key->keydata.rsa;
/* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
unsigned char digest[ISC_SHA512_DIGESTLENGTH];
int status;
int type;
unsigned int digestlen;
int type = 0;
unsigned int digestlen = 0;
char *message;
unsigned long err;
const char* file;
@@ -240,7 +436,9 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
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_NSEC3RSASHA1 ||
dctx->key->key_alg == DST_ALG_RSASHA256 ||
dctx->key->key_alg == DST_ALG_RSASHA512);
isc_buffer_availableregion(sig, &r);
@@ -255,16 +453,46 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
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->ctxdata.md5ctx;
isc_md5_final(md5ctx, digest);
type = NID_md5;
digestlen = ISC_MD5_DIGESTLENGTH;
} else {
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_final(sha1ctx, digest);
type = NID_sha1;
digestlen = ISC_SHA1_DIGESTLENGTH;
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);
type = NID_sha256;
digestlen = ISC_SHA256_DIGESTLENGTH;
}
break;
case DST_ALG_RSASHA512:
{
isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
isc_sha512_final(digest, sha512ctx);
type = NID_sha512;
digestlen = ISC_SHA512_DIGESTLENGTH;
}
break;
default:
INSIST(0);
}
status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
@@ -290,30 +518,62 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
EVP_PKEY *pkey = key->keydata.pkey;
#else
/* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
int type;
unsigned int digestlen;
/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
unsigned char digest[ISC_SHA512_DIGESTLENGTH];
int type = 0;
unsigned int digestlen = 0;
RSA *rsa = key->keydata.rsa;
#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_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
if (dctx->key->key_alg == DST_ALG_RSAMD5) {
isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
isc_md5_final(md5ctx, digest);
type = NID_md5;
digestlen = ISC_MD5_DIGESTLENGTH;
} else {
isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
isc_sha1_final(sha1ctx, digest);
type = NID_sha1;
digestlen = ISC_SHA1_DIGESTLENGTH;
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);
type = NID_sha256;
digestlen = ISC_SHA256_DIGESTLENGTH;
}
break;
case DST_ALG_RSASHA512:
{
isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
isc_sha512_final(digest, sha512ctx);
type = NID_sha512;
digestlen = ISC_SHA512_DIGESTLENGTH;
}
break;
default:
INSIST(0);
}
if (sig->length < (unsigned int) RSA_size(rsa))