• Bug#1106788: unblock: ktls-utils/1.0.0-1 (4/10)

    From Ben Hutchings@1:229/2 to All on Thu May 29 22:40:01 2025
    [continued from previous message]

    + tlshd_tls13_client_anon_handshake(parms);
    + break;
    + case HANDSHAKE_AUTH_X509:
    + tlshd_tls13_client_x509_handshake(parms);
    + break;
    + case HANDSHAKE_AUTH_PSK:
    + tlshd_tls13_client_psk_handshake(parms);
    + break;
    + default:
    + tlshd_log_debug("Unrecognized auth mode (%d)",
    + parms->auth_mode);
    + }
    +}

    - ret = gnutls_global_init();
    - if (ret != GNUTLS_E_SUCCESS) {
    - tlshd_log_gnutls_error(ret);
    - return;
    +#ifdef HAVE_GNUTLS_QUIC
    +static int tlshd_quic_client_x509_verify_function(gnutls_session_t session)
    +{
    + struct tlshd_quic_conn *conn = gnutls_session_get_ptr(session);
    +
    + return tlshd_client_x509_verify_function(session, conn->parms);
    +}
    +
    +#define TLSHD_QUIC_NO_CERT_AUTH 3
    +
    +static int tlshd_quic_client_set_x509_session(struct tlshd_quic_conn *conn)
    +{
    + struct tlshd_handshake_parms *parms = conn->parms;
    + gnutls_certificate_credentials_t cred;
    + gnutls_session_t session;
    + int ret = -EINVAL;
    + char *cafile;
    +
    + if (conn->cert_req != TLSHD_QUIC_NO_CERT_AUTH) {
    + if (!tlshd_x509_client_get_certs(parms) || !tlshd_x509_client_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_client_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);

    - if (tlshd_tls_debug)
    - gnutls_global_set_log_level(tlshd_tls_debug);
    - gnutls_global_set_log_function(tlshd_gnutls_log_func);
    - gnutls_global_set_audit_log_function(tlshd_gnutls_audit_func);
    -
    -#ifdef HAVE_GNUTLS_GET_SYSTEM_CONFIG_FILE
    - tlshd_log_debug("System config file: %s",
    - gnutls_get_system_config_file());
    -#endif
    + if (conn->cert_req == TLSHD_QUIC_NO_CERT_AUTH) {
    + gnutls_certificate_set_verify_flags(cred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2 |
    + GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
    + gnutls_certificate_set_flags(cred, GNUTLS_CERTIFICATE_SKIP_KEY_CERT_MATCH |
    + GNUTLS_CERTIFICATE_SKIP_OCSP_RESPONSE_CHECK);
    + } else {
    + gnutls_certificate_set_verify_function(cred,
    + tlshd_quic_client_x509_verify_function);
    + gnutls_certificate_set_retrieve_function2(cred, tlshd_x509_retrieve_key_cb);
    + }
    +
    + ret = gnutls_init(&session, GNUTLS_CLIENT |
    + GNUTLS_ENABLE_EARLY_DATA | GNUTLS_NO_END_OF_EARLY_DATA);
    + if (ret)
    + goto err_cred;
    + gnutls_session_set_ptr(session, conn);
    + if (conn->ticket_len) {
    + ret = gnutls_session_set_data(session, conn->ticket, conn->ticket_len);
    + if (ret)
    + goto err_session;
    + }
    + ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);
    + if (ret)
    + goto err_session;
    + if (parms->peername) {
    + ret = gnutls_server_name_set(session, GNUTLS_NAME_DNS,
    + parms->peername, strlen(parms->peername));
    + if (ret)
    + goto err_session;
    + }
    + 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_client_set_anon_session(struct tlshd_quic_conn *conn)
    +{
    + conn->cert_req = TLSHD_QUIC_NO_CERT_AUTH;
    + return tlshd_quic_client_set_x509_session(conn);
    +}
    +
    +static int tlshd_quic_client_set_psk_session(struct tlshd_quic_conn *conn)
    +{
    + key_serial_t peerid = conn->parms->peerids[0];
    + gnutls_psk_client_credentials_t cred;
    + gnutls_session_t session;
    + char *identity = NULL;
    + gnutls_datum_t key;
    + int ret = -EINVAL;
    +
    + if (!tlshd_keyring_get_psk_username(peerid, &identity) ||
    + !tlshd_keyring_get_psk_key(peerid, &key)) {
    + free(identity);
    + tlshd_log_error("identity/key get error %d", -ret);
    + return ret;
    + }
    +
    + ret = gnutls_psk_allocate_client_credentials(&cred);
    + if (ret)
    + goto err;
    + ret = gnutls_psk_set_client_credentials(cred, identity, &key, GNUTLS_PSK_KEY_RAW);
    + if (ret)
    + goto err_cred;
    +
    + ret = gnutls_init(&session, GNUTLS_CLIENT);
    + if (ret)
    + goto err_cred;
    + gnutls_session_set_ptr(session, conn);
    + ret = gnutls_credentials_set(session, GNUTLS_CRD_PSK, cred);
    + if (ret)
    + goto err_session;
    + conn->session = session;
    + return 0;
    +err_session:
    + gnutls_deinit(session);
    +err_cred:
    + gnutls_psk_free_client_credentials(cred);
    +err:
    + free(identity);
    + tlshd_log_gnutls_error(ret);
    + return ret;
    +}
    +
    +/**
    + * tlshd_quic_clienthello_handshake - send a QUIC Client Initial
    + * @parms: handshake parameters
    + *
    + */
    +void tlshd_quic_clienthello_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_UNAUTH:
    - tlshd_client_anon_handshake(parms);
    + ret = tlshd_quic_client_set_anon_session(conn);
    break;
    case HANDSHAKE_AUTH_X509:
    - tlshd_client_x509_handshake(parms);
    + ret = tlshd_quic_client_set_x509_session(conn);
    break;
    case HANDSHAKE_AUTH_PSK:
    - tlshd_client_psk_handshake(parms);
    + ret = tlshd_quic_client_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_clienthello_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/config.c ktls-utils-1.0.0/src/tlshd/config.c
    --- ktls-utils-0.11/src/tlshd/config.c 2024-06-14 16:54:21.000000000 +0200
    +++ ktls-utils-1.0.0/src/tlshd/config.c 2025-05-05 19:58:55.000000000 +0200
    @@ -84,17 +84,24 @@
    "nl", NULL);
    tmp = g_key_file_get_integer(tlshd_configuration, "debug",
    "delay_done", NULL);
    - tlshd_delay_done = tmp > 0 ? tmp : 0;
    + tlshd_delay_done = tmp > 0 ? (unsigned int)tmp : 0;

    keyrings = g_key_file_get_string_list(tlshd_configuration,
    "authenticate",
    "keyrings", &length, NULL);
    if (keyrings) {
    for (i = 0; i < length; i++) {
    + if (!strcmp(keyrings[i], ".nvme"))
    + continue;
    tlshd_keyring_link_session(keyrings[i]);
    }
    g_strfreev(keyrings);
    }
    + /*
    + * Always link the default nvme subsystem keyring into the
    + * session.
    + */
    + tlshd_keyring_link_session(".nvme");

    return true;
    }
    @@ -186,6 +193,7 @@
    return false;
    } else if (access(pathname, F_OK)) {
    tlshd_log_debug("client x509.truststore pathname \"%s\" is not accessible", p