Cache X509v3 extensions as soon as we have a cert
authortb <tb@openbsd.org>
Wed, 11 May 2022 16:13:05 +0000 (16:13 +0000)
committertb <tb@openbsd.org>
Wed, 11 May 2022 16:13:05 +0000 (16:13 +0000)
X509 API functions such as X509_check_ca() or X509_get_extension_flags()
can't be used reliably unless we know that X509v3 extensions are cached.
Otherwise they try to cache the extensions themselves but can't report
possible errors sensibly. They carry on and may return nonsense.

An old trick is to call X509_check_purpose() with a purpose of -1 which
is a wrapper around the internal x509v3_cache_extensions() that allows
error checking. Do this when we have a new cert. This way the API
functions affected by this can be relied upon. Another nice side effect
of doing this is that with LibreSSL we then know that the RFC 3779
extensions are in canonical form.

ok beck claudio

usr.sbin/rpki-client/cert.c
usr.sbin/rpki-client/cms.c

index c4114f2..ab6c6d6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cert.c,v 1.77 2022/05/11 09:40:00 tb Exp $ */
+/*     $OpenBSD: cert.c,v 1.78 2022/05/11 16:13:05 tb Exp $ */
 /*
  * Copyright (c) 2021 Job Snijders <job@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -597,6 +597,12 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len)
                goto out;
        }
 
+       /* Cache X509v3 extensions, see X509_check_ca(3). */
+       if (X509_check_purpose(x, -1, -1) <= 0) {
+               cryptowarnx("%s: could not cache X509v3 extensions", p.fn);
+               goto out;
+       }
+
        /* Look for X509v3 extensions. */
 
        if ((extsz = X509_get_ext_count(x)) < 0)
index 24c7b90..cd1d6c4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cms.c,v 1.16 2022/03/28 13:04:01 claudio Exp $ */
+/*     $OpenBSD: cms.c,v 1.17 2022/05/11 16:13:05 tb Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -224,6 +224,12 @@ cms_parse_validate(X509 **xp, const char *fn, const unsigned char *der,
        }
        *xp = X509_dup(sk_X509_value(certs, 0));
 
+       /* Cache X509v3 extensions, see X509_check_ca(3). */
+       if (X509_check_purpose(*xp, -1, -1) <= 0) {
+               cryptowarnx("%s: could not cache X509v3 extensions", fn);
+               goto out;
+       }
+
        if (CMS_SignerInfo_get0_signer_id(si, &kid, NULL, NULL) != 1 ||
            kid == NULL) {
                warnx("%s: RFC 6488: could not extract SKI from SID", fn);