On Wed, Nov 10, 2021 at 11:02:14AM +0100, Martin Kletzander wrote: > On Tue, Nov 09, 2021 at 07:02:54PM +0000, Daniel P. Berrangé wrote: > > On Tue, Nov 09, 2021 at 05:30:33PM +0100, Martin Kletzander wrote: > > > This setting was unsafe for a number of reasons, so bear with me here. > > > > > > In the Distinguished Name (or rather the string representation of ASN.1 > > > RelativeDistinguishedName if you will) the individial fields (or rather each > > > AttributeTypeAndValue) can be in any order as defined in RFC4514, section 2.2. > > > The function we use to get the DN is gnutls_x509_crt_get_dn(3) which claims to > > > return the DN as described in the aforementioned RFC. > > > > > > The help we are providing to the user when no DN from the list of allowed DNs > > > matches an incoming TLS connection says to check the output of certtool, > > > particularly `certtool -i --infile clientcert.pem`. However in the output of > > > that command the order of the fields changed in some previous version exposing > > > the inconsistency (see bugzilla link below for more details). > > > > > > This is one reason why we should not depend on the order of the fields being > > > stable as the same change can happen (and maybe already happened) with the > > > gnutls_x509_crt_get_dn(3) function. > > > > gnutls_x509_crt_get_dn() hasn't changed behaviour recently. > > > > Back in 2016 it was accidentally changed, but they quickly > > fixed that mistake, and introduced a newer > > gnutls_x509_crt_get_dn3() which is what certtool -i uses > > and reports in the opposite order. > > > > What changed recently is the order in which fields are > > written into the created certificate by certtool. > > > > This is fine, libvirt's tls_allowed_dn_list setting > > has to be configured to match the order of the fields > > in the certificates you're actually using. > > > > The primary bug here from libvirt's POV, is that we're > > incorrectly telling people to use the order reported by > > "certtool -i". We need to tell them to use the *reverse* > > of what certtool -i reports. > > > > Or we could possibly add a 'tls_allowed_dn_list_revere = bool' > > setting to make ordering configurable. > > > > One other option, if the output of gnutls_x509_crt_get_dn() is > guaranteed, would be to introduce a tiny helper binary that takes a > certificate on input and outputs the DN in the format libvirt will be > checking it. Yes, that's pretty trivial - could do a 'virt-pki-query-dn' tool In fact I wrote code for that when testing the bug behaviour yesterday #include <gnutls/gnutls.h> #include <gnutls/crypto.h> #include <gnutls/x509.h> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <assert.h> #include <stdlib.h> int main (int argc, char **argv) { char dname[256]; char *dnameptr = dname; size_t dnamesize = sizeof(dname); gnutls_datum_t data; gnutls_x509_crt_t cert = NULL; int ret = -1; char buf[8192]; int fd; if (gnutls_x509_crt_init(&cert) < 0) { abort(); } fd = open(argv[1], O_RDONLY); assert(fd >= 0); read(fd, buf, sizeof(buf)); data.data = (unsigned char *)buf; data.size = strlen(buf); if (gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_PEM) < 0) { abort(); } ret = gnutls_x509_crt_get_dn(cert, dname, &dnamesize); fprintf(stderr, "%s\n", dname); } lack error checking, should use glib (eg for g_file_get_contents), etc, but would nicely isolate us from any behaviour changes in tools. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|