Bug#1106788: unblock: ktls-utils/1.0.0-1 (6/10)
From
Ben Hutchings@1:229/2 to
All on Thu May 29 22:40:01 2025
[continued from previous message]
+ if (timer_settime(conn->timer, 0, &its, NULL)) {
+ tlshd_log_error("timer setup error %d", errno);
+ return -1;
+ }
+ return 0;
+}
+
+static void quic_conn_delete_timer(struct tlshd_quic_conn *conn)
+{
+ timer_delete(conn->timer);
+}
+
+static uint32_t quic_get_tls_cipher_type(gnutls_cipher_algorithm_t cipher)
+{
+ switch (cipher) {
+ case GNUTLS_CIPHER_AES_128_GCM:
+ return TLS_CIPHER_AES_GCM_128;
+ case GNUTLS_CIPHER_AES_128_CCM:
+ return TLS_CIPHER_AES_CCM_128;
+ case GNUTLS_CIPHER_AES_256_GCM:
+ return TLS_CIPHER_AES_GCM_256;
+ case GNUTLS_CIPHER_CHACHA20_POLY1305:
+ return TLS_CIPHER_CHACHA20_POLY1305;
+ default:
+ tlshd_log_notice("%s: %d", __func__, cipher);
+ return 0;
+ }
+}
+
+static enum quic_crypto_level quic_get_crypto_level(gnutls_record_encryption_level_t level)
+{
+ switch (level) {
+ case GNUTLS_ENCRYPTION_LEVEL_INITIAL:
+ return QUIC_CRYPTO_INITIAL;
+ case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
+ return QUIC_CRYPTO_HANDSHAKE;
+ case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
+ return QUIC_CRYPTO_APP;
+ case GNUTLS_ENCRYPTION_LEVEL_EARLY:
+ return QUIC_CRYPTO_EARLY;
+ default:
+ tlshd_log_notice("%s: %d", __func__, level);
+ return QUIC_CRYPTO_MAX;
+ }
+}
+
+static int quic_secret_func(gnutls_session_t session, gnutls_record_encryption_level_t level,
+ const void *rx_secret, const void *tx_secret, size_t secretlen)
+{
+ struct tlshd_quic_conn *conn = gnutls_session_get_ptr(session);
+ gnutls_cipher_algorithm_t type = gnutls_cipher_get(session);
+ struct quic_crypto_secret secret = {};
+ int sockfd, ret, len = sizeof(secret);
+
+ if (conn->completed)
+ return 0;
+
+ if (level == GNUTLS_ENCRYPTION_LEVEL_EARLY)
+ type = gnutls_early_cipher_get(session);
+
+ sockfd = conn->parms->sockfd;
+ secret.level = quic_get_crypto_level(level);
+ secret.type = quic_get_tls_cipher_type(type);
+ if (tx_secret) {
+ secret.send = 1;
+ memcpy(secret.secret, tx_secret, secretlen);
+ if (setsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_CRYPTO_SECRET, &secret, len)) {
+ tlshd_log_error("socket setsockopt tx secret error %d %u", errno, level);
+ return -1;
+ }
+ }
+ if (rx_secret) {
+ secret.send = 0;
+ memcpy(secret.secret, rx_secret, secretlen);
+ if (setsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_CRYPTO_SECRET, &secret, len)) {
+ tlshd_log_error("socket setsockopt rx secret error %d %u", errno, level);
+ return -1;
+ }
+ if (secret.level == QUIC_CRYPTO_APP) {
+ if (conn->is_serv) {
+ ret = gnutls_session_ticket_send(session, 1, 0);
+ if (ret) {
+ tlshd_log_gnutls_error(ret);
+ return ret;
+ }
+ }
+ conn->completed = 1;
+ }
+ }
+ tlshd_log_debug(" Secret func: %u %u %u", secret.level, !!tx_secret, !!rx_secret);
+ return 0;
+}
+
+static int quic_alert_read_func(gnutls_session_t session,
+ gnutls_record_encryption_level_t gtls_level,
+ gnutls_alert_level_t alert_level,
+ gnutls_alert_description_t alert_desc)
+{
+ tlshd_log_notice("%s: %u %u %u %u", __func__,
+ !!session, gtls_level, alert_level, alert_desc);
+ return 0;
+}
+
+static int quic_tp_recv_func(gnutls_session_t session, const uint8_t *buf, size_t len)
+{
+ struct tlshd_quic_conn *conn = gnutls_session_get_ptr(session);
+ int sockfd = conn->parms->sockfd;
+
+ if (setsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_TRANSPORT_PARAM_EXT, buf, len)) {
+ tlshd_log_error("socket setsockopt transport_param_ext error %d", errno);
+ return -1;
+ }
+ return 0;
+}
+
+static int quic_tp_send_func(gnutls_session_t session, gnutls_buffer_t extdata)
+{
+ struct tlshd_quic_conn *conn = gnutls_session_get_ptr(session);
+ int ret, sockfd = conn->parms->sockfd;
+ uint8_t buf[256];
+ unsigned int len;
+
+ len = sizeof(buf);
+ if (getsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_TRANSPORT_PARAM_EXT, buf, &len)) {
+ tlshd_log_error("socket getsockopt transport_param_ext error %d", errno);
+ return -1;
+ }
+
+ ret = gnutls_buffer_append_data(extdata, buf, len);
+ if (ret) {
+ tlshd_log_gnutls_error(ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int quic_read_func(gnutls_session_t session, gnutls_record_encryption_level_t level,
+ gnutls_handshake_description_t htype, const void *data, size_t datalen)
+{
+ struct tlshd_quic_conn *conn = gnutls_session_get_ptr(session);
+ struct tlshd_quic_msg *msg;
+ uint32_t len = datalen;
+
+ if (htype == GNUTLS_HANDSHAKE_KEY_UPDATE)
+ return 0;
+
+ msg = malloc(sizeof(*msg));
+ if (!msg) {
+ tlshd_log_debug("msg malloc error %d", ENOMEM);
+ return -1;
+ }
+ memset(msg, 0, sizeof(*msg));
+ msg->len = len;
+ memcpy(msg->data, data, msg->len);
+
+ msg->level = quic_get_crypto_level(level);
+ if (!conn->send_list)
+ conn->send_list = msg;
+ else
+ conn->send_last->next = msg;
+ conn->send_last = msg;
+
+ tlshd_log_debug(" Read func: %u %u %u", level, htype, datalen);
+ return 0;
+}
+
+static char quic_priority[] =
+ "%DISABLE_TLS13_COMPAT_MODE:NORMAL:-VERS-ALL:+VERS-TLS1.3:+PSK:-CIPHER-ALL:+";
+
+static int quic_session_set_priority(gnutls_session_t session, uint32_t cipher)
+{
+ char p[136] = {};
+
+ memcpy(p, quic_priority, strlen(quic_priority));
+ switch (cipher) {
+ case TLS_CIPHER_AES_GCM_128:
+ strcat(p, "AES-128-GCM");
+ break;
+ case TLS_CIPHER_AES_GCM_256:
+ strcat(p, "AES-256-GCM");
+ break;
+ case TLS_CIPHER_AES_CCM_128:
+ strcat(p, "AES-128-CCM");
+ break;
+ case TLS_CIPHER_CHACHA20_POLY1305:
+ strcat(p, "CHACHA20-POLY1305");
+ break;
+ default:
+ strcat(p, "AES-128-GCM:+AES-256-GCM:+AES-128-CCM:+CHACHA20-POLY1305");
+ }
+
+ return gnutls_priority_set_direct(session, p, NULL);
+}
+
+static int quic_session_set_alpns(gnutls_session_t session, char *alpn_data) +{
+ gnutls_datum_t alpns[TLSHD_QUIC_MAX_ALPNS_LEN / 2];
+ char *alpn = strtok(alpn_data, ",");
+ int count = 0;
+
+ while (alpn) {
+ while (*alpn == ' ')
+ alpn++;
+ alpns[count].data = (unsigned char *)alpn;
+ alpns[count].size = strlen(alpn);
+ count++;
+ alpn = strtok(NULL, ",");
+ }
+
+ return gnutls_alpn_set_protocols(session, alpns, count, GNUTLS_ALPN_MANDATORY);
+}
+
+static gnutls_record_encryption_level_t quic_get_encryption_level(uint8_t level)
+{
+ switch (level) {
+ case QUIC_CRYPTO_INITIAL:
+ return GNUTLS_ENCRYPTION_LEVEL_INITIAL;
+ case QUIC_CRYPTO_HANDSHAKE:
+ return GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE;
+ case QUIC_CRYPTO_APP:
+ return GNUTLS_ENCRYPTION_LEVEL_APPLICATION;
+ case QUIC_CRYPTO_EARLY:
+ return GNUTLS_ENCRYPTION_LEVEL_EARLY;
+ default:
+ tlshd_log_notice("%s: %d", __func__, level);
+ return GNUTLS_ENCRYPTION_LEVEL_APPLICATION + 1;
+ }
+}
+
+static int quic_conn_get_config(struct tlshd_quic_conn *conn)
+{
+ int sockfd = conn->parms->sockfd;
+ struct quic_config config = {};
+ unsigned int len;
+
+ len = sizeof(conn->alpns);
+ if (getsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_ALPN, conn->alpns, &len)) {
+ tlshd_log_error("socket getsockopt alpn error %d", errno);
+ return -1;
+ }
+ len = sizeof(conn->ticket);
+ if (getsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_SESSION_TICKET, conn->ticket, &len)) {
+ tlshd_log_error("socket getsockopt session ticket error %d", errno);
+ return -1;
+ }
+ conn->ticket_len = len;
+ len = sizeof(config);
+ if (getsockopt(sockfd, SOL_QUIC, QUIC_SOCKOPT_CONFIG, &config, &len)) { + tlshd_log_error("socket getsockopt config error %d", errno);
+ return -1;
+ }
+ conn->recv_ticket = config.receive_session_ticket;
+ conn->cert_req = config.certificate_request;
+ conn->cipher = config.payload_cipher_type;
+ return 0;
+}
+
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: you cannot sedate... all the things you hate (1:229/2)