On Thu, Aug 25, 2022 at 01:25:24PM +0000, Job Snijders wrote:
> Hi all,
> 
> Thanks for taking the time to review & suggest improvements. I amended
> the changeset based on your feedback.
> 
> To summarize the changes:
> 
> * to address sloppiness in command line option handling, make pemmode
>   mutually exclusive with filemode and specifying outformats
> * rename PEM printing function to pem_print()
> * don't limit printing PEM to just one file, allow multiple arguments
>   like filemode also does
> * visually align variables inside pem_print()
> * avoid the ASN1_item_d2i gotcha of der_in being advanced past the
>   parsed data
> * free buf unconditionally
> 
> OK?

I wonder why is PEM printing not part of -f? It seems to be something that
should be part of filemode.

> Kind regards,
> 
> Job
> 
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.150
> diff -u -p -r1.150 extern.h
> --- extern.h  19 Aug 2022 12:45:53 -0000      1.150
> +++ extern.h  25 Aug 2022 13:00:26 -0000
> @@ -664,6 +664,7 @@ void               mft_print(const X509 *, const str
>  void          roa_print(const X509 *, const struct roa *);
>  void          gbr_print(const X509 *, const struct gbr *);
>  void          rsc_print(const X509 *, const struct rsc *);
> +int           print_pem(const char *);
>  
>  /* Output! */
>  
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
> retrieving revision 1.209
> diff -u -p -r1.209 main.c
> --- main.c    4 Aug 2022 13:44:07 -0000       1.209
> +++ main.c    25 Aug 2022 13:00:27 -0000
> @@ -64,6 +64,7 @@ const char  *bird_tablename = "ROAS";
>  int  verbose;
>  int  noop;
>  int  filemode;
> +int  pemmode;
>  int  rrdpon = 1;
>  int  repo_timeout;
>  
> @@ -819,7 +820,7 @@ main(int argc, char *argv[])
>           "proc exec unveil", NULL) == -1)
>               err(1, "pledge");
>  
> -     while ((c = getopt(argc, argv, "b:Bcd:e:fjnorRs:S:t:T:vV")) != -1)
> +     while ((c = getopt(argc, argv, "b:Bcd:e:fjnoprRs:S:t:T:vV")) != -1)
>               switch (c) {
>               case 'b':
>                       bind_addr = optarg;
> @@ -849,6 +850,9 @@ main(int argc, char *argv[])
>               case 'o':
>                       outformats |= FORMAT_OPENBGPD;
>                       break;
> +             case 'p':
> +                     pemmode = 1;
> +                     break;
>               case 'R':
>                       rrdpon = 0;
>                       break;
> @@ -888,6 +892,20 @@ main(int argc, char *argv[])
>       argv += optind;
>       argc -= optind;
>  
> +     if (pemmode && (filemode || outformats))
> +             goto usage;
> +
> +     if (pemmode) {
> +             if (pledge("stdio rpath", NULL) == -1)
> +                     err(1, "pledge");
> +
> +             for (; *argv != NULL; argv++) {
> +                     if ((rc = print_pem(*argv)) != 0)
> +                             return rc;
> +             }
> +             return rc;
> +     }
> +
>       if (!filemode) {
>               if (argc == 1)
>                       outputdir = argv[0];
> @@ -1278,6 +1296,7 @@ usage:
>           " [-e rsync_prog]\n"
>           "                   [-S skiplist] [-s timeout] [-T table] [-t tal]"
>           " [outputdir]\n"
> -         "       rpki-client [-Vv] [-d cachedir] [-t tal] -f file ...\n");
> +         "       rpki-client [-Vv] [-d cachedir] [-t tal] -f file ...\n"
> +         "       rpki-client -p file ...\n");
>       return 1;
>  }
> Index: print.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/print.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 print.c
> --- print.c   14 Jul 2022 13:24:56 -0000      1.14
> +++ print.c   25 Aug 2022 13:00:27 -0000
> @@ -1,5 +1,6 @@
>  /*   $OpenBSD: print.c,v 1.14 2022/07/14 13:24:56 job Exp $ */
>  /*
> + * Copyright (c) 2022 Job Snijders <[email protected]>
>   * Copyright (c) 2021 Claudio Jeker <[email protected]>
>   * Copyright (c) 2019 Kristaps Dzonsons <[email protected]>
>   *
> @@ -26,6 +27,8 @@
>  #include <time.h>
>  
>  #include <openssl/evp.h>
> +#include <openssl/pem.h>
> +#include <openssl/x509.h>
>  
>  #include "extern.h"
>  
> @@ -567,4 +570,99 @@ rsc_print(const X509 *x, const struct rs
>  
>       if (outformats & FORMAT_JSON)
>               printf("\t],\n");
> +}
> +
> +/*
> + * Read a file, extract the encapsulated X509 cert and print in PEM format.
> + * Return zero on success, non-zero on failure.
> + */
> +int
> +print_pem(const char *fn)
> +{
> +     BIO                     *bio_out = NULL;
> +     X509                    *x = NULL;
> +     X509_CRL                *c = NULL;
> +     struct gbr              *gbr = NULL;
> +     struct mft              *mft = NULL;
> +     struct roa              *roa = NULL;
> +     struct rsc              *rsc = NULL;
> +     unsigned char           *buf = NULL;
> +     const unsigned char     *der;
> +     size_t                   len;
> +     enum rtype               type;
> +     int                      rc = 1;
> +
> +     x509_init_oid();
> +
> +     type = rtype_from_file_extension(fn);
> +     if (type == RTYPE_INVALID) {
> +             warnx("%s: unsupported file type", fn);
> +             goto out;
> +     }
> +
> +     if ((buf = load_file(fn, &len)) == NULL) {
> +             warnx("load_file failed");
> +             goto out;
> +     }
> +
> +     if ((bio_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
> +             errx(1, "BIO_new_fp");
> +
> +     switch (type) {
> +     case RTYPE_CER:
> +             der = buf;
> +             if ((x = d2i_X509(NULL, &der, len)) == NULL) {
> +                     warnx("d2i_X509 failed");
> +                     goto out;
> +             }
> +             break;
> +     case RTYPE_CRL:
> +             der = buf;
> +             if ((c = d2i_X509_CRL(NULL, &der, len)) == NULL) {
> +                     warnx("d2i_X509_CRL failed");
> +                     goto out;
> +             }
> +             if (!X509_CRL_print(bio_out, c))
> +                     errx(1, "X509_CRL_print");
> +             if (!PEM_write_bio_X509_CRL(bio_out, c))
> +                     errx(1, "PEM_write_bio_X509_CRL");
> +             rc = 0;
> +             goto out;
> +     case RTYPE_GBR:
> +             if ((gbr = gbr_parse(&x, fn, buf, len)) == NULL)
> +                     goto out;
> +             break;
> +     case RTYPE_MFT:
> +             if ((mft = mft_parse(&x, fn, buf, len)) == NULL)
> +                     goto out;
> +             break;
> +     case RTYPE_ROA:
> +             if ((roa = roa_parse(&x, fn, buf, len)) == NULL)
> +                     goto out;
> +             break;
> +     case RTYPE_RSC:
> +             if ((rsc = rsc_parse(&x, fn, buf, len)) == NULL)
> +                     goto out;
> +             break;
> +     default:
> +             errx(1, "%s: unhandled", fn);
> +     }
> +
> +     if (!X509_print(bio_out, x))
> +             errx(1, "X509_print");
> +
> +     if (!PEM_write_bio_X509(bio_out, x))
> +             errx(1, "PEM_write_bio_X509");
> +
> +     rc = 0;
> + out:
> +     BIO_free(bio_out);
> +     free(buf);
> +     X509_free(x);
> +     X509_CRL_free(c);
> +     gbr_free(gbr);
> +     mft_free(mft);
> +     roa_free(roa);
> +     rsc_free(rsc);
> +     return rc;
>  }
> Index: rpki-client.8
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/rpki-client.8,v
> retrieving revision 1.68
> diff -u -p -r1.68 rpki-client.8
> --- rpki-client.8     30 Jun 2022 10:27:52 -0000      1.68
> +++ rpki-client.8     25 Aug 2022 13:00:27 -0000
> @@ -37,6 +37,9 @@
>  .Op Fl t Ar tal
>  .Fl f
>  .Ar
> +.Nm
> +.Fl p
> +.Ar
>  .Sh DESCRIPTION
>  The
>  .Nm
> @@ -144,6 +147,12 @@ If the
>  and
>  .Fl j
>  options are not specified this is the default.
> +.It Fl p Ar
> +Print the encapsulated DER encoded X.509 certificate or CRL in
> +.Ar file
> +in both human-readable and
> +.Em PEM
> +format.
>  .It Fl R
>  Synchronize via RSYNC only.
>  .It Fl r
> 

-- 
:wq Claudio

Reply via email to