From: Claudio Jeker Subject: Re: rpki-client: allow UTF8String for BGPsec router cert subjects To: Theo Buehler Cc: tech@openbsd.org Date: Tue, 18 Nov 2025 13:29:03 +0100 On Tue, Nov 18, 2025 at 12:22:53PM +0100, Theo Buehler wrote: > The diff below allows BGPsec router certs to have a UTF8String in > their subject's commonName, making sure we won't reject those once we > enable the check for the PrintableString type. Since no certs with > UTF8String currently exist, I'm not keen on adding additional checks, a > few possibilities are listed in a comment. I really think that SIDROPS and the IETF need to fix this. BGPsec has currently no users and so this error in the spec should be fixed before it spreads. > Index: cert.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v > diff -u -p -r1.206 cert.c > --- cert.c 16 Oct 2025 06:46:31 -0000 1.206 > +++ cert.c 18 Nov 2025 10:54:55 -0000 > @@ -227,14 +227,14 @@ cert_check_subject_and_issuer(const char > warnx("%s: X509_get_subject_name", fn); > return 0; > } > - if (!x509_valid_name(fn, "subject", name)) > + if (!x509_valid_cert_subject(fn, name, cert->purpose)) > return 0; > > if ((name = X509_get_issuer_name(cert->x509)) == NULL) { > warnx("%s: X509_get_issuer_name", fn); > return 0; > } > - if (!x509_valid_name(fn, "issuer", name)) > + if (!x509_valid_issuer(fn, name)) > return 0; > > return 1; > Index: crl.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v > diff -u -p -r1.50 crl.c > --- crl.c 8 Jul 2025 13:25:54 -0000 1.50 > +++ crl.c 18 Nov 2025 10:54:55 -0000 > @@ -234,7 +234,7 @@ crl_parse(const char *fn, const unsigned > warnx("%s: X509_CRL_get_issuer", fn); > goto out; > } > - if (!x509_valid_name(fn, "issuer", name)) > + if (!x509_valid_issuer(fn, name)) > goto out; > > if (!crl_check_sigalg(fn, crl)) > Index: extern.h > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v > diff -u -p -r1.267 extern.h > --- extern.h 13 Nov 2025 15:18:53 -0000 1.267 > +++ extern.h 18 Nov 2025 10:54:55 -0000 > @@ -981,7 +981,9 @@ int x509_location(const char *, const > char **); > int x509_inherits(X509 *); > int x509_any_inherits(X509 *); > -int x509_valid_name(const char *, const char *, const X509_NAME *); > +int x509_valid_cert_subject(const char *, const X509_NAME *, > + enum cert_purpose); > +int x509_valid_issuer(const char *, const X509_NAME *); > time_t x509_find_expires(time_t, struct auth *, struct crl_tree *); > > /* printers */ > Index: x509.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v > diff -u -p -r1.122 x509.c > --- x509.c 18 Nov 2025 09:18:20 -0000 1.122 > +++ x509.c 18 Nov 2025 10:54:55 -0000 > @@ -403,8 +403,9 @@ valid_printable_string(const char *fn, c > * Check that subject or issuer only contain commonName and serialNumber. > * Return 0 on failure. > */ > -int > -x509_valid_name(const char *fn, const char *descr, const X509_NAME *xn) > +static int > +x509_valid_name_internal(const char *fn, const char *descr, const X509_NAME *xn, > + int allow_utf8) > { > const X509_NAME_ENTRY *ne; > const ASN1_OBJECT *ao; > @@ -435,10 +436,14 @@ x509_valid_name(const char *fn, const ch > fn); > return 0; > } > - /* > - * XXX - For some reason RFC 8209, section 3.1.1 decided > - * to allow UTF8String for BGPsec Router Certificates. > - */ > + if (allow_utf8 && as->type == V_ASN1_UTF8STRING) { > + /* > + * XXX - What to check here? No embedded NUL? > + * Actually attempt to validate UTF-8? Insist > + * on printable string alphabet? > + */ > + continue; > + } > if (!valid_printable_string(fn, descr, as)) > return 0; > break; > @@ -466,6 +471,25 @@ x509_valid_name(const char *fn, const ch > } > > return 1; > +} > + > +int > +x509_valid_cert_subject(const char *fn, const X509_NAME *xn, > + enum cert_purpose purpose) > +{ > + /* > + * For some reason RFC 8209, section 3.1.1 decided to allow UTF8String > + * for the subject of BGPsec Router Certificates, although RECOMMENDED > + * contents fit in a PrintableString. > + */ > + return x509_valid_name_internal(fn, "subject", xn, > + purpose == CERT_PURPOSE_BGPSEC_ROUTER); > +} > + > +int > +x509_valid_issuer(const char *fn, const X509_NAME *xn) > +{ > + return x509_valid_name_internal(fn, "issuer", xn, 0); > } > > /* > -- :wq Claudio