]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Reflecting latest changes in cookie handling in libknot API.
authorKarel Slany <karel.slany@nic.cz>
Fri, 17 Jun 2016 14:09:57 +0000 (16:09 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
lib/cookies/alg_clnt.c
lib/cookies/alg_clnt.h
lib/cookies/alg_srvr.c
lib/cookies/alg_srvr.h
lib/cookies/control.c
lib/layer/cookiemonster.c

index ad748369bf5ff42bedfddf339e6f3a98c9940669..f3d8e5219302c39684278afa13c26342c4ec026f 100644 (file)
  * @note At least one of the arguments must be non-null.
  * @param input  Input parameters.
  * @param cc_out Buffer for computed client cookie.
+ * @param cc_len Size of buffre/written data.
  * @return kr_ok() on success, error code else.
  */
 static int kr_clnt_cookie_alg_fnv64(const struct kr_clnt_cookie_input *input,
-                                    uint8_t cc_out[KNOT_OPT_COOKIE_CLNT])
+                                    uint8_t *cc_out, uint16_t *cc_len)
 {
-       if (!input || !cc_out) {
+       if (!input || !cc_out || !cc_len) {
                return kr_error(EINVAL);
        }
 
@@ -74,8 +75,12 @@ static int kr_clnt_cookie_alg_fnv64(const struct kr_clnt_cookie_input *input,
                               hash_val);
 
        assert(KNOT_OPT_COOKIE_CLNT == sizeof(hash_val));
+       if (*cc_len < KNOT_OPT_COOKIE_CLNT) {
+               return kr_error(ENOSPC);
+       }
 
-       memcpy(cc_out, &hash_val, KNOT_OPT_COOKIE_CLNT);
+       *cc_len = KNOT_OPT_COOKIE_CLNT;
+       memcpy(cc_out, &hash_val, *cc_len);
 
        return kr_ok();
 }
@@ -85,12 +90,13 @@ static int kr_clnt_cookie_alg_fnv64(const struct kr_clnt_cookie_input *input,
  * @note At least one of the arguments must be non-null.
  * @param input  Input parameters.
  * @param cc_out Buffer for computed client cookie.
+ * @param cc_len Size of buffre/written data.
  * @return kr_ok() on success, error code else.
  */
 static int kr_clnt_cookie_alg_hmac_sha256_64(const struct kr_clnt_cookie_input *input,
-                                             uint8_t cc_out[KNOT_OPT_COOKIE_CLNT])
+                                             uint8_t *cc_out, uint16_t *cc_len)
 {
-       if (!input || !cc_out) {
+       if (!input || !cc_out || !cc_len) {
                return kr_error(EINVAL);
        }
 
@@ -150,8 +156,12 @@ static int kr_clnt_cookie_alg_hmac_sha256_64(const struct kr_clnt_cookie_input *
        }
 
        assert(KNOT_OPT_COOKIE_CLNT <= SHA256_DIGEST_LENGTH);
+       if (*cc_len < KNOT_OPT_COOKIE_CLNT) {
+               return kr_error(ENOSPC);
+       }
 
-       memcpy(cc_out, digest, KNOT_OPT_COOKIE_CLNT);
+       *cc_len = KNOT_OPT_COOKIE_CLNT;
+       memcpy(cc_out, digest, *cc_len);
        ret = kr_ok();
 
 fail:
@@ -212,22 +222,27 @@ int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len)
        return kr_ok();
 }
 
-int kr_clnt_cookie_check(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+int kr_clnt_cookie_check(const uint8_t *cc, uint16_t cc_len,
                          const struct kr_clnt_cookie_input *input,
                          const struct kr_clnt_cookie_alg_descr *cc_alg)
 {
-       if (!cc || !input || !cc_alg || !cc_alg->func) {
+       if (!cc || !cc_len || !input || !cc_alg || !cc_alg->func) {
                return kr_error(EINVAL);
        }
 
        uint8_t generated_cc[KNOT_OPT_COOKIE_CLNT] = {0, };
+       uint16_t generated_cc_len = KNOT_OPT_COOKIE_CLNT;
 
-       int ret = cc_alg->func(input, generated_cc);
+       int ret = cc_alg->func(input, generated_cc, &generated_cc_len);
        if (ret != kr_ok()) {
                return ret;
        }
 
-       ret = memcmp(cc, generated_cc, KNOT_OPT_COOKIE_CLNT);
+       if (generated_cc_len != cc_len) {
+               return kr_error(EINVAL);
+       }
+
+       ret = memcmp(cc, generated_cc, generated_cc_len);
        if (ret == 0) {
                return kr_ok();
        }
index 97cf5d1740bf7d4cd3ec81535a9a04b401ba3dad..ec29644c92a985c0378bd085ed99dab0ab6a43d5 100644 (file)
@@ -35,10 +35,11 @@ struct kr_clnt_cookie_input {
  * @brief Client cookie generator function type.
  * @param input Data which to generate the cookie from.
  * @param cc_out Buffer to write the resulting client cookie data into.
+ * @param cc_len Set to length of buffer. After successful return contains size of client cookie.
  * @return kr_ok() or error code
  */
 typedef int (clnt_cookie_alg_t)(const struct kr_clnt_cookie_input *input,
-                                uint8_t *cc_out);
+                                uint8_t *cc_out, uint16_t *cc_len);
 
 /** Holds description of client cookie hashing algorithms. */
 struct kr_clnt_cookie_alg_descr {
@@ -77,11 +78,12 @@ int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len);
  * @brief Check whether supplied client cookie was generated from given client
  * secret and address.
  * @param cc     Client cookie that should be checked.
+ * @param cc_len Client cookie size.
  * @param input  Input cookie algorithm parameters.
  * @param cc_alg Client cookie algorithm.
  * @return kr_ok() or error code
  */
 KR_EXPORT
-int kr_clnt_cookie_check(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+int kr_clnt_cookie_check(const uint8_t *cc, uint16_t cc_len,
                          const struct kr_clnt_cookie_input *input,
                          const struct kr_clnt_cookie_alg_descr *cc_alg);
index f746f2e7b648f70c6c4989a848a1d4334c4bc08b..c3cba6d923bef8d4afb69f85e1fcffc6d8e0c0b1 100644 (file)
@@ -78,15 +78,15 @@ static int srvr_cookie_parse(const uint8_t *sc, uint16_t sc_len,
  * @note Server cookie = FNV-64( client IP | client cookie | server secret )
  */
 static int kr_srvr_cookie_alg_fnv64_simple(const struct kr_srvr_cookie_input *input,
-                                           uint8_t sc_out[KNOT_OPT_COOKIE_SRVR_MAX],
-                                           size_t *sc_size)
+                                           uint8_t *sc_out, uint16_t *sc_len)
 {
        if (!input || !sc_out ||
-           !sc_size || (*sc_size < SRVR_FNV64_SIMPLE_HASH_SIZE)) {
+           !sc_len || (*sc_len < SRVR_FNV64_SIMPLE_HASH_SIZE)) {
                return kr_error(EINVAL);
        }
 
-       if (!input->clnt_cookie || !input->srvr_data ||
+       if (!input->clnt_cookie || !input->clnt_cookie_len ||
+           !input->srvr_data ||
            !input->srvr_data->secret_data || !input->srvr_data->secret_len) {
                return kr_error(EINVAL);
        }
@@ -103,14 +103,14 @@ static int kr_srvr_cookie_alg_fnv64_simple(const struct kr_srvr_cookie_input *in
        }
 
        hash_val = fnv_64a_buf((void *) input->clnt_cookie,
-                              KNOT_OPT_COOKIE_CLNT, hash_val);
+                              input->clnt_cookie_len, hash_val);
 
        hash_val = fnv_64a_buf((void *) input->srvr_data->secret_data,
                               input->srvr_data->secret_len, hash_val);
 
        memcpy(sc_out, &hash_val, sizeof(hash_val));
-       *sc_size = sizeof(hash_val);
-       assert(SRVR_FNV64_SIMPLE_HASH_SIZE == *sc_size);
+       *sc_len = sizeof(hash_val);
+       assert(SRVR_FNV64_SIMPLE_HASH_SIZE == *sc_len);
 
        return kr_ok();
 }
@@ -122,15 +122,15 @@ static int kr_srvr_cookie_alg_fnv64_simple(const struct kr_srvr_cookie_input *in
  * @note Server cookie = nonce | time | FNV-64( client IP | nonce| time | client cookie | server secret )
  */
 static int kr_srvr_cookie_alg_fnv64(const struct kr_srvr_cookie_input *input,
-                                    uint8_t sc_out[KNOT_OPT_COOKIE_SRVR_MAX],
-                                    size_t *sc_size)
+                                    uint8_t *sc_out, uint16_t *sc_len)
 {
        if (!input || !sc_out ||
-           !sc_size || (*sc_size < SRVR_FNV64_SIMPLE_HASH_SIZE)) {
+           !sc_len || (*sc_len < SRVR_FNV64_SIZE)) {
                return kr_error(EINVAL);
        }
 
-       if (!input->clnt_cookie || !input->srvr_data ||
+       if (!input->clnt_cookie || !input->clnt_cookie_len ||
+           !input->srvr_data ||
            !input->srvr_data->secret_data || !input->srvr_data->secret_len) {
                return kr_error(EINVAL);
        }
@@ -155,7 +155,7 @@ static int kr_srvr_cookie_alg_fnv64(const struct kr_srvr_cookie_input *input,
                               hash_val);
 
        hash_val = fnv_64a_buf((void *) input->clnt_cookie,
-                              KNOT_OPT_COOKIE_CLNT, hash_val);
+                              input->clnt_cookie_len, hash_val);
 
        hash_val = fnv_64a_buf((void *) input->srvr_data->secret_data,
                               input->srvr_data->secret_len, hash_val);
@@ -166,8 +166,8 @@ static int kr_srvr_cookie_alg_fnv64(const struct kr_srvr_cookie_input *input,
        memcpy(sc_out + sizeof(aux), &aux, sizeof(aux));
 
        memcpy(sc_out + (2 * sizeof(aux)), &hash_val, sizeof(hash_val));
-       *sc_size = (2 * sizeof(aux)) + sizeof(hash_val);
-       assert(SRVR_FNV64_SIZE == *sc_size);
+       *sc_len = (2 * sizeof(aux)) + sizeof(hash_val);
+       assert(SRVR_FNV64_SIZE == *sc_len);
 
        return kr_ok();
 }
@@ -179,15 +179,16 @@ static int kr_srvr_cookie_alg_fnv64(const struct kr_srvr_cookie_input *input,
  * @note Server cookie = HMAC-SHA256-64( server secret, client cookie | client IP )
  */
 static int kr_srvr_cookie_alg_hmac_sha256_64_simple(const struct kr_srvr_cookie_input *input,
-                                                    uint8_t sc_out[KNOT_OPT_COOKIE_SRVR_MAX],
-                                                    size_t *sc_size)
+                                                    uint8_t *sc_out,
+                                                    uint16_t *sc_len)
 {
        if (!input || !sc_out ||
-           !sc_size || (*sc_size < SRVR_FNV64_SIMPLE_HASH_SIZE)) {
+           !sc_len || (*sc_len < SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE)) {
                return kr_error(EINVAL);
        }
 
-       if (!input->clnt_cookie || !input->srvr_data ||
+       if (!input->clnt_cookie || !input->clnt_cookie_len ||
+           !input->srvr_data ||
            !input->srvr_data->secret_data || !input->srvr_data->secret_len) {
                return kr_error(EINVAL);
        }
@@ -209,7 +210,7 @@ static int kr_srvr_cookie_alg_hmac_sha256_64_simple(const struct kr_srvr_cookie_
                goto fail;
        }
 
-       ret = HMAC_Update(&ctx, input->clnt_cookie, KNOT_OPT_COOKIE_CLNT);
+       ret = HMAC_Update(&ctx, input->clnt_cookie, input->clnt_cookie_len);
        if (ret != 1) {
                ret = kr_error(EINVAL);
                goto fail;
@@ -235,7 +236,7 @@ static int kr_srvr_cookie_alg_hmac_sha256_64_simple(const struct kr_srvr_cookie_
        assert(SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE <= SHA256_DIGEST_LENGTH);
 
        memcpy(sc_out, digest, SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE);
-       *sc_size = SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE;
+       *sc_len = SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE;
 
        ret = kr_ok();
 
@@ -251,15 +252,15 @@ fail:
  * @note Server cookie = nonce | time | HMAC-SHA256-64( server secret, client cookie | nonce| time | client IP )
  */
 static int kr_srvr_cookie_alg_hmac_sha256_64(const struct kr_srvr_cookie_input *input,
-                                             uint8_t sc_out[KNOT_OPT_COOKIE_SRVR_MAX],
-                                             size_t *sc_size)
+                                             uint8_t *sc_out, uint16_t *sc_len)
 {
        if (!input || !sc_out ||
-           !sc_size || (*sc_size < SRVR_FNV64_SIMPLE_HASH_SIZE)) {
+           !sc_len || (*sc_len < SRVR_HMAC_SHA256_64_SIZE)) {
                return kr_error(EINVAL);
        }
 
-       if (!input->clnt_cookie || !input->srvr_data ||
+       if (!input->clnt_cookie || !input->clnt_cookie_len ||
+           !input->srvr_data ||
            !input->srvr_data->secret_data || !input->srvr_data->secret_len) {
                return kr_error(EINVAL);
        }
@@ -281,7 +282,7 @@ static int kr_srvr_cookie_alg_hmac_sha256_64(const struct kr_srvr_cookie_input *
                goto fail;
        }
 
-       ret = HMAC_Update(&ctx, input->clnt_cookie, KNOT_OPT_COOKIE_CLNT);
+       ret = HMAC_Update(&ctx, input->clnt_cookie, input->clnt_cookie_len);
        if (ret != 1) {
                ret = kr_error(EINVAL);
                goto fail;
@@ -325,8 +326,8 @@ static int kr_srvr_cookie_alg_hmac_sha256_64(const struct kr_srvr_cookie_input *
 
        memcpy(sc_out + (2 * sizeof(aux)), digest,
               SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE);
-       *sc_size = (2 * sizeof(aux)) + SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE;
-       assert(SRVR_HMAC_SHA256_64_SIZE == *sc_size);
+       *sc_len = (2 * sizeof(aux)) + SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE;
+       assert(SRVR_HMAC_SHA256_64_SIZE == *sc_len);
 
        ret = kr_ok();
 
@@ -362,7 +363,7 @@ const struct kr_srvr_cookie_alg_descr *kr_srvr_cookie_alg(const struct kr_srvr_c
        return NULL;
 }
 
-int kr_srvr_cookie_check(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+int kr_srvr_cookie_check(const uint8_t *cc, uint16_t cc_len,
                          const uint8_t *sc, uint16_t sc_len,
                          const struct kr_srvr_cookie_check_ctx *check_ctx,
                          const struct kr_srvr_cookie_alg_descr *sc_alg)
@@ -395,9 +396,10 @@ int kr_srvr_cookie_check(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
        }
 
        uint8_t generated_sc[KNOT_OPT_COOKIE_SRVR_MAX] = { 0, };
-       size_t generated_sc_len = KNOT_OPT_COOKIE_SRVR_MAX;
+       uint16_t generated_sc_len = KNOT_OPT_COOKIE_SRVR_MAX;
        struct kr_srvr_cookie_input sc_input = {
                .clnt_cookie = cc,
+               .clnt_cookie_len = cc_len,
                .nonce = inbound_sc.nonce,
                .time = inbound_sc.time,
                .srvr_data = check_ctx
index 94028bb9b8646bf8b84f3d4a865d387c5595d97d..e633ace824197f5bc321f9015b55798b3fe5a845 100644 (file)
@@ -37,7 +37,8 @@ struct kr_srvr_cookie_inbound {
 
 /** Server cookie creation context. */
 struct kr_srvr_cookie_input {
-       const uint8_t *clnt_cookie; /**< Client cookie, must be `KNOT_OPT_COOKIE_CLNT` bytes long. */
+       const uint8_t *clnt_cookie; /**< Client cookie. */
+       uint16_t clnt_cookie_len; /**< Client cookie size. */
        uint32_t nonce; /**< Some generated value. */
        uint32_t time; /**< Cookie time stamp. */
        const struct kr_srvr_cookie_check_ctx *srvr_data; /**< Data known to the server. */
@@ -54,13 +55,13 @@ typedef int (srvr_cookie_parse_t)(const uint8_t *sc, uint16_t sc_len,
                                   struct kr_srvr_cookie_inbound *inbound);
 /**
  * @brief Server cookie generator function type.
- * @param input   Data which to generate the cookie from.
- * @param sc_out  Buffer to write the resulting client cookie data into.
- * @param sc_size On input must contain size of the buffer, on successful return contains size of actual written data.
+ * @param input  Data which to generate the cookie from.
+ * @param sc_out Buffer to write the resulting client cookie data into.
+ * @param sc_len On input must contain size of the buffer, on successful return contains size of actual written data.
  * @return kr_ok() or error code
  */
 typedef int (srvr_cookie_gen_t)(const struct kr_srvr_cookie_input *input,
-                                uint8_t *sc_out, size_t *sc_size);
+                                uint8_t *sc_out, uint16_t *sc_len);
 
 /** Holds description of server cookie hashing algorithms. */
 struct kr_srvr_cookie_alg_descr {
@@ -91,6 +92,7 @@ const struct kr_srvr_cookie_alg_descr *kr_srvr_cookie_alg(const struct kr_srvr_c
 /**
  * @brief Check whether supplied client and server cookie match.
  * @param cc         Client cookie.
+ * @param cc_len     Client cookie length.
  * @param sc         Server cookie that should be checked.
  * @param sc_len     Server cookie length.
  * @param check_ctx  Data known to the server needed for cookie validation.
@@ -98,7 +100,7 @@ const struct kr_srvr_cookie_alg_descr *kr_srvr_cookie_alg(const struct kr_srvr_c
  * @return kr_ok() if check OK, error code else.
  */
 KR_EXPORT
-int kr_srvr_cookie_check(const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+int kr_srvr_cookie_check(const uint8_t *cc, uint16_t cc_len,
                          const uint8_t *sc, uint16_t sc_len,
                          const struct kr_srvr_cookie_check_ctx *check_ctx,
                          const struct kr_srvr_cookie_alg_descr *sc_alg);
index 58259a330f9f8797cab8ddf974ae6a2a53d303db..c9f47f3356004a0aa2107ab86f13e5e3d123d29c 100644 (file)
@@ -38,14 +38,14 @@ struct kr_cookie_ctx kr_glob_cookie_ctx = {
 };
 
 static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
-                              uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+                              uint8_t *cc, uint16_t cc_len,
                               uint8_t *sc, uint16_t sc_len,
                               knot_mm_t *mm)
 {
        uint16_t cookies_size = 0;
        uint8_t *cookies_data = NULL;
 
-       cookies_size = knot_edns_opt_cookie_data_len(sc_len);
+       cookies_size = knot_edns_opt_cookie_data_len(cc_len, sc_len);
 
        int ret = knot_edns_reserve_option(opt_rr, KNOT_EDNS_OPTION_COOKIE,
                                           cookies_size, &cookies_data, mm);
@@ -54,13 +54,13 @@ static int opt_rr_add_cookies(knot_rrset_t *opt_rr,
        }
        assert(cookies_data != NULL);
 
-       ret = knot_edns_opt_cookie_create(cc, sc, sc_len,
-                                         cookies_data, &cookies_size);
+       ret = knot_edns_opt_cookie_write(cc, cc_len, sc, sc_len,
+                                        cookies_data, &cookies_size);
        if (ret != KNOT_EOK) {
                return ret;
        }
 
-       assert(cookies_size == knot_edns_opt_cookie_data_len(sc_len));
+       assert(cookies_size == knot_edns_opt_cookie_data_len(cc_len, sc_len));
 
        return KNOT_EOK;
 }
@@ -92,9 +92,9 @@ static int opt_rr_add_option(knot_rrset_t *opt_rr, uint8_t *option,
  */
 static const uint8_t *peek_and_check_cc(struct kr_cache *cache,
                                         const void *sockaddr,
-                                        const uint8_t cc[KNOT_OPT_COOKIE_CLNT])
+                                        const uint8_t *cc, uint16_t cc_len)
 {
-       assert(cache && sockaddr && cc);
+       assert(cache && sockaddr && cc && cc_len);
 
        uint32_t timestamp = 0;
        struct timed_cookie timed_cookie = { 0, };
@@ -112,7 +112,8 @@ static const uint8_t *peek_and_check_cc(struct kr_cache *cache,
 
        const uint8_t *cached_cc = knot_edns_opt_get_data((uint8_t *) timed_cookie.cookie_opt);
 
-       if (0 == memcmp(cc, cached_cc, KNOT_OPT_COOKIE_CLNT)) {
+       if (cc_len == KNOT_OPT_COOKIE_CLNT &&
+           0 == memcmp(cc, cached_cc, cc_len)) {
                return timed_cookie.cookie_opt;
        }
 
@@ -147,14 +148,17 @@ int kr_request_put_cookie(const struct kr_clnt_cookie_settings *clnt_cntrl,
                .secret_len = clnt_cntrl->csec->size
        };
        uint8_t cc[KNOT_OPT_COOKIE_CLNT];
+       uint16_t cc_len = KNOT_OPT_COOKIE_CLNT;
        assert(clnt_cntrl->calg && clnt_cntrl->calg->func);
-       int ret = clnt_cntrl->calg->func(&input, cc);
+       int ret = clnt_cntrl->calg->func(&input, cc, &cc_len);
        if (ret != kr_ok()) {
                return ret;
        }
+       assert(cc_len == KNOT_OPT_COOKIE_CLNT);
 
        const uint8_t *cached_cookie = peek_and_check_cc(cookie_cache,
-                                                        srvr_sockaddr, cc);
+                                                        srvr_sockaddr,
+                                                        cc, cc_len);
 
        /* This is a very nasty hack that prevents the packet to be corrupted
         * when using contemporary 'Cookie interface'. */
@@ -175,7 +179,8 @@ int kr_request_put_cookie(const struct kr_clnt_cookie_settings *clnt_cntrl,
                ret = opt_rr_add_option(pkt->opt_rr, (uint8_t *) cached_cookie,
                                        &pkt->mm);
        } else {
-               ret = opt_rr_add_cookies(pkt->opt_rr, cc, NULL, 0, &pkt->mm);
+               ret = opt_rr_add_cookies(pkt->opt_rr, cc, cc_len,
+                                        NULL, 0, &pkt->mm);
        }
 
        /* Write to packet. */
index 795cf067c38b225b86480a507a226c268607dcd2..3878837554b61531f0216f7a730f8ca9a62699d0 100644 (file)
@@ -59,16 +59,17 @@ static const struct sockaddr *passed_server_sockaddr(const struct kr_query *qry)
  * Tries to guess the name server address from the reputation mechanism.
  * @param nsrep name server reputation context
  * @param cc client cookie data
+ * @param cc_len client cookie size
  * @param csecr client secret
  * @param cc_alg client cookie algorithm
  * @return pointer to address if a matching found, NULL if none matches
  */
 static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep,
-                                                const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+                                                const uint8_t *cc, uint16_t cc_len,
                                                 const struct kr_cookie_secret *csecr,
                                                 const struct kr_clnt_cookie_alg_descr *cc_alg)
 {
-       assert(nsrep && cc && csecr && cc_alg);
+       assert(nsrep && cc && cc_len && csecr && cc_alg);
 
        const struct sockaddr *sockaddr = NULL;
 
@@ -86,7 +87,7 @@ static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep,
                }
 
                input.srvr_sockaddr = &nsrep->addr[i];
-               int ret = kr_clnt_cookie_check(cc, &input, cc_alg);
+               int ret = kr_clnt_cookie_check(cc, cc_len, &input, cc_alg);
                if (ret == kr_ok()) {
                        sockaddr = (struct sockaddr *) &nsrep->addr[i];
                        break;
@@ -101,15 +102,16 @@ static const struct sockaddr *guess_server_addr(const struct kr_nsrep *nsrep,
  * @param sockaddr pointer to socket address to be set
  * @param is_current set to true if the cookie was generate from current secret
  * @param cc client cookie from the response
+ * @param cc_len client cookie size
  * @param clnt_cntr client cookie control structure
  * @return kr_ok() if matching address found, error code else
  */
 static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
                                   bool *is_current, const struct kr_query *qry,
-                                  const uint8_t cc[KNOT_OPT_COOKIE_CLNT],
+                                  const uint8_t *cc, uint16_t cc_len,
                                   const struct kr_clnt_cookie_ctx *clnt_cntrl)
 {
-       assert(sockaddr && is_current && qry && cc && clnt_cntrl);
+       assert(sockaddr && is_current && qry && cc && cc_len && clnt_cntrl);
 
        const struct sockaddr *tmp_sockaddr = passed_server_sockaddr(qry);
 
@@ -123,14 +125,14 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
                        .secret_data = clnt_cntrl->current.csec->data,
                        .secret_len = clnt_cntrl->current.csec->size
                };
-               int ret = kr_clnt_cookie_check(cc, &input,
+               int ret = kr_clnt_cookie_check(cc, cc_len, &input,
                                               clnt_cntrl->current.calg);
                bool have_current = (ret == kr_ok());
                if ((ret != kr_ok()) &&
                    clnt_cntrl->recent.csec && clnt_cntrl->recent.calg) {
                        input.secret_data = clnt_cntrl->recent.csec->data;
                        input.secret_len = clnt_cntrl->recent.csec->size;
-                       ret = kr_clnt_cookie_check(cc, &input,
+                       ret = kr_clnt_cookie_check(cc, cc_len, &input,
                                                   clnt_cntrl->recent.calg);
                }
                if (ret == kr_ok()) {
@@ -149,13 +151,14 @@ static int srvr_sockaddr_cc_check(const struct sockaddr **sockaddr,
 
        /* Abusing name server reputation mechanism to guess IP addresses. */
        const struct kr_nsrep *ns = &qry->ns;
-       tmp_sockaddr = guess_server_addr(ns, cc, clnt_cntrl->current.csec,
+       tmp_sockaddr = guess_server_addr(ns, cc, cc_len,
+                                        clnt_cntrl->current.csec,
                                         clnt_cntrl->current.calg);
        bool have_current = (tmp_sockaddr != NULL);
        if (!tmp_sockaddr &&
            clnt_cntrl->recent.csec && clnt_cntrl->recent.calg) {
                /* Try recent client secret to check obtained cookie. */
-               tmp_sockaddr = guess_server_addr(ns, cc,
+               tmp_sockaddr = guess_server_addr(ns, cc, cc_len,
                                                 clnt_cntrl->recent.csec,
                                                 clnt_cntrl->recent.calg);
        }
@@ -276,7 +279,7 @@ static bool check_cookie_content_and_cache(struct kr_clnt_cookie_ctx *clnt_cntrl
        const struct sockaddr *srvr_sockaddr = NULL;
        bool returned_current = false;
        ret = srvr_sockaddr_cc_check(&srvr_sockaddr, &returned_current, qry,
-                                    pkt_cc, clnt_cntrl);
+                                    pkt_cc, pkt_cc_len, clnt_cntrl);
        if (ret != kr_ok()) {
                DEBUG_MSG(NULL, "%s\n", "could not match received cookie");
                return false;
@@ -389,7 +392,7 @@ static int answer_opt_rr_add_cookies(knot_pkt_t *answer,
 {
        assert(answer && input && alg);
 
-       size_t cookie_size = KNOT_OPT_COOKIE_CLNT + alg->srvr_cookie_size;
+       size_t cookie_size = input->clnt_cookie_len + alg->srvr_cookie_size;
        uint8_t *data = NULL;
 
        if (!answer->opt_rr) {
@@ -402,9 +405,9 @@ static int answer_opt_rr_add_cookies(knot_pkt_t *answer,
                return kr_error(ret);
        }
 
-       memcpy(data, input->clnt_cookie, KNOT_OPT_COOKIE_CLNT);
+       memcpy(data, input->clnt_cookie, input->clnt_cookie_len);
        cookie_size = alg->srvr_cookie_size;
-       ret = alg->gen_func(input, data + KNOT_OPT_COOKIE_CLNT, &cookie_size);
+       ret = alg->gen_func(input, data + input->clnt_cookie_len, &cookie_size);
        if (ret != kr_ok()) {
                /* TODO -- Delete COOKIE option. */
                return ret;
@@ -491,8 +494,8 @@ static int check_request(knot_layer_t *ctx, void *module_param)
                .secret_len = srvr_cntrl->current.ssec->size
        };
 
-       ret = kr_srvr_cookie_check(req_cc, req_sc, req_sc_len, &check_ctx,
-                                  srvr_cntrl->current.salg);
+       ret = kr_srvr_cookie_check(req_cc, req_cc_len, req_sc, req_sc_len,
+                                  &check_ctx, srvr_cntrl->current.salg);
        if (ret == kr_error(EBADMSG) &&
            srvr_cntrl->recent.ssec && srvr_cntrl->recent.salg) {
                /* Try recent algorithm. */
@@ -501,8 +504,8 @@ static int check_request(knot_layer_t *ctx, void *module_param)
                        .secret_data = srvr_cntrl->recent.ssec->data,
                        .secret_len = srvr_cntrl->recent.ssec->size
                };
-               ret = kr_srvr_cookie_check(req_cc, req_sc, req_sc_len,
-                                          &recent_ctx,
+               ret = kr_srvr_cookie_check(req_cc, req_cc_len, req_sc,
+                                          req_sc_len, &recent_ctx,
                                           srvr_cntrl->recent.salg);
        }
        if (ret != kr_ok()) {
@@ -530,6 +533,7 @@ static int check_request(knot_layer_t *ctx, void *module_param)
        /* Add server cookie into response. */
        struct kr_srvr_cookie_input input = {
                .clnt_cookie = req_cc,
+               .clnt_cookie_len = req_cc_len,
                .nonce = 0, /*TODO -- Some pseudo-random value? */
                .time = req->current_query->timestamp.tv_sec,
                .srvr_data = &check_ctx