Bug#1106788: unblock: ktls-utils/1.0.0-1 (9/10)
From
Ben Hutchings@1:229/2 to
All on Thu May 29 22:40:01 2025
[continued from previous message]
+ parms->num_remote_peerids = 1;
+ return 0;
+}
+
+static int tlshd_quic_server_set_x509_session(struct tlshd_quic_conn *conn)
+{
+ struct tlshd_handshake_parms *parms = conn->parms;
+ gnutls_certificate_credentials_t cred;
+ gnutls_datum_t ticket_key;
+ gnutls_session_t session;
+ int ret = -EINVAL;
+ char *cafile;
+
+ if (!tlshd_x509_server_get_certs(parms) || !tlshd_x509_server_get_privkey(parms)) {
+ tlshd_log_error("cert/privkey get error %d", -ret);
+ return ret;
+ }
+
+ ret = gnutls_certificate_allocate_credentials(&cred);
+ if (ret)
+ goto err;
+ if (tlshd_config_get_server_truststore(&cafile)) {
+ ret = gnutls_certificate_set_x509_trust_file(cred, cafile,
+ GNUTLS_X509_FMT_PEM);
+ free(cafile);
+ } else
+ ret = gnutls_certificate_set_x509_system_trust(cred);
+ if (ret < 0)
+ goto err_cred;
+ tlshd_log_debug("System trust: Loaded %d certificate(s).", ret);
+
+ gnutls_certificate_set_retrieve_function2(cred, tlshd_x509_retrieve_key_cb);
+
+ gnutls_certificate_set_verify_function(cred, tlshd_quic_server_x509_verify_function);
+
+ ret = gnutls_init(&session, GNUTLS_SERVER | GNUTLS_NO_AUTO_SEND_TICKET |
+ GNUTLS_ENABLE_EARLY_DATA | GNUTLS_NO_END_OF_EARLY_DATA);
+ if (ret)
+ goto err_cred;
+
+ if (!tlshd_quic_server_anti_replay) {
+ ret = gnutls_anti_replay_init(&tlshd_quic_server_anti_replay); + if (ret)
+ goto err_session;
+ gnutls_anti_replay_set_add_function(tlshd_quic_server_anti_replay,
+ tlshd_quic_server_anti_replay_db_add_func);
+ gnutls_anti_replay_set_ptr(tlshd_quic_server_anti_replay, NULL);
+ }
+ gnutls_anti_replay_enable(session, tlshd_quic_server_anti_replay);
+ ret = gnutls_record_set_max_early_data_size(session, 0xffffffffu);
+ if (ret)
+ goto err_session;
+
+ gnutls_session_set_ptr(session, conn);
+ ticket_key.data = conn->ticket;
+ ticket_key.size = conn->ticket_len;
+ ret = gnutls_session_ticket_enable_server(session, &ticket_key);
+ if (ret)
+ goto err_session;
+ gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CLIENT_HELLO,
+ GNUTLS_HOOK_POST, tlshd_quic_server_alpn_verify);
+ ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);
+ if (ret)
+ goto err_session;
+ gnutls_certificate_server_set_request(session, conn->cert_req);
+
+ conn->is_serv = 1;
+ conn->session = session;
+ return 0;
+err_session:
+ gnutls_deinit(session);
+err_cred:
+ gnutls_certificate_free_credentials(cred);
+err:
+ tlshd_log_gnutls_error(ret);
+ return ret;
+}
+
+static int tlshd_quic_server_set_psk_session(struct tlshd_quic_conn *conn)
+{
+ gnutls_psk_server_credentials_t cred;
+ gnutls_session_t session;
+ int ret;
+
+ ret = gnutls_psk_allocate_server_credentials(&cred);
+ if (ret)
+ goto err;
+ gnutls_psk_set_server_credentials_function(cred, tlshd_quic_server_psk_cb);
+
+ ret = gnutls_init(&session, GNUTLS_SERVER | GNUTLS_NO_AUTO_SEND_TICKET);
+ if (ret)
+ goto err_cred;
+ gnutls_session_set_ptr(session, conn);
+ gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CLIENT_HELLO,
+ GNUTLS_HOOK_POST, tlshd_quic_server_alpn_verify);
+ ret = gnutls_credentials_set(session, GNUTLS_CRD_PSK, cred);
+ if (ret)
+ goto err_session;
+
+ conn->is_serv = 1;
+ conn->session = session;
+ return 0;
+err_session:
+ gnutls_deinit(session);
+err_cred:
+ gnutls_psk_free_server_credentials(cred);
+err:
+ tlshd_log_gnutls_error(ret);
+ return ret;
+}
+
+/**
+ * tlshd_quic_serverhello_handshake - send a QUIC Server Initial
+ * @parms: handshake parameters
+ *
+ */
+void tlshd_quic_serverhello_handshake(struct tlshd_handshake_parms *parms)
+{
+ struct tlshd_quic_conn *conn;
+ int ret;
+
+ ret = tlshd_quic_conn_create(&conn, parms);
+ if (ret) {
+ parms->session_status = ret;
+ return gnutls_global_deinit();
+ }
switch (parms->auth_mode) {
case HANDSHAKE_AUTH_X509:
- tlshd_server_x509_handshake(parms);
+ ret = tlshd_quic_server_set_x509_session(conn);
break;
case HANDSHAKE_AUTH_PSK:
- tlshd_server_psk_handshake(parms);
+ ret = tlshd_quic_server_set_psk_session(conn);
break;
default:
- tlshd_log_debug("Unrecognized auth mode (%d)",
- parms->auth_mode);
+ ret = -EINVAL;
+ tlshd_log_debug("Unrecognized auth mode (%d)", parms->auth_mode);
+ }
+ if (ret) {
+ conn->errcode = -ret;
+ goto out;
}
- gnutls_global_deinit();
+ tlshd_quic_start_handshake(conn);
+out:
+ parms->session_status = conn->errcode;
+ tlshd_quic_conn_destroy(conn);
}
+#else
+void tlshd_quic_serverhello_handshake(struct tlshd_handshake_parms *parms)
+{
+ tlshd_log_debug("QUIC handshake is not enabled (%d)", parms->auth_mode);
+ parms->session_status = EOPNOTSUPP;
+}
+#endif
diff -Nru ktls-utils-0.11/src/tlshd/tlshd.conf.man ktls-utils-1.0.0/src/tlshd/tlshd.conf.man
--- ktls-utils-0.11/src/tlshd/tlshd.conf.man 2024-06-14 16:54:21.000000000 +0200
+++ ktls-utils-1.0.0/src/tlshd/tlshd.conf.man 2025-05-05 19:58:55.000000000 +0200
@@ -112,10 +112,6 @@
.B x509.private_key
This option specifies the pathname of a file containing
a PEM-encoded private key associated with the above certificate.
-.SH NOTES
-This software is a prototype.
-It's purpose is for demonstration and as a proof-of-concept.
-USE THIS SOFTWARE AT YOUR OWN RISK.
.SH SEE ALSO
.BR tlshd (8)
.SH AUTHOR
diff -Nru ktls-utils-0.11/src/tlshd/tlshd.h ktls-utils-1.0.0/src/tlshd/tlshd.h --- ktls-utils-0.11/src/tlshd/tlshd.h 2024-06-14 16:54:21.000000000 +0200
+++ ktls-utils-1.0.0/src/tlshd/tlshd.h 2025-05-05 19:58:55.000000000 +0200
@@ -32,6 +32,7 @@
struct sockaddr *peeraddr;
socklen_t peeraddr_len;
int sockfd;
+ int ip_proto;
uint32_t handshake_type;
unsigned int timeout_ms;
uint32_t auth_mode;
@@ -48,7 +49,8 @@
};
/* client.c */
-extern void tlshd_clienthello_handsha