This adds the needed bits to print CRL files.
Using ASN1_INTEGER_get() is probably bad at least I think there is the
possibility the serial number wont fit in the long. I hope tb@ has a
better solution :)
I created x509_get_time() to streamline the ASN1_TIME to time_t
conversion and replaced a bunch of calls. mft.c uses ASN1_GENERALIZEDTIME
and can not be converted.
Apart from that it seems to work.
--
:wq Claudio
Index: crl.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.13
diff -u -p -r1.13 crl.c
--- crl.c 8 Feb 2022 14:53:03 -0000 1.13
+++ crl.c 10 Feb 2022 13:27:51 -0000
@@ -33,7 +33,6 @@ crl_parse(const char *fn, const unsigned
{
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
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:
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.118
diff -u -p -r1.118 extern.h
--- extern.h 8 Feb 2022 14:53:03 -0000 1.118
+++ extern.h 10 Feb 2022 13:27:35 -0000
@@ -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! */
Index: parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
retrieving revision 1.63
diff -u -p -r1.63 parser.c
--- parser.c 8 Feb 2022 14:53:03 -0000 1.63
+++ parser.c 10 Feb 2022 13:42:12 -0000
@@ -94,19 +94,6 @@ repo_add(unsigned int id, char *path, ch
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 ch
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 ch
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 ch
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 ch
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 ch
X509_free(x509);
cert_free(cert);
+ crl_free(crl);
mft_free(mft);
roa_free(roa);
gbr_free(gbr);
Index: print.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/print.c,v
retrieving revision 1.3
diff -u -p -r1.3 print.c
--- print.c 22 Dec 2021 09:35:14 -0000 1.3
+++ print.c 10 Feb 2022 13:43:32 -0000
@@ -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)
{
@@ -115,6 +128,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)
{
size_t i;
@@ -139,13 +179,11 @@ 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++) {
Index: roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.37
diff -u -p -r1.37 roa.c
--- roa.c 18 Jan 2022 16:29:06 -0000 1.37
+++ roa.c 10 Feb 2022 13:55:22 -0000
@@ -340,8 +340,6 @@ roa_parse(X509 **x509, const char *fn, c
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, c
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;
Index: x509.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
retrieving revision 1.34
diff -u -p -r1.34 x509.c
--- x509.c 4 Feb 2022 16:08:53 -0000 1.34
+++ x509.c 10 Feb 2022 13:55:32 -0000
@@ -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;
}
@@ -482,4 +475,22 @@ x509_crl_get_aki(X509_CRL *crl, const ch
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;
}