On Mon, Aug 22, 2022 at 12:14:53PM +0200, Theo Buehler wrote:
> rpki-client portable makes sure that libcrypto has RFC 3779 support.
> Therefore the X509_verify_cert() call in valid_x509() will already
> perform the checks that the RFC 3779 extensions are covered along the
> chain. While valid_cert()'s errors would be nicer than the validator's,
> they can't be reached anymore.
I wonderd if we could beef up the error handler of X509_verify_cert() to
return better errors. Like calling the valid_ip/valid_as functions to
figure out what is not covered.
More urgently a similar change is needed for .mft files where the common
error of no valid mft found is very unhelpful to diagnose issues.
> The check that a BGPsec cert's AS numbers must not be inherited can be
> done in cert_parse_pre() like most of the other checks for BGPsec certs.
Sounds good to me.
> With the removal of valid_cert(), valid_as() and valid_ip() are unused
> and can also go.
In general I'm ok with the diff but see above about the wish for better
error reporting.
> Index: cert.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
> retrieving revision 1.85
> diff -u -p -r1.85 cert.c
> --- cert.c 19 Aug 2022 12:45:53 -0000 1.85
> +++ cert.c 22 Aug 2022 09:52:07 -0000
> @@ -736,6 +736,13 @@ cert_parse_pre(const char *fn, const uns
> p.fn);
> goto out;
> }
> + for (i = 0; i < p.res->asz; i++) {
> + if (p.res->as[i].type == CERT_AS_INHERIT) {
> + warnx("%s: inherited AS numbers in BGPsec cert",
> + p.fn);
> + goto out;
> + }
> + }
> if (sia_present) {
> warnx("%s: unexpected SIA extension in BGPsec cert",
> p.fn);
> Index: filemode.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 filemode.c
> --- filemode.c 19 Aug 2022 12:45:53 -0000 1.8
> +++ filemode.c 19 Aug 2022 19:53:17 -0000
> @@ -168,8 +168,7 @@ parse_load_certchain(char *uri)
> uri = filestack[i];
>
> crl = crl_get(&crlt, a);
> - if (!valid_x509(uri, ctx, cert->x509, a, crl, 0) ||
> - !valid_cert(uri, a, cert))
> + if (!valid_x509(uri, ctx, cert->x509, a, crl, 0))
> goto fail;
> cert->talid = a->cert->talid;
> a = auth_insert(&auths, cert, a);
> Index: parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> retrieving revision 1.74
> diff -u -p -r1.74 parser.c
> --- parser.c 19 Aug 2022 12:45:53 -0000 1.74
> +++ parser.c 19 Aug 2022 19:52:53 -0000
> @@ -404,8 +404,7 @@ proc_parser_cert(char *file, const unsig
> a = valid_ski_aki(file, &auths, cert->ski, cert->aki);
> crl = crl_get(&crlt, a);
>
> - if (!valid_x509(file, ctx, cert->x509, a, crl, 0) ||
> - !valid_cert(file, a, cert)) {
> + if (!valid_x509(file, ctx, cert->x509, a, crl, 0)) {
> cert_free(cert);
> return NULL;
> }
> Index: validate.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
> retrieving revision 1.41
> diff -u -p -r1.41 validate.c
> --- validate.c 19 Aug 2022 12:45:53 -0000 1.41
> +++ validate.c 19 Aug 2022 19:52:22 -0000
> @@ -33,56 +33,6 @@
> extern ASN1_OBJECT *certpol_oid;
>
> /*
> - * Walk up the chain of certificates trying to match our AS number to
> - * one of the allocations in that chain.
> - * Returns 1 if covered or 0 if not.
> - */
> -static int
> -valid_as(struct auth *a, uint32_t min, uint32_t max)
> -{
> - int c;
> -
> - if (a == NULL)
> - return 0;
> -
> - /* Does this certificate cover our AS number? */
> - c = as_check_covered(min, max, a->cert->as, a->cert->asz);
> - if (c > 0)
> - return 1;
> - else if (c < 0)
> - return 0;
> -
> - /* If it inherits, walk up the chain. */
> - return valid_as(a->parent, min, max);
> -}
> -
> -/*
> - * Walk up the chain of certificates (really just the last one, but in
> - * the case of inheritance, the ones before) making sure that our IP
> - * prefix is covered in the first non-inheriting specification.
> - * Returns 1 if covered or 0 if not.
> - */
> -static int
> -valid_ip(struct auth *a, enum afi afi,
> - const unsigned char *min, const unsigned char *max)
> -{
> - int c;
> -
> - if (a == NULL)
> - return 0;
> -
> - /* Does this certificate cover our IP prefix? */
> - c = ip_addr_check_covered(afi, min, max, a->cert->ips, a->cert->ipsz);
> - if (c > 0)
> - return 1;
> - else if (c < 0)
> - return 0;
> -
> - /* If it inherits, walk up the chain. */
> - return valid_ip(a->parent, afi, min, max);
> -}
> -
> -/*
> * Make sure that the SKI doesn't already exist and return the parent by
> * its AKI.
> * Returns the parent auth or NULL on failure.
> @@ -131,65 +81,6 @@ valid_ta(const char *fn, struct auth_tre
> /* SKI must not be a dupe. */
> if (auth_find(auths, cert->ski) != NULL) {
> warnx("%s: RFC 6487: duplicate SKI", fn);
> - return 0;
> - }
> -
> - return 1;
> -}
> -
> -/*
> - * Validate a non-TA certificate: make sure its IP and AS resources are
> - * fully covered by those in the authority key (which must exist).
> - * Returns 1 if valid, 0 otherwise.
> - */
> -int
> -valid_cert(const char *fn, struct auth *a, const struct cert *cert)
> -{
> - size_t i;
> - uint32_t min, max;
> - char buf1[64], buf2[64];
> -
> - for (i = 0; i < cert->asz; i++) {
> - if (cert->as[i].type == CERT_AS_INHERIT) {
> - if (cert->purpose == CERT_PURPOSE_BGPSEC_ROUTER)
> - return 0; /* BGPsec doesn't permit inheriting */
> - continue;
> - }
> - min = cert->as[i].type == CERT_AS_ID ?
> - cert->as[i].id : cert->as[i].range.min;
> - max = cert->as[i].type == CERT_AS_ID ?
> - cert->as[i].id : cert->as[i].range.max;
> - if (valid_as(a, min, max))
> - continue;
> - warnx("%s: RFC 6487: uncovered AS: "
> - "%u--%u", fn, min, max);
> - return 0;
> - }
> -
> - for (i = 0; i < cert->ipsz; i++) {
> - if (valid_ip(a, cert->ips[i].afi, cert->ips[i].min,
> - cert->ips[i].max))
> - continue;
> - switch (cert->ips[i].type) {
> - case CERT_IP_RANGE:
> - ip_addr_print(&cert->ips[i].range.min,
> - cert->ips[i].afi, buf1, sizeof(buf1));
> - ip_addr_print(&cert->ips[i].range.max,
> - cert->ips[i].afi, buf2, sizeof(buf2));
> - warnx("%s: RFC 6487: uncovered IP: "
> - "%s--%s", fn, buf1, buf2);
> - break;
> - case CERT_IP_ADDR:
> - ip_addr_print(&cert->ips[i].ip,
> - cert->ips[i].afi, buf1, sizeof(buf1));
> - warnx("%s: RFC 6487: uncovered IP: "
> - "%s", fn, buf1);
> - break;
> - case CERT_IP_INHERIT:
> - warnx("%s: RFC 6487: uncovered IP: "
> - "(inherit)", fn);
> - break;
> - }
> return 0;
> }
>
>
--
:wq Claudio