aboutsummaryrefslogtreecommitdiffstats
path: root/sm/keylist.c
diff options
context:
space:
mode:
Diffstat (limited to 'sm/keylist.c')
-rw-r--r--sm/keylist.c1252
1 files changed, 0 insertions, 1252 deletions
diff --git a/sm/keylist.c b/sm/keylist.c
deleted file mode 100644
index 27c67ded3..000000000
--- a/sm/keylist.c
+++ /dev/null
@@ -1,1252 +0,0 @@
-/* keylist.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- * 2004 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include "gpgsm.h"
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#include "keydb.h"
-#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
-#include "i18n.h"
-
-struct list_external_parm_s {
- ctrl_t ctrl;
- FILE *fp;
- int print_header;
- int with_colons;
- int with_chain;
- int raw_mode;
-};
-
-
-/* This table is to map Extended Key Usage OIDs to human readable
- names. */
-struct {
- const char *oid;
- const char *name;
-} key_purpose_map[] = {
- { "1.3.6.1.5.5.7.3.1", "serverAuth" },
- { "1.3.6.1.5.5.7.3.2", "clientAuth" },
- { "1.3.6.1.5.5.7.3.3", "codeSigning" },
- { "1.3.6.1.5.5.7.3.4", "emailProtection" },
- { "1.3.6.1.5.5.7.3.5", "ipsecEndSystem" },
- { "1.3.6.1.5.5.7.3.6", "ipsecTunnel" },
- { "1.3.6.1.5.5.7.3.7", "ipsecUser" },
- { "1.3.6.1.5.5.7.3.8", "timeStamping" },
- { "1.3.6.1.5.5.7.3.9", "ocspSigning" },
- { "1.3.6.1.5.5.7.3.10", "dvcs" },
- { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
- { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
- { "1.3.6.1.5.5.7.3.14", "wlanSSID" },
- { NULL, NULL }
-};
-
-
-/* A table mapping OIDs to a descriptive string. */
-static struct {
- char *oid;
- char *name;
- unsigned int flag;
-} oidtranstbl[] = {
-
- /* Algorithms. */
- { "1.2.840.10040.4.1", "dsa" },
- { "1.2.840.10040.4.3", "dsaWithSha1" },
-
- { "1.2.840.113549.1.1.1", "rsaEncryption" },
- { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
- { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
- { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
- { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
- { "1.2.840.113549.1.1.7", "rsaOAEP" },
- { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
- { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
- { "1.2.840.113549.1.1.10", "rsaPSS" },
- { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
- { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
- { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
-
- { "1.3.14.3.2.26", "sha1" },
- { "1.3.14.3.2.29", "sha-1WithRSAEncryption" },
- { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
-
-
- /* Telesec extensions. */
- { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
- { "0.2.262.1.10.12.1", "telesecCertIdExt" },
- { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
- { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
- { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
- { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
- { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
-
- /* PKIX private extensions. */
- { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
- { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
- { "1.3.6.1.5.5.7.1.3", "qcStatements" },
- { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
- { "1.3.6.1.5.5.7.1.5", "acTargeting" },
- { "1.3.6.1.5.5.7.1.6", "acAaControls" },
- { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
- { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
- { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
- { "1.3.6.1.5.5.7.1.10", "acProxying" },
- { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
-
- /* X.509 id-ce */
- { "2.5.29.14", "subjectKeyIdentifier"},
- { "2.5.29.15", "keyUsage", 1 },
- { "2.5.29.16", "privateKeyUsagePeriod" },
- { "2.5.29.17", "subjectAltName", 1 },
- { "2.5.29.18", "issuerAltName", 1 },
- { "2.5.29.19", "basicConstraints", 1},
- { "2.5.29.20", "cRLNumber" },
- { "2.5.29.21", "cRLReason" },
- { "2.5.29.22", "expirationDate" },
- { "2.5.29.23", "instructionCode" },
- { "2.5.29.24", "invalidityDate" },
- { "2.5.29.27", "deltaCRLIndicator" },
- { "2.5.29.28", "issuingDistributionPoint" },
- { "2.5.29.29", "certificateIssuer" },
- { "2.5.29.30", "nameConstraints" },
- { "2.5.29.31", "cRLDistributionPoints", 1 },
- { "2.5.29.32", "certificatePolicies", 1 },
- { "2.5.29.32.0", "anyPolicy" },
- { "2.5.29.33", "policyMappings" },
- { "2.5.29.35", "authorityKeyIdentifier", 1 },
- { "2.5.29.36", "policyConstraints" },
- { "2.5.29.37", "extKeyUsage", 1 },
- { "2.5.29.46", "freshestCRL" },
- { "2.5.29.54", "inhibitAnyPolicy" },
-
- /* Netscape certificate extensions. */
- { "2.16.840.1.113730.1.1", "netscape-cert-type" },
- { "2.16.840.1.113730.1.2", "netscape-base-url" },
- { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
- { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
- { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
- { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
- { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
- { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
- { "2.16.840.1.113730.1.11", "netscape-userPicture" },
- { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
- { "2.16.840.1.113730.1.13", "netscape-comment" },
-
- { NULL }
-};
-
-
-/* Return the description for OID; if no description is available
- NULL is returned. */
-static const char *
-get_oid_desc (const char *oid, unsigned int *flag)
-{
- int i;
-
- if (oid)
- for (i=0; oidtranstbl[i].oid; i++)
- if (!strcmp (oidtranstbl[i].oid, oid))
- {
- if (flag)
- *flag = oidtranstbl[i].flag;
- return oidtranstbl[i].name;
- }
- if (flag)
- *flag = 0;
- return NULL;
-}
-
-
-static void
-print_key_data (ksba_cert_t cert, FILE *fp)
-{
-#if 0
- int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
- int i;
-
- for(i=0; i < n; i++ )
- {
- fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
- mpi_print(stdout, pk->pkey[i], 1 );
- putchar(':');
- putchar('\n');
- }
-#endif
-}
-
-static void
-print_capabilities (ksba_cert_t cert, FILE *fp)
-{
- gpg_error_t err;
- unsigned int use;
-
- err = ksba_cert_get_key_usage (cert, &use);
- if (gpg_err_code (err) == GPG_ERR_NO_DATA)
- {
- putc ('e', fp);
- putc ('s', fp);
- putc ('c', fp);
- putc ('E', fp);
- putc ('S', fp);
- putc ('C', fp);
- return;
- }
- if (err)
- {
- log_error (_("error getting key usage information: %s\n"),
- gpg_strerror (err));
- return;
- }
-
- if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
- putc ('e', fp);
- if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
- putc ('s', fp);
- if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
- putc ('c', fp);
- if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
- putc ('E', fp);
- if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
- putc ('S', fp);
- if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
- putc ('C', fp);
-}
-
-
-static void
-print_time (gnupg_isotime_t t, FILE *fp)
-{
- if (!t || !*t)
- ;
- else
- fputs (t, fp);
-}
-
-
-/* return an allocated string with the email address extracted from a
- DN */
-static char *
-email_kludge (const char *name)
-{
- const unsigned char *p;
- unsigned char *buf;
- int n;
-
- if (strncmp (name, "1.2.840.113549.1.9.1=#", 22))
- return NULL;
- /* This looks pretty much like an email address in the subject's DN
- we use this to add an additional user ID entry. This way,
- openSSL generated keys get a nicer and usable listing */
- name += 22;
- for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
- ;
- if (*p != '#' || !n)
- return NULL;
- buf = xtrymalloc (n+3);
- if (!buf)
- return NULL; /* oops, out of core */
- *buf = '<';
- for (n=1, p=name; *p != '#'; p +=2, n++)
- buf[n] = xtoi_2 (p);
- buf[n++] = '>';
- buf[n] = 0;
- return buf;
-}
-
-
-
-
-/* List one certificate in colon mode */
-static void
-list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
- FILE *fp, int have_secret)
-{
- int rc;
- int idx;
- char truststring[2];
- char *p;
- ksba_sexp_t sexp;
- char *fpr;
- ksba_isotime_t t;
- gpg_error_t valerr;
- int algo;
- unsigned int nbits;
- const char *chain_id;
- char *chain_id_buffer = NULL;
- int is_root = 0;
-
- if (ctrl->with_validation)
- valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
- else
- valerr = 0;
-
-
- /* We need to get the fingerprint and the chaining ID in advance. */
- fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
- {
- ksba_cert_t next;
-
- rc = gpgsm_walk_cert_chain (cert, &next);
- if (!rc) /* We known the issuer's certificate. */
- {
- p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
- chain_id_buffer = p;
- chain_id = chain_id_buffer;
- ksba_cert_release (next);
- }
- else if (rc == -1) /* We have reached the root certificate. */
- {
- chain_id = fpr;
- is_root = 1;
- }
- else
- chain_id = NULL;
- }
-
-
- fputs (have_secret? "crs:":"crt:", fp);
- truststring[0] = 0;
- truststring[1] = 0;
- if ((validity & VALIDITY_REVOKED)
- || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
- *truststring = 'r';
- else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
- *truststring = 'e';
- else if (valerr)
- *truststring = 'i';
- else
- {
- /* Lets also check whether the certificate under question
- expired. This is merely a hack until we found a proper way
- to store the expiration flag in the keybox. */
- ksba_isotime_t current_time, not_after;
-
- gnupg_get_isotime (current_time);
- if (!opt.ignore_expiration
- && !ksba_cert_get_validity (cert, 1, not_after)
- && *not_after && strcmp (current_time, not_after) > 0 )
- *truststring = 'e';
- }
-
- /* Is we have no truststring yet (i.e. the certificate might be
- good) and this is a root certificate, we ask the agent whether
- this is a trusted root certificate. */
- if (!*truststring && is_root)
- {
- rc = gpgsm_agent_istrusted (ctrl, cert);
- if (!rc)
- *truststring = 'u'; /* Yes, we trust this one (ultimately). */
- else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
- *truststring = 'n'; /* No, we do not trust this one. */
- /* (in case of an error we can't tell anything.) */
- }
-
- if (*truststring)
- fputs (truststring, fp);
-
- algo = gpgsm_get_key_algo_info (cert, &nbits);
- fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
-
- /* We assume --fixed-list-mode for gpgsm */
- ksba_cert_get_validity (cert, 0, t);
- print_time (t, fp);
- putc (':', fp);
- ksba_cert_get_validity (cert, 1, t);
- print_time ( t, fp);
- putc (':', fp);
- /* Field 8, serial number: */
- if ((sexp = ksba_cert_get_serial (cert)))
- {
- int len;
- const unsigned char *s = sexp;
-
- if (*s == '(')
- {
- s++;
- for (len=0; *s && *s != ':' && digitp (s); s++)
- len = len*10 + atoi_1 (s);
- if (*s == ':')
- for (s++; len; len--, s++)
- fprintf (fp,"%02X", *s);
- }
- xfree (sexp);
- }
- putc (':', fp);
- /* Field 9, ownertrust - not used here */
- putc (':', fp);
- /* field 10, old user ID - we use it here for the issuer DN */
- if ((p = ksba_cert_get_issuer (cert,0)))
- {
- print_sanitized_string (fp, p, ':');
- xfree (p);
- }
- putc (':', fp);
- /* Field 11, signature class - not used */
- putc (':', fp);
- /* Field 12, capabilities: */
- print_capabilities (cert, fp);
- putc (':', fp);
- putc ('\n', fp);
-
- /* FPR record */
- fprintf (fp, "fpr:::::::::%s:::", fpr);
- /* Print chaining ID (field 13)*/
- if (chain_id)
- fputs (chain_id, fp);
- putc (':', fp);
- putc ('\n', fp);
- xfree (fpr); fpr = NULL; chain_id = NULL;
- xfree (chain_id_buffer); chain_id_buffer = NULL;
-
- if (opt.with_key_data)
- {
- if ( (p = gpgsm_get_keygrip_hexstring (cert)))
- {
- fprintf (fp, "grp:::::::::%s:\n", p);
- xfree (p);
- }
- print_key_data (cert, fp);
- }
-
- for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
- {
- fprintf (fp, "uid:%s::::::::", truststring);
- print_sanitized_string (fp, p, ':');
- putc (':', fp);
- putc (':', fp);
- putc ('\n', fp);
- if (!idx)
- {
- /* It would be better to get the faked email address from
- the keydb. But as long as we don't have a way to pass
- the meta data back, we just check it the same way as the
- code used to create the keybox meta data does */
- char *pp = email_kludge (p);
- if (pp)
- {
- fprintf (fp, "uid:%s::::::::", truststring);
- print_sanitized_string (fp, pp, ':');
- putc (':', fp);
- putc (':', fp);
- putc ('\n', fp);
- xfree (pp);
- }
- }
- xfree (p);
- }
-}
-
-
-static void
-print_name_raw (FILE *fp, const char *string)
-{
- if (!string)
- fputs ("[error]", fp);
- else
- print_sanitized_string (fp, string, 0);
-}
-
-static void
-print_names_raw (FILE *fp, int indent, ksba_name_t name)
-{
- int idx;
- const char *s;
- int indent_all;
-
- if ((indent_all = (indent < 0)))
- indent = - indent;
-
- if (!name)
- {
- fputs ("none\n", fp);
- return;
- }
-
- for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
- {
- char *p = ksba_name_get_uri (name, idx);
- printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s);
- xfree (p);
- }
-}
-
-
-/* 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;
- size_t off, len;
- ksba_sexp_t sexp;
- char *dn;
- ksba_isotime_t t;
- int idx, i;
- int is_ca, chainlen;
- unsigned int kusage;
- char *string, *p, *pend;
- const char *oid, *s;
- ksba_name_t name, name2;
- unsigned int reason;
-
- 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);
- print_name_raw (fp, dn);
- ksba_free (dn);
- putc ('\n', fp);
- for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
- {
- fputs (" aka: ", fp);
- print_name_raw (fp, dn);
- ksba_free (dn);
- putc ('\n', fp);
- }
-
- dn = ksba_cert_get_subject (cert, 0);
- fputs (" Subject: ", fp);
- print_name_raw (fp, dn);
- ksba_free (dn);
- putc ('\n', fp);
- for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
- {
- fputs (" aka: ", fp);
- print_name_raw (fp, dn);
- ksba_free (dn);
- putc ('\n', fp);
- }
-
- dn = gpgsm_get_fingerprint_string (cert, 0);
- fprintf (fp, " sha1_fpr: %s\n", dn?dn:"error");
- xfree (dn);
-
- dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
- fprintf (fp, " md5_fpr: %s\n", dn?dn:"error");
- xfree (dn);
-
- ksba_cert_get_validity (cert, 0, t);
- fputs (" notBefore: ", fp);
- gpgsm_print_time (fp, t);
- putc ('\n', fp);
- fputs (" notAfter: ", fp);
- ksba_cert_get_validity (cert, 1, t);
- gpgsm_print_time (fp, t);
- putc ('\n', fp);
-
- oid = ksba_cert_get_digest_algo (cert);
- s = get_oid_desc (oid, NULL);
- fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
-
- {
- const char *algoname;
- unsigned int nbits;
-
- algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
- fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?");
- }
-
- /* authorityKeyIdentifier */
- fputs (" authKeyId: ", fp);
- err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp);
- if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
- {
- if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
- fputs ("[none]\n", fp);
- else
- {
- gpgsm_print_serial (fp, sexp);
- ksba_free (sexp);
- putc ('\n', fp);
- print_names_raw (fp, -15, name);
- ksba_name_release (name);
- }
- }
- else
- fputs ("[?]\n", fp);
-
- fputs (" keyUsage:", fp);
- err = ksba_cert_get_key_usage (cert, &kusage);
- if (gpg_err_code (err) != GPG_ERR_NO_DATA)
- {
- 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);
- }
- else
- fputs ("[none]\n", fp);
-
- fputs (" extKeyUsage: ", fp);
- err = ksba_cert_get_ext_key_usages (cert, &string);
- if (gpg_err_code (err) != GPG_ERR_NO_DATA)
- {
- 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 ("\n ", fp);
- }
- }
- xfree (string);
- }
- putc ('\n', fp);
- }
- else
- fputs ("[none]\n", fp);
-
-
- fputs (" policies: ", fp);
- err = ksba_cert_get_cert_policies (cert, &string);
- if (gpg_err_code (err) != GPG_ERR_NO_DATA)
- {
- 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 (p, fp);
- p = pend;
- if (*p == 'C')
- fputs (" (critical)", fp);
- if ((p = strchr (p, '\n')))
- {
- p++;
- fputs ("\n ", fp);
- }
- }
- xfree (string);
- }
- putc ('\n', fp);
- }
- else
- fputs ("[none]\n", fp);
-
- fputs (" chainLength: ", fp);
- err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
- if (err || is_ca)
- {
- if (err)
- fprintf (fp, "[error: %s]", gpg_strerror (err));
- else if (chainlen == -1)
- fputs ("unlimited", fp);
- else
- fprintf (fp, "%d", chainlen);
- putc ('\n', fp);
- }
- else
- fputs ("not a CA\n", fp);
-
-
- /* CRL distribution point */
- for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
- &reason)) ;idx++)
- {
- fputs (" crlDP: ", fp);
- print_names_raw (fp, 15, name);
- if (reason)
- {
- fputs (" reason: ", fp);
- if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
- fputs (" unused", stdout);
- if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
- fputs (" keyCompromise", stdout);
- if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
- fputs (" caCompromise", stdout);
- if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
- fputs (" affiliationChanged", stdout);
- if ( (reason & KSBA_CRLREASON_SUPERSEDED))
- fputs (" superseded", stdout);
- if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
- fputs (" cessationOfOperation", stdout);
- if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
- fputs (" certificateHold", stdout);
- putchar ('\n');
- }
- fputs (" issuer: ", fp);
- print_names_raw (fp, 23, name2);
- ksba_name_release (name);
- ksba_name_release (name2);
- }
- if (err && gpg_err_code (err) != GPG_ERR_EOF)
- fputs (" crlDP: [error]\n", fp);
- else if (!idx)
- fputs (" crlDP: [none]\n", fp);
-
-
- /* authorityInfoAccess. */
- for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
- &name)); idx++)
- {
- fputs (" authInfo: ", fp);
- s = get_oid_desc (string, NULL);
- fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
- print_names_raw (fp, -15, name);
- ksba_name_release (name);
- ksba_free (string);
- }
- if (err && gpg_err_code (err) != GPG_ERR_EOF)
- fputs (" authInfo: [error]\n", fp);
- else if (!idx)
- fputs (" authInfo: [none]\n", fp);
-
- /* subjectInfoAccess. */
- for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
- &name)); idx++)
- {
- fputs (" subjectInfo: ", fp);
- s = get_oid_desc (string, NULL);
- fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
- print_names_raw (fp, -15, name);
- ksba_name_release (name);
- ksba_free (string);
- }
- if (err && gpg_err_code (err) != GPG_ERR_EOF)
- fputs (" subjInfo: [error]\n", fp);
- else if (!idx)
- fputs (" subjInfo: [none]\n", fp);
-
-
- for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
- &oid, &i, &off, &len));idx++)
- {
- unsigned int flag;
-
- s = get_oid_desc (oid, &flag);
-
- if (!(flag & 1))
- fprintf (fp, " %s: %s%s%s%s [%d octets]\n",
- i? "critExtn":" extn",
- oid, s?" (":"", s?s:"", s?")":"", (int)len);
- }
-
-
- 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,
- 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);
-
-
- {
- const char *algoname;
- unsigned int nbits;
-
- algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
- fprintf (fp, " key type: %u bit %s\n", nbits, algoname? algoname:"?");
- }
-
-
- 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);
- }
-
- if (opt.with_md5_fingerprint)
- {
- 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));
- }
-}
-
-
-/* Same as standard mode mode list all certifying certs too. */
-static void
-list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, int raw_mode,
- FILE *fp, int with_validation)
-{
- ksba_cert_t next = NULL;
-
- 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);
- 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);
- putc ('\n', fp);
-}
-
-
-
-/* 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_t ctrl, STRLIST names, FILE *fp,
- unsigned int mode, int raw_mode)
-{
- KEYDB_HANDLE hd;
- KEYDB_SEARCH_DESC *desc = NULL;
- STRLIST sl;
- int ndesc;
- ksba_cert_t cert = NULL;
- gpg_error_t rc = 0;
- const char *lastresname, *resname;
- int have_secret;
-
- hd = keydb_new (0);
- if (!hd)
- {
- log_error ("keydb_new failed\n");
- rc = gpg_error (GPG_ERR_GENERAL);
- goto leave;
- }
-
- if (!names)
- ndesc = 1;
- else
- {
- for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
- ;
- }
-
- desc = xtrycalloc (ndesc, sizeof *desc);
- if (!ndesc)
- {
- rc = gpg_error_from_errno (errno);
- log_error ("out of core\n");
- goto leave;
- }
-
- if (!names)
- desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
- else
- {
- for (ndesc=0, sl=names; sl; sl = sl->next)
- {
- rc = keydb_classify_name (sl->d, desc+ndesc);
- if (rc)
- {
- log_error ("key `%s' not found: %s\n",
- sl->d, gpg_strerror (rc));
- rc = 0;
- }
- else
- ndesc++;
- }
-
- }
-
- /* It would be nice to see which of the given users did actually
- match one in the keyring. To implement this we need to have a
- found flag for each entry in desc and to set this we must check
- all those entries after a match to mark all matched one -
- currently we stop at the first match. To do this we need an
- extra flag to enable this feature so */
-
- lastresname = NULL;
- while (!(rc = keydb_search (hd, desc, ndesc)))
- {
- unsigned int validity;
-
- if (!names)
- desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
-
- rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
- if (rc)
- {
- log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
- goto leave;
- }
- rc = keydb_get_cert (hd, &cert);
- if (rc)
- {
- log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
- goto leave;
- }
-
- resname = keydb_get_resource_name (hd);
-
- if (lastresname != resname )
- {
- int i;
-
- if (ctrl->no_server)
- {
- fprintf (fp, "%s\n", resname );
- for (i=strlen(resname); i; i-- )
- putchar('-');
- putc ('\n', fp);
- lastresname = resname;
- }
- }
-
- have_secret = 0;
- if (mode)
- {
- char *p = gpgsm_get_keygrip_hexstring (cert);
- if (p)
- {
- rc = gpgsm_agent_havekey (ctrl, p);
- if (!rc)
- have_secret = 1;
- else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
- goto leave;
- rc = 0;
- xfree (p);
- }
- }
-
- if (!mode
- || ((mode & 1) && !have_secret)
- || ((mode & 2) && have_secret) )
- {
- if (ctrl->with_colons)
- list_cert_colon (ctrl, cert, validity, fp, have_secret);
- else if (ctrl->with_chain)
- list_cert_chain (ctrl, cert, raw_mode, fp, ctrl->with_validation);
- else
- {
- 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);
- }
- }
- ksba_cert_release (cert);
- cert = NULL;
- }
- if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
- rc = 0;
- if (rc)
- log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
-
- leave:
- ksba_cert_release (cert);
- xfree (desc);
- keydb_release (hd);
- return rc;
-}
-
-
-
-static void
-list_external_cb (void *cb_value, ksba_cert_t cert)
-{
- struct list_external_parm_s *parm = cb_value;
-
- if (keydb_store_cert (cert, 1, NULL))
- log_error ("error storing certificate as ephemeral\n");
-
- if (parm->print_header)
- {
- const char *resname = "[external keys]";
- int i;
-
- fprintf (parm->fp, "%s\n", resname );
- for (i=strlen(resname); i; i-- )
- putchar('-');
- putc ('\n', parm->fp);
- parm->print_header = 0;
- }
-
- 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->raw_mode, parm->fp, 0);
- else
- {
- 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);
- }
-}
-
-
-/* List external keys similar to internal one. Note: mode does not
- 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, int raw_mode)
-{
- int rc;
- struct list_external_parm_s parm;
-
- parm.fp = fp;
- parm.ctrl = ctrl,
- 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)
- log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
- return rc;
-}
-
-/* List all keys or just the key given as NAMES.
- MODE controls the operation mode:
- Bit 0-2:
- 0 = list all public keys but don't flag secret ones
- 1 = list only public keys
- 2 = list only secret keys
- 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)
-{
- gpg_error_t err = 0;
-
- if ((mode & (1<<6)))
- err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
- if (!err && (mode & (1<<7)))
- err = list_external_keys (ctrl, names, fp, (mode&256));
- return err;
-}