Re: rpki-client parse and check caRepository Subject Information Access

2021-02-05 Thread Theo Buehler
On Fri, Feb 05, 2021 at 02:45:41PM +0100, Claudio Jeker wrote:
> RPKI certificates have 3 possible Subject Information Access URI that we
> may be interested in:
> - 1.3.6.1.5.5.7.48.5 (caRepository)
> - 1.3.6.1.5.5.7.48.10 (rpkiManifest)
> - 1.3.6.1.5.5.7.48.13 (rpkiNotify)
> 
> rpkiManifest points to the .mft file inside the caRepository.
> Because of this caRepository is the base URI for all the files below
> this certificate. rpkiNotify points to an RRDP endpoint where the XML
> data also contains URI that again need to match the caRepository. If not
> something strange is going on.
> 
> Since the caRepository data is useful extract it from the cert and also
> do a simple strstr() check to ensure that rpkiManifest starts with
> caRepository.
> 
> Currently the data is not used further than that but I want to add it to
> the repository information as a next step.

ok tb



rpki-client parse and check caRepository Subject Information Access

2021-02-05 Thread Claudio Jeker
RPKI certificates have 3 possible Subject Information Access URI that we
may be interested in:
- 1.3.6.1.5.5.7.48.5 (caRepository)
- 1.3.6.1.5.5.7.48.10 (rpkiManifest)
- 1.3.6.1.5.5.7.48.13 (rpkiNotify)

rpkiManifest points to the .mft file inside the caRepository.
Because of this caRepository is the base URI for all the files below
this certificate. rpkiNotify points to an RRDP endpoint where the XML
data also contains URI that again need to match the caRepository. If not
something strange is going on.

Since the caRepository data is useful extract it from the cert and also
do a simple strstr() check to ensure that rpkiManifest starts with
caRepository.

Currently the data is not used further than that but I want to add it to
the repository information as a next step.
-- 
:wq Claudio

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.24
diff -u -p -r1.24 cert.c
--- cert.c  4 Feb 2021 08:58:19 -   1.24
+++ cert.c  5 Feb 2021 13:26:14 -
@@ -194,6 +194,7 @@ sbgp_sia_resource_mft(struct parse *p,
p->fn);
return 0;
}
+
if (strcasecmp(d + dsz - 4, ".mft") != 0) {
warnx("%s: RFC 6487 section 4.8.8: SIA: "
"invalid rsync URI suffix", p->fn);
@@ -214,6 +215,43 @@ sbgp_sia_resource_mft(struct parse *p,
 }
 
 /*
+ * Parse the SIA manifest, 4.8.8.1.
+ * Returns zero on failure, non-zero on success.
+ */
+static int
+sbgp_sia_resource_carepo(struct parse *p,
+   const unsigned char *d, size_t dsz)
+{
+   size_t i;
+
+   if (p->res->repo != NULL) {
+   warnx("%s: RFC 6487 section 4.8.8: SIA: "
+   "CA repository already specified", p->fn);
+   return 0;
+   }
+
+   /* Make sure it's an rsync:// address. */
+   if (dsz <= 8 || strncasecmp(d, "rsync://", 8)) {
+   warnx("%s: RFC 6487 section 4.8.8: not using rsync schema",
+   p->fn);
+   return 0;
+   }
+
+   /* make sure only US-ASCII chars are in the URL */
+   for (i = 0; i < dsz; i++) {
+   if (isalnum(d[i]) || ispunct(d[i]))
+   continue;
+   warnx("%s: invalid URI", p->fn);
+   return 0;
+   }
+
+   if ((p->res->repo = strndup((const char *)d, dsz)) == NULL)
+   err(1, NULL);
+
+   return 1;
+}
+
+/*
  * Parse the SIA entries, 4.8.8.1.
  * There may be multiple different resources at this location, so throw
  * out all but the matching resource type. Currently only two entries
@@ -271,11 +309,13 @@ sbgp_sia_resource_entry(struct parse *p,
/*
 * Ignore all but manifest and RRDP notify URL.
 * Things we may see:
+*  - 1.3.6.1.5.5.7.48.5 (caRepository)
 *  - 1.3.6.1.5.5.7.48.10 (rpkiManifest)
 *  - 1.3.6.1.5.5.7.48.13 (rpkiNotify)
-*  - 1.3.6.1.5.5.7.48.5 (CA repository)
 */
-   if (strcmp(buf, "1.3.6.1.5.5.7.48.10") == 0)
+   if (strcmp(buf, "1.3.6.1.5.5.7.48.5") == 0)
+   rc = sbgp_sia_resource_carepo(p, d, plen);
+   else if (strcmp(buf, "1.3.6.1.5.5.7.48.10") == 0)
rc = sbgp_sia_resource_mft(p, d, plen);
else if (strcmp(buf, "1.3.6.1.5.5.7.48.13") == 0)
rc = sbgp_sia_resource_notify(p, d, plen);
@@ -317,6 +357,12 @@ sbgp_sia_resource(struct parse *p, const
goto out;
}
 
+   if (strstr(p->res->mft, p->res->repo) != p->res->mft) {
+   warnx("%s: RFC 6487 section 4.8.8: SIA: "
+   "conflicting URIs for caRepository and rpkiManifest",
+   p->fn);
+   goto out;
+   }
rc = 1;
 out:
sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free);
@@ -1172,6 +1218,7 @@ cert_free(struct cert *p)
return;
 
free(p->crl);
+   free(p->repo);
free(p->mft);
free(p->notify);
free(p->ips);
@@ -1230,6 +1277,7 @@ cert_buffer(struct ibuf *b, const struct
 
io_str_buffer(b, p->mft);
io_str_buffer(b, p->notify);
+   io_str_buffer(b, p->repo);
io_str_buffer(b, p->crl);
io_str_buffer(b, p->aki);
io_str_buffer(b, p->ski);
@@ -1297,6 +1345,7 @@ cert_read(int fd)
io_str_read(fd, >mft);
assert(p->mft);
io_str_read(fd, >notify);
+   io_str_read(fd, >repo);
io_str_read(fd, >crl);
io_str_read(fd, >aki);
io_str_read(fd, >ski);
Index: extern.h
===
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.41
diff -u -p -r1.41 extern.h
--- extern.h4 Feb 2021 14:32:01 -   1.41
+++ extern.h5 Feb 2021 13:20:29 -
@@ -112,6 +112,7 @@ struct cert {
size_t   ipsz; /* length of "ips" */
struct cert_as  *as; /*