1 /* keylist.c - Print certificates in various formats.
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3 * 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
36 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
40 struct list_external_parm_s
51 /* This table is to map Extended Key Usage OIDs to human readable
57 } key_purpose_map
[] = {
58 { "1.3.6.1.5.5.7.3.1", "serverAuth" },
59 { "1.3.6.1.5.5.7.3.2", "clientAuth" },
60 { "1.3.6.1.5.5.7.3.3", "codeSigning" },
61 { "1.3.6.1.5.5.7.3.4", "emailProtection" },
62 { "1.3.6.1.5.5.7.3.5", "ipsecEndSystem" },
63 { "1.3.6.1.5.5.7.3.6", "ipsecTunnel" },
64 { "1.3.6.1.5.5.7.3.7", "ipsecUser" },
65 { "1.3.6.1.5.5.7.3.8", "timeStamping" },
66 { "1.3.6.1.5.5.7.3.9", "ocspSigning" },
67 { "1.3.6.1.5.5.7.3.10", "dvcs" },
68 { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
69 { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
70 { "1.3.6.1.5.5.7.3.14", "wlanSSID" },
72 { "2.16.840.1.113730.4.1", "serverGatedCrypto.ns" }, /* Netscape. */
73 { "1.3.6.1.4.1.311.10.3.3", "serverGatedCrypto.ms"}, /* Microsoft. */
75 { "1.3.6.1.5.5.7.48.1.5", "ocspNoCheck" },
81 /* Do not print this extension in the list of extensions. This is set
82 for oids which are already available via ksba fucntions. */
83 #define OID_FLAG_SKIP 1
84 /* The extension is a simple UTF8String and should be printed. */
85 #define OID_FLAG_UTF8 2
87 /* A table mapping OIDs to a descriptive string. */
92 unsigned int flag
; /* A flag as described above. */
96 { "1.2.840.10040.4.1", "dsa" },
97 { "1.2.840.10040.4.3", "dsaWithSha1" },
99 { "1.2.840.113549.1.1.1", "rsaEncryption" },
100 { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
101 { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
102 { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
103 { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
104 { "1.2.840.113549.1.1.7", "rsaOAEP" },
105 { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
106 { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
107 { "1.2.840.113549.1.1.10", "rsaPSS" },
108 { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
109 { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
110 { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
112 { "1.3.14.3.2.26", "sha1" },
113 { "1.3.14.3.2.29", "sha-1WithRSAEncryption" },
114 { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
117 /* Telesec extensions. */
118 { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
119 { "0.2.262.1.10.12.1", "telesecCertIdExt" },
120 { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
121 { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
122 { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
123 { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
124 { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
125 #define OIDSTR_restriction \
127 { OIDSTR_restriction
, "restriction", OID_FLAG_UTF8
},
130 /* PKIX private extensions. */
131 { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
132 { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
133 { "1.3.6.1.5.5.7.1.3", "qcStatements" },
134 { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
135 { "1.3.6.1.5.5.7.1.5", "acTargeting" },
136 { "1.3.6.1.5.5.7.1.6", "acAaControls" },
137 { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
138 { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
139 { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
140 { "1.3.6.1.5.5.7.1.10", "acProxying" },
141 { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
143 { "1.3.6.1.5.5.7.48.1", "ocsp" },
144 { "1.3.6.1.5.5.7.48.2", "caIssuers" },
145 { "1.3.6.1.5.5.7.48.3", "timeStamping" },
146 { "1.3.6.1.5.5.7.48.5", "caRepository" },
149 { "2.5.29.14", "subjectKeyIdentifier", OID_FLAG_SKIP
},
150 { "2.5.29.15", "keyUsage", OID_FLAG_SKIP
},
151 { "2.5.29.16", "privateKeyUsagePeriod" },
152 { "2.5.29.17", "subjectAltName", OID_FLAG_SKIP
},
153 { "2.5.29.18", "issuerAltName", OID_FLAG_SKIP
},
154 { "2.5.29.19", "basicConstraints", OID_FLAG_SKIP
},
155 { "2.5.29.20", "cRLNumber" },
156 { "2.5.29.21", "cRLReason" },
157 { "2.5.29.22", "expirationDate" },
158 { "2.5.29.23", "instructionCode" },
159 { "2.5.29.24", "invalidityDate" },
160 { "2.5.29.27", "deltaCRLIndicator" },
161 { "2.5.29.28", "issuingDistributionPoint" },
162 { "2.5.29.29", "certificateIssuer" },
163 { "2.5.29.30", "nameConstraints" },
164 { "2.5.29.31", "cRLDistributionPoints", OID_FLAG_SKIP
},
165 { "2.5.29.32", "certificatePolicies", OID_FLAG_SKIP
},
166 { "2.5.29.32.0", "anyPolicy" },
167 { "2.5.29.33", "policyMappings" },
168 { "2.5.29.35", "authorityKeyIdentifier", OID_FLAG_SKIP
},
169 { "2.5.29.36", "policyConstraints" },
170 { "2.5.29.37", "extKeyUsage", OID_FLAG_SKIP
},
171 { "2.5.29.46", "freshestCRL" },
172 { "2.5.29.54", "inhibitAnyPolicy" },
174 /* Netscape certificate extensions. */
175 { "2.16.840.1.113730.1.1", "netscape-cert-type" },
176 { "2.16.840.1.113730.1.2", "netscape-base-url" },
177 { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
178 { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
179 { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
180 { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
181 { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
182 { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
183 { "2.16.840.1.113730.1.11", "netscape-userPicture" },
184 { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
185 { "2.16.840.1.113730.1.13", "netscape-comment" },
187 /* GnuPG extensions */
188 { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
190 /* Extensions used by the Bundesnetzagentur. */
191 { "1.3.6.1.4.1.8301.3.5", "validityModel" },
197 /* Return the description for OID; if no description is available
200 get_oid_desc (const char *oid
, unsigned int *flag
)
205 for (i
=0; oidtranstbl
[i
].oid
; i
++)
206 if (!strcmp (oidtranstbl
[i
].oid
, oid
))
209 *flag
= oidtranstbl
[i
].flag
;
210 return oidtranstbl
[i
].name
;
219 print_key_data (ksba_cert_t cert
, estream_t fp
)
222 int n
= pk
? pubkey_get_npkey( pk
->pubkey_algo
) : 0;
225 for(i
=0; i
< n
; i
++ )
227 es_fprintf (fp
, "pkd:%d:%u:", i
, mpi_get_nbits( pk
->pkey
[i
] ) );
228 mpi_print(stdout
, pk
->pkey
[i
], 1 );
239 print_capabilities (ksba_cert_t cert
, estream_t fp
)
246 err
= ksba_cert_get_user_data (cert
, "is_qualified",
247 &buffer
, sizeof (buffer
), &buflen
);
253 else if (gpg_err_code (err
) == GPG_ERR_NOT_FOUND
)
254 ; /* Don't know - will not get marked as 'q' */
256 log_debug ("get_user_data(is_qualified) failed: %s\n",
259 err
= ksba_cert_get_key_usage (cert
, &use
);
260 if (gpg_err_code (err
) == GPG_ERR_NO_DATA
)
272 log_error (_("error getting key usage information: %s\n"),
277 if ((use
& (KSBA_KEYUSAGE_KEY_ENCIPHERMENT
|KSBA_KEYUSAGE_DATA_ENCIPHERMENT
)))
279 if ((use
& (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
|KSBA_KEYUSAGE_NON_REPUDIATION
)))
281 if ((use
& KSBA_KEYUSAGE_KEY_CERT_SIGN
))
283 if ((use
& (KSBA_KEYUSAGE_KEY_ENCIPHERMENT
|KSBA_KEYUSAGE_DATA_ENCIPHERMENT
)))
285 if ((use
& (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
|KSBA_KEYUSAGE_NON_REPUDIATION
)))
287 if ((use
& KSBA_KEYUSAGE_KEY_CERT_SIGN
))
293 print_time (gnupg_isotime_t t
, estream_t fp
)
302 /* Return an allocated string with the email address extracted from a
303 DN. Note hat we use this code also in ../kbx/keybox-blob.c. */
305 email_kludge (const char *name
)
307 const char *p
, *string
;
314 p
= strstr (string
, "1.2.840.113549.1.9.1=#");
317 if (p
== name
|| (p
> string
+1 && p
[-1] == ',' && p
[-2] != '\\'))
326 /* This looks pretty much like an email address in the subject's DN
327 we use this to add an additional user ID entry. This way,
328 OpenSSL generated keys get a nicer and usable listing. */
329 for (n
=0, p
=name
; hexdigitp (p
) && hexdigitp (p
+1); p
+=2, n
++)
333 buf
= xtrymalloc (n
+3);
335 return NULL
; /* oops, out of core */
337 for (n
=1, p
=name
; hexdigitp (p
); p
+=2, n
++)
347 /* List one certificate in colon mode */
349 list_cert_colon (ctrl_t ctrl
, ksba_cert_t cert
, unsigned int validity
,
350 estream_t fp
, int have_secret
)
362 const char *chain_id
;
363 char *chain_id_buffer
= NULL
;
367 if (ctrl
->with_validation
)
368 valerr
= gpgsm_validate_chain (ctrl
, cert
, "", NULL
, 1, NULL
, 0, NULL
);
373 /* We need to get the fingerprint and the chaining ID in advance. */
374 fpr
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
378 rc
= gpgsm_walk_cert_chain (ctrl
, cert
, &next
);
379 if (!rc
) /* We known the issuer's certificate. */
381 p
= gpgsm_get_fingerprint_hexstring (next
, GCRY_MD_SHA1
);
383 chain_id
= chain_id_buffer
;
384 ksba_cert_release (next
);
386 else if (rc
== -1) /* We have reached the root certificate. */
396 es_fputs (have_secret
? "crs:":"crt:", fp
);
398 /* Note: We can't use multiple flags, like "ei", because the
399 validation check does only return one error. */
402 if ((validity
& VALIDITY_REVOKED
)
403 || gpg_err_code (valerr
) == GPG_ERR_CERT_REVOKED
)
405 else if (gpg_err_code (valerr
) == GPG_ERR_CERT_EXPIRED
)
409 /* Lets also check whether the certificate under question
410 expired. This is merely a hack until we found a proper way
411 to store the expiration flag in the keybox. */
412 ksba_isotime_t current_time
, not_after
;
414 gnupg_get_isotime (current_time
);
415 if (!opt
.ignore_expiration
416 && !ksba_cert_get_validity (cert
, 1, not_after
)
417 && *not_after
&& strcmp (current_time
, not_after
) > 0 )
421 else if (ctrl
->with_validation
&& !is_root
)
425 /* If we have no truststring yet (i.e. the certificate might be
426 good) and this is a root certificate, we ask the agent whether
427 this is a trusted root certificate. */
428 if (!*truststring
&& is_root
)
430 struct rootca_flags_s dummy_flags
;
432 rc
= gpgsm_agent_istrusted (ctrl
, cert
, NULL
, &dummy_flags
);
434 *truststring
= 'u'; /* Yes, we trust this one (ultimately). */
435 else if (gpg_err_code (rc
) == GPG_ERR_NOT_TRUSTED
)
436 *truststring
= 'n'; /* No, we do not trust this one. */
437 /* (in case of an error we can't tell anything.) */
441 es_fputs (truststring
, fp
);
443 algo
= gpgsm_get_key_algo_info (cert
, &nbits
);
444 es_fprintf (fp
, ":%u:%d:%s:", nbits
, algo
, fpr
+24);
446 /* We assume --fixed-list-mode for gpgsm */
447 ksba_cert_get_validity (cert
, 0, t
);
450 ksba_cert_get_validity (cert
, 1, t
);
453 /* Field 8, serial number: */
454 if ((sexp
= ksba_cert_get_serial (cert
)))
457 const unsigned char *s
= sexp
;
462 for (len
=0; *s
&& *s
!= ':' && digitp (s
); s
++)
463 len
= len
*10 + atoi_1 (s
);
465 for (s
++; len
; len
--, s
++)
466 es_fprintf (fp
,"%02X", *s
);
471 /* Field 9, ownertrust - not used here */
473 /* field 10, old user ID - we use it here for the issuer DN */
474 if ((p
= ksba_cert_get_issuer (cert
,0)))
476 es_write_sanitized (fp
, p
, strlen (p
), ":", NULL
);
480 /* Field 11, signature class - not used */
482 /* Field 12, capabilities: */
483 print_capabilities (cert
, fp
);
484 /* Field 13, not used: */
490 p
= gpgsm_get_keygrip_hexstring (cert
);
491 if (!gpgsm_agent_keyinfo (ctrl
, p
, &cardsn
) && cardsn
)
493 /* Field 14, not used: */
495 /* Field 15: Token serial number. */
496 es_fputs (cardsn
, fp
);
505 es_fprintf (fp
, "fpr:::::::::%s:::", fpr
);
506 /* Print chaining ID (field 13)*/
508 es_fputs (chain_id
, fp
);
511 xfree (fpr
); fpr
= NULL
; chain_id
= NULL
;
512 xfree (chain_id_buffer
); chain_id_buffer
= NULL
;
514 if (opt
.with_key_data
)
516 if ( (p
= gpgsm_get_keygrip_hexstring (cert
)))
518 es_fprintf (fp
, "grp:::::::::%s:\n", p
);
521 print_key_data (cert
, fp
);
525 for (idx
=0; (p
= ksba_cert_get_subject (cert
,idx
)); idx
++)
527 /* In the case that the same email address is in the subject DN
528 as well as in an alternate subject name we avoid printing it
530 if (kludge_uid
&& !strcmp (kludge_uid
, p
))
533 es_fprintf (fp
, "uid:%s::::::::", truststring
);
534 es_write_sanitized (fp
, p
, strlen (p
), ":", NULL
);
540 /* It would be better to get the faked email address from
541 the keydb. But as long as we don't have a way to pass
542 the meta data back, we just check it the same way as the
543 code used to create the keybox meta data does */
544 kludge_uid
= email_kludge (p
);
547 es_fprintf (fp
, "uid:%s::::::::", truststring
);
548 es_write_sanitized (fp
, kludge_uid
, strlen (kludge_uid
),
562 print_name_raw (estream_t fp
, const char *string
)
565 es_fputs ("[error]", fp
);
567 es_write_sanitized (fp
, string
, strlen (string
), NULL
, NULL
);
571 print_names_raw (estream_t fp
, int indent
, ksba_name_t name
)
577 if ((indent_all
= (indent
< 0)))
582 es_fputs ("none\n", fp
);
586 for (idx
=0; (s
= ksba_name_enum (name
, idx
)); idx
++)
588 char *p
= ksba_name_get_uri (name
, idx
);
589 es_fprintf (fp
, "%*s", idx
||indent_all
?indent
:0, "");
590 es_write_sanitized (fp
, p
?p
:s
, strlen (p
?p
:s
), NULL
, NULL
);
598 print_utf8_extn_raw (estream_t fp
, int indent
,
599 const unsigned char *der
, size_t derlen
)
602 int class, tag
, constructed
, ndef
;
603 size_t objlen
, hdrlen
;
608 err
= parse_ber_header (&der
, &derlen
, &class, &tag
, &constructed
,
609 &ndef
, &objlen
, &hdrlen
);
610 if (!err
&& (objlen
> derlen
|| tag
!= TAG_UTF8_STRING
))
611 err
= gpg_error (GPG_ERR_INV_OBJ
);
614 es_fprintf (fp
, "%*s[%s]\n", indent
, "", gpg_strerror (err
));
617 es_fprintf (fp
, "%*s(%.*s)\n", indent
, "", (int)objlen
, der
);
622 print_utf8_extn (estream_t fp
, int indent
,
623 const unsigned char *der
, size_t derlen
)
626 int class, tag
, constructed
, ndef
;
627 size_t objlen
, hdrlen
;
630 if ((indent_all
= (indent
< 0)))
633 err
= parse_ber_header (&der
, &derlen
, &class, &tag
, &constructed
,
634 &ndef
, &objlen
, &hdrlen
);
635 if (!err
&& (objlen
> derlen
|| tag
!= TAG_UTF8_STRING
))
636 err
= gpg_error (GPG_ERR_INV_OBJ
);
639 es_fprintf (fp
, "%*s[%s%s]\n",
640 indent_all
? indent
:0, "", _("Error - "), gpg_strerror (err
));
643 es_fprintf (fp
, "%*s\"", indent_all
? indent
:0, "");
644 /* Fixme: we should implement word wrapping */
645 es_write_sanitized (fp
, der
, objlen
, "\"", NULL
);
646 es_fputs ("\"\n", fp
);
650 /* List one certificate in raw mode useful to have a closer look at
651 the certificate. This one does no beautification and only minimal
652 output sanitation. It is mainly useful for debugging. */
654 list_cert_raw (ctrl_t ctrl
, KEYDB_HANDLE hd
,
655 ksba_cert_t cert
, estream_t fp
, int have_secret
,
660 ksba_sexp_t sexp
, keyid
;
666 char *string
, *p
, *pend
;
668 ksba_name_t name
, name2
;
670 const unsigned char *cert_der
= NULL
;
674 es_fprintf (fp
, " ID: 0x%08lX\n",
675 gpgsm_get_short_fingerprint (cert
, NULL
));
677 sexp
= ksba_cert_get_serial (cert
);
678 es_fputs (" S/N: ", fp
);
679 gpgsm_print_serial (fp
, sexp
);
683 dn
= ksba_cert_get_issuer (cert
, 0);
684 es_fputs (" Issuer: ", fp
);
685 print_name_raw (fp
, dn
);
688 for (idx
=1; (dn
= ksba_cert_get_issuer (cert
, idx
)); idx
++)
690 es_fputs (" aka: ", fp
);
691 print_name_raw (fp
, dn
);
696 dn
= ksba_cert_get_subject (cert
, 0);
697 es_fputs (" Subject: ", fp
);
698 print_name_raw (fp
, dn
);
701 for (idx
=1; (dn
= ksba_cert_get_subject (cert
, idx
)); idx
++)
703 es_fputs (" aka: ", fp
);
704 print_name_raw (fp
, dn
);
709 dn
= gpgsm_get_fingerprint_string (cert
, 0);
710 es_fprintf (fp
, " sha1_fpr: %s\n", dn
?dn
:"error");
713 dn
= gpgsm_get_fingerprint_string (cert
, GCRY_MD_MD5
);
714 es_fprintf (fp
, " md5_fpr: %s\n", dn
?dn
:"error");
717 dn
= gpgsm_get_certid (cert
);
718 es_fprintf (fp
, " certid: %s\n", dn
?dn
:"error");
721 dn
= gpgsm_get_keygrip_hexstring (cert
);
722 es_fprintf (fp
, " keygrip: %s\n", dn
?dn
:"error");
725 ksba_cert_get_validity (cert
, 0, t
);
726 es_fputs (" notBefore: ", fp
);
727 gpgsm_print_time (fp
, t
);
729 es_fputs (" notAfter: ", fp
);
730 ksba_cert_get_validity (cert
, 1, t
);
731 gpgsm_print_time (fp
, t
);
734 oid
= ksba_cert_get_digest_algo (cert
);
735 s
= get_oid_desc (oid
, NULL
);
736 es_fprintf (fp
, " hashAlgo: %s%s%s%s\n", oid
, s
?" (":"",s
?s
:"",s
?")":"");
739 const char *algoname
;
742 algoname
= gcry_pk_algo_name (gpgsm_get_key_algo_info (cert
, &nbits
));
743 es_fprintf (fp
, " keyType: %u bit %s\n",
744 nbits
, algoname
? algoname
:"?");
747 /* subjectKeyIdentifier */
748 es_fputs (" subjKeyId: ", fp
);
749 err
= ksba_cert_get_subj_key_id (cert
, NULL
, &keyid
);
750 if (!err
|| gpg_err_code (err
) == GPG_ERR_NO_DATA
)
752 if (gpg_err_code (err
) == GPG_ERR_NO_DATA
)
753 es_fputs ("[none]\n", fp
);
756 gpgsm_print_serial (fp
, keyid
);
762 es_fputs ("[?]\n", fp
);
765 /* authorityKeyIdentifier */
766 es_fputs (" authKeyId: ", fp
);
767 err
= ksba_cert_get_auth_key_id (cert
, &keyid
, &name
, &sexp
);
768 if (!err
|| gpg_err_code (err
) == GPG_ERR_NO_DATA
)
770 if (gpg_err_code (err
) == GPG_ERR_NO_DATA
|| !name
)
771 es_fputs ("[none]\n", fp
);
774 gpgsm_print_serial (fp
, sexp
);
777 print_names_raw (fp
, -15, name
);
778 ksba_name_release (name
);
782 es_fputs (" authKeyId.ki: ", fp
);
783 gpgsm_print_serial (fp
, keyid
);
789 es_fputs ("[?]\n", fp
);
791 es_fputs (" keyUsage:", fp
);
792 err
= ksba_cert_get_key_usage (cert
, &kusage
);
793 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
796 es_fprintf (fp
, " [error: %s]", gpg_strerror (err
));
799 if ( (kusage
& KSBA_KEYUSAGE_DIGITAL_SIGNATURE
))
800 es_fputs (" digitalSignature", fp
);
801 if ( (kusage
& KSBA_KEYUSAGE_NON_REPUDIATION
))
802 es_fputs (" nonRepudiation", fp
);
803 if ( (kusage
& KSBA_KEYUSAGE_KEY_ENCIPHERMENT
))
804 es_fputs (" keyEncipherment", fp
);
805 if ( (kusage
& KSBA_KEYUSAGE_DATA_ENCIPHERMENT
))
806 es_fputs (" dataEncipherment", fp
);
807 if ( (kusage
& KSBA_KEYUSAGE_KEY_AGREEMENT
))
808 es_fputs (" keyAgreement", fp
);
809 if ( (kusage
& KSBA_KEYUSAGE_KEY_CERT_SIGN
))
810 es_fputs (" certSign", fp
);
811 if ( (kusage
& KSBA_KEYUSAGE_CRL_SIGN
))
812 es_fputs (" crlSign", fp
);
813 if ( (kusage
& KSBA_KEYUSAGE_ENCIPHER_ONLY
))
814 es_fputs (" encipherOnly", fp
);
815 if ( (kusage
& KSBA_KEYUSAGE_DECIPHER_ONLY
))
816 es_fputs (" decipherOnly", fp
);
821 es_fputs (" [none]\n", fp
);
823 es_fputs (" extKeyUsage: ", fp
);
824 err
= ksba_cert_get_ext_key_usages (cert
, &string
);
825 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
828 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
832 while (p
&& (pend
=strchr (p
, ':')))
835 for (i
=0; key_purpose_map
[i
].oid
; i
++)
836 if ( !strcmp (key_purpose_map
[i
].oid
, p
) )
838 es_fputs (key_purpose_map
[i
].oid
?key_purpose_map
[i
].name
:p
, fp
);
841 es_fputs (" (suggested)", fp
);
842 if ((p
= strchr (p
, '\n')))
845 es_fputs ("\n ", fp
);
853 es_fputs ("[none]\n", fp
);
856 es_fputs (" policies: ", fp
);
857 err
= ksba_cert_get_cert_policies (cert
, &string
);
858 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
861 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
865 while (p
&& (pend
=strchr (p
, ':')))
868 for (i
=0; key_purpose_map
[i
].oid
; i
++)
869 if ( !strcmp (key_purpose_map
[i
].oid
, p
) )
874 es_fputs (" (critical)", fp
);
875 if ((p
= strchr (p
, '\n')))
878 es_fputs ("\n ", fp
);
886 es_fputs ("[none]\n", fp
);
888 es_fputs (" chainLength: ", fp
);
889 err
= ksba_cert_is_ca (cert
, &is_ca
, &chainlen
);
892 if (gpg_err_code (err
) == GPG_ERR_NO_VALUE
)
893 es_fprintf (fp
, "[none]");
895 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
896 else if (chainlen
== -1)
897 es_fputs ("unlimited", fp
);
899 es_fprintf (fp
, "%d", chainlen
);
903 es_fputs ("not a CA\n", fp
);
906 /* CRL distribution point */
907 for (idx
=0; !(err
=ksba_cert_get_crl_dist_point (cert
, idx
, &name
, &name2
,
910 es_fputs (" crlDP: ", fp
);
911 print_names_raw (fp
, 15, name
);
914 es_fputs (" reason: ", fp
);
915 if ( (reason
& KSBA_CRLREASON_UNSPECIFIED
))
916 es_fputs (" unused", fp
);
917 if ( (reason
& KSBA_CRLREASON_KEY_COMPROMISE
))
918 es_fputs (" keyCompromise", fp
);
919 if ( (reason
& KSBA_CRLREASON_CA_COMPROMISE
))
920 es_fputs (" caCompromise", fp
);
921 if ( (reason
& KSBA_CRLREASON_AFFILIATION_CHANGED
))
922 es_fputs (" affiliationChanged", fp
);
923 if ( (reason
& KSBA_CRLREASON_SUPERSEDED
))
924 es_fputs (" superseded", fp
);
925 if ( (reason
& KSBA_CRLREASON_CESSATION_OF_OPERATION
))
926 es_fputs (" cessationOfOperation", fp
);
927 if ( (reason
& KSBA_CRLREASON_CERTIFICATE_HOLD
))
928 es_fputs (" certificateHold", fp
);
931 es_fputs (" issuer: ", fp
);
932 print_names_raw (fp
, 23, name2
);
933 ksba_name_release (name
);
934 ksba_name_release (name2
);
936 if (err
&& gpg_err_code (err
) != GPG_ERR_EOF
937 && gpg_err_code (err
) != GPG_ERR_NO_VALUE
)
938 es_fputs (" crlDP: [error]\n", fp
);
940 es_fputs (" crlDP: [none]\n", fp
);
943 /* authorityInfoAccess. */
944 for (idx
=0; !(err
=ksba_cert_get_authority_info_access (cert
, idx
, &string
,
947 es_fputs (" authInfo: ", fp
);
948 s
= get_oid_desc (string
, NULL
);
949 es_fprintf (fp
, "%s%s%s%s\n", string
, s
?" (":"", s
?s
:"", s
?")":"");
950 print_names_raw (fp
, -15, name
);
951 ksba_name_release (name
);
954 if (err
&& gpg_err_code (err
) != GPG_ERR_EOF
955 && gpg_err_code (err
) != GPG_ERR_NO_VALUE
)
956 es_fputs (" authInfo: [error]\n", fp
);
958 es_fputs (" authInfo: [none]\n", fp
);
960 /* subjectInfoAccess. */
961 for (idx
=0; !(err
=ksba_cert_get_subject_info_access (cert
, idx
, &string
,
964 es_fputs (" subjectInfo: ", fp
);
965 s
= get_oid_desc (string
, NULL
);
966 es_fprintf (fp
, "%s%s%s%s\n", string
, s
?" (":"", s
?s
:"", s
?")":"");
967 print_names_raw (fp
, -15, name
);
968 ksba_name_release (name
);
971 if (err
&& gpg_err_code (err
) != GPG_ERR_EOF
972 && gpg_err_code (err
) != GPG_ERR_NO_VALUE
)
973 es_fputs (" subjInfo: [error]\n", fp
);
975 es_fputs (" subjInfo: [none]\n", fp
);
978 for (idx
=0; !(err
=ksba_cert_get_extension (cert
, idx
,
979 &oid
, &i
, &off
, &len
));idx
++)
983 s
= get_oid_desc (oid
, &flag
);
984 if ((flag
& OID_FLAG_SKIP
))
987 es_fprintf (fp
, " %s: %s%s%s%s [%d octets]\n",
988 i
? "critExtn":" extn",
989 oid
, s
?" (":"", s
?s
:"", s
?")":"", (int)len
);
990 if ((flag
& OID_FLAG_UTF8
))
993 cert_der
= ksba_cert_get_image (cert
, NULL
);
995 print_utf8_extn_raw (fp
, -15, cert_der
+off
, len
);
1000 if (with_validation
)
1002 err
= gpgsm_validate_chain (ctrl
, cert
, "", NULL
, 1, fp
, 0, NULL
);
1004 es_fprintf (fp
, " [certificate is good]\n");
1006 es_fprintf (fp
, " [certificate is bad: %s]\n", gpg_strerror (err
));
1011 unsigned int blobflags
;
1013 err
= keydb_get_flags (hd
, KEYBOX_FLAG_BLOB
, 0, &blobflags
);
1015 es_fprintf (fp
, " [error getting keyflags: %s]\n",gpg_strerror (err
));
1016 else if ((blobflags
& KEYBOX_FLAG_BLOB_EPHEMERAL
))
1017 es_fprintf (fp
, " [stored as ephemeral]\n");
1025 /* List one certificate in standard mode */
1027 list_cert_std (ctrl_t ctrl
, ksba_cert_t cert
, estream_t fp
, int have_secret
,
1028 int with_validation
)
1035 int is_ca
, chainlen
;
1036 unsigned int kusage
;
1037 char *string
, *p
, *pend
;
1040 const unsigned char *cert_der
= NULL
;
1043 es_fprintf (fp
, " ID: 0x%08lX\n",
1044 gpgsm_get_short_fingerprint (cert
, NULL
));
1046 sexp
= ksba_cert_get_serial (cert
);
1047 es_fputs (" S/N: ", fp
);
1048 gpgsm_print_serial (fp
, sexp
);
1052 dn
= ksba_cert_get_issuer (cert
, 0);
1053 es_fputs (" Issuer: ", fp
);
1054 gpgsm_es_print_name (fp
, dn
);
1057 for (idx
=1; (dn
= ksba_cert_get_issuer (cert
, idx
)); idx
++)
1059 es_fputs (" aka: ", fp
);
1060 gpgsm_es_print_name (fp
, dn
);
1065 dn
= ksba_cert_get_subject (cert
, 0);
1066 es_fputs (" Subject: ", fp
);
1067 gpgsm_es_print_name (fp
, dn
);
1070 for (idx
=1; (dn
= ksba_cert_get_subject (cert
, idx
)); idx
++)
1072 es_fputs (" aka: ", fp
);
1073 gpgsm_es_print_name (fp
, dn
);
1078 ksba_cert_get_validity (cert
, 0, t
);
1079 es_fputs (" validity: ", fp
);
1080 gpgsm_print_time (fp
, t
);
1081 es_fputs (" through ", fp
);
1082 ksba_cert_get_validity (cert
, 1, t
);
1083 gpgsm_print_time (fp
, t
);
1088 const char *algoname
;
1091 algoname
= gcry_pk_algo_name (gpgsm_get_key_algo_info (cert
, &nbits
));
1092 es_fprintf (fp
, " key type: %u bit %s\n",
1093 nbits
, algoname
? algoname
:"?");
1097 err
= ksba_cert_get_key_usage (cert
, &kusage
);
1098 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
1100 es_fputs (" key usage:", fp
);
1102 es_fprintf (fp
, " [error: %s]", gpg_strerror (err
));
1105 if ( (kusage
& KSBA_KEYUSAGE_DIGITAL_SIGNATURE
))
1106 es_fputs (" digitalSignature", fp
);
1107 if ( (kusage
& KSBA_KEYUSAGE_NON_REPUDIATION
))
1108 es_fputs (" nonRepudiation", fp
);
1109 if ( (kusage
& KSBA_KEYUSAGE_KEY_ENCIPHERMENT
))
1110 es_fputs (" keyEncipherment", fp
);
1111 if ( (kusage
& KSBA_KEYUSAGE_DATA_ENCIPHERMENT
))
1112 es_fputs (" dataEncipherment", fp
);
1113 if ( (kusage
& KSBA_KEYUSAGE_KEY_AGREEMENT
))
1114 es_fputs (" keyAgreement", fp
);
1115 if ( (kusage
& KSBA_KEYUSAGE_KEY_CERT_SIGN
))
1116 es_fputs (" certSign", fp
);
1117 if ( (kusage
& KSBA_KEYUSAGE_CRL_SIGN
))
1118 es_fputs (" crlSign", fp
);
1119 if ( (kusage
& KSBA_KEYUSAGE_ENCIPHER_ONLY
))
1120 es_fputs (" encipherOnly", fp
);
1121 if ( (kusage
& KSBA_KEYUSAGE_DECIPHER_ONLY
))
1122 es_fputs (" decipherOnly", fp
);
1127 err
= ksba_cert_get_ext_key_usages (cert
, &string
);
1128 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
1130 es_fputs ("ext key usage: ", fp
);
1132 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
1136 while (p
&& (pend
=strchr (p
, ':')))
1139 for (i
=0; key_purpose_map
[i
].oid
; i
++)
1140 if ( !strcmp (key_purpose_map
[i
].oid
, p
) )
1142 es_fputs (key_purpose_map
[i
].oid
?key_purpose_map
[i
].name
:p
, fp
);
1145 es_fputs (" (suggested)", fp
);
1146 if ((p
= strchr (p
, '\n')))
1149 es_fputs (", ", fp
);
1157 /* Print restrictions. */
1158 for (idx
=0; !(err
=ksba_cert_get_extension (cert
, idx
,
1159 &oid
, NULL
, &off
, &len
));idx
++)
1161 if (!strcmp (oid
, OIDSTR_restriction
) )
1164 cert_der
= ksba_cert_get_image (cert
, NULL
);
1166 es_fputs (" restriction: ", fp
);
1167 print_utf8_extn (fp
, 15, cert_der
+off
, len
);
1171 /* Print policies. */
1172 err
= ksba_cert_get_cert_policies (cert
, &string
);
1173 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
1175 es_fputs (" policies: ", fp
);
1177 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
1180 for (p
=string
; *p
; p
++)
1185 es_write_sanitized (fp
, string
, strlen (string
), NULL
, NULL
);
1191 err
= ksba_cert_is_ca (cert
, &is_ca
, &chainlen
);
1194 es_fputs (" chain length: ", fp
);
1195 if (gpg_err_code (err
) == GPG_ERR_NO_VALUE
)
1196 es_fprintf (fp
, "none");
1198 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
1199 else if (chainlen
== -1)
1200 es_fputs ("unlimited", fp
);
1202 es_fprintf (fp
, "%d", chainlen
);
1206 if (opt
.with_md5_fingerprint
)
1208 dn
= gpgsm_get_fingerprint_string (cert
, GCRY_MD_MD5
);
1209 es_fprintf (fp
, " md5 fpr: %s\n", dn
?dn
:"error");
1213 dn
= gpgsm_get_fingerprint_string (cert
, 0);
1214 es_fprintf (fp
, " fingerprint: %s\n", dn
?dn
:"error");
1221 p
= gpgsm_get_keygrip_hexstring (cert
);
1222 if (!gpgsm_agent_keyinfo (ctrl
, p
, &cardsn
) && cardsn
)
1223 es_fprintf (fp
, " card s/n: %s\n", cardsn
);
1228 if (with_validation
)
1234 err
= gpgsm_validate_chain (ctrl
, cert
, "", NULL
, 1, fp
, 0, NULL
);
1235 tmperr
= ksba_cert_get_user_data (cert
, "is_qualified",
1236 &buffer
, sizeof (buffer
), &buflen
);
1237 if (!tmperr
&& buflen
)
1240 es_fputs (" [qualified]\n", fp
);
1242 else if (gpg_err_code (tmperr
) == GPG_ERR_NOT_FOUND
)
1243 ; /* Don't know - will not get marked as 'q' */
1245 log_debug ("get_user_data(is_qualified) failed: %s\n",
1246 gpg_strerror (tmperr
));
1249 es_fprintf (fp
, " [certificate is good]\n");
1251 es_fprintf (fp
, " [certificate is bad: %s]\n", gpg_strerror (err
));
1256 /* Same as standard mode mode list all certifying certs too. */
1258 list_cert_chain (ctrl_t ctrl
, KEYDB_HANDLE hd
,
1259 ksba_cert_t cert
, int raw_mode
,
1260 estream_t fp
, int with_validation
)
1262 ksba_cert_t next
= NULL
;
1265 list_cert_raw (ctrl
, hd
, cert
, fp
, 0, with_validation
);
1267 list_cert_std (ctrl
, cert
, fp
, 0, with_validation
);
1268 ksba_cert_ref (cert
);
1269 while (!gpgsm_walk_cert_chain (ctrl
, cert
, &next
))
1271 ksba_cert_release (cert
);
1272 es_fputs ("Certified by\n", fp
);
1274 list_cert_raw (ctrl
, hd
, next
, fp
, 0, with_validation
);
1276 list_cert_std (ctrl
, next
, fp
, 0, with_validation
);
1279 ksba_cert_release (cert
);
1285 /* List all internal keys or just the keys given as NAMES. MODE is a
1286 bit vector to specify what keys are to be included; see
1287 gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
1288 output mode will be used instead of the standard beautified one.
1291 list_internal_keys (ctrl_t ctrl
, strlist_t names
, estream_t fp
,
1292 unsigned int mode
, int raw_mode
)
1295 KEYDB_SEARCH_DESC
*desc
= NULL
;
1298 ksba_cert_t cert
= NULL
;
1299 ksba_cert_t lastcert
= NULL
;
1301 const char *lastresname
, *resname
;
1303 int want_ephemeral
= ctrl
->with_ephemeral_keys
;
1308 log_error ("keydb_new failed\n");
1309 rc
= gpg_error (GPG_ERR_GENERAL
);
1317 for (sl
=names
, ndesc
=0; sl
; sl
= sl
->next
, ndesc
++)
1321 desc
= xtrycalloc (ndesc
, sizeof *desc
);
1324 rc
= gpg_error_from_syserror ();
1325 log_error ("out of core\n");
1330 desc
[0].mode
= KEYDB_SEARCH_MODE_FIRST
;
1333 for (ndesc
=0, sl
=names
; sl
; sl
= sl
->next
)
1335 rc
= keydb_classify_name (sl
->d
, desc
+ndesc
);
1338 log_error ("key `%s' not found: %s\n",
1339 sl
->d
, gpg_strerror (rc
));
1348 /* If all specifications are done by fingerprint or keygrip, we
1349 switch to ephemeral mode so that _all_ currently available and
1350 matching certificates are listed. */
1351 if (!want_ephemeral
&& names
&& ndesc
)
1355 for (i
=0; (i
< ndesc
1356 && (desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR
1357 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR20
1358 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR16
1359 || desc
[i
].mode
== KEYDB_SEARCH_MODE_KEYGRIP
)); i
++)
1366 keydb_set_ephemeral (hd
, 1);
1368 /* It would be nice to see which of the given users did actually
1369 match one in the keyring. To implement this we need to have a
1370 found flag for each entry in desc and to set this we must check
1371 all those entries after a match to mark all matched one -
1372 currently we stop at the first match. To do this we need an
1373 extra flag to enable this feature so */
1375 /* Suppress duplicates at least when they follow each other. */
1377 while (!(rc
= keydb_search (hd
, desc
, ndesc
)))
1379 unsigned int validity
;
1382 desc
[0].mode
= KEYDB_SEARCH_MODE_NEXT
;
1384 rc
= keydb_get_flags (hd
, KEYBOX_FLAG_VALIDITY
, 0, &validity
);
1387 log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc
));
1390 rc
= keydb_get_cert (hd
, &cert
);
1393 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc
));
1396 /* Skip duplicated certificates, at least if they follow each
1397 others. This works best if a single key is searched for and
1398 expected. FIXME: Non-sequential duplicates remain. */
1399 if (gpgsm_certs_identical_p (cert
, lastcert
))
1401 ksba_cert_release (cert
);
1406 resname
= keydb_get_resource_name (hd
);
1408 if (lastresname
!= resname
)
1412 if (ctrl
->no_server
)
1414 es_fprintf (fp
, "%s\n", resname
);
1415 for (i
=strlen(resname
); i
; i
-- )
1418 lastresname
= resname
;
1425 char *p
= gpgsm_get_keygrip_hexstring (cert
);
1428 rc
= gpgsm_agent_havekey (ctrl
, p
);
1431 else if ( gpg_err_code (rc
) != GPG_ERR_NO_SECKEY
)
1439 || ((mode
& 1) && !have_secret
)
1440 || ((mode
& 2) && have_secret
) )
1442 if (ctrl
->with_colons
)
1443 list_cert_colon (ctrl
, cert
, validity
, fp
, have_secret
);
1444 else if (ctrl
->with_chain
)
1445 list_cert_chain (ctrl
, hd
, cert
,
1446 raw_mode
, fp
, ctrl
->with_validation
);
1450 list_cert_raw (ctrl
, hd
, cert
, fp
, have_secret
,
1451 ctrl
->with_validation
);
1453 list_cert_std (ctrl
, cert
, fp
, have_secret
,
1454 ctrl
->with_validation
);
1459 ksba_cert_release (lastcert
);
1463 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| rc
== -1 )
1466 log_error ("keydb_search failed: %s\n", gpg_strerror (rc
));
1469 ksba_cert_release (cert
);
1470 ksba_cert_release (lastcert
);
1479 list_external_cb (void *cb_value
, ksba_cert_t cert
)
1481 struct list_external_parm_s
*parm
= cb_value
;
1483 if (keydb_store_cert (cert
, 1, NULL
))
1484 log_error ("error storing certificate as ephemeral\n");
1486 if (parm
->print_header
)
1488 const char *resname
= "[external keys]";
1491 es_fprintf (parm
->fp
, "%s\n", resname
);
1492 for (i
=strlen(resname
); i
; i
-- )
1493 es_putc('-', parm
->fp
);
1494 es_putc ('\n', parm
->fp
);
1495 parm
->print_header
= 0;
1498 if (parm
->with_colons
)
1499 list_cert_colon (parm
->ctrl
, cert
, 0, parm
->fp
, 0);
1500 else if (parm
->with_chain
)
1501 list_cert_chain (parm
->ctrl
, NULL
, cert
, parm
->raw_mode
, parm
->fp
, 0);
1505 list_cert_raw (parm
->ctrl
, NULL
, cert
, parm
->fp
, 0, 0);
1507 list_cert_std (parm
->ctrl
, cert
, parm
->fp
, 0, 0);
1508 es_putc ('\n', parm
->fp
);
1513 /* List external keys similar to internal one. Note: mode does not
1514 make sense here because it would be unwise to list external secret
1517 list_external_keys (ctrl_t ctrl
, strlist_t names
, estream_t fp
, int raw_mode
)
1520 struct list_external_parm_s parm
;
1524 parm
.print_header
= ctrl
->no_server
;
1525 parm
.with_colons
= ctrl
->with_colons
;
1526 parm
.with_chain
= ctrl
->with_chain
;
1527 parm
.raw_mode
= raw_mode
;
1529 rc
= gpgsm_dirmngr_lookup (ctrl
, names
, 0, list_external_cb
, &parm
);
1530 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| rc
== -1
1531 || gpg_err_code (rc
) == GPG_ERR_NOT_FOUND
)
1532 rc
= 0; /* "Not found" is not an error here. */
1534 log_error ("listing external keys failed: %s\n", gpg_strerror (rc
));
1538 /* List all keys or just the key given as NAMES.
1539 MODE controls the operation mode:
1541 0 = list all public keys but don't flag secret ones
1542 1 = list only public keys
1543 2 = list only secret keys
1544 3 = list secret and public keys
1545 Bit 6: list internal keys
1546 Bit 7: list external keys
1547 Bit 8: Do a raw format dump.
1550 gpgsm_list_keys (ctrl_t ctrl
, strlist_t names
, estream_t fp
,
1553 gpg_error_t err
= 0;
1555 if ((mode
& (1<<6)))
1556 err
= list_internal_keys (ctrl
, names
, fp
, (mode
& 3), (mode
&256));
1557 if (!err
&& (mode
& (1<<7)))
1558 err
= list_external_keys (ctrl
, names
, fp
, (mode
&256));