diff --git a/src/dnssec-crypto.h b/src/dnssec-crypto.h index c5e191b..3591556 100644 --- a/src/dnssec-crypto.h +++ b/src/dnssec-crypto.h @@ -25,32 +25,25 @@ * alg->verify(key1, 16); * alg->verify(key2, 16); */ + +typedef struct VerifyAlgCtx VerifyAlgCtx; + typedef struct { - int (*set_signature)(unsigned char *data, unsigned len); - void (*begin_data)(void); - void (*add_data)(void *data, unsigned len); - void (*end_data)(void); - int (*verify)(unsigned char *key, unsigned key_len); + int (*set_signature)(VerifyAlgCtx *ctx, unsigned char *data, unsigned len); + void (*begin_data)(VerifyAlgCtx *ctx); + void (*add_data)(VerifyAlgCtx *ctx, void *data, unsigned len); + void (*end_data)(VerifyAlgCtx *ctx); + int (*verify)(VerifyAlgCtx *ctx, unsigned char *key, unsigned key_len); } VerifyAlg; -#define DEFINE_VALG(alg) \ - void alg ## _set_signature(unsigned char *data, unsigned len); \ - void alg ## _begin_data(void); \ - void alg ## _add_data(void *data, unsigned len); \ - void alg ## _end_data(void); \ - int alg ## _verify(unsigned char *key, unsigned key_len) \ - /**/ +struct VerifyAlgCtx +{ + const VerifyAlg *vtbl; +}; -#define VALG_VTABLE(alg) { \ - alg ## _set_signature, \ - alg ## _begin_data, \ - alg ## _add_data, \ - alg ## _end_data, \ - alg ## _verify \ - } /**/ - -DEFINE_VALG(rsasha1); -DEFINE_VALG(rsasha256); +int verifyalg_supported(int algo); +VerifyAlgCtx* verifyalg_alloc(int algo); +void verifyalg_free(VerifyAlgCtx *a); #endif /* DNSSEC_CRYPTO_H */ diff --git a/src/dnssec-openssl.c b/src/dnssec-openssl.c index 4dfb2ac..5cf2c41 100644 --- a/src/dnssec-openssl.c +++ b/src/dnssec-openssl.c @@ -1,72 +1,203 @@ #include +#include "dnsmasq.h" +#include "dnssec-crypto.h" #include -struct rsasha_state +typedef struct VACTX_rsasha1 { + VerifyAlgCtx base; + unsigned char *sig; + unsigned siglen; + union + { + EVP_MD_CTX hash; + unsigned char digest[20]; + }; +} VACTX_rsasha1; + +typedef struct VACTX_rsasha256 +{ + VerifyAlgCtx base; + unsigned char *sig; + unsigned siglen; union { EVP_MD_CTX hash; unsigned char digest[32]; }; - unsigned char *sig; - unsigned siglen; +} VACTX_rsasha256; -} RSASHA; - -int rsasha1_set_signature(unsigned char *data, unsigned len) +#define POOL_SIZE 1 +static union _Pool { - RSASHA.sig = data; - RSASHA.siglen = len; + VACTX_rsasha1 rsasha1; + VACTX_rsasha256 rsasha256; +} Pool[POOL_SIZE]; +static char pool_used = 0; + +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; } -int rsasha256_set_signature(unsigned char *data, unsigned len) +static int rsasha256_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len) { - RSASHA.sig = data; - RSASHA.siglen = len; + VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; + ctx->sig = data; + ctx->siglen = len; return 1; } -void rsasha1_begin_data(void) +static void rsasha1_begin_data(VerifyAlgCtx *ctx_) { - EVP_MD_CTX_init(&RSASHA.hash); - EVP_DigestInit_ex(&RSASHA.hash, EVP_sha1(), NULL); + VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; + EVP_MD_CTX_init(&ctx->hash); + EVP_DigestInit_ex(&ctx->hash, EVP_sha1(), NULL); } -void rsasha256_begin_data(void) +static void rsasha256_begin_data(VerifyAlgCtx *ctx_) { - EVP_MD_CTX_init(&RSASHA.hash); - EVP_DigestInit_ex(&RSASHA.hash, EVP_sha256(), NULL); + VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; + EVP_MD_CTX_init(&ctx->hash); + EVP_DigestInit_ex(&ctx->hash, EVP_sha256(), NULL); } -void rsasha1_add_data(void *data, unsigned len) +static void rsasha1_add_data(VerifyAlgCtx *ctx_, void *data, unsigned len) { - EVP_DigestUpdate(&RSASHA.hash, data, len); + VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; + EVP_DigestUpdate(&ctx->hash, data, len); } -void rsasha256_add_data(void *data, unsigned len) +static void rsasha256_add_data(VerifyAlgCtx *ctx_, void *data, unsigned len) { - EVP_DigestUpdate(&RSASHA.hash, data, len); + VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; + EVP_DigestUpdate(&ctx->hash, data, len); } -void rsasha1_end_data(void) +static void rsasha1_end_data(VerifyAlgCtx *ctx_) { + VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; unsigned char digest[20]; - EVP_DigestFinal(&RSASHA.hash, digest, NULL); - memcpy(RSASHA.digest, digest, 20); + EVP_DigestFinal(&ctx->hash, digest, NULL); + memcpy(ctx->digest, digest, 20); } -void rsasha256_end_data(void) +static void rsasha256_end_data(VerifyAlgCtx *ctx_) { + VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; unsigned char digest[32]; - EVP_DigestFinal(&RSASHA.hash, digest, NULL); - memcpy(RSASHA.digest, digest, 32); + EVP_DigestFinal(&ctx->hash, digest, NULL); + memcpy(ctx->digest, digest, 32); } -int rsasha1_verify(unsigned char *key, unsigned key_len) +static int rsasha1_verify(VerifyAlgCtx *ctx_, unsigned char *key, unsigned key_len) { + VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_; return 0; } -int rsasha256_verify(unsigned char *key, unsigned key_len) +static int rsasha256_verify(VerifyAlgCtx *ctx_, unsigned char *key, unsigned key_len) { + VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_; return 0; } +#define DEFINE_VALG(alg) \ + int alg ## _set_signature(VerifyAlgCtx *ctx, unsigned char *data, unsigned len); \ + void alg ## _begin_data(VerifyAlgCtx *ctx); \ + void alg ## _add_data(VerifyAlgCtx *ctx, void *data, unsigned len); \ + void alg ## _end_data(VerifyAlgCtx *ctx); \ + int alg ## _verify(VerifyAlgCtx *ctx, unsigned char *key, unsigned key_len) \ + /**/ + +#define VALG_VTABLE(alg) { \ + alg ## _set_signature, \ + alg ## _begin_data, \ + alg ## _add_data, \ + alg ## _end_data, \ + alg ## _verify \ + } /**/ + +DEFINE_VALG(rsasha1); +DEFINE_VALG(rsasha256); + +/* Updated registry that merges various RFCs: + https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */ +static const VerifyAlg valgs[] = +{ + {0,0,0,0,0}, /* 0: reserved */ + {0,0,0,0,0}, /* 1: RSAMD5 */ + {0,0,0,0,0}, /* 2: DH */ + {0,0,0,0,0}, /* 3: DSA */ + {0,0,0,0,0}, /* 4: ECC */ + VALG_VTABLE(rsasha1), /* 5: RSASHA1 */ + {0,0,0,0,0}, /* 6: DSA-NSEC3-SHA1 */ + {0,0,0,0,0}, /* 7: RSASHA1-NSEC3-SHA1 */ + VALG_VTABLE(rsasha256), /* 8: RSASHA256 */ + {0,0,0,0,0}, /* 9: unassigned */ + {0,0,0,0,0}, /* 10: RSASHA512 */ + {0,0,0,0,0}, /* 11: unassigned */ + {0,0,0,0,0}, /* 12: ECC-GOST */ + {0,0,0,0,0}, /* 13: ECDSAP256SHA256 */ + {0,0,0,0,0}, /* 14: ECDSAP384SHA384 */ +}; + +static const int valgctx_size[] = +{ + 0, /* 0: reserved */ + 0, /* 1: RSAMD5 */ + 0, /* 2: DH */ + 0, /* 3: DSA */ + 0, /* 4: ECC */ + sizeof(VACTX_rsasha1), /* 5: RSASHA1 */ + 0, /* 6: DSA-NSEC3-SHA1 */ + 0, /* 7: RSASHA1-NSEC3-SHA1 */ + sizeof(VACTX_rsasha256), /* 8: RSASHA256 */ + 0, /* 9: unassigned */ + 0, /* 10: RSASHA512 */ + 0, /* 11: unassigned */ + 0, /* 12: ECC-GOST */ + 0, /* 13: ECDSAP256SHA256 */ + 0, /* 14: ECDSAP384SHA384 */ +}; + +int verifyalg_supported(int algo) +{ + return (algo < countof(valgctx_size) && valgctx_size[algo] != 0); +} + +VerifyAlgCtx* verifyalg_alloc(int algo) +{ + int i; + VerifyAlgCtx *ret = 0; + + if (!verifyalg_supported(algo)) + return 0; + + if (pool_used == (1<vtbl = &valgs[algo]; + return ret; +} + +void verifyalg_free(VerifyAlgCtx *a) +{ + int pool_idx = ((char*)a - (char*)&Pool[0]) / sizeof(Pool[0]); + if (pool_idx < 0 || pool_idx >= POOL_SIZE) + { + free(a); + return; + } + + pool_used &= ~(1 << pool_idx); +} diff --git a/src/dnssec.c b/src/dnssec.c index 1e95479..f0e2251 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -8,27 +8,6 @@ #define SERIAL_LT -1 #define SERIAL_GT 1 -/* Updated registry that merges various RFCs: - https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */ -static const VerifyAlg valgs[] = -{ - {0,0,0,0,0}, /* 0: reserved */ - {0,0,0,0,0}, /* 1: RSAMD5 */ - {0,0,0,0,0}, /* 2: DH */ - {0,0,0,0,0}, /* 3: DSA */ - {0,0,0,0,0}, /* 4: ECC */ - VALG_VTABLE(rsasha1), /* 5: RSASHA1 */ - {0,0,0,0,0}, /* 6: DSA-NSEC3-SHA1 */ - {0,0,0,0,0}, /* 7: RSASHA1-NSEC3-SHA1 */ - VALG_VTABLE(rsasha256), /* 8: RSASHA256 */ - {0,0,0,0,0}, /* 9: unassigned */ - {0,0,0,0,0}, /* 10: RSASHA512 */ - {0,0,0,0,0}, /* 11: unassigned */ - {0,0,0,0,0}, /* 12: ECC-GOST */ - {0,0,0,0,0}, /* 13: ECDSAP256SHA256 */ - {0,0,0,0,0}, /* 14: ECDSAP384SHA384 */ -}; - /* Implement RFC1982 wrapped compare for 32-bit numbers */ static int serial_compare_32(unsigned long s1, unsigned long s2) {