Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
Re: rpki-client: allow UTF8String for BGPsec router cert subjects
To:
Theo Buehler <tb@theobuehler.org>
Cc:
tech@openbsd.org
Date:
Tue, 18 Nov 2025 13:29:03 +0100

Download raw body.

Thread
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