398 Commits
Author SHA1 Message Date
Daniel P. Berrangé 211fc7e416 crypto: support upto 5 parallel certificate identities
The default (required) identity is stored in server-cert.pem /
client-cert.pem and server-key.pem / client-key.pem.

The 4 extra (optional) identities are stored in server-cert-$N.pem /
client-cert-$N.pem and server-key-$N.pem / client-key-$N.pem. The
numbering starts at 0 and the first missing cert/key pair will
terminate the loading process.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé c497a51481 crypto: expand logic to cope with multiple certificate identities
Currently only a single set of certificates can be loaded for a
server / client. Certificates are created using a particular
key algorithm and in some scenarios it can be useful to support
multiple algorithms in parallel. This requires the ability to
load multiple sets of certificates.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 8031b5fb1a crypto: avoid loading the identity certs twice
The x509 TLS credentials code will load the identity certs once to
perform sanity chcking on the certs, then discard the certificate
objects and let gnutls load them a second time.

This extends the previous QCryptoTLSCredsX509Files struct to also
hold the identity certificates & key loaded for sanity checking
and pass them on to gnutls, avoiding the duplicated loading.

The unit tests need updating because we now correctly diagnose the
error scenario where the cert PEM file exists, without its matching
key PEM file. Previously that error was mistakenly ignored.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé aeac275c11 crypto: avoid loading the CA certs twice
The x509 TLS credentials code will load the CA certs once to perform
sanity chcking on the certs, then discard the certificate objects
and let gnutls load them a second time.

This introduces a new QCryptoTLSCredsX509Files struct which will
hold the CA certificates loaded for sanity checking and pass them on
to gnutls, avoiding the duplicated loading.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé d58f9b20c7 crypto: deprecate use of external dh-params.pem file
GNUTLS has deprecated use of externally provided diffie-hellman
parameters. Since 3.6.0 it will automatically negotiate DH params
in accordance with RFC7919.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé fac244b019 crypto: make TLS credentials structs private
Now that the TLS session code no longer needs to look at the TLS
credential structs, they can be made private.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 70f9fd8dbf crypto: fix lifecycle handling of gnutls credentials objects
As described in the previous commit, the gnutls credentials need to
be kept alive for as long as the gnutls session object exists. Convert
the QCryptoTLSCreds objects to use QCryptoTLSCredsBox and holding the
gnutls credential objects. When loading the credentials into a gnutls
session, store a reference to the box into the QCryptoTLSSession object.

This has the useful side effect that the QCryptoTLSSession code no
longer needs to know about all the different credential types, it can
use the generic pointer stored in the box.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 51e24d46e0 crypto: introduce a wrapper around gnutls credentials
The gnutls_credentials_set() method has a very suprising API contract
that requires the caller to preserve the passed in credentials pointer
for as long as the gnutls_session_t object is alive. QEMU is failing
to ensure this happens.

In QEMU the GNUTLS credentials object is owned by the QCryptoTLSCreds
object instance while the GNUTLS session object is owned by the
QCryptoTLSSession object instance. Their lifetimes are not guaranteed
to be the same, though in most common usage the credentials will outlive
the session. This is notably not the case, however, after the VNC server
gained the ability to reload credentials on the fly with:

  commit 1f08e34151
  Author: Zihao Chang <changzihao1@huawei.com>
  Date:   Tue Mar 16 15:58:44 2021 +0800

    vnc: support reload x509 certificates for vnc

If that is triggered while a VNC client is in the middle of performing
a TLS handshake, we might hit a use-after-free.

It is difficult to correct this problem because there's no way to deep-
clone a GNUTLS credentials object, nor is it reference counted. Thus we
introduce a QCryptoTLSCredsBox object whose only purpose is to add
reference counting around the GNUTLS credentials object.

The DH parameters set against a credentials object also have to be kept
alive for as long as the credentials exist. So the box must also hold
the DH parameters pointer.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé a5d2bf4a87 crypto: introduce method for reloading TLS creds
This prevents direct access of the class members by the VNC
display code.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé e82fccb4a3 crypto: reduce duplication in handling TLS priority strings
The logic for setting the TLS priority string on a session object has a
significant amount of logic duplication across the different credential
types. By recording the extra priority string suffix against the
credential class, we can introduce a common method for building the
priority string. The TLS session can now set the priority string without
caring about the credential type.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé fb8a0b0bfc crypto: remove duplication loading x509 CA cert
The CA cert is mandatory in both client and server scenarios.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 7751083fa4 crypto: shorten the endpoint == server check in TLS creds
This eliminates a number of long lines aiding readability.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 11ea2bffda crypto: move release of DH parameters into TLS creds parent
The code for releasing DH parameters is common to all credential
subclasses, and the unload function is only called from the
finalizers, except for x509 reload, so can be moved into the
parent with a little update of the reload method.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 20ee306418 crypto: remove needless indirection via parent_obj field
The reload method already has a pointer to the parent object in
the 'creds' parameter that is passed in, so indirect access via
the subclass 'parent_obj' field is redundant.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 916501aa07 crypto: use g_autofree when loading x509 credentials
This allows removal of goto jumps during loading of the credentials
and will simplify the diff in following commits.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 9d3343b00b crypto: move check for TLS creds 'dir' property
The check for the 'dir' property is being repeated for every
credential file to be loaded, but this results in incorrect
logic for optional credentials. The 'dir' property is mandatory
for PSK and x509 creds, even if some individual files are
optional. Address this by separating the check for the 'dir'
property.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 9fe991d0a4 crypto: remove redundant access() checks before loading certs
The qcrypto_tls_creds_get_path method will perform an access()
check on the file and return a NULL path if it fails. By the
time we get to loading the cert files we know they must exist
on disk and thus the second access() check is redundant.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 2114ae9faa crypto: replace stat() with access() for credential checks
Readability of the credential files is what matters for our usage,
so access() is more appropriate than stat().

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 0de19c148a crypto: add missing free of certs array
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 3821a538f7 crypto: remove redundant parameter checking CA certs
The only caller of qcrypto_tls_creds_check_authority_chain always
passes 'true' for the 'isCA' parameter. The point of this method
is to check the CA chani, so no other value would ever make sense.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 167194d087 crypto: drop in-tree XTS cipher mode impl
nettle included XTS in 3.4.1, so with the new min version we
no longer require the in-tree XTS cipher mode impl.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé 9e6ce4d22e crypto: unconditionally enable gnutls XTS support
The XTS support required 3.6.8 which is older than our min
required version now.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Daniel P. Berrangé c4b3d0074e crypto: bump min gnutls to 3.7.5
Per repology, current shipping versions are:

                 RHEL-9: 3.8.3
              Debian 13: 3.8.9
       openSUSE Leap 15: 3.8.3
       Ubuntu LTS 22.04: 3.7.5
                FreeBSD: 3.8.10
              Fedora 42: 3.8.10
                OpenBSD: 3.8.10
         macOS HomeBrew: 3.8.10

Ubuntu 22.04 is our oldest constraint at this time.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:45:55 +00:00
Philippe Mathieu-DaudéandDaniel P. Berrangé abf6e02dfb crypto/hash: Have hashing functions take void * buffer argument
Cryptographic hash function can operate on any area of memory,
regardless of the content their represent. Do not restrict to
array of char, use the void* type, which is also the type of
the underlying iovec::iov_base field.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-11-03 10:05:40 +00:00
Daniel P. Berrangé 3b3257b00f crypto: switch to newer gnutls API for distinguished name
The new API automatically allocates the right amount of memory
to hold the distinguished name, avoiding the need to loop and
realloc.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2025-10-24 16:36:48 +01:00