summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sm/ChangeLog5
-rw-r--r--sm/certdump.c1
-rw-r--r--sm/gpgsm.c32
-rw-r--r--sm/keylist.c216
4 files changed, 241 insertions, 13 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 02f627a4d..796098f9d 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,8 @@
+2004-04-22 Werner Koch <wk@gnupg.org>
+
+ * gpgsm.c (main): New commands --dump-keys, --dump-external-keys,
+ --dump-secret-keys.
+
2004-04-13 Werner Koch <wk@gnupg.org>
* misc.c (setup_pinentry_env): New.
diff --git a/sm/certdump.c b/sm/certdump.c
index aefaf27ef..21581dca3 100644
--- a/sm/certdump.c
+++ b/sm/certdump.c
@@ -184,6 +184,7 @@ gpgsm_dump_string (const char *string)
}
+/* This simple dump function is mainly used for debugging purposes. */
void
gpgsm_dump_cert (const char *text, ksba_cert_t cert)
{
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 7140e34ac..322f893a4 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -82,6 +82,9 @@ enum cmd_and_opt_values {
aCallProtectTool,
aPasswd,
aGPGConfList,
+ aDumpKeys,
+ aDumpSecretKeys,
+ aDumpExternalKeys,
oOptions,
oDebug,
@@ -246,6 +249,10 @@ static ARGPARSE_OPTS opts[] = {
{ aPasswd, "passwd", 256, N_("change a passphrase")},
{ aGPGConfList, "gpgconf-list", 256, "@" },
+ { aDumpKeys, "dump-keys", 256, "@"},
+ { aDumpExternalKeys, "dump-external-keys", 256, "@"},
+ { aDumpSecretKeys, "dump-secret-keys", 256, "@"},
+
{ 301, NULL, 0, N_("@\nOptions:\n ") },
{ oArmor, "armor", 0, N_("create ascii armored output")},
@@ -878,6 +885,9 @@ main ( int argc, char **argv)
case aRecvKeys:
case aExport:
case aExportSecretKeyP12:
+ case aDumpKeys:
+ case aDumpExternalKeys:
+ case aDumpSecretKeys:
case aListKeys:
case aListExternalKeys:
case aListSecretKeys:
@@ -1416,6 +1426,13 @@ main ( int argc, char **argv)
free_strlist(sl);
break;
+ case aDumpKeys:
+ for (sl=NULL; argc; argc--, argv++)
+ add_to_strlist (&sl, *argv);
+ gpgsm_list_keys (&ctrl, sl, stdout, (256 | (1<<6)));
+ free_strlist(sl);
+ break;
+
case aListExternalKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
@@ -1424,6 +1441,14 @@ main ( int argc, char **argv)
free_strlist(sl);
break;
+ case aDumpExternalKeys:
+ for (sl=NULL; argc; argc--, argv++)
+ add_to_strlist (&sl, *argv);
+ gpgsm_list_keys (&ctrl, sl, stdout,
+ (256 | (1<<7)));
+ free_strlist(sl);
+ break;
+
case aListSecretKeys:
for (sl=NULL; argc; argc--, argv++)
add_to_strlist (&sl, *argv);
@@ -1431,6 +1456,13 @@ main ( int argc, char **argv)
free_strlist(sl);
break;
+ case aDumpSecretKeys:
+ for (sl=NULL; argc; argc--, argv++)
+ add_to_strlist (&sl, *argv);
+ gpgsm_list_keys (&ctrl, sl, stdout, (256 | 2 | (1<<6)));
+ free_strlist(sl);
+ break;
+
case aKeygen: /* generate a key */
log_error ("this function is not yet available from the commandline\n");
break;
diff --git a/sm/keylist.c b/sm/keylist.c
index 4e6f28db8..74a5e623a 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -43,6 +43,7 @@ struct list_external_parm_s {
int print_header;
int with_colons;
int with_chain;
+ int raw_mode;
};
@@ -324,6 +325,175 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
}
+/* List one certificate in raw mode useful to have a closer look at
+ the certificate. This one does not beautification and only minimal
+ output sanitation. It is mainly useful for debugging. */
+static void
+list_cert_raw (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
+ int with_validation)
+{
+ gpg_error_t err;
+ ksba_sexp_t sexp;
+ char *dn;
+ ksba_isotime_t t;
+ int idx, i;
+ int is_ca, chainlen;
+ unsigned int kusage;
+ char *string, *p, *pend;
+
+ sexp = ksba_cert_get_serial (cert);
+ fputs ("Serial number: ", fp);
+ gpgsm_print_serial (fp, sexp);
+ ksba_free (sexp);
+ putc ('\n', fp);
+
+ dn = ksba_cert_get_issuer (cert, 0);
+ fputs (" Issuer: ", fp);
+ gpgsm_print_name (fp, dn);
+ ksba_free (dn);
+ putc ('\n', fp);
+ for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
+ {
+ fputs (" aka: ", fp);
+ gpgsm_print_name (fp, dn);
+ ksba_free (dn);
+ putc ('\n', fp);
+ }
+
+ dn = ksba_cert_get_subject (cert, 0);
+ fputs (" Subject: ", fp);
+ gpgsm_print_name (fp, dn);
+ ksba_free (dn);
+ putc ('\n', fp);
+ for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
+ {
+ fputs (" aka: ", fp);
+ gpgsm_print_name (fp, dn);
+ ksba_free (dn);
+ putc ('\n', fp);
+ }
+
+ ksba_cert_get_validity (cert, 0, t);
+ fputs (" validity: ", fp);
+ gpgsm_print_time (fp, t);
+ fputs (" through ", fp);
+ ksba_cert_get_validity (cert, 1, t);
+ gpgsm_print_time (fp, t);
+ putc ('\n', fp);
+
+ err = ksba_cert_get_key_usage (cert, &kusage);
+ if (gpg_err_code (err) != GPG_ERR_NO_DATA)
+ {
+ fputs (" key usage:", fp);
+ if (err)
+ fprintf (fp, " [error: %s]", gpg_strerror (err));
+ else
+ {
+ if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
+ fputs (" digitalSignature", fp);
+ if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
+ fputs (" nonRepudiation", fp);
+ if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
+ fputs (" keyEncipherment", fp);
+ if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
+ fputs (" dataEncipherment", fp);
+ if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
+ fputs (" keyAgreement", fp);
+ if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
+ fputs (" certSign", fp);
+ if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
+ fputs (" crlSign", fp);
+ if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
+ fputs (" encipherOnly", fp);
+ if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
+ fputs (" decipherOnly", fp);
+ }
+ putc ('\n', fp);
+ }
+
+ err = ksba_cert_get_ext_key_usages (cert, &string);
+ if (gpg_err_code (err) != GPG_ERR_NO_DATA)
+ {
+ fputs ("ext key usage: ", fp);
+ if (err)
+ fprintf (fp, "[error: %s]", gpg_strerror (err));
+ else
+ {
+ p = string;
+ while (p && (pend=strchr (p, ':')))
+ {
+ *pend++ = 0;
+ for (i=0; key_purpose_map[i].oid; i++)
+ if ( !strcmp (key_purpose_map[i].oid, p) )
+ break;
+ fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
+ p = pend;
+ if (*p != 'C')
+ fputs (" (suggested)", fp);
+ if ((p = strchr (p, '\n')))
+ {
+ p++;
+ fputs (", ", fp);
+ }
+ }
+ xfree (string);
+ }
+ putc ('\n', fp);
+ }
+
+ err = ksba_cert_get_cert_policies (cert, &string);
+ if (gpg_err_code (err) != GPG_ERR_NO_DATA)
+ {
+ fputs (" policies: ", fp);
+ if (err)
+ fprintf (fp, "[error: %s]", gpg_strerror (err));
+ else
+ {
+ for (p=string; *p; p++)
+ {
+ if (*p == '\n')
+ *p = ',';
+ }
+ print_sanitized_string (fp, string, 0);
+ xfree (string);
+ }
+ putc ('\n', fp);
+ }
+
+ err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
+ if (err || is_ca)
+ {
+ fputs (" chain length: ", fp);
+ if (err)
+ fprintf (fp, "[error: %s]", gpg_strerror (err));
+ else if (chainlen == -1)
+ fputs ("unlimited", fp);
+ else
+ fprintf (fp, "%d", chainlen);
+ putc ('\n', fp);
+ }
+
+ dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
+ fprintf (fp, " md5 fpr: %s\n", dn?dn:"error");
+ xfree (dn);
+
+ dn = gpgsm_get_fingerprint_string (cert, 0);
+ fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
+ xfree (dn);
+
+ if (with_validation)
+ {
+ err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
+ if (!err)
+ fprintf (fp, " [certificate is good]\n");
+ else
+ fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
+ }
+}
+
+
+
+
/* List one certificate in standard mode */
static void
list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
@@ -494,17 +664,24 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
/* Same as standard mode mode list all certifying certs too. */
static void
-list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int with_validation)
+list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, int raw_mode,
+ FILE *fp, int with_validation)
{
ksba_cert_t next = NULL;
- list_cert_std (ctrl, cert, fp, 0, with_validation);
+ if (raw_mode)
+ list_cert_raw (ctrl, cert, fp, 0, with_validation);
+ else
+ list_cert_std (ctrl, cert, fp, 0, with_validation);
ksba_cert_ref (cert);
while (!gpgsm_walk_cert_chain (cert, &next))
{
ksba_cert_release (cert);
fputs ("Certified by\n", fp);
- list_cert_std (ctrl, next, fp, 0, with_validation);
+ if (raw_mode)
+ list_cert_raw (ctrl, next, fp, 0, with_validation);
+ else
+ list_cert_std (ctrl, next, fp, 0, with_validation);
cert = next;
}
ksba_cert_release (cert);
@@ -513,10 +690,14 @@ list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int with_validation)
-/* List all internal keys or just the key given as NAMES.
+/* List all internal keys or just the keys given as NAMES. MODE is a
+ bit vector to specify what keys are to be included; see
+ gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
+ output mode will be used intead of the standard beautified one.
*/
static gpg_error_t
-list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
+list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp,
+ unsigned int mode, int raw_mode)
{
KEYDB_HANDLE hd;
KEYDB_SEARCH_DESC *desc = NULL;
@@ -637,11 +818,15 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
if (ctrl->with_colons)
list_cert_colon (ctrl, cert, validity, fp, have_secret);
else if (ctrl->with_chain)
- list_cert_chain (ctrl, cert, fp, ctrl->with_validation);
+ list_cert_chain (ctrl, cert, raw_mode, fp, ctrl->with_validation);
else
{
- list_cert_std (ctrl, cert, fp, have_secret,
- ctrl->with_validation);
+ if (raw_mode)
+ list_cert_raw (ctrl, cert, fp, have_secret,
+ ctrl->with_validation);
+ else
+ list_cert_std (ctrl, cert, fp, have_secret,
+ ctrl->with_validation);
putc ('\n', fp);
}
}
@@ -685,10 +870,13 @@ list_external_cb (void *cb_value, ksba_cert_t cert)
if (parm->with_colons)
list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
else if (parm->with_chain)
- list_cert_chain (parm->ctrl, cert, parm->fp, 0);
+ list_cert_chain (parm->ctrl, cert, parm->raw_mode, parm->fp, 0);
else
{
- list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
+ if (parm->raw_mode)
+ list_cert_raw (parm->ctrl, cert, parm->fp, 0, 0);
+ else
+ list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
putc ('\n', parm->fp);
}
}
@@ -698,7 +886,7 @@ list_external_cb (void *cb_value, ksba_cert_t cert)
make sense here because it would be unwise to list external secret
keys */
static gpg_error_t
-list_external_keys (CTRL ctrl, STRLIST names, FILE *fp)
+list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode)
{
int rc;
struct list_external_parm_s parm;
@@ -708,6 +896,7 @@ list_external_keys (CTRL ctrl, STRLIST names, FILE *fp)
parm.print_header = ctrl->no_server;
parm.with_colons = ctrl->with_colons;
parm.with_chain = ctrl->with_chain;
+ parm.raw_mode = raw_mode;
rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
if (rc)
@@ -724,6 +913,7 @@ list_external_keys (CTRL ctrl, STRLIST names, FILE *fp)
3 = list secret and public keys
Bit 6: list internal keys
Bit 7: list external keys
+ Bit 8: Do a raw format dump.
*/
gpg_error_t
gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
@@ -731,8 +921,8 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
gpg_error_t err = 0;
if ((mode & (1<<6)))
- err = list_internal_keys (ctrl, names, fp, (mode & 3));
+ err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
if (!err && (mode & (1<<7)))
- err = list_external_keys (ctrl, names, fp);
+ err = list_external_keys (ctrl, names, fp, (mode&256));
return err;
}