rpki-client is currently very strict about the ip ranges and as ranges in
certificates. If a child certificate has a uncovered range in its list it
is considered invalid and is removed from the pool (with it all the ROA
entries as well).

Now rfc8360 relaxes this a bit and mentions that a ROA for 192.0.2.0/24
is valid if that prefix is covered in all certs in the chain. So if we
have this chain:
Cert 1 (TA):
Resources 192.0.2.0/24, 198.51.100.0/24
Certs 2:
Resources 192.0.2.0/24
Cert 3:
Resources 192.0.2.0/24, 198.51.100.0/24
ROA:
Resources 192.0.2.0/24

The rpki-client would currently remove cert3 with an error:
RFC 6487: uncovered IP: 198.51.100.0/24
and 192.0.2.0/24 would be missing in the roa-set.
This diff changes this behaviour. It only reports a warning for
certificates that have uncovered IP or AS ranges but at the same time
it will validate the IP range all the way up to the TA (both for cert and
ROA). With this 192.0.2.0/24 remains in the roa-set even though Cert 3 has
an uncovered IP range included.

This makes it a bit easier to update certificates since they can be
updated independently from each other.

Please test
-- 
:wq Claudio

Index: validate.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
retrieving revision 1.11
diff -u -p -r1.11 validate.c
--- validate.c  12 Sep 2020 15:46:48 -0000      1.11
+++ validate.c  8 Jan 2021 13:42:32 -0000
@@ -37,8 +37,8 @@ tracewarn(const struct auth *a)
 }
 
 /*
- * Walk up the chain of certificates trying to match our AS number to
- * one of the allocations in that chain.
+ * Walk up the full chain of certificates trying to match our AS number to
+ * one of the allocations in all the certs in that chain.
  * Returns 1 if covered or 0 if not.
  */
 static int
@@ -47,26 +47,21 @@ valid_as(struct auth *a, uint32_t min, u
        int      c;
 
        if (a == NULL)
-               return 0;
+               return 1;
 
        /* Does this certificate cover our AS number? */
-       if (a->cert->asz) {
-               c = as_check_covered(min, max,
-                   a->cert->as, a->cert->asz);
-               if (c > 0)
-                       return 1;
-               else if (c < 0)
-                       return 0;
-       }
+       c = as_check_covered(min, max,
+           a->cert->as, a->cert->asz);
+       if (c < 0)
+               return 0;
 
        /* If it doesn't, 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 inheritence, the ones before) making sure that our IP
- * prefix is covered in the first non-inheriting specification.
+ * Walk up the full chain of certificates making sure that our IP
+ * prefix is covered in all certs non-inheriting specification.
  * Returns 1 if covered or 0 if not.
  */
 static int
@@ -76,14 +71,12 @@ valid_ip(struct auth *a, enum afi afi,
        int      c;
 
        if (a == NULL)
-               return 0;
+               return 1;
 
        /* 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)
+       if (c < 0)
                return 0;
 
        /* If it doesn't, walk up the chain. */
@@ -173,8 +166,6 @@ valid_cert(const char *fn, struct auth_t
                        continue;
                warnx("%s: RFC 6487: uncovered AS: "
                    "%u--%u", fn, min, max);
-               tracewarn(a);
-               return 0;
        }
 
        for (i = 0; i < cert->ipsz; i++) {
@@ -200,8 +191,6 @@ valid_cert(const char *fn, struct auth_t
                            "(inherit)", fn);
                        break;
                }
-               tracewarn(a);
-               return 0;
        }
 
        return 1;

Reply via email to