From: Theo Buehler Subject: rpki-client: allow UTF8String for BGPsec router cert subjects To: tech@openbsd.org Date: Tue, 18 Nov 2025 12:22:53 +0100 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. 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); } /*