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

Reply via email to