diff options
author | Sebastian Benoit <benno@cvs.openbsd.org> | 2019-11-27 17:08:13 +0000 |
---|---|---|
committer | Sebastian Benoit <benno@cvs.openbsd.org> | 2019-11-27 17:08:13 +0000 |
commit | eea03b2cf9ebda5eab296063580192f3601c9f64 (patch) | |
tree | 923c0c500dd5a6a06a8ad1e52ad2cc641821e868 /usr.sbin/rpki-client | |
parent | 523a66b22700e0f81caa104dd4c0696b5828493d (diff) |
Only store ta certs in the trust store and build chains of the
intermediate certificates for use in X509_STORE_CTX_init(). To do that
save the X509 cert in struct cert.
claudio sees > 2x speed increase.
ok claudio@ and feedback from jsing@ and beck@.
Diffstat (limited to 'usr.sbin/rpki-client')
-rw-r--r-- | usr.sbin/rpki-client/cert.c | 4 | ||||
-rw-r--r-- | usr.sbin/rpki-client/extern.h | 4 | ||||
-rw-r--r-- | usr.sbin/rpki-client/main.c | 72 | ||||
-rw-r--r-- | usr.sbin/rpki-client/validate.c | 4 |
4 files changed, 67 insertions, 17 deletions
diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index 2e17694bfd3..d8d56c508b1 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.7 2019/08/13 13:27:26 claudio Exp $ */ +/* $OpenBSD: cert.c,v 1.8 2019/11/27 17:08:12 benno Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -1251,6 +1251,7 @@ cert_parse_inner(X509 **xp, const char *fn, const unsigned char *dgst, int ta) "missing SIA", p.fn); goto out; } + p.res->x509 = x; rc = 1; out: @@ -1326,6 +1327,7 @@ cert_free(struct cert *p) free(p->as); free(p->aki); free(p->ski); + X509_free(p->x509); free(p); } diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 62817183a0f..942f7926e93 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.12 2019/11/27 04:32:09 benno Exp $ */ +/* $OpenBSD: extern.h,v 1.13 2019/11/27 17:08:12 benno Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -255,6 +255,8 @@ X509_CRL *crl_parse(const char *, const unsigned char *); /* Validation of our objects. */ +ssize_t valid_ski_aki(const char *, const struct auth *, size_t, + const char *, const char *); ssize_t valid_cert(const char *, const struct auth *, size_t, const struct cert *); ssize_t valid_roa(const char *, const struct auth *, size_t, const struct roa *); ssize_t valid_ta(const char *, const struct auth *, size_t, const struct cert *); diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index cbc6039cf09..2d122b26a6b 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.24 2019/11/27 03:39:16 benno Exp $ */ +/* $OpenBSD: main.c,v 1.25 2019/11/27 17:08:12 benno Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -130,6 +130,9 @@ static void proc_rsync(const char *, const char *, int, int) __attribute__((noreturn)); static void logx(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +static STACK_OF(X509) * + build_chain(ssize_t idx, const struct auth *auths, + const size_t authsz); enum output_fmt { BGPD, @@ -780,13 +783,18 @@ proc_parser_roa(struct entity *entp, int norev, X509_VERIFY_PARAM *param; unsigned int fl, nfl; ssize_t aidx; + ssize_t idx; + STACK_OF(X509) *chain; assert(entp->has_dgst); if ((roa = roa_parse(&x509, entp->uri, entp->dgst)) == NULL) return NULL; + idx = valid_ski_aki(entp->uri, auths, authsz, roa->ski, roa->aki); + chain = build_chain(idx, auths, authsz); + assert(x509 != NULL); - if (!X509_STORE_CTX_init(ctx, store, x509, NULL)) + if (!X509_STORE_CTX_init(ctx, store, x509, chain)) cryptoerrx("X509_STORE_CTX_init"); if ((param = X509_STORE_CTX_get0_param(ctx)) == NULL) @@ -809,6 +817,7 @@ proc_parser_roa(struct entity *entp, int norev, return NULL; } X509_STORE_CTX_cleanup(ctx); + sk_X509_free(chain); X509_free(x509); /* @@ -844,12 +853,17 @@ proc_parser_mft(struct entity *entp, int force, X509_STORE *store, int c; unsigned int fl, nfl; X509_VERIFY_PARAM *param; + ssize_t idx; + STACK_OF(X509) *chain; assert(!entp->has_dgst); if ((mft = mft_parse(&x509, entp->uri, force)) == NULL) return NULL; - if (!X509_STORE_CTX_init(ctx, store, x509, NULL)) + idx = valid_ski_aki(entp->uri, auths, authsz, mft->ski, mft->aki); + chain = build_chain(idx, auths, authsz); + + if (!X509_STORE_CTX_init(ctx, store, x509, chain)) cryptoerrx("X509_STORE_CTX_init"); if ((param = X509_STORE_CTX_get0_param(ctx)) == NULL) @@ -869,6 +883,7 @@ proc_parser_mft(struct entity *entp, int force, X509_STORE *store, } X509_STORE_CTX_cleanup(ctx); + sk_X509_free(chain); X509_free(x509); return mft; } @@ -891,8 +906,9 @@ proc_parser_cert(const struct entity *entp, int norev, int c; X509_VERIFY_PARAM *param; unsigned int fl, nfl; - ssize_t id; + ssize_t id, idx; char *tal; + STACK_OF(X509) *chain; assert(!entp->has_dgst != !entp->has_pkey); @@ -903,13 +919,20 @@ proc_parser_cert(const struct entity *entp, int norev, if (cert == NULL) return NULL; + /* Validate the cert to get the parent */ + id = entp->has_pkey ? + valid_ta(entp->uri, *auths, *authsz, cert) : + valid_cert(entp->uri, *auths, *authsz, cert); + + chain = build_chain(id, *auths, *authsz); + /* * Validate certificate chain w/CRLs. * Only check the CRLs if specifically asked. */ assert(x509 != NULL); - if (!X509_STORE_CTX_init(ctx, store, x509, NULL)) + if (!X509_STORE_CTX_init(ctx, store, x509, chain)) cryptoerrx("X509_STORE_CTX_init"); if ((param = X509_STORE_CTX_get0_param(ctx)) == NULL) cryptoerrx("X509_STORE_CTX_get0_param"); @@ -934,16 +957,12 @@ proc_parser_cert(const struct entity *entp, int norev, X509_STORE_CTX_cleanup(ctx); X509_free(x509); cert_free(cert); + sk_X509_free(chain); return NULL; } } X509_STORE_CTX_cleanup(ctx); - - /* Semantic validation of RPKI content. */ - - id = entp->has_pkey ? - valid_ta(entp->uri, *auths, *authsz, cert) : - valid_cert(entp->uri, *auths, *authsz, cert); + sk_X509_free(chain); if (id < 0) { X509_free(x509); @@ -972,10 +991,12 @@ proc_parser_cert(const struct entity *entp, int norev, (*auths)[*authsz].fn = strdup(entp->uri); if ((*auths)[*authsz].fn == NULL) err(EXIT_FAILURE, NULL); + + /* only a ta goes into the store */ + if (id == *authsz) + X509_STORE_add_cert(store, x509); (*authsz)++; - X509_STORE_add_cert(store, x509); - X509_free(x509); return cert; } @@ -1611,3 +1632,28 @@ usage: "[-T table] [-t tal] output\n"); return EXIT_FAILURE; } + +/* use the parent (id) to walk the tree to the root and + build a certificate chain from cert->x509 */ +STACK_OF(X509) * +build_chain(ssize_t idx, const struct auth *auths, const size_t authsz) +{ + STACK_OF(X509) *chain = NULL; + + if (idx == -1) + return NULL; + if (idx == authsz) + return NULL; + + if ((chain = sk_X509_new_null()) == NULL) + err(EXIT_FAILURE, "sk_X509_new_null"); + while (auths[idx].parent != (size_t)idx) { + if (auths[idx].cert->x509 == NULL) + errx(EXIT_FAILURE, "build_chain"); + if (sk_X509_push(chain, auths[idx].cert->x509) == 0) + err(EXIT_FAILURE, "sk_X509_push"); + idx = auths[idx].parent; + } + + return chain; +} diff --git a/usr.sbin/rpki-client/validate.c b/usr.sbin/rpki-client/validate.c index 4d3ddb1589f..a56ea0c02ba 100644 --- a/usr.sbin/rpki-client/validate.c +++ b/usr.sbin/rpki-client/validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: validate.c,v 1.6 2019/11/18 08:38:27 claudio Exp $ */ +/* $OpenBSD: validate.c,v 1.7 2019/11/27 17:08:12 benno Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -144,7 +144,7 @@ valid_ta(const char *fn, const struct auth *auths, * its AKI. * Returns the parent index or -1 on failure. */ -static ssize_t +ssize_t valid_ski_aki(const char *fn, const struct auth *auths, size_t authsz, const char *ski, const char *aki) { |