sm: New command --show-certs

* sm/keylist.c (do_show_certs): New.
(gpgsm_show_certs): New.
* sm/gpgsm.c (aShowCerts): New.
(opts): Add --show-certs.
(main): Call gpgsm_show_certs.
--

I have been using libksba test programs for countless times to look at
certificates and I always wanted to add such a feature to gpgsm.  This
is simply much more convenient.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-04-20 09:37:56 +02:00
parent 5fe60576d5
commit 51419d6341
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 120 additions and 0 deletions

View File

@ -221,6 +221,17 @@ List certificates matching @var{pattern} using an external server.
This utilizes the @code{dirmngr} service. It uses a format useful
mainly for debugging.
@item --show-certs [@var{files}]
@opindex show-certs
This command takes certificate files as input and prints information
about them in the same format as @option{--dump-cert} does. Each file
may either contain a single binary certificate or several PEM encoded
certificates. If no files are given, the input is taken from stdin.
Please note that the listing format may be changed in future releases
and that the option @option{--with-colons} has currently no effect.
@item --keydb-clear-some-cert-flags
@opindex keydb-clear-some-cert-flags
This is a debugging aid to reset certain flags in the key database

View File

@ -96,6 +96,7 @@ enum cmd_and_opt_values {
aDumpChain,
aDumpSecretKeys,
aDumpExternalKeys,
aShowCerts,
aKeydbClearSomeCertFlags,
aFingerprint,
@ -252,6 +253,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
ARGPARSE_c (aShowCerts, "show-certs", "@"),
ARGPARSE_c (aDumpKeys, "dump-cert", "@"),
ARGPARSE_c (aDumpKeys, "dump-keys", "@"),
ARGPARSE_c (aDumpChain, "dump-chain", "@"),
@ -1212,6 +1214,7 @@ main ( int argc, char **argv)
case aExportSecretKeyP12:
case aExportSecretKeyP8:
case aExportSecretKeyRaw:
case aShowCerts:
case aDumpKeys:
case aDumpChain:
case aDumpExternalKeys:
@ -2121,6 +2124,15 @@ main ( int argc, char **argv)
}
break;
case aShowCerts:
{
estream_t fp;
fp = open_es_fwrite (opt.outfile?opt.outfile:"-");
gpgsm_show_certs (&ctrl, argc, argv, fp);
es_fclose (fp);
}
break;
case aKeygen: /* Generate a key; well kind of. */
{

View File

@ -389,6 +389,8 @@ int gpgsm_find_cert (ctrl_t ctrl, const char *name, ksba_sexp_t keyid,
/*-- keylist.c --*/
gpg_error_t gpgsm_list_keys (ctrl_t ctrl, strlist_t names,
estream_t fp, unsigned int mode);
gpg_error_t gpgsm_show_certs (ctrl_t ctrl, int nfiles, char **files,
estream_t fp);
/*-- import.c --*/
int gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode);

View File

@ -1710,3 +1710,98 @@ gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
err = list_external_keys (ctrl, names, fp, (mode&256));
return err;
}
static gpg_error_t
do_show_certs (ctrl_t ctrl, const char *fname, estream_t outfp)
{
gpg_error_t err;
gnupg_ksba_io_t b64reader = NULL;
ksba_reader_t reader;
ksba_cert_t cert = NULL;
estream_t fp;
int any = 0;
if (!fname || (fname[0] == '-' && !fname[1]))
{
fp = es_stdin;
fname = "[stdin]";
}
else
{
fp = es_fopen (fname, "rb");
if (!fp)
{
err = gpg_error_from_syserror ();
log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
return err;
}
}
err = gnupg_ksba_create_reader
(&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0)
| (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0)
| (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0)
| GNUPG_KSBA_IO_MULTIPEM),
fp, &reader);
if (err)
{
log_error ("can't create reader: %s\n", gpg_strerror (err));
goto leave;
}
/* We need to loop here to handle multiple PEM objects per file. */
do
{
ksba_cert_release (cert); cert = NULL;
err = ksba_cert_new (&cert);
if (err)
goto leave;
err = ksba_cert_read_der (cert, reader);
if (err)
goto leave;
es_fprintf (outfp, "File ........: %s\n", fname);
list_cert_raw (ctrl, NULL, cert, outfp, 0, 0);
es_putc ('\n', outfp);
any = 1;
ksba_reader_clear (reader, NULL, NULL);
}
while (!gnupg_ksba_reader_eof_seen (b64reader));
leave:
if (any && gpg_err_code (err) == GPG_ERR_EOF)
err = 0;
ksba_cert_release (cert);
gnupg_ksba_destroy_reader (b64reader);
if (fp != es_stdin)
es_fclose (fp);
return err;
}
/* Show a raw dump of the certificates found in the files given in
* the arrag FILES. Write output to FP. */
gpg_error_t
gpgsm_show_certs (ctrl_t ctrl, int nfiles, char **files, estream_t fp)
{
gpg_error_t saveerr = 0;
gpg_error_t err;
if (!nfiles)
saveerr = do_show_certs (ctrl, NULL, fp);
else
{
for (; nfiles; nfiles--, files++)
{
err = do_show_certs (ctrl, *files, fp);
if (err && !saveerr)
saveerr = err;
}
}
return saveerr;
}