Download raw body.
rpki-client: rework handling of expiry
The cert->expires field was added as a hack for filemode. We can use it
in normal mode and avoid some lock contention on the CRL tree. On
insertion of a CA cert, we can calculate its expiry time and use that
and the CRL's notafter to determine the one of all signed objects. This
way x509_find_expires() can run without locks and without need to walk
up the full chain while looking up the same CRLs over and over again.
For TAs the expiry will be the notAfter, and intermediate CAs will use
the minimum of their notAfter, the expiry moment of their issuer and the
relevant CRL's nextupdate. Similarly for signed objects.
The handling of the BRK's expiry in the BRK tree doesn't seem right
either. I think they should use the the expiry of the entire validating
chain rather than their notAfter. That needs some fiddling left for a
follow-up.
Index: cert.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
diff -u -p -r1.244 cert.c
--- cert.c 13 Jul 2026 10:53:12 -0000 1.244
+++ cert.c 6 Oct 2026 09:58:03 -0000
@@ -1983,10 +1983,12 @@ auth_find(struct auth_tree *auths, int i
struct auth *
auth_insert(const char *fn, struct auth_tree *auths, struct cert *cert,
- struct auth *issuer)
+ struct auth *issuer, struct crl *crl)
{
struct auth *na;
int error;
+
+ cert->expires = x509_find_expires(cert->notafter, issuer, crl);
na = calloc(1, sizeof(*na));
if (na == NULL)
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
diff -u -p -r1.301 extern.h
--- extern.h 6 Oct 2026 06:55:41 -0000 1.301
+++ extern.h 6 Oct 2026 09:58:03 -0000
@@ -573,7 +573,7 @@ RB_HEAD(auth_tree, auth);
struct auth *auth_find(struct auth_tree *, int);
struct auth *auth_insert(const char *, struct auth_tree *, struct cert *,
- struct auth *);
+ struct auth *, struct crl *);
enum http_result {
HTTP_FAILED, /* anything else */
@@ -1005,7 +1005,7 @@ int x509_inherits(X509 *);
int x509_any_inherits(X509 *);
int x509_valid_subject_name(const char *, const X509_NAME *);
int x509_valid_issuer_name(const char *, const X509_NAME *);
-time_t x509_find_expires(time_t, struct auth *, struct crl_tree *);
+time_t x509_find_expires(time_t, struct auth *, struct crl *);
/* printers */
char *nid2str(int);
Index: filemode.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
diff -u -p -r1.91 filemode.c
--- filemode.c 24 Sep 2026 14:44:03 -0000 1.91
+++ filemode.c 6 Oct 2026 09:58:03 -0000
@@ -230,7 +230,7 @@ parse_load_certchain(char *uri)
goto fail;
}
cert->talid = a->cert->talid;
- a = auth_insert(uri, &auths, cert, a);
+ a = auth_insert(uri, &auths, cert, a, crl);
uripath_add(uri, cert);
stack[i - 1] = NULL;
}
@@ -270,7 +270,7 @@ parse_load_ta(struct tal *tal)
goto out;
cert->talid = tal->id;
- auth_insert(file, &auths, cert, NULL);
+ auth_insert(file, &auths, cert, NULL, NULL);
for (i = 0; i < tal->num_uris; i++) {
if (strncasecmp(tal->uri[i], RSYNC_PROTO, RSYNC_PROTO_LEN) != 0)
continue;
@@ -434,7 +434,7 @@ proc_parser_file(char *file, unsigned ch
time_t *notbefore = NULL, *expires = NULL, *notafter = NULL;
time_t now;
struct auth *a = NULL;
- struct crl *c;
+ struct crl *c = NULL;
const char *errstr = NULL, *valid;
int status = 0;
char filehash[SHA256_DIGEST_LENGTH];
@@ -645,7 +645,7 @@ proc_parser_file(char *file, unsigned ch
if (expires != NULL) {
if ((status && aia != NULL) || is_ta)
- *expires = x509_find_expires(*notafter, a, &crls);
+ *expires = x509_find_expires(*notafter, a, c);
switch (type) {
case RTYPE_ASPA:
Index: parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
diff -u -p -r1.189 parser.c
--- parser.c 24 Sep 2026 14:44:03 -0000 1.189
+++ parser.c 6 Oct 2026 09:58:03 -0000
@@ -227,7 +227,7 @@ proc_parser_roa(char *file, const unsign
roa->talid = a->cert->talid;
- roa->expires = x509_find_expires(cert->notafter, a, &crls);
+ roa->expires = x509_find_expires(cert->notafter, a, crl);
cert_free(cert);
return roa;
@@ -269,7 +269,7 @@ proc_parser_spl(char *file, const unsign
spl->talid = a->cert->talid;
- spl->expires = x509_find_expires(cert->notafter, a, &crls);
+ spl->expires = x509_find_expires(cert->notafter, a, crl);
cert_free(cert);
return spl;
@@ -653,7 +653,7 @@ proc_parser_cert(char *file, const unsig
errx(1, "%s: corrupted entity", file);
memcpy(cert->mfthash, entp->data, entp->datasz);
- auth_insert(file, &auths, cert, a);
+ auth_insert(file, &auths, cert, a, crl);
}
return cert;
@@ -742,7 +742,7 @@ proc_parser_root_cert(struct entity *ent
free(file2);
cert1->talid = entp->talid;
- auth_insert(file1, &auths, cert1, NULL);
+ auth_insert(file1, &auths, cert1, NULL, NULL);
*out_cert = cert1;
return file1;
@@ -756,7 +756,7 @@ proc_parser_root_cert(struct entity *ent
cert2->talid = entp->talid;
if ((cert2->path = strdup(file2)) == NULL)
err(1, NULL);
- auth_insert(file2, &auths, cert2, NULL);
+ auth_insert(file2, &auths, cert2, NULL, NULL);
}
*out_cert = cert2;
@@ -793,7 +793,7 @@ proc_parser_aspa(char *file, const unsig
aspa->talid = a->cert->talid;
- aspa->expires = x509_find_expires(cert->notafter, a, &crls);
+ aspa->expires = x509_find_expires(cert->notafter, a, crl);
cert_free(cert);
return aspa;
@@ -838,7 +838,7 @@ proc_parser_tak(char *file, const unsign
tak->talid = a->cert->talid;
- tak->expires = x509_find_expires(cert->notafter, a, &crls);
+ tak->expires = x509_find_expires(cert->notafter, a, crl);
cert_free(cert);
return tak;
Index: x509.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
diff -u -p -r1.135 x509.c
--- x509.c 20 Sep 2026 20:04:03 -0000 1.135
+++ x509.c 6 Oct 2026 09:58:03 -0000
@@ -604,20 +604,15 @@ x509_check_tbs_sigalg(const char *fn, co
* Find the closest expiry moment by walking the chain of authorities.
*/
time_t
-x509_find_expires(time_t notafter, struct auth *a, struct crl_tree *crls)
+x509_find_expires(time_t notafter, struct auth *a, struct crl *crl)
{
- struct crl *crl;
time_t expires;
expires = notafter;
-
- for (; a != NULL; a = a->issuer) {
- if (expires > a->cert->notafter)
- expires = a->cert->notafter;
- crl = crl_get(crls, a);
- if (crl != NULL && expires > crl->nextupdate)
- expires = crl->nextupdate;
- }
+ if (a != NULL && expires > a->cert->expires)
+ expires = a->cert->expires;
+ if (crl != NULL && expires > crl->nextupdate)
+ expires = crl->nextupdate;
return expires;
}
rpki-client: rework handling of expiry