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;
 }

Reply via email to