From 3af1ea8cbc120c7237f1e2ed11d7c6028edce7a6 Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Wed, 2 May 2012 19:06:47 +0200 Subject: [PATCH] Simplify abstraction of verification algorithms (it was too flexible) --- src/dnssec-crypto.h | 8 ++- src/dnssec-openssl.c | 159 +++++++++++-------------------------------- src/dnssec.c | 9 +-- 3 files changed, 51 insertions(+), 125 deletions(-) diff --git a/src/dnssec-crypto.h b/src/dnssec-crypto.h index 3daac0b..b1c7ef8 100644 --- a/src/dnssec-crypto.h +++ b/src/dnssec-crypto.h @@ -32,15 +32,16 @@ typedef struct VerifyAlgCtx VerifyAlgCtx; typedef struct { - int (*set_signature)(VerifyAlgCtx *ctx, unsigned char *data, unsigned len); - int (*get_digestalgo)(VerifyAlgCtx *ctx); - void (*set_digest)(VerifyAlgCtx *ctx, unsigned char *digest); + int digest_algo; int (*verify)(VerifyAlgCtx *ctx, struct keydata *key, unsigned key_len); } VerifyAlg; struct VerifyAlgCtx { const VerifyAlg *vtbl; + unsigned char *sig; + size_t siglen; + unsigned char digest[32]; }; int verifyalg_supported(int algo); @@ -53,6 +54,7 @@ int verifyalg_algonum(VerifyAlgCtx *a); /* RFC4034 digest algorithms */ #define DIGESTALG_SHA1 1 #define DIGESTALG_SHA256 2 +#define DIGESTALG_MD5 256 int digestalg_supported(int algo); int digestalg_begin(int algo); diff --git a/src/dnssec-openssl.c b/src/dnssec-openssl.c index f7cb880..dc37294 100644 --- a/src/dnssec-openssl.c +++ b/src/dnssec-openssl.c @@ -6,37 +6,10 @@ #include #include -typedef struct VACTX_rsasha1 -{ - VerifyAlgCtx base; - unsigned char *sig; - unsigned siglen; - unsigned char digest[20]; -} VACTX_rsasha1; - -typedef struct VACTX_rsasha256 -{ - VerifyAlgCtx base; - unsigned char *sig; - unsigned siglen; - unsigned char digest[32]; -} VACTX_rsasha256; - -typedef struct VACTX_dsasha1 -{ - VerifyAlgCtx base; - unsigned char *sig; - unsigned siglen; - unsigned char digest[20]; -} VACTX_dsasha1; - - #define POOL_SIZE 1 static union _Pool { - VACTX_rsasha1 rsasha1; - VACTX_rsasha256 rsasha256; - VACTX_dsasha1 dsasha1; + VerifyAlgCtx ctx; } Pool[POOL_SIZE]; static char pool_used = 0; @@ -50,62 +23,6 @@ static void print_hex(unsigned char *data, unsigned len) printf("\n"); } -static int rsasha1_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len) -{ - VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; - ctx->sig = data; - ctx->siglen = len; - return 1; -} - -static int rsasha256_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len) -{ - VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; - ctx->sig = data; - ctx->siglen = len; - return 1; -} - -static int dsasha1_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len) -{ - VACTX_dsasha1 *ctx = (VACTX_dsasha1 *)ctx_; - ctx->sig = data; - ctx->siglen = len; - return 1; -} - -static int rsasha1_get_digestalgo(VerifyAlgCtx *ctx_) -{ - (void)ctx_; - return DIGESTALG_SHA1; -} -static int rsasha256_get_digestalgo(VerifyAlgCtx *ctx_) -{ - (void)ctx_; - return DIGESTALG_SHA256; -} -static int dsasha1_get_digestalgo(VerifyAlgCtx *ctx_) -{ - (void)ctx_; - return DIGESTALG_SHA1; -} - -static void rsasha1_set_digest(VerifyAlgCtx *ctx_, unsigned char *digest) -{ - VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; - memcpy(ctx->digest, digest, sizeof(ctx->digest)); -} -static void rsasha256_set_digest(VerifyAlgCtx *ctx_, unsigned char *digest) -{ - VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; - memcpy(ctx->digest, digest, sizeof(ctx->digest)); -} -static void dsasha1_set_digest(VerifyAlgCtx *ctx_, unsigned char *digest) -{ - VACTX_dsasha1 *ctx = (VACTX_dsasha1 *)ctx_; - memcpy(ctx->digest, digest, sizeof(ctx->digest)); -} - static int keydata_to_bn(BIGNUM *ret, struct keydata **key_data, unsigned char **p, unsigned len) { size_t cnt; @@ -160,9 +77,13 @@ static int dsasha1_parse_key(BIGNUM *Q, BIGNUM *P, BIGNUM *G, BIGNUM *Y, struct keydata_to_bn(Y, &key_data, &p, 64+T*8); } -static int rsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned key_len) +static int rsamd5_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) +{ + return 0; +} + +static int rsasha1_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) { - VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; int validated = 0; RSA *rsa = RSA_new(); @@ -176,9 +97,8 @@ static int rsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned return validated; } -static int rsasha256_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned key_len) +static int rsasha256_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) { - VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; int validated = 0; RSA *rsa = RSA_new(); @@ -192,7 +112,7 @@ static int rsasha256_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsign return validated; } -static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned key_len) +static int dsasha1_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) { static unsigned char asn1_signature[] = { @@ -202,7 +122,6 @@ static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned 0x02, 21, // large integer (21 bytes) 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // S }; - VACTX_dsasha1 *ctx = (VACTX_dsasha1 *)ctx_; int validated = 0; /* A DSA signature is made of 2 bignums (R & S). We could parse them manually with BN_bin2bn(), @@ -227,13 +146,11 @@ static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned } #define VALG_UNSUPPORTED() { \ - 0,0,0,0 \ + 0,0 \ } /**/ -#define VALG_VTABLE(alg) { \ - alg ## _set_signature, \ - alg ## _get_digestalgo, \ - alg ## _set_digest, \ +#define VALG_VTABLE(alg, digest) { \ + digest, \ alg ## _verify \ } /**/ @@ -241,34 +158,36 @@ static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */ static const VerifyAlg valgs[] = { - VALG_UNSUPPORTED(), /* 0: reserved */ - VALG_UNSUPPORTED(), /* 1: RSAMD5 */ - VALG_UNSUPPORTED(), /* 2: DH */ - VALG_VTABLE(dsasha1), /* 3: DSA */ - VALG_UNSUPPORTED(), /* 4: ECC */ - VALG_VTABLE(rsasha1), /* 5: RSASHA1 */ - VALG_UNSUPPORTED(), /* 6: DSA-NSEC3-SHA1 */ - VALG_VTABLE(rsasha1), /* 7: RSASHA1-NSEC3-SHA1 */ - VALG_VTABLE(rsasha256), /* 8: RSASHA256 */ - VALG_UNSUPPORTED(), /* 9: unassigned */ - VALG_UNSUPPORTED(), /* 10: RSASHA512 */ - VALG_UNSUPPORTED(), /* 11: unassigned */ - VALG_UNSUPPORTED(), /* 12: ECC-GOST */ - VALG_UNSUPPORTED(), /* 13: ECDSAP256SHA256 */ - VALG_UNSUPPORTED(), /* 14: ECDSAP384SHA384 */ + VALG_UNSUPPORTED(), /* 0: reserved */ + VALG_VTABLE(rsamd5, DIGESTALG_MD5), /* 1: RSAMD5 */ + VALG_UNSUPPORTED(), /* 2: DH */ + VALG_VTABLE(dsasha1, DIGESTALG_SHA1), /* 3: DSA */ + VALG_UNSUPPORTED(), /* 4: ECC */ + VALG_VTABLE(rsasha1, DIGESTALG_SHA1), /* 5: RSASHA1 */ + VALG_UNSUPPORTED(), /* 6: DSA-NSEC3-SHA1 */ + VALG_VTABLE(rsasha1, DIGESTALG_SHA1), /* 7: RSASHA1-NSEC3-SHA1 */ + VALG_VTABLE(rsasha256, DIGESTALG_SHA256), /* 8: RSASHA256 */ + VALG_UNSUPPORTED(), /* 9: unassigned */ + VALG_UNSUPPORTED(), /* 10: RSASHA512 */ + VALG_UNSUPPORTED(), /* 11: unassigned */ + VALG_UNSUPPORTED(), /* 12: ECC-GOST */ + VALG_UNSUPPORTED(), /* 13: ECDSAP256SHA256 */ + VALG_UNSUPPORTED(), /* 14: ECDSAP384SHA384 */ }; +/* TODO: remove if we don't need this anymore + (to be rechecked if we ever remove OpenSSL) */ static const int valgctx_size[] = { 0, /* 0: reserved */ - 0, /* 1: RSAMD5 */ + sizeof(VerifyAlgCtx), /* 1: RSAMD5 */ 0, /* 2: DH */ - sizeof(VACTX_dsasha1), /* 3: DSA */ + sizeof(VerifyAlgCtx), /* 3: DSA */ 0, /* 4: ECC */ - sizeof(VACTX_rsasha1), /* 5: RSASHA1 */ + sizeof(VerifyAlgCtx), /* 5: RSASHA1 */ 0, /* 6: DSA-NSEC3-SHA1 */ - sizeof(VACTX_rsasha1), /* 7: RSASHA1-NSEC3-SHA1 */ - sizeof(VACTX_rsasha256), /* 8: RSASHA256 */ + sizeof(VerifyAlgCtx), /* 7: RSASHA1-NSEC3-SHA1 */ + sizeof(VerifyAlgCtx), /* 8: RSASHA256 */ 0, /* 9: unassigned */ 0, /* 10: RSASHA512 */ 0, /* 11: unassigned */ @@ -330,16 +249,20 @@ static EVP_MD_CTX digctx; int digestalg_supported(int algo) { - return (algo == DIGESTALG_SHA1 || algo == DIGESTALG_SHA256); + return (algo == DIGESTALG_SHA1 || + algo == DIGESTALG_SHA256 || + algo == DIGESTALG_MD5); } int digestalg_begin(int algo) { EVP_MD_CTX_init(&digctx); - if (algo == 1) + if (algo == DIGESTALG_SHA1) EVP_DigestInit_ex(&digctx, EVP_sha1(), NULL); - else if (algo == 2) + else if (algo == DIGESTALG_SHA256) EVP_DigestInit_ex(&digctx, EVP_sha256(), NULL); + else if (algo == DIGESTALG_MD5) + EVP_DigestInit_ex(&digctx, EVP_md5(), NULL); else return 0; return 1; diff --git a/src/dnssec.c b/src/dnssec.c index 71fca24..b2abb94 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -561,8 +561,8 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, VerifyAlgCtx *alg = verifyalg_alloc(sigalg); if (!alg) return 0; - if (!alg->vtbl->set_signature(alg, sig, sigrdlen)) - return 0; + alg->sig = sig; + alg->siglen = sigrdlen; sigtype = htons(sigtype); sigclass = htons(sigclass); @@ -575,7 +575,7 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, unsigned char owner_wire[MAXCDNAME]; int owner_wire_len = convert_domain_to_wire(owner, owner_wire); - digestalg_begin(alg->vtbl->get_digestalgo(alg)); + digestalg_begin(alg->vtbl->digest_algo); digestalg_add_data(sigrdata, 18+signer_name_rdlen); for (i = 0; i < rrsetidx; ++i) { @@ -590,7 +590,8 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen, if (!digestalg_add_rdata(ntohs(sigtype), header, pktlen, p)) return 0; } - alg->vtbl->set_digest(alg, digestalg_final()); + int digest_len = digestalg_len(); + memcpy(alg->digest, digestalg_final(), digest_len); /* We don't need the owner name anymore; now extract the signer name */ if (!extract_name_no_compression(sigrdata+18, signer_name_rdlen, signer_name))