On Mon, May 03, 2021 at 10:40:53AM -0600, Theo de Raadt wrote:
> This needs a cast from time_t to long long, otherwise the code won't compile
> or operate correctly on laggard legacy 32-bit time_t systems.
thanks, fixed!
OK?
Index: usr.sbin/rpki-client/extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.63
diff -u -p -r1.63 extern.h
--- usr.sbin/rpki-client/extern.h 14 Apr 2021 18:05:47 -0000 1.63
+++ usr.sbin/rpki-client/extern.h 3 May 2021 16:59:29 -0000
@@ -188,6 +188,7 @@ struct roa {
char *aki; /* AKI */
char *ski; /* SKI */
char *tal; /* basename of TAL for this cert */
+ time_t until; /* do not use after */
};
/*
@@ -210,6 +211,7 @@ struct vrp {
char *tal; /* basename of TAL for this cert */
enum afi afi;
unsigned char maxlength;
+ time_t until;
};
/*
* Tree of VRP sorted by afi, addr, maxlength and asid
Index: usr.sbin/rpki-client/output-csv.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/output-csv.c,v
retrieving revision 1.9
diff -u -p -r1.9 output-csv.c
--- usr.sbin/rpki-client/output-csv.c 19 Apr 2021 17:04:35 -0000 1.9
+++ usr.sbin/rpki-client/output-csv.c 3 May 2021 16:59:29 -0000
@@ -24,15 +24,16 @@ output_csv(FILE *out, struct vrp_tree *v
{
struct vrp *v;
- if (fprintf(out, "ASN,IP Prefix,Max Length,Trust Anchor\n") < 0)
+ if (fprintf(out, "ASN,IP Prefix,Max Length,Trust Anchor,Until\n") < 0)
return -1;
RB_FOREACH(v, vrp_tree, vrps) {
char buf[64];
ip_addr_print(&v->addr, v->afi, buf, sizeof(buf));
- if (fprintf(out, "AS%u,%s,%u,%s\n", v->asid, buf, v->maxlength,
- v->tal) < 0)
+
+ if (fprintf(out, "AS%u,%s,%u,%s,%lld\n", v->asid, buf,
+ v->maxlength, v->tal, (long long)v->until) < 0)
return -1;
}
return 0;
Index: usr.sbin/rpki-client/output-json.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/output-json.c,v
retrieving revision 1.15
diff -u -p -r1.15 output-json.c
--- usr.sbin/rpki-client/output-json.c 8 Apr 2021 19:49:27 -0000 1.15
+++ usr.sbin/rpki-client/output-json.c 3 May 2021 16:59:29 -0000
@@ -101,8 +101,9 @@ output_json(FILE *out, struct vrp_tree *
ip_addr_print(&v->addr, v->afi, buf, sizeof(buf));
if (fprintf(out, "\t\t{ \"asn\": \"AS%u\", \"prefix\": \"%s\", "
- "\"maxLength\": %u, \"ta\": \"%s\" }",
- v->asid, buf, v->maxlength, v->tal) < 0)
+ "\"maxLength\": %u, \"ta\": \"%s\", \"until\": %lld }",
+ v->asid, buf, v->maxlength, v->tal, (long long)v->until)
+ < 0)
return -1;
}
Index: usr.sbin/rpki-client/parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
retrieving revision 1.7
diff -u -p -r1.7 parser.c
--- usr.sbin/rpki-client/parser.c 1 Apr 2021 08:29:10 -0000 1.7
+++ usr.sbin/rpki-client/parser.c 3 May 2021 16:59:29 -0000
@@ -52,10 +52,12 @@ proc_parser_roa(struct entity *entp,
{
struct roa *roa;
X509 *x509;
- int c;
+ int c, i;
struct auth *a;
STACK_OF(X509) *chain;
STACK_OF(X509_CRL) *crls;
+ const ASN1_TIME *at;
+ struct tm until;
if ((roa = roa_parse(&x509, entp->file)) == NULL)
return NULL;
@@ -85,17 +87,46 @@ proc_parser_roa(struct entity *entp,
return NULL;
}
X509_STORE_CTX_cleanup(ctx);
- sk_X509_free(chain);
- sk_X509_CRL_free(crls);
- X509_free(x509);
+
+ /*
+ * Scan the stack of CRLs to figure out the soonest transitive
+ * expiry moment
+ */
+ for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+ X509_CRL *ci = sk_X509_CRL_value(crls, i);
+ if (ci->crl == NULL) {
+ err(1, "sk_X509_value failed");
+ goto out;
+ }
+ at = X509_CRL_get0_nextUpdate(ci);
+ if (at == NULL) {
+ err(1, "X509_CRL_get0_nextUpdate failed");
+ goto out;
+ }
+ if (ASN1_time_parse(at->data, at->length, &until,
+ V_ASN1_UTCTIME) != V_ASN1_UTCTIME) {
+ err(1, "ASN1_time_parse failed");
+ goto out;
+ }
+ if (mktime(&until) == -1) {
+ err(1, "mktime failed");
+ goto out;
+ }
+ if (roa->until > mktime(&until))
+ roa->until = mktime(&until);
+ }
/*
* 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(entp->file, auths, roa))
roa->valid = 1;
+
+out:
+ sk_X509_free(chain);
+ sk_X509_CRL_free(crls);
+ X509_free(x509);
return roa;
}
Index: usr.sbin/rpki-client/roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.17
diff -u -p -r1.17 roa.c
--- usr.sbin/rpki-client/roa.c 29 Mar 2021 06:50:44 -0000 1.17
+++ usr.sbin/rpki-client/roa.c 3 May 2021 16:59:29 -0000
@@ -335,6 +335,8 @@ roa_parse(X509 **x509, const char *fn)
size_t cmsz;
unsigned char *cms;
int rc = 0;
+ const ASN1_TIME *at;
+ struct tm until;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
@@ -358,6 +360,21 @@ roa_parse(X509 **x509, const char *fn)
goto out;
}
+ at = X509_get0_notAfter(*x509);
+ if (at == NULL) {
+ warnx("%s: X509_get0_notAfter failed", fn);
+ goto out;
+ }
+ if (ASN1_time_parse(at->data, at->length, &until, 0) == -1) {
+ warnx("%s: ASN1_time_parse failed", fn);
+ goto out;
+ }
+ if (mktime(&until) == -1) {
+ err(1, "mktime failed");
+ goto out;
+ }
+ p.res->until = mktime(&until);
+
if (!roa_parse_econtent(cms, cmsz, &p))
goto out;
@@ -404,6 +421,7 @@ roa_buffer(struct ibuf *b, const struct
io_simple_buffer(b, &p->valid, sizeof(int));
io_simple_buffer(b, &p->asid, sizeof(uint32_t));
io_simple_buffer(b, &p->ipsz, sizeof(size_t));
+ io_simple_buffer(b, &p->until, sizeof(time_t));
for (i = 0; i < p->ipsz; i++) {
io_simple_buffer(b, &p->ips[i].afi, sizeof(enum afi));
@@ -436,6 +454,7 @@ roa_read(int fd)
io_simple_read(fd, &p->valid, sizeof(int));
io_simple_read(fd, &p->asid, sizeof(uint32_t));
io_simple_read(fd, &p->ipsz, sizeof(size_t));
+ io_simple_read(fd, &p->until, sizeof(time_t));
if ((p->ips = calloc(p->ipsz, sizeof(struct roa_ip))) == NULL)
err(1, NULL);
@@ -476,6 +495,7 @@ roa_insert_vrps(struct vrp_tree *tree, s
v->addr = roa->ips[i].addr;
v->maxlength = roa->ips[i].maxlength;
v->asid = roa->asid;
+ v->until = roa->until;
if ((v->tal = strdup(roa->tal)) == NULL)
err(1, NULL);
if (RB_INSERT(vrp_tree, tree, v) == NULL)
@@ -522,6 +542,11 @@ vrpcmp(struct vrp *a, struct vrp *b)
if (a->asid < b->asid)
return -1;
+ if (a->until > b->until)
+ return 1;
+ if (a->until < b->until)
+ return -1;
+
return 0;
}
Index: regress/usr.sbin/rpki-client/Makefile.inc
===================================================================
RCS file: /cvs/src/regress/usr.sbin/rpki-client/Makefile.inc,v
retrieving revision 1.9
diff -u -p -r1.9 Makefile.inc
--- regress/usr.sbin/rpki-client/Makefile.inc 1 Apr 2021 06:47:18 -0000
1.9
+++ regress/usr.sbin/rpki-client/Makefile.inc 3 May 2021 16:59:29 -0000
@@ -40,14 +40,23 @@ mft_gen.c: mft.c
cat $> >> [email protected]
mv -f [email protected] $@
-CLEANFILES += mft_gen.c mft_gen.c.tmp
+# Provide missing prototypes for OpenSSL
+roa_gen.c: roa.c
+ echo '#include <openssl/asn1.h>\n' > [email protected]
+ echo 'int ASN1_time_parse(const char *, size_t, struct tm *, int);' \
+ >> [email protected]
+ echo 'int ASN1_time_tm_cmp(struct tm *, struct tm *);' >> [email protected]
+ cat $> >> [email protected]
+ mv -f [email protected] $@
+
+CLEANFILES += mft_gen.c mft_gen.c.tmp roa_gen.c roa_gen.c.tmp
SRCS_test-mft+= test-mft.c mft_gen.c cms.c x509.c io.c log.c validate.c
\
encoding.c dummy.c
run-regress-test-mft: test-mft
./test-mft -v ${.CURDIR}/../mft/*.mft
-SRCS_test-roa= test-roa.c roa.c cms.c x509.c ip.c as.c io.c log.c encoding.c
+SRCS_test-roa+= test-roa.c roa_gen.c cms.c x509.c ip.c as.c io.c log.c
encoding.c
run-regress-test-roa: test-roa
./test-roa -v ${.CURDIR}/../roa/*.roa
Index: regress/usr.sbin/rpki-client/test-roa.c
===================================================================
RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-roa.c,v
retrieving revision 1.10
diff -u -p -r1.10 test-roa.c
--- regress/usr.sbin/rpki-client/test-roa.c 29 Mar 2021 15:47:34 -0000
1.10
+++ regress/usr.sbin/rpki-client/test-roa.c 3 May 2021 16:59:29 -0000
@@ -32,6 +32,14 @@
#include "test-common.c"
+#ifndef ASN1error
+void
+ASN1error(int err)
+{
+ ASN1err(0, err);
+}
+#endif
+
int verbose;
static void
Index: regress/usr.sbin/rpki-client/openssl11/Makefile
===================================================================
RCS file: /cvs/src/regress/usr.sbin/rpki-client/openssl11/Makefile,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile
--- regress/usr.sbin/rpki-client/openssl11/Makefile 9 Nov 2020 16:05:10
-0000 1.2
+++ regress/usr.sbin/rpki-client/openssl11/Makefile 3 May 2021 16:59:29
-0000
@@ -13,6 +13,7 @@ a_time_tm_gen.c: a_time_tm.c
CLEANFILES += a_time_tm_gen.c a_time_tm_gen.c.tmp
SRCS_test-mft = a_time_tm_gen.c o_time.c
+SRCS_test-roa = a_time_tm_gen.c o_time.c
CFLAGS += -I${.CURDIR}/../../../../lib/libcrypto/
.PATH: ${.CURDIR}/..