diff options
Diffstat (limited to 'tests/libknot/test_cookies.c')
-rw-r--r-- | tests/libknot/test_cookies.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/tests/libknot/test_cookies.c b/tests/libknot/test_cookies.c new file mode 100644 index 0000000..b50b940 --- /dev/null +++ b/tests/libknot/test_cookies.c @@ -0,0 +1,177 @@ +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/cookies.h" +#include "libknot/endian.h" +#include "libknot/errcode.h" +#include "contrib/sockaddr.h" + +static void client_generate(struct sockaddr_storage *c_addr, struct sockaddr_storage *s_addr, + const uint8_t *secret, const char *msg, int code, uint64_t le_cc) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + .server_addr = (struct sockaddr *)s_addr, + }; + memcpy(params.secret, secret, sizeof(params.secret)); + + knot_edns_cookie_t cc; + int ret = knot_edns_cookie_client_generate(&cc, ¶ms); + is_int(ret, code, "client_generate ret: %s", msg); + if (ret == KNOT_EOK) { + uint64_t ref = le64toh(le_cc); + ok(cc.len == sizeof(ref) && memcmp(cc.data, &ref, cc.len) == 0, + "client_generate value: %s", msg); + } +} + +static void server_generate(struct sockaddr_storage *c_addr, const uint8_t *secret, + const knot_edns_cookie_t *cc, const char *msg, int code, + uint64_t le_sc) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + }; + memcpy(params.secret, secret, sizeof(params.secret)); + + knot_edns_cookie_t sc; + int ret = knot_edns_cookie_server_generate(&sc, cc, ¶ms); + is_int(ret, code, "server_generate ret: %s", msg); + if (ret == KNOT_EOK) { + uint64_t ref = le64toh(le_sc); + ok(sc.len == sizeof(ref) && memcmp(sc.data, &ref, sc.len) == 0, + "server_generate value: %s", msg); + } +} + +static void client_check(struct sockaddr_storage *c_addr, struct sockaddr_storage *s_addr, + const uint8_t *secret, const char *msg, uint16_t le_cc_len, + uint64_t le_cc, int code) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + .server_addr = (struct sockaddr *)s_addr, + }; + if (secret != NULL) { + memcpy(params.secret, secret, sizeof(params.secret)); + } + + uint64_t ref = le64toh(le_cc); + knot_edns_cookie_t cc = { + .len = le_cc_len + }; + memcpy(cc.data, &ref, le_cc_len); + + int ret = knot_edns_cookie_client_check(&cc, ¶ms); + is_int(ret, code, "client_check ret: %s", msg); +} + +static void server_check(struct sockaddr_storage *c_addr, const uint8_t *secret, + const char *msg, uint16_t le_cc_len, uint64_t le_cc, + uint16_t le_sc_len, uint64_t le_sc, int code) +{ + knot_edns_cookie_params_t params = { + .client_addr = (struct sockaddr *)c_addr, + }; + if (secret != NULL) { + memcpy(params.secret, secret, sizeof(params.secret)); + } + + uint64_t ref = le64toh(le_cc); + knot_edns_cookie_t cc = { + .len = le_cc_len + }; + memcpy(cc.data, &ref, le_cc_len); + + ref = le64toh(le_sc); + knot_edns_cookie_t sc = { + .len = le_sc_len + }; + memcpy(sc.data, &ref, le_sc_len); + + int ret = knot_edns_cookie_server_check(&sc, &cc, ¶ms); + is_int(ret, code, "server_check ret: %s", msg); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + const uint8_t secret[] = "\xCE\xFA\xEF\xBE\xAD\xDE\x00\x00\xEF\xBE\xAD\xDE\xCE\xFA\x00\x00"; + + struct sockaddr_storage unspec_sa = { 0 }; + + struct sockaddr_storage c4_sa = { 0 }; + struct sockaddr_storage s4_sa = { 0 }; + sockaddr_set(&c4_sa, AF_INET, "127.0.0.1", 0); + sockaddr_set(&s4_sa, AF_INET, "10.0.0.1", 0); + + struct sockaddr_storage c6_sa = { 0 }; + struct sockaddr_storage s6_sa = { 0 }; + sockaddr_set(&c6_sa, AF_INET6, "2001:db8:8714:3a90::12", 0); + sockaddr_set(&s6_sa, AF_INET6, "::1", 0); + + /* Client cookie generate. */ + client_generate(NULL, &s4_sa, secret, "NULL, IPv4", KNOT_EINVAL, 0); + client_generate(&c4_sa, NULL, secret, "IPv4, NULL", KNOT_EINVAL, 0); + client_generate(&c4_sa, &s4_sa, secret, "IPv4, IPv4", KNOT_EOK, 0xde3832f4f59bf5ab); + client_generate(&unspec_sa, &s4_sa, secret, "unspec, IPv4", KNOT_EOK, 0x6b636ff225a1b340); + client_generate(&c4_sa, &unspec_sa, secret, "IPv4, unspec", KNOT_EOK, 0xd713ab1a81179bb3); + + /* Client cookie check. */ + client_check(NULL, &s6_sa, secret, "no client addr", 8, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, NULL, secret, "no server addr", 8, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, NULL, "no secret", 8, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "no cookie", 0, 0, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "bad cookie length", 7, 0xf99dbd02b69ab3c2, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "invalid cookie", 8, 0, KNOT_EINVAL); + client_check(&c6_sa, &s6_sa, secret, "good cookie", 8, 0xf99dbd02b69ab3c2, KNOT_EOK); + + const knot_edns_cookie_t cc = { + .data = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .len = 8 + }; + + /* Server cookie generate. */ + knot_edns_cookie_t cc_part = cc; cc_part.len--; + server_generate(NULL, secret, &cc, "NULL", KNOT_EINVAL, 0); + server_generate(&c4_sa, secret, &cc_part, "cookie part", KNOT_EINVAL, 0); + server_generate(&c4_sa, secret, &cc, "IPv4", KNOT_EOK, 0x52f86bfcc98ded6); + server_generate(&c6_sa, secret, &cc, "IPv6", KNOT_EOK, 0x33ac6c9005acf469); + server_generate(&unspec_sa, secret, &cc, "unspec", KNOT_EOK, 0x96df9dbf28f0f59e); + + /* Server cookie check. */ + server_check(NULL, secret, "no addr", 8, 0x0706050403020100, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, NULL, "no secret", 8, 0x0706050403020100, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, secret, "no client cookie", 0, 0, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, secret, "no server cookie", 8, 0x0706050403020100, + 0, 0, KNOT_EINVAL); + server_check(&c6_sa, secret, "bad client cookie", 8, 0, + 8, 0x33ac6c9005acf469, KNOT_EINVAL); + server_check(&c6_sa, secret, "bad server cookie", 8, 0x0706050403020100, + 8, 0, KNOT_EINVAL); + server_check(&c6_sa, secret, "good cookie 1", 8, 0x0706050403020100, + 8, 0x33ac6c9005acf469, KNOT_EOK); + + return 0; +} |