summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Salzman <daniel.salzman@nic.cz>2023-03-12 18:44:19 +0100
committerDaniel Salzman <daniel.salzman@nic.cz>2023-03-21 09:45:15 +0100
commit6d07b557cffd29a5874d34c5da2e435d82c17d8b (patch)
tree578e74e14e40bb44b00262ca09e9eeaa7feb4ed3 /src
parentquic: simplify ALPN handling (diff)
downloadknot-6d07b557cffd29a5874d34c5da2e435d82c17d8b.tar.xz
knot-6d07b557cffd29a5874d34c5da2e435d82c17d8b.zip
quic: move acl/cert_pin() to libknot/knot_quic_conn_pin()
Diffstat (limited to 'src')
-rw-r--r--src/knot/conf/tools.c10
-rw-r--r--src/knot/include/module.h2
-rw-r--r--src/knot/nameserver/process_query.c15
-rw-r--r--src/knot/server/handler.c4
-rw-r--r--src/knot/server/handler.h8
-rw-r--r--src/knot/server/server.c2
-rw-r--r--src/knot/updates/acl.c75
-rw-r--r--src/knot/updates/acl.h31
-rw-r--r--src/libknot/quic/quic.c44
-rw-r--r--src/libknot/quic/quic.h14
10 files changed, 110 insertions, 95 deletions
diff --git a/src/knot/conf/tools.c b/src/knot/conf/tools.c
index afd8cdf6d..f79a75aa9 100644
--- a/src/knot/conf/tools.c
+++ b/src/knot/conf/tools.c
@@ -38,8 +38,10 @@
#include "knot/conf/module.h"
#include "knot/conf/schema.h"
#include "knot/common/log.h"
-#include "knot/updates/acl.h"
#include "libknot/errcode.h"
+#ifdef ENABLE_QUIC
+#include "libknot/quic/quic.h"
+#endif // ENABLE_QUIC
#include "libknot/yparser/yptrafo.h"
#include "libknot/xdp.h"
#include "contrib/files.h"
@@ -321,13 +323,15 @@ int check_xdp_listen(
int check_cert_pin(
knotd_conf_check_args_t *args)
{
- if (args->data_len != sizeof(uint16_t) + CERT_PIN_LEN) {
+#ifdef ENABLE_QUIC
+ if (args->data_len != sizeof(uint16_t) + KNOT_QUIC_PIN_LEN) {
(void)snprintf(check_str, sizeof(check_str),
"invalid certificate pin, expected base64-encoded "
- "%u bytes", CERT_PIN_LEN);
+ "%u bytes", KNOT_QUIC_PIN_LEN);
args->err_str = check_str;
return KNOT_EINVAL;
}
+#endif // ENABLE_QUIC
return KNOT_EOK;
}
diff --git a/src/knot/include/module.h b/src/knot/include/module.h
index b6d406dea..1af997201 100644
--- a/src/knot/include/module.h
+++ b/src/knot/include/module.h
@@ -410,7 +410,7 @@ typedef struct {
unsigned thread_id; /*!< Current thread id. */
void *server; /*!< Server object private item. */
const struct knot_xdp_msg *xdp_msg; /*!< Possible XDP message context. */
- struct gnutls_session_int *session; /*!< QUIC session. */
+ struct knot_xquic_conn *quic_conn; /*!< QUIC connection context. */
uint32_t measured_rtt; /*!< Measured RTT in usecs: QUIC or TCP-XDP. */
} knotd_qdata_params_t;
diff --git a/src/knot/nameserver/process_query.c b/src/knot/nameserver/process_query.c
index 5de641ca4..9fcb1bac6 100644
--- a/src/knot/nameserver/process_query.c
+++ b/src/knot/nameserver/process_query.c
@@ -30,6 +30,9 @@
#include "knot/nameserver/notify.h"
#include "knot/server/server.h"
#include "libknot/libknot.h"
+#ifdef ENABLE_QUIC
+#include "libknot/quic/quic.h"
+#endif // ENABLE_QUIC
#include "contrib/base64.h"
#include "contrib/macros.h"
#include "contrib/mempattern.h"
@@ -706,22 +709,26 @@ bool process_query_acl_check(conf_t *conf, acl_action_t action,
const yp_name_t *item = (action == ACL_ACTION_NOTIFY) ? C_MASTER : C_NOTIFY;
conf_val_t rmts = conf_zone_get(conf, item, zone_name);
allowed = rmt_allowed(conf, &rmts, query_source, &tsig,
- qdata->params->session);
+ qdata->params->quic_conn);
automatic = allowed;
}
if (!allowed) {
conf_val_t acl = conf_zone_get(conf, C_ACL, zone_name);
allowed = acl_allowed(conf, &acl, action, query_source, &tsig,
- zone_name, query, qdata->params->session);
+ zone_name, query, qdata->params->quic_conn);
}
int pin_size = 0;
- uint8_t bin_pin[CERT_PIN_LEN], pin[2 * CERT_PIN_LEN];
+#ifdef ENABLE_QUIC
+ uint8_t bin_pin[KNOT_QUIC_PIN_LEN], pin[2 * KNOT_QUIC_PIN_LEN];
size_t bin_pin_size = sizeof(bin_pin);
- cert_pin(qdata->params->session, bin_pin, &bin_pin_size, false);
+ knot_quic_conn_pin(qdata->params->quic_conn, bin_pin, &bin_pin_size, false);
if (bin_pin_size > 0) {
pin_size = knot_base64_encode(bin_pin, bin_pin_size, pin, sizeof(pin));
}
+#else
+ uint8_t pin[1];
+#endif // ENABLE_QUIC
log_zone_debug(zone_name,
"ACL, %s, action %s, remote %s%s%s%s%.*s%s",
diff --git a/src/knot/server/handler.c b/src/knot/server/handler.c
index d57290b2c..394dc26ff 100644
--- a/src/knot/server/handler.c
+++ b/src/knot/server/handler.c
@@ -108,10 +108,10 @@ void handle_quic_streams(knot_xquic_conn_t *conn, knotd_qdata_params_t *params,
if (msg) {
#ifdef ENABLE_XDP
params_xdp_update(params, KNOTD_QUERY_PROTO_QUIC, msg,
- knot_xquic_conn_rtt(conn), conn->tls_session);
+ knot_xquic_conn_rtt(conn), conn);
#endif // ENABLE_XDP
} else {
- params_update(params, knot_xquic_conn_rtt(conn), conn->tls_session);
+ params_update(params, knot_xquic_conn_rtt(conn), conn);
}
handle_quic_stream(conn, stream_id, stream->inbuf_fin, layer, params,
ans_buf, sizeof(ans_buf));
diff --git a/src/knot/server/handler.h b/src/knot/server/handler.h
index 7d4121339..784435d98 100644
--- a/src/knot/server/handler.h
+++ b/src/knot/server/handler.h
@@ -52,10 +52,10 @@ inline static knotd_qdata_params_t params_init(knotd_query_proto_t proto,
}
inline static void params_update(knotd_qdata_params_t *params, uint32_t rtt,
- struct gnutls_session_int *session)
+ struct knot_xquic_conn *conn)
{
params->measured_rtt = rtt;
- params->session = session;
+ params->quic_conn = conn;
}
#ifdef ENABLE_XDP
@@ -75,14 +75,14 @@ inline static void params_xdp_update(knotd_qdata_params_t *params,
knotd_query_proto_t proto,
struct knot_xdp_msg *msg,
uint32_t rtt,
- struct gnutls_session_int *session)
+ struct knot_xquic_conn *conn)
{
params->proto = proto;
params->remote = (struct sockaddr_storage *)&msg->ip_from;
params->local = (struct sockaddr_storage *)&msg->ip_to;
params->xdp_msg = msg;
params->measured_rtt = rtt;
- params->session = session;
+ params->quic_conn = conn;
}
#endif // ENABLE_XDP
diff --git a/src/knot/server/server.c b/src/knot/server/server.c
index ede542a7a..b215ecfb9 100644
--- a/src/knot/server/server.c
+++ b/src/knot/server/server.c
@@ -545,7 +545,7 @@ static int init_creds(server_t *server, conf_t *conf)
}
int pin_size = 0;
- uint8_t bin_pin[CERT_PIN_LEN], pin[2 * CERT_PIN_LEN];
+ uint8_t bin_pin[KNOT_QUIC_PIN_LEN], pin[2 * KNOT_QUIC_PIN_LEN];
size_t bin_pin_size = sizeof(bin_pin);
gnutls_x509_crt_t cert;
if (knot_xquic_creds_cert(server->quic_creds, &cert) == KNOT_EOK &&
diff --git a/src/knot/updates/acl.c b/src/knot/updates/acl.c
index da904411b..3ec6d4fbe 100644
--- a/src/knot/updates/acl.c
+++ b/src/knot/updates/acl.c
@@ -14,56 +14,15 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <gnutls/x509.h>
-
#include "knot/updates/acl.h"
-#include "contrib/wire_ctx.h"
-
-void cert_pin(gnutls_session_t session, uint8_t *out, size_t *out_len, bool local)
-{
- if (session == NULL) {
- goto error;
- }
-
- const gnutls_datum_t *data;
- if (local) {
- data = gnutls_certificate_get_ours(session);
- } else {
- unsigned count = 0;
- data = gnutls_certificate_get_peers(session, &count);
- if (count == 0) {
- goto error;
- }
- }
-
- gnutls_x509_crt_t cert;
- int ret = gnutls_x509_crt_init(&cert);
- if (ret != GNUTLS_E_SUCCESS) {
- goto error;
- }
-
- ret = gnutls_x509_crt_import(cert, &data[0], GNUTLS_X509_FMT_DER);
- if (ret != GNUTLS_E_SUCCESS) {
- gnutls_x509_crt_deinit(cert);
- goto error;
- }
-
- ret = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, out, out_len);
- if (ret != GNUTLS_E_SUCCESS) {
- gnutls_x509_crt_deinit(cert);
- goto error;
- }
- gnutls_x509_crt_deinit(cert);
-
- return;
-error:
- if (out_len != NULL) {
- *out_len = 0;
- }
-}
+#include "contrib/wire_ctx.h"
+#ifdef ENABLE_QUIC
+#include "libknot/quic/quic.h"
+#endif // ENABLE_QUIC
-bool cert_pin_check(const uint8_t *session_pin, size_t session_pin_size, conf_val_t *pins)
+static bool cert_pin_check(const uint8_t *session_pin, size_t session_pin_size,
+ conf_val_t *pins)
{
if (pins->code == KNOT_ENOENT) { // No certificate pin authentication required.
return true;
@@ -295,15 +254,20 @@ static bool check_addr_key(conf_t *conf, conf_val_t *addr_val, conf_val_t *key_v
bool acl_allowed(conf_t *conf, conf_val_t *acl, acl_action_t action,
const struct sockaddr_storage *addr, knot_tsig_key_t *tsig,
const knot_dname_t *zone_name, knot_pkt_t *query,
- gnutls_session_t session)
+ struct knot_xquic_conn *conn)
{
if (acl == NULL || addr == NULL || tsig == NULL) {
return false;
}
- uint8_t session_pin[CERT_PIN_LEN];
+#ifdef ENABLE_QUIC
+ uint8_t session_pin[KNOT_QUIC_PIN_LEN];
size_t session_pin_size = sizeof(session_pin);
- cert_pin(session, session_pin, &session_pin_size, false);
+ knot_quic_conn_pin(conn, session_pin, &session_pin_size, false);
+#else
+ uint8_t session_pin[1];
+ size_t session_pin_size = 0;
+#endif // ENABLE_QUIC
while (acl->code == KNOT_EOK) {
conf_val_t rmt_val = conf_id_get(conf, C_ACL, C_RMT, acl);
@@ -388,15 +352,20 @@ next_acl:
}
bool rmt_allowed(conf_t *conf, conf_val_t *rmts, const struct sockaddr_storage *addr,
- knot_tsig_key_t *tsig, gnutls_session_t session)
+ knot_tsig_key_t *tsig, struct knot_xquic_conn *conn)
{
if (!conf->cache.srv_auto_acl) {
return false;
}
- uint8_t session_pin[CERT_PIN_LEN];
+#ifdef ENABLE_QUIC
+ uint8_t session_pin[KNOT_QUIC_PIN_LEN];
size_t session_pin_size = sizeof(session_pin);
- cert_pin(session, session_pin, &session_pin_size, false);
+ knot_quic_conn_pin(conn, session_pin, &session_pin_size, false);
+#else
+ uint8_t session_pin[1];
+ size_t session_pin_size = 0;
+#endif // ENABLE_QUIC
conf_mix_iter_t iter;
conf_mix_iter_init(conf, rmts, &iter);
diff --git a/src/knot/updates/acl.h b/src/knot/updates/acl.h
index d0d9b5110..88fc289ed 100644
--- a/src/knot/updates/acl.h
+++ b/src/knot/updates/acl.h
@@ -18,13 +18,10 @@
#include <stdbool.h>
#include <sys/socket.h>
-#include <gnutls/gnutls.h>
#include "libknot/tsig.h"
#include "knot/conf/conf.h"
-#define CERT_PIN_LEN 32
-
/*! \brief ACL actions. */
typedef enum {
ACL_ACTION_QUERY = 0,
@@ -49,26 +46,6 @@ typedef enum {
} acl_update_owner_match_t;
/*!
- * \brief Gets local or remote certificate pin.
- *
- * \param session QUIC session.
- * \param session_pin Output certificate pin.
- * \param session_pin_size Input size of the storage / output size of the stored pin.
- */
-void cert_pin(gnutls_session_t session, uint8_t *out, size_t *out_len, bool local);
-
-/*!
- * \brief Checks if remote certificate pin matches the given list.
- *
- * \param session_pin QUIC session certificate pin.
- * \param session_pin_size QUIC session certificate pin size.
- * \param pins Configured certificate pins.
- *
- * \retval True if match.
- */
-bool cert_pin_check(const uint8_t *session_pin, size_t session_pin_size, conf_val_t *pins);
-
-/*!
* \brief Checks if the address and/or tsig key matches given ACL list.
*
* If a proper ACL rule is found and tsig.name is not empty, tsig.secret is filled.
@@ -80,14 +57,14 @@ bool cert_pin_check(const uint8_t *session_pin, size_t session_pin_size, conf_va
* \param tsig TSIG parameters.
* \param zone_name Zone name.
* \param query Update query.
- * \param session Possible QUIC session.
+ * \param conn Possible QUIC connection.
*
* \retval True if authenticated.
*/
bool acl_allowed(conf_t *conf, conf_val_t *acl, acl_action_t action,
const struct sockaddr_storage *addr, knot_tsig_key_t *tsig,
const knot_dname_t *zone_name, knot_pkt_t *query,
- gnutls_session_t session);
+ struct knot_xquic_conn *conn);
/*!
* \brief Checks if the address and/or tsig key matches a remote from the list.
@@ -101,9 +78,9 @@ bool acl_allowed(conf_t *conf, conf_val_t *acl, acl_action_t action,
* \param rmts Pointer to REMOTE config multivalued identifier.
* \param addr IP address.
* \param tsig TSIG parameters.
- * \param session Possible QUIC session.
+ * \param conn Possible QUIC connection.
*
* \retval True if authenticated.
*/
bool rmt_allowed(conf_t *conf, conf_val_t *rmts, const struct sockaddr_storage *addr,
- knot_tsig_key_t *tsig, gnutls_session_t session);
+ knot_tsig_key_t *tsig, struct knot_xquic_conn *conn);
diff --git a/src/libknot/quic/quic.c b/src/libknot/quic/quic.c
index 0d16bb247..460b05b7d 100644
--- a/src/libknot/quic/quic.c
+++ b/src/libknot/quic/quic.c
@@ -21,6 +21,7 @@
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#include <ngtcp2/ngtcp2_crypto_gnutls.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -380,6 +381,49 @@ uint32_t knot_xquic_conn_rtt(knot_xquic_conn_t *conn)
return stat.smoothed_rtt / 1000; // nanosec --> usec
}
+_public_
+void knot_quic_conn_pin(knot_xquic_conn_t *conn, uint8_t *pin, size_t *pin_size, bool local)
+{
+ if (conn == NULL) {
+ goto error;
+ }
+
+ const gnutls_datum_t *data;
+ if (local) {
+ data = gnutls_certificate_get_ours(conn->tls_session);
+ } else {
+ unsigned count = 0;
+ data = gnutls_certificate_get_peers(conn->tls_session, &count);
+ if (count == 0) {
+ goto error;
+ }
+ }
+
+ gnutls_x509_crt_t cert;
+ int ret = gnutls_x509_crt_init(&cert);
+ if (ret != GNUTLS_E_SUCCESS) {
+ goto error;
+ }
+
+ ret = gnutls_x509_crt_import(cert, &data[0], GNUTLS_X509_FMT_DER);
+ if (ret != GNUTLS_E_SUCCESS) {
+ gnutls_x509_crt_deinit(cert);
+ goto error;
+ }
+
+ ret = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, pin, pin_size);
+ if (ret != GNUTLS_E_SUCCESS) {
+ gnutls_x509_crt_deinit(cert);
+ goto error;
+ }
+
+ gnutls_x509_crt_deinit(cert);
+error:
+ if (pin_size != NULL) {
+ *pin_size = 0;
+ }
+}
+
static void knot_quic_rand_cb(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx)
{
(void)rand_ctx;
diff --git a/src/libknot/quic/quic.h b/src/libknot/quic/quic.h
index aafcf21db..9da4f8099 100644
--- a/src/libknot/quic/quic.h
+++ b/src/libknot/quic/quic.h
@@ -30,6 +30,8 @@
#include "libknot/quic/quic_conn.h"
+#define KNOT_QUIC_PIN_LEN 32
+
struct gnutls_x509_crt_int;
struct knot_quic_creds;
struct knot_quic_session;
@@ -118,6 +120,18 @@ bool xquic_conn_timeout(knot_xquic_conn_t *conn, uint64_t *now);
uint32_t knot_xquic_conn_rtt(knot_xquic_conn_t *conn);
/*!
+ * \brief Gets local or remote certificate pin.
+ *
+ * \note Zero output pin_size value means no certificate available or error.
+ *
+ * \param conn QUIC connection.
+ * \param pin Output certificate pin.
+ * \param pin_size Input size of the storage / output size of the stored pin.
+ * \param local Local or remote certificate indication.
+ */
+void knot_quic_conn_pin(knot_xquic_conn_t *conn, uint8_t *pin, size_t *pin_size, bool local);
+
+/*!
* \brief Create new outgoing QUIC connection.
*
* \param table QUIC connections table to be added to.