On Tue, May 10, 2022 at 08:32:15AM +0000, Job Snijders wrote:
> Hi,
>
> Following this errata report https://www.rfc-editor.org/errata/eid6854
>
> If the Basic Constraints extension is present, and the certificate is
> *not* a CA - as determined by X509_check_ca(3), leave the purpose as
> CERT_PURPOSE_INVALID.
LibreSSL's X509_check_ca() has a bug that will make it return 1 if
x509v3_cache_extensions() fails... That shouldn't affect us here since
x should already have its extensions cached.
I think for your purposes it is better to check the extension flags
instead of parsing the basic constraints extension another time:
if (X509_get_extension_flags(x) & EXFLAG_BCONS) {
warnx("%s: Basic Constraints in non-CA cert", fn);
goto out;
}
and we should probably consider rewriting this function to inspect
extension flags also for the CA case.
>
> While there, use the value name rather than 0.
>
> OK?
>
> Kind regards,
>
> Job
>
> Index: x509.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
> retrieving revision 1.42
> diff -u -p -r1.42 x509.c
> --- x509.c 9 May 2022 17:13:06 -0000 1.42
> +++ x509.c 10 May 2022 08:31:03 -0000
> @@ -182,15 +182,22 @@ out:
> enum cert_purpose
> x509_get_purpose(X509 *x, const char *fn)
> {
> + BASIC_CONSTRAINTS *bc = NULL;
> EXTENDED_KEY_USAGE *eku = NULL;
> int crit;
> - enum cert_purpose purpose = 0;
> + enum cert_purpose purpose = CERT_PURPOSE_INVALID;
>
> if (X509_check_ca(x) == 1) {
> purpose = CERT_PURPOSE_CA;
> goto out;
> }
>
> + bc = X509_get_ext_d2i(x, NID_basic_constraints, &crit, NULL);
> + if (bc != NULL) {
> + warnx("%s: Basic Constraints ext in CA:FALSE cert", fn);
> + goto out;
> + }
> +
> eku = X509_get_ext_d2i(x, NID_ext_key_usage, &crit, NULL);
> if (eku == NULL) {
> warnx("%s: EKU: extension missing", fn);
> @@ -212,6 +219,7 @@ x509_get_purpose(X509 *x, const char *fn
> }
>
> out:
> + BASIC_CONSTRAINTS_free(bc);
> EXTENDED_KEY_USAGE_free(eku);
> return purpose;
> }
>