diff options
Diffstat (limited to 'sm/keylist.c')
-rw-r--r-- | sm/keylist.c | 1252 |
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; -} |