From 220c707c546f15d12bd824192a3a93c5d17b88f6 Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 10 Feb 2022 15:33:47 +0000 Subject: [PATCH] Implement some code to print crls with -f. For this introduce x509_get_time() that converts a ASN1_TIME to time_t. Also move time2str() to print.c where it makes more sense. This needs more work but that will happen in tree. OK tb@ --- usr.sbin/rpki-client/crl.c | 14 +++------- usr.sbin/rpki-client/extern.h | 15 ++++++----- usr.sbin/rpki-client/parser.c | 38 ++++++++++++--------------- usr.sbin/rpki-client/print.c | 48 +++++++++++++++++++++++++++++++---- usr.sbin/rpki-client/roa.c | 11 ++------ usr.sbin/rpki-client/x509.c | 29 ++++++++++++++------- 6 files changed, 93 insertions(+), 62 deletions(-) diff --git a/usr.sbin/rpki-client/crl.c b/usr.sbin/rpki-client/crl.c index b50aff63ad0..8d2235f7c77 100644 --- a/usr.sbin/rpki-client/crl.c +++ b/usr.sbin/rpki-client/crl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crl.c,v 1.13 2022/02/08 14:53:03 tb Exp $ */ +/* $OpenBSD: crl.c,v 1.14 2022/02/10 15:33:47 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -33,7 +33,6 @@ crl_parse(const char *fn, const unsigned char *der, size_t len) { struct crl *crl; const ASN1_TIME *at; - struct tm issued_tm, expires_tm; int rc = 0; /* just fail for empty buffers, the warning was printed elsewhere */ @@ -58,27 +57,20 @@ crl_parse(const char *fn, const unsigned char *der, size_t len) warnx("%s: X509_CRL_get0_lastUpdate failed", fn); goto out; } - memset(&issued_tm, 0, sizeof(issued_tm)); - if (ASN1_time_parse(at->data, at->length, &issued_tm, 0) == -1) { + if (x509_get_time(at, &crl->issued) == -1) { warnx("%s: ASN1_time_parse failed", fn); goto out; } - if ((crl->issued = mktime(&issued_tm)) == -1) - errx(1, "%s: mktime failed", fn); - /* extract expire time for later use */ at = X509_CRL_get0_nextUpdate(crl->x509_crl); if (at == NULL) { warnx("%s: X509_CRL_get0_nextUpdate failed", fn); goto out; } - memset(&expires_tm, 0, sizeof(expires_tm)); - if (ASN1_time_parse(at->data, at->length, &expires_tm, 0) == -1) { + if (x509_get_time(at, &crl->expires) == -1) { warnx("%s: ASN1_time_parse failed", fn); goto out; } - if ((crl->expires = mktime(&expires_tm)) == -1) - errx(1, "%s: mktime failed", fn); rc = 1; out: diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index a9b4429b83a..277a7bb2c74 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.118 2022/02/08 14:53:03 tb Exp $ */ +/* $OpenBSD: extern.h,v 1.119 2022/02/10 15:33:47 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -585,13 +585,16 @@ char *x509_get_crl(X509 *, const char *); char *x509_crl_get_aki(X509_CRL *, const char *); char *x509_get_pubkey(X509 *, const char *); enum cert_purpose x509_get_purpose(X509 *, const char *); +int x509_get_time(const ASN1_TIME *, time_t *); /* printers */ -void tal_print(const struct tal *); -void cert_print(const struct cert *); -void mft_print(const struct mft *); -void roa_print(const struct roa *); -void gbr_print(const struct gbr *); +char *time2str(time_t); +void tal_print(const struct tal *); +void cert_print(const struct cert *); +void crl_print(const struct crl *); +void mft_print(const struct mft *); +void roa_print(const struct roa *); +void gbr_print(const struct gbr *); /* Output! */ diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c index f32a77dbb39..1b737edd8fd 100644 --- a/usr.sbin/rpki-client/parser.c +++ b/usr.sbin/rpki-client/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.63 2022/02/08 14:53:03 tb Exp $ */ +/* $OpenBSD: parser.c,v 1.64 2022/02/10 15:33:47 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -94,19 +94,6 @@ repo_add(unsigned int id, char *path, char *validpath) errx(1, "repository already added: id %d, %s", id, path); } -static char * -time2str(time_t t) -{ - static char buf[64]; - struct tm tm; - - if (gmtime_r(&t, &tm) == NULL) - return "could not convert time"; - - strftime(buf, sizeof(buf), "%h %d %T %Y %Z", &tm); - return buf; -} - /* * Build access path to file based on repoid, path, location and file values. */ @@ -1009,6 +996,7 @@ proc_parser_file(char *file, unsigned char *buf, size_t len) static int num; X509 *x509 = NULL; struct cert *cert = NULL; + struct crl *crl = NULL; struct mft *mft = NULL; struct roa *roa = NULL; struct gbr *gbr = NULL; @@ -1044,6 +1032,12 @@ proc_parser_file(char *file, unsigned char *buf, size_t len) if (X509_up_ref(x509) == 0) errx(1, "%s: X509_up_ref failed", __func__); break; + case RTYPE_CRL: + crl = crl_parse(file, buf, len); + if (crl == NULL) + break; + crl_print(crl); + break; case RTYPE_MFT: mft = mft_parse(&x509, file, buf, len); if (mft == NULL) @@ -1074,7 +1068,6 @@ proc_parser_file(char *file, unsigned char *buf, size_t len) break; tal_print(tal); break; - case RTYPE_CRL: /* XXX no printer yet */ default: printf("%s: unsupported file type\n", file); break; @@ -1082,18 +1075,18 @@ proc_parser_file(char *file, unsigned char *buf, size_t len) if (aia != NULL) { struct auth *a; - struct crl *crl; - char *c; + struct crl *c; + char *crl_uri; - c = x509_get_crl(x509, file); - parse_load_crl(c); - free(c); + crl_uri = x509_get_crl(x509, file); + parse_load_crl(crl_uri); + free(crl_uri); if (auth_find(&auths, aki) == NULL) parse_load_certchain(aia); a = auth_find(&auths, aki); - crl = get_crl(a); + c = get_crl(a); - if (valid_x509(file, x509, a, crl, 0)) + if (valid_x509(file, x509, a, c, 0)) printf("Validation: OK\n"); else printf("Validation: Failed\n"); @@ -1101,6 +1094,7 @@ proc_parser_file(char *file, unsigned char *buf, size_t len) X509_free(x509); cert_free(cert); + crl_free(crl); mft_free(mft); roa_free(roa); gbr_free(gbr); diff --git a/usr.sbin/rpki-client/print.c b/usr.sbin/rpki-client/print.c index e5fdfc1ac7a..958a87a7c56 100644 --- a/usr.sbin/rpki-client/print.c +++ b/usr.sbin/rpki-client/print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print.c,v 1.3 2021/12/22 09:35:14 claudio Exp $ */ +/* $OpenBSD: print.c,v 1.4 2022/02/10 15:33:47 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -44,6 +44,19 @@ pretty_key_id(char *hex) return buf; } +char * +time2str(time_t t) +{ + static char buf[64]; + struct tm tm; + + if (gmtime_r(&t, &tm) == NULL) + return "could not convert time"; + + strftime(buf, sizeof(buf), "%h %d %T %Y %Z", &tm); + return buf; +} + void tal_print(const struct tal *p) { @@ -114,6 +127,33 @@ cert_print(const struct cert *p) } +void +crl_print(const struct crl *p) +{ + STACK_OF(X509_REVOKED) *revlist; + X509_REVOKED *rev; + int i; + long serial; + time_t t; + + printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); + printf("CRL valid since: %s\n", time2str(p->issued)); + printf("CRL valid until: %s\n", time2str(p->expires)); + + revlist = X509_CRL_get_REVOKED(p->x509_crl); + for (i = 0; i < sk_X509_REVOKED_num(revlist); i++) { + if (i == 0) + printf("Revoked Certificates:\n"); + rev = sk_X509_REVOKED_value(revlist, i); + serial = ASN1_INTEGER_get(X509_REVOKED_get0_serialNumber(rev)); + x509_get_time(X509_REVOKED_get0_revocationDate(rev), &t); + printf(" Serial: %8lx\tRevocation Date: %s\n", serial, + time2str(t)); + } + if (i == 0) + printf("No Revoked Certificates\n"); +} + void mft_print(const struct mft *p) { @@ -139,14 +179,12 @@ roa_print(const struct roa *p) { char buf[128]; size_t i; - char tbuf[21]; printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); printf("Authority info access: %s\n", p->aia); - strftime(tbuf, sizeof(tbuf), "%FT%TZ", gmtime(&p->expires)); - printf("ROA valid until: %s\n", tbuf); - + printf("ROA valid until: %s\n", time2str(p->expires)); + printf("asID: %u\n", p->asid); for (i = 0; i < p->ipsz; i++) { ip_addr_print(&p->ips[i].addr, diff --git a/usr.sbin/rpki-client/roa.c b/usr.sbin/rpki-client/roa.c index a67e6ff322d..de3534421d5 100644 --- a/usr.sbin/rpki-client/roa.c +++ b/usr.sbin/rpki-client/roa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roa.c,v 1.37 2022/01/18 16:29:06 claudio Exp $ */ +/* $OpenBSD: roa.c,v 1.38 2022/02/10 15:33:47 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -340,8 +340,6 @@ roa_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len) unsigned char *cms; int rc = 0; const ASN1_TIME *at; - struct tm expires_tm; - time_t expires; memset(&p, 0, sizeof(struct parse)); p.fn = fn; @@ -367,15 +365,10 @@ roa_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len) warnx("%s: X509_get0_notAfter failed", fn); goto out; } - memset(&expires_tm, 0, sizeof(expires_tm)); - if (ASN1_time_parse(at->data, at->length, &expires_tm, 0) == -1) { + if (x509_get_time(at, &p.res->expires) == -1) { warnx("%s: ASN1_time_parse failed", fn); goto out; } - if ((expires = mktime(&expires_tm)) == -1) - errx(1, "mktime failed"); - - p.res->expires = expires; if (!roa_parse_econtent(cms, cmsz, &p)) goto out; diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c index 0899e0df382..7e1b855129f 100644 --- a/usr.sbin/rpki-client/x509.c +++ b/usr.sbin/rpki-client/x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.c,v 1.34 2022/02/04 16:08:53 tb Exp $ */ +/* $OpenBSD: x509.c,v 1.35 2022/02/10 15:33:47 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -329,23 +329,16 @@ int x509_get_expire(X509 *x, const char *fn, time_t *tt) { const ASN1_TIME *at; - struct tm expires_tm; - time_t expires; at = X509_get0_notAfter(x); if (at == NULL) { warnx("%s: X509_get0_notafter failed", fn); return 0; } - memset(&expires_tm, 0, sizeof(expires_tm)); - if (ASN1_time_parse(at->data, at->length, &expires_tm, 0) == -1) { + if (x509_get_time(at, tt) == -1) { warnx("%s: ASN1_time_parse failed", fn); return 0; } - if ((expires = mktime(&expires_tm)) == -1) - errx(1, "%s: mktime failed", fn); - - *tt = expires; return 1; } @@ -483,3 +476,21 @@ out: AUTHORITY_KEYID_free(akid); return res; } + +/* + * Convert passed ASN1_TIME to time_t *t. + * Returns 1 on success and 0 on failure. + */ +int +x509_get_time(const ASN1_TIME *at, time_t *t) +{ + struct tm tm; + + *t = 0; + memset(&tm, 0, sizeof(tm)); + if (ASN1_time_parse(at->data, at->length, &tm, 0) == -1) + return 0; + if ((*t = mktime(&tm)) == -1) + errx(1, "mktime failed"); + return 1; +} -- 2.20.1