]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
libknot: update DNS Cookies implementation
authorDaniel Salzman <daniel.salzman@nic.cz>
Tue, 17 Sep 2019 12:00:57 +0000 (14:00 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Thu, 26 Sep 2019 18:43:35 +0000 (20:43 +0200)
To conform to https://tools.ietf.org/html/draft-sury-toorop-dns-cookies-algorithms-00,
with siphash24 as the only available algorithm.

Initial work was done by Witold KrÄ™cicki <wpk@culm.net>

src/knot/modules/cookies/cookies.c
src/libknot/cookies.c
src/libknot/cookies.h
src/libknot/rrtype/opt.h
tests/libknot/test_cookies.c

index eb85f89040825504cf540a2c8ac27e3e752b74cf..c9a1f3dc8077c41c3ff693d230e9a4a0587f4b34 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <pthread.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "knot/include/module.h"
@@ -176,8 +177,13 @@ static knotd_state_t cookies_process(knotd_state_t state, knot_pkt_t *pkt,
        }
 
        // Prepare data for server cookie computation.
-       knot_edns_cookie_params_t params;
-       params.client_addr = (struct sockaddr *)qdata->params->remote;
+       knot_edns_cookie_params_t params = {
+               .version = KNOT_EDNS_COOKIE_VERSION,
+               .timestamp = (uint32_t)time(NULL),
+               .lifetime_before = 3600,
+               .lifetime_after = 300,
+               .client_addr = qdata->params->remote
+       };
        uint64_t current_secret = ATOMIC_GET(ctx->secret.variable);
        memcpy(params.secret, &current_secret, sizeof(current_secret));
        memcpy(params.secret + sizeof(current_secret), &ctx->secret.constant,
index c7a04eaab2e921f71021baa48eba23901948c3f4..bf9e1b00609dccdfaac824f2775166b75a5e4996 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 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
@@ -19,6 +19,7 @@
 
 #include "libknot/attribute.h"
 #include "libknot/cookies.h"
+#include "libknot/endian.h"
 #include "libknot/errcode.h"
 #include "contrib/string.h"
 #include "contrib/sockaddr.h"
@@ -28,8 +29,7 @@ _public_
 int knot_edns_cookie_client_generate(knot_edns_cookie_t *out,
                                      const knot_edns_cookie_params_t *params)
 {
-       if (out == NULL || params == NULL || params->client_addr == NULL ||
-           params->server_addr == NULL) {
+       if (out == NULL || params == NULL || params->server_addr == NULL) {
                return KNOT_EINVAL;
        }
 
@@ -38,11 +38,8 @@ int knot_edns_cookie_client_generate(knot_edns_cookie_t *out,
        SipHash24_Init(&ctx, (const SIPHASH_KEY *)params->secret);
 
        size_t addr_len = 0;
-       void *addr = sockaddr_raw(params->client_addr, &addr_len);
-       SipHash24_Update(&ctx, addr, addr_len);
-
-       addr_len = 0;
-       addr = sockaddr_raw(params->server_addr, &addr_len);
+       void *addr = sockaddr_raw((const struct sockaddr *)params->server_addr, &addr_len);
+       assert(addr);
        SipHash24_Update(&ctx, addr, addr_len);
 
        uint64_t hash = SipHash24_End(&ctx);
@@ -75,31 +72,59 @@ int knot_edns_cookie_client_check(const knot_edns_cookie_t *cc,
        return KNOT_EOK;
 }
 
-_public_
-int knot_edns_cookie_server_generate(knot_edns_cookie_t *out,
-                                     const knot_edns_cookie_t *cc,
-                                     const knot_edns_cookie_params_t *params)
+static int cookie_server_generate(knot_edns_cookie_t *out,
+                                  const knot_edns_cookie_t *cc,
+                                  const knot_edns_cookie_params_t *params)
 {
-       if (out == NULL || cc == NULL || cc->len != KNOT_EDNS_COOKIE_CLNT_SIZE ||
-           params == NULL || params->client_addr == NULL) {
+       assert(out && params);
+
+       if (cc == NULL || cc->len != KNOT_EDNS_COOKIE_CLNT_SIZE ||
+           params->client_addr == NULL) {
                return KNOT_EINVAL;
+       } else if (out->data[0] != KNOT_EDNS_COOKIE_VERSION) {
+               return KNOT_ENOTSUP;
        }
 
        SIPHASH_CTX ctx;
        assert(sizeof(params->secret) == sizeof(SIPHASH_KEY));
        SipHash24_Init(&ctx, (const SIPHASH_KEY *)params->secret);
 
+       SipHash24_Update(&ctx, cc->data, cc->len);
+       SipHash24_Update(&ctx, out->data, out->len);
+
        size_t addr_len = 0;
-       void *addr = sockaddr_raw(params->client_addr, &addr_len);
+       void *addr = sockaddr_raw((const struct sockaddr *)params->client_addr, &addr_len);
+       assert(addr);
        SipHash24_Update(&ctx, addr, addr_len);
 
-       SipHash24_Update(&ctx, cc->data, cc->len);
-
        uint64_t hash = SipHash24_End(&ctx);
-       memcpy(out->data, &hash, sizeof(hash));
-       out->len = sizeof(hash);
+       memcpy(out->data + out->len, &hash, sizeof(hash));
+       out->len += sizeof(hash);
 
        return KNOT_EOK;
+
+}
+
+_public_
+int knot_edns_cookie_server_generate(knot_edns_cookie_t *out,
+                                     const knot_edns_cookie_t *cc,
+                                     const knot_edns_cookie_params_t *params)
+{
+       if (out == NULL || params == NULL) {
+               return KNOT_EINVAL;
+       }
+
+       out->data[0] = params->version;
+       out->data[1] = 0; /* reserved */
+       out->data[2] = 0; /* reserved */
+       out->data[3] = 0; /* reserved */
+       out->len = 4;
+
+       uint32_t now = htobe32(params->timestamp);
+       memcpy(&out->data[out->len], &now, sizeof(now));
+       out->len += sizeof(now);
+
+       return cookie_server_generate(out, cc, params);
 }
 
 _public_
@@ -107,12 +132,26 @@ int knot_edns_cookie_server_check(const knot_edns_cookie_t *sc,
                                   const knot_edns_cookie_t *cc,
                                   const knot_edns_cookie_params_t *params)
 {
-       if (sc == NULL || cc == NULL || params == NULL) {
+       if (sc == NULL || sc->len < KNOT_EDNS_COOKIE_SRVR_MIN_SIZE || params == NULL) {
                return KNOT_EINVAL;
        }
 
+       uint32_t cookie_time;
+       memcpy(&cookie_time, &sc->data[4], sizeof(cookie_time));
+       cookie_time = be32toh(cookie_time);
+
+       uint32_t min_time = params->timestamp - params->lifetime_before;
+       uint32_t max_time = params->timestamp + params->lifetime_after;
+       if (cookie_time < min_time || cookie_time > max_time) {
+               return KNOT_ERANGE;
+       }
+
+       const int fixed_len = 8;
        knot_edns_cookie_t ref;
-       int ret = knot_edns_cookie_server_generate(&ref, cc, params);
+       memcpy(ref.data, sc->data, fixed_len);
+       ref.len = fixed_len;
+
+       int ret = cookie_server_generate(&ref, cc, params);
        if (ret != KNOT_EOK) {
                return ret;
        }
@@ -121,7 +160,8 @@ int knot_edns_cookie_server_check(const knot_edns_cookie_t *sc,
                return KNOT_EINVAL;
        }
 
-       ret = const_time_memcmp(sc->data, ref.data, sc->len);
+       ret = const_time_memcmp(sc->data + fixed_len, ref.data + fixed_len,
+                               sc->len - fixed_len);
        if (ret != 0) {
                return KNOT_EINVAL;
        }
index 8fbeed4682b528c82dc2cb588f7e1724aec9439f..b39ca93fa4148ed5c04dff58e2899e45448cab4d 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 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
 #define KNOT_EDNS_COOKIE_SECRET_SIZE 16
 
 /*!
- * \brief DNS Cookie parameters needed to compute the cookie value.
+ * \brief DNS Cookie parameters needed to generate/check the cookie value.
  *
- * \note Server address is not used for the server cookie check.
+ * \note Client address is not used for the client cookie generation/check.
+ * \note Server address is not used for the server cookie generation/check.
  */
 typedef struct {
-       const struct sockaddr *client_addr; /*!< Client socket address. */
-       const struct sockaddr *server_addr; /*!< Server socket address. */
+       uint8_t version;          /*!< Server cookie version to generate. */
+       uint32_t timestamp;       /*!< [s] Server cookie generate or check time. */
+       uint32_t lifetime_before; /*!< [s] Server cookie lifetime in the past. */
+       uint32_t lifetime_after;  /*!< [s] Server cookie lifetime in the future. */
+       const struct sockaddr_storage *client_addr;   /*!< Client socket address. */
+       const struct sockaddr_storage *server_addr;   /*!< Server socket address. */
        uint8_t secret[KNOT_EDNS_COOKIE_SECRET_SIZE]; /*!< Cookie secret data. */
 } knot_edns_cookie_params_t;
 
index f2b7b44c9550ece1073d3fc4390ef87205528075..51bc7c703eb0712eb7cce10648244f50910c9d62 100644 (file)
@@ -62,6 +62,8 @@ enum {
        /*! \brief Default EDNS alignment size for a response. */
        KNOT_EDNS_ALIGNMENT_RESPONSE_DEFAULT = 468,
 
+       /*! \brief Current EDNS cookie version. */
+       KNOT_EDNS_COOKIE_VERSION       = 1,
        /*! \brief EDNS client cookie size. */
        KNOT_EDNS_COOKIE_CLNT_SIZE     = 8,
        /*! \brief EDNS minimum server cookie size. */
index 4c22d5fe94093fce4e12691cee3c63f1426fd6cc..53e4106d815de46c8b687258a8646b2c6e8157b8 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 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
 #include <stdlib.h>
 #include <string.h>
 #include <tap/basic.h>
+#include <time.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)
+static knot_edns_cookie_t client_generate(
+       struct sockaddr_storage *s_addr, const uint8_t *c_secret,
+       const char *msg, int code, const char *ref)
 {
        knot_edns_cookie_params_t params = {
-               .client_addr = (struct sockaddr *)c_addr,
-               .server_addr = (struct sockaddr *)s_addr,
+               .server_addr = s_addr,
        };
-       memcpy(params.secret, secret, sizeof(params.secret));
+       memcpy(params.secret, c_secret, sizeof(params.secret));
 
        knot_edns_cookie_t cc;
        int ret = knot_edns_cookie_client_generate(&cc, &params);
-       is_int(ret, code, "client_generate ret: %s", msg);
+       is_int(code, ret, "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,
+               ok(cc.len == KNOT_EDNS_COOKIE_CLNT_SIZE && memcmp(cc.data, ref, cc.len) == 0,
                   "client_generate value: %s", msg);
        }
+       return cc;
 }
 
-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)
+static knot_edns_cookie_t server_generate(
+       struct sockaddr_storage *c_addr, const uint8_t *s_secret, uint32_t timestamp,
+       const knot_edns_cookie_t *cc, const char *msg, int code, const char *ref)
 {
        knot_edns_cookie_params_t params = {
-               .client_addr = (struct sockaddr *)c_addr,
+               .version = KNOT_EDNS_COOKIE_VERSION,
+               .timestamp = timestamp,
+               .client_addr = c_addr,
        };
-       memcpy(params.secret, secret, sizeof(params.secret));
+       memcpy(params.secret, s_secret, sizeof(params.secret));
 
        knot_edns_cookie_t sc;
        int ret = knot_edns_cookie_server_generate(&sc, cc, &params);
-       is_int(ret, code, "server_generate ret: %s", msg);
+       is_int(code, ret, "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,
+               ok(sc.len == 16 && memcmp(sc.data, ref, sc.len) == 0,
                   "server_generate value: %s", msg);
        }
+       return sc;
 }
 
-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)
+static void client_check(
+       struct sockaddr_storage *s_addr, const uint8_t *secret,
+       knot_edns_cookie_t *cc, const char *msg, 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
+               .server_addr = s_addr,
        };
-       memcpy(cc.data, &ref, le_cc_len);
+       memcpy(params.secret, secret, sizeof(params.secret));
 
-       int ret = knot_edns_cookie_client_check(&cc, &params);
-       is_int(ret, code, "client_check ret: %s", msg);
+       int ret = knot_edns_cookie_client_check(cc, &params);
+       is_int(code, ret, "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)
+static void server_check(
+       struct sockaddr_storage *c_addr, const uint8_t *secret,
+       knot_edns_cookie_t *sc, knot_edns_cookie_t *cc, uint32_t timestamp,
+       const char *msg, int code)
 {
        knot_edns_cookie_params_t params = {
-               .client_addr = (struct sockaddr *)c_addr,
+               .version = KNOT_EDNS_COOKIE_VERSION,
+               .timestamp = timestamp,
+               .lifetime_before = 3600,
+               .lifetime_after = 300,
+               .client_addr = 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);
+       memcpy(params.secret, secret, sizeof(params.secret));
 
-       int ret = knot_edns_cookie_server_check(&sc, &cc, &params);
-       is_int(ret, code, "server_check ret: %s", msg);
+       int ret = knot_edns_cookie_server_check(sc, cc, &params);
+       is_int(code, ret, "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";
+       knot_edns_cookie_t cc;
+       knot_edns_cookie_t sc;
 
-       struct sockaddr_storage unspec_sa = { 0 };
+       const uint8_t c_secret1[] = "\x3F\x66\x51\xC9\x81\xC1\xD7\x3E\x58\x79\x25\xD2\xF9\x98\x5F\x08";
+       const uint8_t c_secret2[] = "\x4C\x31\x15\x17\xFA\xB6\xBF\xE2\xE1\x49\xAB\x74\xEC\x1B\xC9\xA0";
+       const uint8_t s_secret1[] = "\xE5\xE9\x73\xE5\xA6\xB2\xA4\x3F\x48\xE7\xDC\x84\x9E\x37\xBF\xCF";
 
-       struct sockaddr_storage c4_sa = { 0 };
+       struct sockaddr_storage c4_sa1 = { 0 };
+       struct sockaddr_storage c4_sa2 = { 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);
+       sockaddr_set(&c4_sa1,  AF_INET, "198.51.100.100", 0);
+       sockaddr_set(&c4_sa2, AF_INET, "203.0.113.203", 0);
+       sockaddr_set(&s4_sa,  AF_INET, "192.0.2.53", 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
-       };
+       sockaddr_set(&c6_sa, AF_INET6, "2001:db8:220:1:59de:d0f4:8769:82b8", 0);
+       sockaddr_set(&s6_sa, AF_INET6, "2001:db8:8f::53", 0);
+
+       const uint8_t c_secret6[] = "\x3B\x49\x5B\xA6\xA5\xB7\xFD\x87\x73\x5B\xD5\x8F\x1E\xF7\x26\x1D";
+       const uint8_t s_secret6[] = "\xDD\x3B\xDF\x93\x44\xB6\x78\xB1\x85\xA6\xF5\xCB\x60\xFC\xA7\x15";
+       const uint8_t s_secret7[] = "\x44\x55\x36\xBC\xD2\x51\x32\x98\x07\x5A\x5D\x37\x96\x63\xC9\x62";
+
+       // Learning a new Server Cookie
+
+       cc = client_generate(&s4_sa, c_secret1, "IPv4", KNOT_EOK,
+                            "\x24\x64\xC4\xAB\xCF\x10\xC9\x57");
+       client_check(&s4_sa, c_secret1, &cc, "IPv4", KNOT_EOK);
+       sc = server_generate(&c4_sa1, s_secret1, 1559731985, &cc, "IPv4", KNOT_EOK,
+                            "\x01\x00\x00\x00\x5C\xF7\x9F\x11\x1F\x81\x30\xC3\xEE\xE2\x94\x80");
+       server_check(&c4_sa1, s_secret1, &sc, &cc, 1559731985, "IPv4", KNOT_EOK);
+
+       // The same client learning a renewed (fresh) Server Cookie
+
+       server_generate(&c4_sa1, s_secret1, 1559734385, &cc, "IPv4", KNOT_EOK,
+                       "\x01\x00\x00\x00\x5C\xF7\xA8\x71\xD4\xA5\x64\xA1\x44\x2A\xCA\x77");
+
+       // Another client learning a renewed Server Cookie
+
+       cc = client_generate(&s4_sa, c_secret2, "IPv4", KNOT_EOK,
+                            "\xFC\x93\xFC\x62\x80\x7D\xDB\x86");
+       char *sc_reserverd = "\x01\xAB\xCD\xEF\x5C\xF7\x8F\x71\xA3\x14\x22\x7B\x66\x79\xEB\xF5";
+       memcpy(sc.data, sc_reserverd, strlen(sc_reserverd));
+       server_check(&c4_sa2, s_secret1, &sc, &cc, 1559727985, "IPv4", KNOT_EOK);
+
+       // Version check
+
+       sc.data[0] = 10;
+       server_check(&c4_sa2, s_secret1, &sc, &cc, 1559727985, "version", KNOT_ENOTSUP);
+
+       // IPv6 query with rolled over secret
+
+       cc = client_generate(&s6_sa, c_secret6, "IPv6", KNOT_EOK,
+                            "\x22\x68\x1A\xB9\x7D\x52\xC2\x98");
+       client_check(&s6_sa, c_secret6, &cc, "IPv6", KNOT_EOK);
+       sc = server_generate(&c6_sa, s_secret6, 1559741817, &cc, "IPv6", KNOT_EOK,
+                            "\x01\x00\x00\x00\x5C\xF7\xC5\x79\x26\x55\x6B\xD0\x93\x4C\x72\xF8");
+       server_check(&c6_sa, s_secret6, &sc, &cc, 1559741961, "IPv6", KNOT_EOK);
+       sc = server_generate(&c6_sa, s_secret7, 1559741961, &cc, "IPv6", KNOT_EOK,
+                            "\x01\x00\x00\x00\x5C\xF7\xC6\x09\xA6\xBB\x79\xD1\x66\x25\x50\x7A");
+
+       // Past lifetime check
+
+       server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 + 3600, "last old", KNOT_EOK);
+       server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 + 3601, "too old", KNOT_ERANGE);
+
+       // Future lifetime check
 
-       /* 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);
+       server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 - 300, "last new", KNOT_EOK);
+       server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 - 301, "too new", KNOT_ERANGE);
 
        return 0;
 }