• 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)