diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-08-27 08:18:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-08-27 08:18:59 +0300 |
commit | 9b752a26211d60c7003a7590b027bd0000344523 (patch) | |
tree | 0891580a64555994d16742ff05e8ea9b0d3e3d0b | |
parent | 09f7816510fb99aa66bcd212e88ff0c6d06f4a31 (diff) | |
download | nsu-9b752a26211d60c7003a7590b027bd0000344523.tar.gz nsu-9b752a26211d60c7003a7590b027bd0000344523.tar.bz2 |
Move TSIG support to a separate file.
* Makefile: Add alg.c
* alg.c: New file.
* nsu.h: s/nsu_signer/nsu_tsig/; s/tsig_alg/nsu_tsig_alg/. All uses changed.
(nsu_tsig_alg_find_code,nsu_tsig_alg_find_name): New protos.
(nsu_tsig_create,nsu_tsig_free): New protos.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | alg.c | 174 | ||||
-rw-r--r-- | grammar.y | 2 | ||||
-rw-r--r-- | main.c | 194 | ||||
-rw-r--r-- | nsu.c | 20 | ||||
-rw-r--r-- | nsu.h | 26 | ||||
-rw-r--r-- | nsu_app.h | 2 |
7 files changed, 225 insertions, 195 deletions
@@ -3,7 +3,7 @@ CFLAGS=-ggdb APPSRC=main.c y.tab.c lex.yy.c APPOBJ=${APPSRC: .c=.o} -NSUSRC=nsu.c typestr.c +NSUSRC=nsu.c typestr.c alg.c NSUOBJ=${NSUSRC: .c=.o} nsu: main.o $(NSUOBJ) $(APPOBJ) @@ -0,0 +1,174 @@ +#include <stdlib.h> +#include <string.h> +#include <nettle/md5.h> +#include <nettle/sha1.h> +#include <nettle/sha2.h> +#include <nettle/hmac.h> +#include <nettle/base64.h> +#include "nsu.h" + +struct nsu_tsig_alg { + char *name; + int code; + size_t digest_size; + size_t ctx_size; + const struct nettle_hash *nhash; +}; + +char const * +nsu_tsig_alg_name(struct nsu_tsig_alg const *alg) +{ + return alg->name; +} + +size_t +nsu_tsig_alg_digest_size(struct nsu_tsig_alg const *alg) +{ + return alg->digest_size; +} + +enum { CTX_INNER, CTX_OUTER, CTX_STATE }; + +static inline void * +nsu_tsig_ctx(struct nsu_tsig *sgn, int n) +{ + return sgn->ctx + n * sgn->alg->ctx_size; +} + +void +nsu_tsig_set_key(struct nsu_tsig *sgn, u_char const *key, size_t len) +{ + hmac_set_key(nsu_tsig_ctx(sgn, CTX_OUTER), + nsu_tsig_ctx(sgn, CTX_INNER), + nsu_tsig_ctx(sgn, CTX_STATE), + sgn->alg->nhash, + len, key); +} + +void +nsu_tsig_update(struct nsu_tsig *sgn, u_char const *data, size_t len) +{ + hmac_update(nsu_tsig_ctx(sgn, CTX_STATE), sgn->alg->nhash, len, data); +} + +void +nsu_tsig_digest(struct nsu_tsig *sgn, u_char *data, size_t len) +{ + hmac_digest(nsu_tsig_ctx(sgn, CTX_OUTER), + nsu_tsig_ctx(sgn, CTX_INNER), + nsu_tsig_ctx(sgn, CTX_STATE), + sgn->alg->nhash, + len, data); +} + +#define CODE_END 0 +#define CODE_ALIAS (-1) + +static struct nsu_tsig_alg algtab[] = { + { .name = "HMAC-MD5.SIG-ALG.REG.INT", + .code = 157, + .digest_size = MD5_DIGEST_SIZE, + .ctx_size = sizeof(struct md5_ctx), + .nhash = &nettle_md5, + }, + { .name = "HMAC-MD5", + .code = CODE_ALIAS, + }, + { .name = "HMAC-SHA1", + .code = 161, + .digest_size = SHA1_DIGEST_SIZE, + .nhash = &nettle_sha1, + .ctx_size = sizeof(struct sha1_ctx), + }, + { .name = "HMAC-SHA", + .code = CODE_ALIAS + }, + { .name = "HMAC-SHA224", + .code = 162, + .digest_size = SHA224_DIGEST_SIZE, + .nhash = &nettle_sha224, + .ctx_size = sizeof(struct sha224_ctx), + }, + { .name = "HMAC-SHA256", + .code = 163, + .digest_size = SHA256_DIGEST_SIZE, + .nhash = &nettle_sha256, + .ctx_size = sizeof(struct sha256_ctx), + }, + { .name = "HMAC-SHA384", + .code = 164, + .digest_size = SHA384_DIGEST_SIZE, + .nhash = &nettle_sha384, + .ctx_size = sizeof(struct sha384_ctx), + }, + { .name = "HMAC-SHA512", + .code = 165, + .digest_size = SHA512_DIGEST_SIZE, + .nhash = &nettle_sha512, + .ctx_size = sizeof(struct sha512_ctx), + }, + { .code = CODE_END } +}; + +struct nsu_tsig_alg const * +nsu_tsig_alg_find_code(int code) +{ + struct nsu_tsig_alg *ap; + for (ap = algtab; ap->code != CODE_END; ap++) + if (ap->code == code) + return ap; + return NULL; +} + +struct nsu_tsig_alg const * +nsu_tsig_alg_find_name(char const *name) +{ + struct nsu_tsig_alg *ap; + + for (ap = algtab; ap->code == CODE_END; ap++) { + if (strcasecmp(ap->name, name) == 0) + break; + } + + while (ap->code == CODE_ALIAS && ap > algtab) + ap--; + + if (ap->code <= 0) + return NULL; + + return ap; +} + +struct nsu_tsig * +nsu_tsig_create(struct nsu_tsig_alg const *alg, char const *keyname) +{ + struct nsu_tsig *sgn; + + sgn = calloc(1, sizeof(*sgn)); + if (!sgn) + return NULL; + if ((sgn->name = strdup(keyname)) == NULL || + (sgn->ctx = malloc(3 * alg->ctx_size)) == NULL || + (sgn->digest = malloc(nsu_tsig_alg_digest_size(alg))) == NULL) { + nsu_tsig_free(sgn); + return NULL; + } + sgn->alg = alg; + sgn->fudge = 300; //FIXME + return sgn; +} + +void +nsu_tsig_free(struct nsu_tsig *sgn) +{ + if (!sgn) + return; + free(sgn->name); + free(sgn->ctx); + free(sgn->digest); + free(sgn); +} + + + + @@ -152,7 +152,7 @@ domain : { need_domain(); } T_STRING ttl : /* empty */ { - $$ = default_ttl; //FIXME + $$ = default_ttl; } | T_NUMBER ; @@ -27,7 +27,7 @@ unsigned long default_ttl = 600; char const *domain_name; struct sockaddr_in *server_addr; char const domain_service[] = "53"; -struct nsu_signer *tsig; +struct nsu_tsig *tsig; void vdiagprt(char const *fmt, va_list ap) @@ -319,138 +319,6 @@ get_arg_ul(char const *arg, unsigned long *np) return 0; } -struct tsig_alg { - char *name; - int code; - size_t digest_size; - size_t ctx_size; - const struct nettle_hash *nhash; -}; - -char const * -tsig_alg_name(struct tsig_alg const *alg) -{ - return alg->name; -} - -size_t -tsig_alg_digest_size(struct tsig_alg const *alg) -{ - return alg->digest_size; -} - -enum { CTX_INNER, CTX_OUTER, CTX_STATE }; - -static inline void * -nsu_signer_ctx(struct nsu_signer *sgn, int n) -{ - return sgn->ctx + n * sgn->alg->ctx_size; -} - -void -nsu_signer_set_key(struct nsu_signer *sgn, u_char const *key, size_t len) -{ - hmac_set_key(nsu_signer_ctx(sgn, CTX_OUTER), - nsu_signer_ctx(sgn, CTX_INNER), - nsu_signer_ctx(sgn, CTX_STATE), - sgn->alg->nhash, - len, key); -} - -void -nsu_signer_update(struct nsu_signer *sgn, u_char const *data, size_t len) -{ - hmac_update(nsu_signer_ctx(sgn, CTX_STATE), sgn->alg->nhash, len, data); -} - -void -nsu_signer_digest(struct nsu_signer *sgn, u_char *data, size_t len) -{ - hmac_digest(nsu_signer_ctx(sgn, CTX_OUTER), - nsu_signer_ctx(sgn, CTX_INNER), - nsu_signer_ctx(sgn, CTX_STATE), - sgn->alg->nhash, - len, data); -} - -#define CODE_END 0 -#define CODE_ALIAS (-1) - -static struct tsig_alg algtab[] = { - { .name = "HMAC-MD5.SIG-ALG.REG.INT", - .code = 157, - .digest_size = MD5_DIGEST_SIZE, - .ctx_size = sizeof(struct md5_ctx), - .nhash = &nettle_md5, - }, - { .name = "HMAC-MD5", - .code = CODE_ALIAS, - }, - { .name = "HMAC-SHA1", - .code = 161, - .digest_size = SHA1_DIGEST_SIZE, - .nhash = &nettle_sha1, - .ctx_size = sizeof(struct sha1_ctx), - }, - { .name = "HMAC-SHA", - .code = CODE_ALIAS - }, - { .name = "HMAC-SHA224", - .code = 162, - .digest_size = SHA224_DIGEST_SIZE, - .nhash = &nettle_sha224, - .ctx_size = sizeof(struct sha224_ctx), - }, - { .name = "HMAC-SHA256", - .code = 163, - .digest_size = SHA256_DIGEST_SIZE, - .nhash = &nettle_sha256, - .ctx_size = sizeof(struct sha256_ctx), - }, - { .name = "HMAC-SHA384", - .code = 164, - .digest_size = SHA384_DIGEST_SIZE, - .nhash = &nettle_sha384, - .ctx_size = sizeof(struct sha384_ctx), - }, - { .name = "HMAC-SHA512", - .code = 165, - .digest_size = SHA512_DIGEST_SIZE, - .nhash = &nettle_sha512, - .ctx_size = sizeof(struct sha512_ctx), - }, - { .code = CODE_END } -}; - -static struct tsig_alg const * -alg_find_code(int code) -{ - struct tsig_alg *ap; - for (ap = algtab; ap->code != CODE_END; ap++) - if (ap->code == code) - return ap; - return NULL; -} - -static struct tsig_alg const * -alg_find_name(char const *name) -{ - struct tsig_alg *ap; - - for (ap = algtab; ap->code == CODE_END; ap++) { - if (strcasecmp(ap->name, name) == 0) - break; - } - - while (ap->code == CODE_ALIAS && ap > algtab) - ap--; - - if (ap->code <= 0) - return NULL; - - return ap; -} - static int is_suffix(char const *suf, char const *str) { @@ -462,7 +330,7 @@ is_suffix(char const *suf, char const *str) static char const *priv_suffix = ".private"; static char const *key_suffix = ".key"; -static struct tsig_alg const * +static struct nsu_tsig_alg const * keyfile_read_private(char const *name, uint8_t **pkey, size_t *pkey_len) { char *tmpname = NULL; @@ -470,7 +338,7 @@ keyfile_read_private(char const *name, uint8_t **pkey, size_t *pkey_len) char buf[512]; int lno = 0; - struct tsig_alg const *alg = NULL; + struct nsu_tsig_alg const *alg = NULL; uint8_t *key; size_t key_len; @@ -523,7 +391,7 @@ keyfile_read_private(char const *name, uint8_t **pkey, size_t *pkey_len) if (errno || *p != ' ') abend("%s:%d: malformed line", name, lno); - alg = alg_find_code(code); + alg = nsu_tsig_alg_find_code(code); if (!alg) abend("%s:%d: unsupported algorithm %s", name, lno, buf + n); @@ -642,14 +510,14 @@ keyfile_read_key(char const *name, uint8_t **pkey, size_t *pkey_len) return ret; } -static struct nsu_signer * +static struct nsu_tsig * keyfile_read(char const *name) { - struct tsig_alg const *alg; + struct nsu_tsig_alg const *alg; uint8_t *pkey, *key; size_t pkey_len, key_len; char *keyname; - struct nsu_signer *sgn; + struct nsu_tsig *sgn; alg = keyfile_read_private(name, &pkey, &pkey_len); keyname = keyfile_read_key(name, &key, &key_len); @@ -658,37 +526,17 @@ keyfile_read(char const *name) abend("%s: keys don't match", name); free(pkey); - sgn = calloc(1, sizeof(*sgn)); + sgn = nsu_tsig_create(alg, keyname); + free(keyname); if (!sgn) abend_nomem(); - sgn->ctx = malloc(3 * alg->ctx_size); - if (!sgn->ctx) - abend_nomem(); - sgn->digest = malloc(tsig_alg_digest_size(alg)); - if (!sgn->digest) - abend_nomem(); - - sgn->name = keyname; - sgn->alg = alg; - sgn->fudge = 300; //FIXME - nsu_signer_set_key(sgn, key, key_len); + nsu_tsig_set_key(sgn, key, key_len); free(key); return sgn; } -void -nsu_signer_free(struct nsu_signer *sgn) -{ - if (!sgn) - return; - free(sgn->name); - free(sgn->ctx); - free(sgn->digest); - free(sgn); -} - /* * nsu */ @@ -804,16 +652,18 @@ send_update_query(res_state state, char const *zone, u_char *qbuf, int qlen) rcode = ns_msg_getflag(handle, ns_f_rcode); switch (rcode) { -/* - * If a response is received whose RCODE is SERVFAIL or NOTIMP, or - * if no response is received within an implementation dependent timeout - * period, or if an ICMP error is received indicating that the server's - * port is unreachable, then the requestor will delete the unusable - * server from its internal name server list and try the next one, - * repeating until the name server list is empty. If the requestor runs - * out of servers to try, an appropriate error will be returned to the - * requestor's caller. - */ + /* + * If a response is received whose RCODE is SERVFAIL or + * NOTIMP, or if no response is received within an + * implementation dependent timeout period, or if an ICMP + * error is received indicating that the server's port is + * unreachable, then the requestor will delete the unusable + * server from its internal name server list and try the + * next one, repeating until the name server list is empty. + * If the requestor runs out of servers to try, an + * appropriate error will be returned to the requestor's + * caller. + */ case ns_r_notimpl: case ns_r_servfail: if (state->options & RES_DEBUG) { @@ -117,7 +117,7 @@ nsu_nmkquery(res_state statp, char const *zone, nsu_rr *prereq, int num_prereq, nsu_rr *update, int num_update, - struct nsu_signer *tsig, + struct nsu_tsig *tsig, u_char *buf, int buflen) { UPDATE_HEADER *hp; @@ -366,7 +366,7 @@ nsu_nmkquery(res_state statp, if (tsig) { size_t msglen = cp - buf; /* Length of the original message */ - size_t tsig_digest_len = tsig_alg_digest_size(tsig->alg); + size_t tsig_digest_len = nsu_tsig_alg_digest_size(tsig->alg); struct timeval tv; u_char lcbuf[NS_MAXDNAME]; /* Buffer for converting domain names to lower case. */ @@ -459,7 +459,7 @@ nsu_nmkquery(res_state statp, * in domain name syntax. */ - n = ns_name_compress(lcase(tsig_alg_name(tsig->alg), lcbuf), + n = ns_name_compress(lcase(nsu_tsig_alg_name(tsig->alg), lcbuf), cp, buflen, NULL, NULL); if (n < 0) @@ -514,22 +514,22 @@ nsu_nmkquery(res_state statp, NS_PUT16(0, cp); /* Hash the original message */ - nsu_signer_update(tsig, buf, msglen); + nsu_tsig_update(tsig, buf, msglen); /* Add NAME to the digest */ - nsu_signer_update(tsig, tsig_name_ptr, tsig_name_len); + nsu_tsig_update(tsig, tsig_name_ptr, tsig_name_len); /* Add CLASS and TTL to the digest. */ - nsu_signer_update(tsig, classp, 6); + nsu_tsig_update(tsig, classp, 6); /* Hash the Algorighm Name, Time Signed and Fudge */ - nsu_signer_update(tsig, rdatap, ilen); + nsu_tsig_update(tsig, rdatap, ilen); /* Hash the tail portion of rdata: Error, Other Length (0) */ - nsu_signer_update(tsig, tailp, cp-tailp); + nsu_tsig_update(tsig, tailp, cp-tailp); /* Add the digest */ - nsu_signer_digest(tsig, tsig->digest, tsig_digest_len); + nsu_tsig_digest(tsig, tsig->digest, tsig_digest_len); memcpy(macp, tsig->digest, tsig_digest_len); /* Store the actual RDATA length */ @@ -545,7 +545,7 @@ int nsu_mkquery(char const *zone, nsu_rr *prereq, int num_prereq, nsu_rr *update, int num_update, - struct nsu_signer *tsig, + struct nsu_tsig *tsig, u_char *buf, int buflen) { return nsu_nmkquery(&_res, @@ -70,22 +70,28 @@ typedef struct { unsigned adcount: 16; /*%< number of RRs in the Additional Data Section */ } UPDATE_HEADER; -struct tsig_alg; +struct nsu_tsig_alg; -struct nsu_signer { +struct nsu_tsig { char *name; - struct tsig_alg const *alg; + struct nsu_tsig_alg const *alg; unsigned short fudge; char *ctx; unsigned char *digest; }; -char const *tsig_alg_name(struct tsig_alg const *alg); -size_t tsig_alg_digest_size(struct tsig_alg const *alg); +struct nsu_tsig_alg const *nsu_tsig_alg_find_code(int code); +struct nsu_tsig_alg const *nsu_tsig_alg_find_name(char const *name); -void nsu_signer_set_key(struct nsu_signer *sgn, u_char const *key, size_t len); -void nsu_signer_update(struct nsu_signer *sgn, u_char const *data, size_t len); -void nsu_signer_digest(struct nsu_signer *sgn, u_char *data, size_t len); +char const *nsu_tsig_alg_name(struct nsu_tsig_alg const *alg); +size_t nsu_tsig_alg_digest_size(struct nsu_tsig_alg const *alg); + +struct nsu_tsig *nsu_tsig_create(struct nsu_tsig_alg const *alg, char const *keyname); +void nsu_tsig_free(struct nsu_tsig *sgn); + +void nsu_tsig_set_key(struct nsu_tsig *sgn, u_char const *key, size_t len); +void nsu_tsig_update(struct nsu_tsig *sgn, u_char const *data, size_t len); +void nsu_tsig_digest(struct nsu_tsig *sgn, u_char *data, size_t len); int nsu_str_to_type(char const *str); char const *nsu_type_to_str(int type); @@ -94,12 +100,12 @@ int nsu_nmkquery(res_state statp, char const *zone, nsu_rr *prereq, int num_prereq, nsu_rr *update, int num_update, - struct nsu_signer *tsig, + struct nsu_tsig *tsig, u_char *buf, int buflen); int nsu_mkquery(char const *zone, nsu_rr *prereq, int num_prereq, nsu_rr *update, int num_update, - struct nsu_signer *tsig, + struct nsu_tsig *tsig, u_char *buf, int buflen); @@ -3,7 +3,7 @@ void need_domain(); extern unsigned long default_ttl; extern int yydebug; extern int yy_flex_debug; -extern struct nsu_signer *tsig; +extern struct nsu_tsig *tsig; void panic(char const *fmt, ...); void abend(char const *fmt, ...); |