along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <arpa/inet.h> /* inet_ntop() */
-#include <sys/socket.h>
-#include <netinet/in.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
+#include <libknot/errcode.h>
+#include <libknot/rrtype/opt_cookie.h>
+
#include "contrib/fnv/fnv.h"
#include "lib/cookies/alg_clnt.h"
* @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.
+ * @return KNOT_EOK on success, error code else.
*/
-static int kr_clnt_cookie_alg_fnv64(const struct kr_clnt_cookie_input *input,
+static int kr_clnt_cookie_alg_fnv64(const struct knot_ccookie_input *input,
uint8_t *cc_out, uint16_t *cc_len)
{
if (!input || !cc_out || !cc_len) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
if ((!input->clnt_sockaddr && !input->srvr_sockaddr) ||
!(input->secret_data && input->secret_len)) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
const uint8_t *addr = NULL;
#if defined(CC_HASH_USE_CLIENT_ADDRESS)
if (input->clnt_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->clnt_sockaddr, &addr,
- &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->clnt_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
hash_val = fnv_64a_buf(addr, alen, hash_val);
}
#endif /* defined(CC_HASH_USE_CLIENT_ADDRESS) */
if (input->srvr_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->srvr_sockaddr, &addr,
- &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->srvr_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
hash_val = fnv_64a_buf((void *) addr, alen, hash_val);
}
assert(KNOT_OPT_COOKIE_CLNT == sizeof(hash_val));
if (*cc_len < KNOT_OPT_COOKIE_CLNT) {
- return kr_error(ENOSPC);
+ return KNOT_ESPACE;
}
*cc_len = KNOT_OPT_COOKIE_CLNT;
memcpy(cc_out, &hash_val, *cc_len);
- return kr_ok();
+ return KNOT_EOK;
}
/**
* @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.
+ * @return KNOT_EOK on success, error code else.
*/
-static int kr_clnt_cookie_alg_hmac_sha256_64(const struct kr_clnt_cookie_input *input,
+static int kr_clnt_cookie_alg_hmac_sha256_64(const struct knot_ccookie_input *input,
uint8_t *cc_out, uint16_t *cc_len)
{
if (!input || !cc_out || !cc_len) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
if ((!input->clnt_sockaddr && !input->srvr_sockaddr) ||
!(input->secret_data && input->secret_len)) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
const uint8_t *addr = NULL;
int ret = HMAC_Init_ex(&ctx, input->secret_data, input->secret_len,
EVP_sha256(), NULL);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
#if defined(CC_HASH_USE_CLIENT_ADDRESS)
if (input->clnt_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->clnt_sockaddr, &addr,
- &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->clnt_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
ret = HMAC_Update(&ctx, addr, alen);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
}
#endif /* defined(CC_HASH_USE_CLIENT_ADDRESS) */
if (input->srvr_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->srvr_sockaddr, &addr,
- &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->srvr_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
ret = HMAC_Update(&ctx, addr, alen);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
}
}
if (1 != HMAC_Final(&ctx, digest, &digest_len)) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
assert(KNOT_OPT_COOKIE_CLNT <= SHA256_DIGEST_LENGTH);
if (*cc_len < KNOT_OPT_COOKIE_CLNT) {
- return kr_error(ENOSPC);
+ return KNOT_ESPACE;
}
*cc_len = KNOT_OPT_COOKIE_CLNT;
memcpy(cc_out, digest, *cc_len);
- ret = kr_ok();
+ ret = KNOT_EOK;
fail:
HMAC_CTX_cleanup(&ctx);
}
const struct kr_clnt_cookie_alg_descr kr_clnt_cookie_algs[] = {
- { "FNV-64", kr_clnt_cookie_alg_fnv64 },
- { "HMAC-SHA256-64", kr_clnt_cookie_alg_hmac_sha256_64 },
- { NULL, NULL }
+ { "FNV-64", { KNOT_OPT_COOKIE_CLNT, kr_clnt_cookie_alg_fnv64 } },
+ { "HMAC-SHA256-64", { KNOT_OPT_COOKIE_CLNT, kr_clnt_cookie_alg_hmac_sha256_64 } },
+ { NULL, { 0, NULL } }
};
const struct kr_clnt_cookie_alg_descr *kr_clnt_cookie_alg(const struct kr_clnt_cookie_alg_descr cc_algs[],
}
const struct kr_clnt_cookie_alg_descr *aux_ptr = cc_algs;
- while (aux_ptr && aux_ptr->func) {
+ while (aux_ptr && aux_ptr->alg.gen_func) {
assert(aux_ptr->name);
if (strcmp(aux_ptr->name, name) == 0) {
return aux_ptr;
return NULL;
}
-int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len)
-{
- if (!sockaddr || !addr || !len) {
- return kr_error(EINVAL);
- }
-
- int addr_family = ((struct sockaddr *) sockaddr)->sa_family;
-
- switch (addr_family) {
- case AF_INET:
- *addr = (uint8_t *) &((struct sockaddr_in *) sockaddr)->sin_addr;
- *len = 4;
- break;
- case AF_INET6:
- *addr = (uint8_t *) &((struct sockaddr_in6 *) sockaddr)->sin6_addr;
- *len = 16;
- break;
- default:
- *addr = NULL;
- *len = 0;
- addr_family = AF_UNSPEC;
- return kr_error(EINVAL);
- break;
- }
-
- return kr_ok();
-}
-
int kr_clnt_cookie_check(const uint8_t *cc, uint16_t cc_len,
- const struct kr_clnt_cookie_input *input,
+ const struct knot_ccookie_input *input,
const struct kr_clnt_cookie_alg_descr *cc_alg)
{
- 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, &generated_cc_len);
- if (ret != kr_ok()) {
- return ret;
- }
-
- if (generated_cc_len != cc_len) {
+ if (!cc || !cc_len || !input || !cc_alg) {
return kr_error(EINVAL);
}
- ret = memcmp(cc, generated_cc, generated_cc_len);
- if (ret == 0) {
- return kr_ok();
- }
+ int ret = knot_ccookie_check(cc, cc_len, input, &cc_alg->alg);
- return kr_error(EINVAL);
+ return (ret == KNOT_EOK) ? kr_ok() : kr_error(EINVAL);
}
#pragma once
-#include <libknot/rrtype/opt_cookie.h>
+#include <libknot/cookies/client.h>
#include "lib/defines.h"
/** Maximal size of a cookie option. */
#define KR_COOKIE_OPT_MAX_LEN (KNOT_EDNS_OPTION_HDRLEN + KNOT_OPT_COOKIE_CLNT + KNOT_OPT_COOKIE_SRVR_MAX)
-/** Client cookie computation context. */
-struct kr_clnt_cookie_input {
- const void *clnt_sockaddr; /**< Client (local) socket address. */
- const void *srvr_sockaddr; /**< Server (remote) socket address. */
- const uint8_t *secret_data; /**< Client secret data. */
- size_t secret_len; /**< Secret data length. */
-};
-
-/**
- * @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, uint16_t *cc_len);
-
/** Holds description of client cookie hashing algorithms. */
struct kr_clnt_cookie_alg_descr {
- const char *name; /**< Hash function name. */
- clnt_cookie_alg_t *func; /**< Pointer to hash function. */
+ const char *name; /**< Hash algorithgm name. */
+ struct knot_cc_alg alg; /**< Hash algorithm. */
};
/**
const struct kr_clnt_cookie_alg_descr *kr_clnt_cookie_alg(const struct kr_clnt_cookie_alg_descr cc_algs[],
const char *name);
-/**
- * @brief Get pointers to IP address bytes.
- * @param sockaddr socket address
- * @param addr pointer to address
- * @param len address length
- * @return kr_ok() on success, error code else.
- */
-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.
*/
KR_EXPORT
int kr_clnt_cookie_check(const uint8_t *cc, uint16_t cc_len,
- const struct kr_clnt_cookie_input *input,
+ const struct knot_ccookie_input *input,
const struct kr_clnt_cookie_alg_descr *cc_alg);
#include <openssl/hmac.h>
#include <openssl/sha.h>
+#include <libknot/cookies/client.h> /* knot_sockaddr_bytes() */
+#include <libknot/errcode.h>
+#include <libknot/rrtype/opt_cookie.h>
+
#include "contrib/fnv/fnv.h"
-#include "lib/cookies/alg_clnt.h" /* kr_address_bytes() */
#include "lib/cookies/alg_srvr.h"
/**
* @note DNS Cookies -- Appendix B.1
*/
static int srvr_cookie_parse_simple(const uint8_t *sc, uint16_t sc_len,
- struct kr_srvr_cookie_inbound *inbound)
+ struct knot_scookie_inbound *inbound)
{
if (!sc || !sc_len || !inbound) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
//memset(inbound, 0, sizeof(*inbound));
inbound->hash_data = sc; /* Entire server cookie contains data. */
inbound->hash_len = sc_len;
- return kr_ok();
+ return KNOT_EOK;
}
/**
* @note DNS Cookies -- Appendix B.2
*/
static int srvr_cookie_parse(const uint8_t *sc, uint16_t sc_len,
- struct kr_srvr_cookie_inbound *inbound)
+ struct knot_scookie_inbound *inbound)
{
if (!sc || !sc_len || !inbound) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
if (sc_len <= (2 * sizeof(uint32_t))) { /* nonce + time */
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
uint32_t aux;
inbound->hash_data = sc + (2 * sizeof(aux));
inbound->hash_len = sc_len - (2 * sizeof(aux));
- return kr_ok();
+ return KNOT_EOK;
}
#define SRVR_FNV64_SIMPLE_HASH_SIZE 8
* @brief Compute server cookie using FNV-64 (hash only).
* @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,
+static int kr_srvr_cookie_alg_fnv64_simple(const struct knot_scookie_input *input,
uint8_t *sc_out, uint16_t *sc_len)
{
if (!input || !sc_out ||
!sc_len || (*sc_len < SRVR_FNV64_SIMPLE_HASH_SIZE)) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
- if (!input->clnt_cookie || !input->clnt_cookie_len ||
- !input->srvr_data ||
+ if (!input->cc || !input->cc_len || !input->srvr_data ||
!input->srvr_data->secret_data || !input->srvr_data->secret_len) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
const uint8_t *addr = NULL;
Fnv64_t hash_val = FNV1A_64_INIT;
- if (kr_ok() == kr_address_bytes(input->srvr_data->clnt_sockaddr, &addr,
- &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->srvr_data->clnt_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
hash_val = fnv_64a_buf((void *) addr, alen, hash_val);
}
- hash_val = fnv_64a_buf((void *) input->clnt_cookie,
- input->clnt_cookie_len, hash_val);
+ hash_val = fnv_64a_buf((void *) input->cc, input->cc_len, hash_val);
hash_val = fnv_64a_buf((void *) input->srvr_data->secret_data,
input->srvr_data->secret_len, hash_val);
*sc_len = sizeof(hash_val);
assert(SRVR_FNV64_SIMPLE_HASH_SIZE == *sc_len);
- return kr_ok();
+ return KNOT_EOK;
}
#define SRVR_FNV64_SIZE 16
* @brief Compute server cookie using FNV-64.
* @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,
+static int kr_srvr_cookie_alg_fnv64(const struct knot_scookie_input *input,
uint8_t *sc_out, uint16_t *sc_len)
{
if (!input || !sc_out ||
!sc_len || (*sc_len < SRVR_FNV64_SIZE)) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
- if (!input->clnt_cookie || !input->clnt_cookie_len ||
- !input->srvr_data ||
+ if (!input->cc || !input->cc_len || !input->srvr_data ||
!input->srvr_data->secret_data || !input->srvr_data->secret_len) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
const uint8_t *addr = NULL;
Fnv64_t hash_val = FNV1A_64_INIT;
if (input->srvr_data->clnt_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->srvr_data->clnt_sockaddr,
- &addr, &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->srvr_data->clnt_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
hash_val = fnv_64a_buf((void *) addr, alen, hash_val);
}
hash_val = fnv_64a_buf((void *) &input->time, sizeof(input->time),
hash_val);
- hash_val = fnv_64a_buf((void *) input->clnt_cookie,
- input->clnt_cookie_len, hash_val);
+ hash_val = fnv_64a_buf((void *) input->cc, input->cc_len, hash_val);
hash_val = fnv_64a_buf((void *) input->srvr_data->secret_data,
input->srvr_data->secret_len, hash_val);
*sc_len = (2 * sizeof(aux)) + sizeof(hash_val);
assert(SRVR_FNV64_SIZE == *sc_len);
- return kr_ok();
+ return KNOT_EOK;
}
#define SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE 8
* @brief Compute server cookie using HMAC-SHA256-64 (hash only).
* @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,
+static int kr_srvr_cookie_alg_hmac_sha256_64_simple(const struct knot_scookie_input *input,
uint8_t *sc_out,
uint16_t *sc_len)
{
if (!input || !sc_out ||
!sc_len || (*sc_len < SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE)) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
- if (!input->clnt_cookie || !input->clnt_cookie_len ||
- !input->srvr_data ||
+ if (!input->cc || !input->cc_len || !input->srvr_data ||
!input->srvr_data->secret_data || !input->srvr_data->secret_len) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
const uint8_t *addr = NULL;
input->srvr_data->secret_len,
EVP_sha256(), NULL);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
- ret = HMAC_Update(&ctx, input->clnt_cookie, input->clnt_cookie_len);
+ ret = HMAC_Update(&ctx, input->cc, input->cc_len);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
if (input->srvr_data->clnt_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->srvr_data->clnt_sockaddr,
- &addr, &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->srvr_data->clnt_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
ret = HMAC_Update(&ctx, addr, alen);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
}
}
if (1 != HMAC_Final(&ctx, digest, &digest_len)) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
memcpy(sc_out, digest, SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE);
*sc_len = SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE;
- ret = kr_ok();
+ ret = KNOT_EOK;
fail:
HMAC_CTX_cleanup(&ctx);
* @brief Compute server cookie using HMAC-SHA256-64).
* @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,
+static int kr_srvr_cookie_alg_hmac_sha256_64(const struct knot_scookie_input *input,
uint8_t *sc_out, uint16_t *sc_len)
{
if (!input || !sc_out ||
!sc_len || (*sc_len < SRVR_HMAC_SHA256_64_SIZE)) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
- if (!input->clnt_cookie || !input->clnt_cookie_len ||
- !input->srvr_data ||
+ if (!input->cc || !input->cc_len || !input->srvr_data ||
!input->srvr_data->secret_data || !input->srvr_data->secret_len) {
- return kr_error(EINVAL);
+ return KNOT_EINVAL;
}
const uint8_t *addr = NULL;
input->srvr_data->secret_len,
EVP_sha256(), NULL);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
- ret = HMAC_Update(&ctx, input->clnt_cookie, input->clnt_cookie_len);
+ ret = HMAC_Update(&ctx, input->cc, input->cc_len);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
ret = HMAC_Update(&ctx, (void *) &input->nonce, sizeof(input->nonce));
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
ret = HMAC_Update(&ctx, (void *) &input->time, sizeof(input->time));
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
if (input->srvr_data->clnt_sockaddr) {
- if (kr_ok() == kr_address_bytes(input->srvr_data->clnt_sockaddr,
- &addr, &alen)) {
+ if (KNOT_EOK == knot_sockaddr_bytes(input->srvr_data->clnt_sockaddr,
+ &addr, &alen)) {
assert(addr && alen);
ret = HMAC_Update(&ctx, addr, alen);
if (ret != 1) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
}
}
if (1 != HMAC_Final(&ctx, digest, &digest_len)) {
- ret = kr_error(EINVAL);
+ ret = KNOT_EINVAL;
goto fail;
}
*sc_len = (2 * sizeof(aux)) + SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE;
assert(SRVR_HMAC_SHA256_64_SIZE == *sc_len);
- ret = kr_ok();
+ ret = KNOT_EOK;
fail:
HMAC_CTX_cleanup(&ctx);
}
const struct kr_srvr_cookie_alg_descr kr_srvr_cookie_algs[] = {
- { "FNV-64-SIMPLE", SRVR_FNV64_SIMPLE_HASH_SIZE, srvr_cookie_parse_simple, kr_srvr_cookie_alg_fnv64_simple },
- { "FNV-64", SRVR_FNV64_SIZE, srvr_cookie_parse, kr_srvr_cookie_alg_fnv64 },
- { "HMAC-SHA256-64-SIMPLE", SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE, srvr_cookie_parse_simple, kr_srvr_cookie_alg_hmac_sha256_64_simple },
- { "HMAC-SHA256-64", SRVR_HMAC_SHA256_64_SIZE, srvr_cookie_parse, kr_srvr_cookie_alg_hmac_sha256_64 },
- { NULL, 0, NULL, NULL }
+ { "FNV-64-SIMPLE", { SRVR_FNV64_SIMPLE_HASH_SIZE, srvr_cookie_parse_simple, kr_srvr_cookie_alg_fnv64_simple } },
+ { "FNV-64", { SRVR_FNV64_SIZE, srvr_cookie_parse, kr_srvr_cookie_alg_fnv64 } },
+ { "HMAC-SHA256-64-SIMPLE", { SRVR_HMAC_SHA256_64_SIMPLE_HASH_SIZE, srvr_cookie_parse_simple, kr_srvr_cookie_alg_hmac_sha256_64_simple } },
+ { "HMAC-SHA256-64", { SRVR_HMAC_SHA256_64_SIZE, srvr_cookie_parse, kr_srvr_cookie_alg_hmac_sha256_64 } },
+ { NULL, { 0, NULL, NULL } }
};
const struct kr_srvr_cookie_alg_descr *kr_srvr_cookie_alg(const struct kr_srvr_cookie_alg_descr sc_algs[],
}
const struct kr_srvr_cookie_alg_descr *aux_ptr = sc_algs;
- while (aux_ptr && aux_ptr->gen_func) {
+ while (aux_ptr && aux_ptr->alg.gen_func) {
assert(aux_ptr->name);
if (strcmp(aux_ptr->name, name) == 0) {
return aux_ptr;
return NULL;
}
-int kr_srvr_cookie_check(const struct kr_dns_cookies *cookies,
- const struct kr_srvr_cookie_check_ctx *check_ctx,
+int kr_srvr_cookie_check(const struct knot_dns_cookies *cookies,
+ const struct knot_scookie_check_ctx *check_ctx,
const struct kr_srvr_cookie_alg_descr *sc_alg)
{
if (!cookies || !check_ctx || !sc_alg) {
return kr_error(EINVAL);
}
- if (!cookies->cc || !cookies->cc_len ||
- !cookies->sc || !cookies->sc_len) {
- return kr_error(EINVAL);
- }
+ int ret = knot_scookie_check(cookies, check_ctx, sc_alg);
- if (!check_ctx->clnt_sockaddr ||
- !check_ctx->secret_data || !check_ctx->secret_len) {
- return kr_error(EINVAL);
- }
-
- if (!sc_alg->srvr_cookie_size ||
- !sc_alg->opt_parse_func || !sc_alg->gen_func) {
- return kr_error(EINVAL);
- }
-
- if (cookies->sc_len != sc_alg->srvr_cookie_size) {
- /* Cookie size does to match. */
- return kr_error(EBADMSG);
- }
-
- struct kr_srvr_cookie_inbound inbound_sc = { 0, };
-
- /* Obtain data from received server cookie. */
- int ret = sc_alg->opt_parse_func(cookies->sc, cookies->sc_len,
- &inbound_sc);
- if (ret != kr_ok()) {
- return ret;
- }
-
- uint8_t generated_sc[KNOT_OPT_COOKIE_SRVR_MAX] = { 0, };
- uint16_t generated_sc_len = KNOT_OPT_COOKIE_SRVR_MAX;
- struct kr_srvr_cookie_input sc_input = {
- .clnt_cookie = cookies->cc,
- .clnt_cookie_len = cookies->cc_len,
- .nonce = inbound_sc.nonce,
- .time = inbound_sc.time,
- .srvr_data = check_ctx
- };
-
- /* Generate a new server cookie. */
- ret = sc_alg->gen_func(&sc_input, generated_sc, &generated_sc_len);
- if (ret != kr_ok()) {
- return ret;
- }
- assert(generated_sc_len == sc_alg->srvr_cookie_size);
-
- ret = (memcmp(cookies->sc, generated_sc, generated_sc_len) == 0) ?
- kr_ok() : kr_error(EBADMSG);
-
- return ret;
+ return (ret == KNOT_EOK) ? kr_ok() : kr_error(EINVAL);
}
#pragma once
-#include <libknot/rrtype/opt_cookie.h>
+#include <libknot/cookies/server.h>
#include "lib/defines.h"
-/** Convenience Structure holding both, server and client, cookies. */
-struct kr_dns_cookies {
- const uint8_t *cc; /**< Client cookie. */
- uint16_t cc_len; /**< Client cookie size. */
- const uint8_t *sc; /**< Server cookie. */
- uint16_t sc_len; /**< Server cookie size. */
-};
-
-/** Inbound server cookie checking context. */
-struct kr_srvr_cookie_check_ctx {
- const void *clnt_sockaddr; /**< Client (remote) socket address. */
- const uint8_t *secret_data; /**< Server secret data. */
- size_t secret_len; /**< Server secret data length. */
-};
-
-/** Inbound server cookie content structure. */
-struct kr_srvr_cookie_inbound {
- uint32_t nonce; /**< Some value. */
- uint32_t time; /**< Time stamp. */
- const uint8_t *hash_data; /**< Hash data. */
- uint16_t hash_len; /**< Hash data length. */
-};
-
-/** Server cookie creation context. */
-struct kr_srvr_cookie_input {
- 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. */
-};
-
-/**
- * @brief Server cookie parser function type.
- * @param sc Server cookie data.
- * @param data_len Server cookie data length.
- * @param inbound Inbound cookie structure to be set.
- * @return kr_ok() or error code.
- */
-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_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, uint16_t *sc_len);
-
/** Holds description of server cookie hashing algorithms. */
struct kr_srvr_cookie_alg_descr {
- const char *name; /**< Server cookie algorithm name. */
- const uint16_t srvr_cookie_size; /**< Size of the generated server cookie. */
- srvr_cookie_parse_t *opt_parse_func; /**< Cookie option parser function. */
- srvr_cookie_gen_t *gen_func; /**< Cookie generator function. */
+ const char *name; /**< Algorithm name. */
+ struct knot_sc_alg alg; /**< Algorithm. */
};
/**
* @return kr_ok() if check OK, error code else.
*/
KR_EXPORT
-int kr_srvr_cookie_check(const struct kr_dns_cookies *cookies,
- const struct kr_srvr_cookie_check_ctx *check_ctx,
+int kr_srvr_cookie_check(const struct knot_dns_cookies *cookies,
+ const struct knot_scookie_check_ctx *check_ctx,
const struct kr_srvr_cookie_alg_descr *sc_alg);
*/
#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
#include <libknot/db/db_lmdb.h>
+#include <libknot/cookies/client.h>
#include "contrib/cleanup.h"
#include "lib/cdb_lmdb.h"
const uint8_t *addr = NULL;
size_t addr_len = 0;
- if (kr_ok() != kr_address_bytes(sockaddr, &addr, &addr_len)) {
+ if (kr_ok() != knot_sockaddr_bytes(sockaddr, &addr, &addr_len)) {
return 0;
}
assert(addr_len > 0);
/* Generate client cookie.
* TODO -- generate client cookie from client address, server address
* and secret quantity. */
- struct kr_clnt_cookie_input input = {
+ struct knot_ccookie_input input = {
.clnt_sockaddr = clnt_sockaddr,
.srvr_sockaddr = srvr_sockaddr,
.secret_data = clnt_cntrl->csec->data,
};
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, &cc_len);
+ assert(clnt_cntrl->calg && clnt_cntrl->calg->alg.gen_func);
+ int ret = clnt_cntrl->calg->alg.gen_func(&input, cc, &cc_len);
if (ret != kr_ok()) {
return ret;
}
return knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, pkt->opt_rr, KNOT_PF_FREE);
}
-int kr_answer_opt_rr_add_cookies(const struct kr_srvr_cookie_input *input,
- const struct kr_srvr_cookie_alg_descr *alg,
+int kr_answer_opt_rr_add_cookies(const struct knot_scookie_input *input,
+ const struct kr_srvr_cookie_alg_descr *sc_alg,
knot_pkt_t *pkt)
{
- if (!input || !alg || pkt) {
+ if (!input || !sc_alg || pkt) {
kr_error(EINVAL);
}
- uint16_t cookie_size = input->clnt_cookie_len + alg->srvr_cookie_size;
+ uint16_t cookie_size = input->cc_len + sc_alg->alg.sc_size;
uint8_t *data = NULL;
if (!pkt->opt_rr) {
return kr_error(ret);
}
- memcpy(data, input->clnt_cookie, input->clnt_cookie_len);
- cookie_size = alg->srvr_cookie_size;
- ret = alg->gen_func(input, data + input->clnt_cookie_len, &cookie_size);
+ memcpy(data, input->cc, input->cc_len);
+ cookie_size = sc_alg->alg.sc_size;
+ ret = sc_alg->alg.gen_func(input, data + input->cc_len, &cookie_size);
if (ret != kr_ok()) {
/* TODO -- Delete COOKIE option. */
return ret;
return knot_edns_get_option(pkt->opt_rr, KNOT_EDNS_OPTION_COOKIE);
}
-int kr_parse_cookie_opt(uint8_t *cookie_opt, struct kr_dns_cookies *cookies)
+int kr_parse_cookie_opt(uint8_t *cookie_opt, struct knot_dns_cookies *cookies)
{
if (!cookie_opt || !cookies) {
kr_error(EINVAL);
* @brief Add cookies into answer.
* @note Data are only added into the OPT RR.
* @param input input data to generate server cookie from
- * @param alg algorithm to use
+ * @param sc_alg algorithm to use
* @param pkt packet which to put cookie into
* @return kr_ok() or error code
*/
KR_EXPORT
-int kr_answer_opt_rr_add_cookies(const struct kr_srvr_cookie_input *input,
- const struct kr_srvr_cookie_alg_descr *alg,
+int kr_answer_opt_rr_add_cookies(const struct knot_scookie_input *input,
+ const struct kr_srvr_cookie_alg_descr *sc_alg,
knot_pkt_t *pkt);
/**
* @return kr_ok() on success, error if cookies are malformed.
*/
KR_EXPORT
-int kr_parse_cookie_opt(uint8_t *cookie_opt, struct kr_dns_cookies *cookies);
+int kr_parse_cookie_opt(uint8_t *cookie_opt, struct knot_dns_cookies *cookies);
const struct sockaddr *sockaddr = NULL;
- struct kr_clnt_cookie_input input = {
+ struct knot_ccookie_input input = {
.clnt_sockaddr = NULL,
.srvr_sockaddr = NULL,
.secret_data = csecr->data,
if (tmp_sockaddr) {
assert(clnt_cntrl->current.csec);
- struct kr_clnt_cookie_input input = {
+ struct knot_ccookie_input input = {
.clnt_sockaddr = NULL,
.srvr_sockaddr = tmp_sockaddr,
.secret_data = clnt_cntrl->current.csec->data,
return ctx->state; /* Don't do anything without cookies. */
}
- struct kr_dns_cookies cookies = { 0, };
+ struct knot_dns_cookies cookies = { 0, };
int ret = kr_parse_cookie_opt(req_cookie_opt, &cookies);
if (ret != kr_ok()) {
/* FORMERR -- malformed cookies. */
int return_state = ctx->state;
- struct kr_srvr_cookie_check_ctx check_ctx = {
+ struct knot_scookie_check_ctx check_ctx = {
.clnt_sockaddr = req->qsource.addr,
.secret_data = srvr_cntrl->current.ssec->data,
.secret_len = srvr_cntrl->current.ssec->size
};
- struct kr_srvr_cookie_input input = {
- .clnt_cookie = cookies.cc,
- .clnt_cookie_len = cookies.cc_len,
+ struct knot_scookie_input input = {
+ .cc = cookies.cc,
+ .cc_len = cookies.cc_len,
.nonce = kr_rand_uint(UINT32_MAX),
.time = req->current_query->timestamp.tv_sec,
.srvr_data = &check_ctx
if (ret == kr_error(EBADMSG) &&
srvr_cntrl->recent.ssec && srvr_cntrl->recent.salg) {
/* Try recent algorithm. */
- struct kr_srvr_cookie_check_ctx recent_ctx = {
+ struct knot_scookie_check_ctx recent_ctx = {
.clnt_sockaddr = req->qsource.addr,
.secret_data = srvr_cntrl->recent.ssec->data,
.secret_len = srvr_cntrl->recent.ssec->size
*/
static int cookie_answer(const void *clnt_sockaddr,
const struct kr_srvr_cookie_ctx *srvr_cntrl,
- struct kr_dns_cookies *cookies, knot_pkt_t *answer)
+ struct knot_dns_cookies *cookies, knot_pkt_t *answer)
{
assert(srvr_cntrl && cookies && answer);
knot_wire_set_ra(answer->wire);
knot_wire_set_rcode(answer->wire, KNOT_RCODE_NOERROR);
- struct kr_srvr_cookie_check_ctx check_ctx = {
+ struct knot_scookie_check_ctx check_ctx = {
.clnt_sockaddr = clnt_sockaddr,
.secret_data = srvr_cntrl->current.ssec->data,
.secret_len = srvr_cntrl->current.ssec->size
struct timeval tv;
gettimeofday(&tv, NULL);
- struct kr_srvr_cookie_input input = {
- .clnt_cookie = cookies->cc,
- .clnt_cookie_len = cookies->cc_len,
+ struct knot_scookie_input input = {
+ .cc = cookies->cc,
+ .cc_len = cookies->cc_len,
.nonce = kr_rand_uint(UINT32_MAX),
.time = tv.tv_sec,
.srvr_data = &check_ctx
if (!qry) {
#if defined(ENABLE_COOKIES)
/* May be a DNS cookies query. */
- struct kr_dns_cookies cookies = { 0, };
+ struct knot_dns_cookies cookies = { 0, };
uint8_t *cookie_opt = kr_is_cookie_query(packet);
if (cookie_opt && kr_glob_cookie_ctx.clnt.enabled) {
if (kr_ok() != kr_parse_cookie_opt(cookie_opt,
}
const struct kr_clnt_cookie_alg_descr *aux_ptr = kr_clnt_cookie_algs;
- while (aux_ptr && aux_ptr->func) {
+ while (aux_ptr && aux_ptr->alg.gen_func) {
assert(aux_ptr->name);
JsonNode *element = json_mkstring(aux_ptr->name);
if (!element) {
}
const struct kr_srvr_cookie_alg_descr *aux_ptr = kr_srvr_cookie_algs;
- while (aux_ptr && aux_ptr->gen_func) {
+ while (aux_ptr && aux_ptr->alg.gen_func) {
assert(aux_ptr->name);
JsonNode *element = json_mkstring(aux_ptr->name);
if (!element) {