-/* $OpenBSD: cert.c,v 1.84 2022/05/31 18:51:35 tb Exp $ */
+/* $OpenBSD: cert.c,v 1.85 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2021 Job Snijders <job@openbsd.org>
return rc;
}
+/*
+ * Lightweight version of cert_parse_pre() for ASPA, ROA, and RSC EE certs.
+ * This only parses the RFC 3779 extensions since these are necessary for
+ * validation.
+ * Returns cert on success and NULL on failure.
+ */
+struct cert *
+cert_parse_ee_cert(const char *fn, X509 *x)
+{
+ struct parse p;
+ X509_EXTENSION *ext;
+ int index;
+
+ memset(&p, 0, sizeof(struct parse));
+ p.fn = fn;
+ if ((p.res = calloc(1, sizeof(struct cert))) == NULL)
+ err(1, NULL);
+
+ index = X509_get_ext_by_NID(x, NID_sbgp_ipAddrBlock, -1);
+ if ((ext = X509_get_ext(x, index)) != NULL) {
+ if (!sbgp_ipaddrblk(&p, ext))
+ goto out;
+ }
+
+ index = X509_get_ext_by_NID(x, NID_sbgp_autonomousSysNum, -1);
+ if ((ext = X509_get_ext(x, index)) != NULL) {
+ if (!sbgp_assysnum(&p, ext))
+ goto out;
+ }
+
+ if (!X509_up_ref(x)) {
+ cryptowarnx("%s: X509_up_ref failed", fn);
+ goto out;
+ }
+
+ p.res->x509 = x;
+ return p.res;
+
+ out:
+ cert_free(p.res);
+ return NULL;
+}
+
/*
* Parse and partially validate an RPKI X509 certificate (either a trust
* anchor or a certificate) as defined in RFC 6487.
-/* $OpenBSD: extern.h,v 1.149 2022/08/18 15:20:27 job Exp $ */
+/* $OpenBSD: extern.h,v 1.150 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
void cert_buffer(struct ibuf *, const struct cert *);
void cert_free(struct cert *);
+struct cert *cert_parse_ee_cert(const char *, X509 *);
struct cert *cert_parse_pre(const char *, const unsigned char *, size_t);
struct cert *cert_parse(const char *, struct cert *);
struct cert *ta_parse(const char *, struct cert *, const unsigned char *,
int valid_ta(const char *, struct auth_tree *,
const struct cert *);
int valid_cert(const char *, struct auth *, const struct cert *);
-int valid_roa(const char *, struct auth *, struct roa *);
+int valid_roa(const char *, struct cert *, struct roa *);
int valid_filehash(int, const char *, size_t);
int valid_hash(unsigned char *, size_t, const char *, size_t);
int valid_filename(const char *, size_t);
int valid_origin(const char *, const char *);
int valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
struct crl *, int);
-int valid_rsc(const char *, struct auth *, struct rsc *);
+int valid_rsc(const char *, struct cert *, struct rsc *);
int valid_econtent_version(const char *, const ASN1_INTEGER *);
/* Working with CMS. */
-/* $OpenBSD: filemode.c,v 1.7 2022/05/11 14:42:01 job Exp $ */
+/* $OpenBSD: filemode.c,v 1.8 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
if ((status = valid_x509(file, ctx, x509, a, c, 0))) {
if (type == RTYPE_ROA)
- status = valid_roa(file, a, roa);
+ status = roa->valid;
else if (type == RTYPE_RSC)
- status = valid_rsc(file, a, rsc);
+ status = rsc->valid;
}
if (status)
printf("OK");
-/* $OpenBSD: parser.c,v 1.73 2022/04/21 12:59:03 claudio Exp $ */
+/* $OpenBSD: parser.c,v 1.74 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
roa->talid = a->cert->talid;
- /*
- * If the ROA isn't valid, we accept it anyway and depend upon
- * the code around roa_read() to check the "valid" field itself.
- */
-
- if (valid_roa(file, a, roa))
- roa->valid = 1;
-
/*
* Check CRL to figure out the soonest transitive expiry moment
*/
-/* $OpenBSD: roa.c,v 1.49 2022/08/10 14:54:03 job Exp $ */
+/* $OpenBSD: roa.c,v 1.50 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
struct parse p;
size_t cmsz;
unsigned char *cms;
- int rc = 0;
const ASN1_TIME *at;
+ struct cert *cert = NULL;
+ int rc = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
goto out;
}
- if (X509_get_ext_by_NID(*x509, NID_sbgp_autonomousSysNum, -1) != -1) {
- warnx("%s: superfluous AS Resources extension present", fn);
- goto out;
- }
-
at = X509_get0_notAfter(*x509);
if (at == NULL) {
warnx("%s: X509_get0_notAfter failed", fn);
if (!roa_parse_econtent(cms, cmsz, &p))
goto out;
+ if ((cert = cert_parse_ee_cert(fn, *x509)) == NULL)
+ goto out;
+
+ if (cert->asz > 0) {
+ warnx("%s: superfluous AS Resources extension present", fn);
+ goto out;
+ }
+
+ /*
+ * If the ROA isn't valid, we accept it anyway and depend upon
+ * the code around roa_read() to check the "valid" field itself.
+ */
+ p.res->valid = valid_roa(fn, cert, p.res);
+
rc = 1;
out:
if (rc == 0) {
X509_free(*x509);
*x509 = NULL;
}
+ cert_free(cert);
free(cms);
return p.res;
}
-/* $OpenBSD: rsc.c,v 1.12 2022/06/10 10:41:09 tb Exp $ */
+/* $OpenBSD: rsc.c,v 1.13 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2022 Job Snijders <job@fastly.com>
unsigned char *cms;
size_t cmsz;
const ASN1_TIME *at;
+ struct cert *cert = NULL;
int rc = 0;
memset(&p, 0, sizeof(struct parse));
goto out;
}
+ /* XXX - check that SIA is absent. */
+
if (!rsc_parse_econtent(cms, cmsz, &p))
goto out;
+ if ((cert = cert_parse_ee_cert(fn, *x509)) == NULL)
+ goto out;
+
+ p.res->valid = valid_rsc(fn, cert, p.res);
+
rc = 1;
out:
if (rc == 0) {
X509_free(*x509);
*x509 = NULL;
}
+ cert_free(cert);
free(cms);
return p.res;
}
-/* $OpenBSD: validate.c,v 1.40 2022/06/10 10:36:43 tb Exp $ */
+/* $OpenBSD: validate.c,v 1.41 2022/08/19 12:45:53 tb Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Returns 1 if valid, 0 otherwise.
*/
int
-valid_roa(const char *fn, struct auth *a, struct roa *roa)
+valid_roa(const char *fn, struct cert *cert, struct roa *roa)
{
size_t i;
char buf[64];
for (i = 0; i < roa->ipsz; i++) {
- if (valid_ip(a, roa->ips[i].afi, roa->ips[i].min,
- roa->ips[i].max))
+ if (ip_addr_check_covered(roa->ips[i].afi, roa->ips[i].min,
+ roa->ips[i].max, cert->ips, cert->ipsz) > 0)
continue;
- ip_addr_print(&roa->ips[i].addr,
- roa->ips[i].afi, buf, sizeof(buf));
- warnx("%s: RFC 6482: uncovered IP: "
- "%s", fn, buf);
+
+ ip_addr_print(&roa->ips[i].addr, roa->ips[i].afi, buf,
+ sizeof(buf));
+ warnx("%s: RFC 6482: uncovered IP: %s", fn, buf);
return 0;
}
* Returns 1 if valid, 0 otherwise.
*/
int
-valid_rsc(const char *fn, struct auth *a, struct rsc *rsc)
+valid_rsc(const char *fn, struct cert *cert, struct rsc *rsc)
{
size_t i;
uint32_t min, max;
max = rsc->as[i].type == CERT_AS_RANGE ? rsc->as[i].range.max
: rsc->as[i].id;
- if (valid_as(a, min, max))
+ if (as_check_covered(min, max, cert->as, cert->asz) > 0)
continue;
switch (rsc->as[i].type) {
return 0;
}
- if (valid_ip(a, rsc->ips[i].afi, rsc->ips[i].min,
- rsc->ips[i].max))
+ if (ip_addr_check_covered(rsc->ips[i].afi, rsc->ips[i].min,
+ rsc->ips[i].max, cert->ips, cert->ipsz) > 0)
continue;
switch (rsc->ips[i].type) {