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
))
295 print_time (gnupg_isotime_t t
, estream_t fp
)
304 /* Return an allocated string with the email address extracted from a
305 DN. Note hat we use this code also in ../kbx/keybox-blob.c. */
307 email_kludge (const char *name
)
309 const char *p
, *string
;
316 p
= strstr (string
, "1.2.840.113549.1.9.1=#");
319 if (p
== name
|| (p
> string
+1 && p
[-1] == ',' && p
[-2] != '\\'))
328 /* This looks pretty much like an email address in the subject's DN
329 we use this to add an additional user ID entry. This way,
330 OpenSSL generated keys get a nicer and usable listing. */
331 for (n
=0, p
=name
; hexdigitp (p
) && hexdigitp (p
+1); p
+=2, n
++)
335 buf
= xtrymalloc (n
+3);
337 return NULL
; /* oops, out of core */
339 for (n
=1, p
=name
; hexdigitp (p
); p
+=2, n
++)
349 /* List one certificate in colon mode */
351 list_cert_colon (ctrl_t ctrl
, ksba_cert_t cert
, unsigned int validity
,
352 estream_t fp
, int have_secret
)
364 const char *chain_id
;
365 char *chain_id_buffer
= NULL
;
369 if (ctrl
->with_validation
)
370 valerr
= gpgsm_validate_chain (ctrl
, cert
, "", NULL
, 1, NULL
, 0, NULL
);
375 /* We need to get the fingerprint and the chaining ID in advance. */
376 fpr
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
380 rc
= gpgsm_walk_cert_chain (ctrl
, cert
, &next
);
381 if (!rc
) /* We known the issuer's certificate. */
383 p
= gpgsm_get_fingerprint_hexstring (next
, GCRY_MD_SHA1
);
385 chain_id
= chain_id_buffer
;
386 ksba_cert_release (next
);
388 else if (rc
== -1) /* We have reached the root certificate. */
398 es_fputs (have_secret
? "crs:":"crt:", fp
);
400 /* Note: We can't use multiple flags, like "ei", because the
401 validation check does only return one error. */
404 if ((validity
& VALIDITY_REVOKED
)
405 || gpg_err_code (valerr
) == GPG_ERR_CERT_REVOKED
)
407 else if (gpg_err_code (valerr
) == GPG_ERR_CERT_EXPIRED
)
411 /* Lets also check whether the certificate under question
412 expired. This is merely a hack until we found a proper way
413 to store the expiration flag in the keybox. */
414 ksba_isotime_t current_time
, not_after
;
416 gnupg_get_isotime (current_time
);
417 if (!opt
.ignore_expiration
418 && !ksba_cert_get_validity (cert
, 1, not_after
)
419 && *not_after
&& strcmp (current_time
, not_after
) > 0 )
423 else if (ctrl
->with_validation
&& !is_root
)
427 /* If we have no truststring yet (i.e. the certificate might be
428 good) and this is a root certificate, we ask the agent whether
429 this is a trusted root certificate. */
430 if (!*truststring
&& is_root
)
432 struct rootca_flags_s dummy_flags
;
434 rc
= gpgsm_agent_istrusted (ctrl
, cert
, NULL
, &dummy_flags
);
436 *truststring
= 'u'; /* Yes, we trust this one (ultimately). */
437 else if (gpg_err_code (rc
) == GPG_ERR_NOT_TRUSTED
)
438 *truststring
= 'n'; /* No, we do not trust this one. */
439 /* (in case of an error we can't tell anything.) */
443 es_fputs (truststring
, fp
);
445 algo
= gpgsm_get_key_algo_info (cert
, &nbits
);
446 es_fprintf (fp
, ":%u:%d:%s:", nbits
, algo
, fpr
+24);
448 /* We assume --fixed-list-mode for gpgsm */
449 ksba_cert_get_validity (cert
, 0, t
);
452 ksba_cert_get_validity (cert
, 1, t
);
455 /* Field 8, serial number: */
456 if ((sexp
= ksba_cert_get_serial (cert
)))
459 const unsigned char *s
= sexp
;
464 for (len
=0; *s
&& *s
!= ':' && digitp (s
); s
++)
465 len
= len
*10 + atoi_1 (s
);
467 for (s
++; len
; len
--, s
++)
468 es_fprintf (fp
,"%02X", *s
);
473 /* Field 9, ownertrust - not used here */
475 /* field 10, old user ID - we use it here for the issuer DN */
476 if ((p
= ksba_cert_get_issuer (cert
,0)))
478 es_write_sanitized (fp
, p
, strlen (p
), ":", NULL
);
482 /* Field 11, signature class - not used */
484 /* Field 12, capabilities: */
485 print_capabilities (cert
, fp
);
486 /* Field 13, not used: */
492 p
= gpgsm_get_keygrip_hexstring (cert
);
493 if (!gpgsm_agent_keyinfo (ctrl
, p
, &cardsn
) && cardsn
)
495 /* Field 14, not used: */
497 /* Field 15: Token serial number. */
498 es_fputs (cardsn
, fp
);
507 es_fprintf (fp
, "fpr:::::::::%s:::", fpr
);
508 /* Print chaining ID (field 13)*/
510 es_fputs (chain_id
, fp
);
513 xfree (fpr
); fpr
= NULL
; chain_id
= NULL
;
514 xfree (chain_id_buffer
); chain_id_buffer
= NULL
;
516 if (opt
.with_key_data
)
518 if ( (p
= gpgsm_get_keygrip_hexstring (cert
)))
520 es_fprintf (fp
, "grp:::::::::%s:\n", p
);
523 print_key_data (cert
, fp
);
527 for (idx
=0; (p
= ksba_cert_get_subject (cert
,idx
)); idx
++)
529 /* In the case that the same email address is in the subject DN
530 as well as in an alternate subject name we avoid printing it
532 if (kludge_uid
&& !strcmp (kludge_uid
, p
))
535 es_fprintf (fp
, "uid:%s::::::::", truststring
);
536 es_write_sanitized (fp
, p
, strlen (p
), ":", NULL
);
542 /* It would be better to get the faked email address from
543 the keydb. But as long as we don't have a way to pass
544 the meta data back, we just check it the same way as the
545 code used to create the keybox meta data does */
546 kludge_uid
= email_kludge (p
);
549 es_fprintf (fp
, "uid:%s::::::::", truststring
);
550 es_write_sanitized (fp
, kludge_uid
, strlen (kludge_uid
),
564 print_name_raw (estream_t fp
, const char *string
)
567 es_fputs ("[error]", fp
);
569 es_write_sanitized (fp
, string
, strlen (string
), NULL
, NULL
);
573 print_names_raw (estream_t fp
, int indent
, ksba_name_t name
)
579 if ((indent_all
= (indent
< 0)))
584 es_fputs ("none\n", fp
);
588 for (idx
=0; (s
= ksba_name_enum (name
, idx
)); idx
++)
590 char *p
= ksba_name_get_uri (name
, idx
);
591 es_fprintf (fp
, "%*s", idx
||indent_all
?indent
:0, "");
592 es_write_sanitized (fp
, p
?p
:s
, strlen (p
?p
:s
), NULL
, NULL
);
600 print_utf8_extn_raw (estream_t fp
, int indent
,
601 const unsigned char *der
, size_t derlen
)
604 int class, tag
, constructed
, ndef
;
605 size_t objlen
, hdrlen
;
610 err
= parse_ber_header (&der
, &derlen
, &class, &tag
, &constructed
,
611 &ndef
, &objlen
, &hdrlen
);
612 if (!err
&& (objlen
> derlen
|| tag
!= TAG_UTF8_STRING
))
613 err
= gpg_error (GPG_ERR_INV_OBJ
);
616 es_fprintf (fp
, "%*s[%s]\n", indent
, "", gpg_strerror (err
));
619 es_fprintf (fp
, "%*s(%.*s)\n", indent
, "", (int)objlen
, der
);
624 print_utf8_extn (estream_t fp
, int indent
,
625 const unsigned char *der
, size_t derlen
)
628 int class, tag
, constructed
, ndef
;
629 size_t objlen
, hdrlen
;
632 if ((indent_all
= (indent
< 0)))
635 err
= parse_ber_header (&der
, &derlen
, &class, &tag
, &constructed
,
636 &ndef
, &objlen
, &hdrlen
);
637 if (!err
&& (objlen
> derlen
|| tag
!= TAG_UTF8_STRING
))
638 err
= gpg_error (GPG_ERR_INV_OBJ
);
641 es_fprintf (fp
, "%*s[%s%s]\n",
642 indent_all
? indent
:0, "", _("Error - "), gpg_strerror (err
));
645 es_fprintf (fp
, "%*s\"", indent_all
? indent
:0, "");
646 /* Fixme: we should implement word wrapping */
647 es_write_sanitized (fp
, der
, objlen
, "\"", NULL
);
648 es_fputs ("\"\n", fp
);
652 /* List one certificate in raw mode useful to have a closer look at
653 the certificate. This one does no beautification and only minimal
654 output sanitation. It is mainly useful for debugging. */
656 list_cert_raw (ctrl_t ctrl
, KEYDB_HANDLE hd
,
657 ksba_cert_t cert
, estream_t fp
, int have_secret
,
662 ksba_sexp_t sexp
, keyid
;
668 char *string
, *p
, *pend
;
670 ksba_name_t name
, name2
;
672 const unsigned char *cert_der
= NULL
;
676 es_fprintf (fp
, " ID: 0x%08lX\n",
677 gpgsm_get_short_fingerprint (cert
, NULL
));
679 sexp
= ksba_cert_get_serial (cert
);
680 es_fputs (" S/N: ", fp
);
681 gpgsm_print_serial (fp
, sexp
);
685 dn
= ksba_cert_get_issuer (cert
, 0);
686 es_fputs (" Issuer: ", fp
);
687 print_name_raw (fp
, dn
);
690 for (idx
=1; (dn
= ksba_cert_get_issuer (cert
, idx
)); idx
++)
692 es_fputs (" aka: ", fp
);
693 print_name_raw (fp
, dn
);
698 dn
= ksba_cert_get_subject (cert
, 0);
699 es_fputs (" Subject: ", fp
);
700 print_name_raw (fp
, dn
);
703 for (idx
=1; (dn
= ksba_cert_get_subject (cert
, idx
)); idx
++)
705 es_fputs (" aka: ", fp
);
706 print_name_raw (fp
, dn
);
711 dn
= gpgsm_get_fingerprint_string (cert
, 0);
712 es_fprintf (fp
, " sha1_fpr: %s\n", dn
?dn
:"error");
715 dn
= gpgsm_get_fingerprint_string (cert
, GCRY_MD_MD5
);
716 es_fprintf (fp
, " md5_fpr: %s\n", dn
?dn
:"error");
719 dn
= gpgsm_get_certid (cert
);
720 es_fprintf (fp
, " certid: %s\n", dn
?dn
:"error");
723 dn
= gpgsm_get_keygrip_hexstring (cert
);
724 es_fprintf (fp
, " keygrip: %s\n", dn
?dn
:"error");
727 ksba_cert_get_validity (cert
, 0, t
);
728 es_fputs (" notBefore: ", fp
);
729 gpgsm_print_time (fp
, t
);
731 es_fputs (" notAfter: ", fp
);
732 ksba_cert_get_validity (cert
, 1, t
);
733 gpgsm_print_time (fp
, t
);
736 oid
= ksba_cert_get_digest_algo (cert
);
737 s
= get_oid_desc (oid
, NULL
);
738 es_fprintf (fp
, " hashAlgo: %s%s%s%s\n", oid
, s
?" (":"",s
?s
:"",s
?")":"");
741 const char *algoname
;
744 algoname
= gcry_pk_algo_name (gpgsm_get_key_algo_info (cert
, &nbits
));
745 es_fprintf (fp
, " keyType: %u bit %s\n",
746 nbits
, algoname
? algoname
:"?");
749 /* subjectKeyIdentifier */
750 es_fputs (" subjKeyId: ", fp
);
751 err
= ksba_cert_get_subj_key_id (cert
, NULL
, &keyid
);
752 if (!err
|| gpg_err_code (err
) == GPG_ERR_NO_DATA
)
754 if (gpg_err_code (err
) == GPG_ERR_NO_DATA
)
755 es_fputs ("[none]\n", fp
);
758 gpgsm_print_serial (fp
, keyid
);
764 es_fputs ("[?]\n", fp
);
767 /* authorityKeyIdentifier */
768 es_fputs (" authKeyId: ", fp
);
769 err
= ksba_cert_get_auth_key_id (cert
, &keyid
, &name
, &sexp
);
770 if (!err
|| gpg_err_code (err
) == GPG_ERR_NO_DATA
)
772 if (gpg_err_code (err
) == GPG_ERR_NO_DATA
|| !name
)
773 es_fputs ("[none]\n", fp
);
776 gpgsm_print_serial (fp
, sexp
);
779 print_names_raw (fp
, -15, name
);
780 ksba_name_release (name
);
784 es_fputs (" authKeyId.ki: ", fp
);
785 gpgsm_print_serial (fp
, keyid
);
791 es_fputs ("[?]\n", fp
);
793 es_fputs (" keyUsage:", fp
);
794 err
= ksba_cert_get_key_usage (cert
, &kusage
);
795 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
798 es_fprintf (fp
, " [error: %s]", gpg_strerror (err
));
801 if ( (kusage
& KSBA_KEYUSAGE_DIGITAL_SIGNATURE
))
802 es_fputs (" digitalSignature", fp
);
803 if ( (kusage
& KSBA_KEYUSAGE_NON_REPUDIATION
))
804 es_fputs (" nonRepudiation", fp
);
805 if ( (kusage
& KSBA_KEYUSAGE_KEY_ENCIPHERMENT
))
806 es_fputs (" keyEncipherment", fp
);
807 if ( (kusage
& KSBA_KEYUSAGE_DATA_ENCIPHERMENT
))
808 es_fputs (" dataEncipherment", fp
);
809 if ( (kusage
& KSBA_KEYUSAGE_KEY_AGREEMENT
))
810 es_fputs (" keyAgreement", fp
);
811 if ( (kusage
& KSBA_KEYUSAGE_KEY_CERT_SIGN
))
812 es_fputs (" certSign", fp
);
813 if ( (kusage
& KSBA_KEYUSAGE_CRL_SIGN
))
814 es_fputs (" crlSign", fp
);
815 if ( (kusage
& KSBA_KEYUSAGE_ENCIPHER_ONLY
))
816 es_fputs (" encipherOnly", fp
);
817 if ( (kusage
& KSBA_KEYUSAGE_DECIPHER_ONLY
))
818 es_fputs (" decipherOnly", fp
);
823 es_fputs (" [none]\n", fp
);
825 es_fputs (" extKeyUsage: ", fp
);
826 err
= ksba_cert_get_ext_key_usages (cert
, &string
);
827 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
830 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
834 while (p
&& (pend
=strchr (p
, ':')))
837 for (i
=0; key_purpose_map
[i
].oid
; i
++)
838 if ( !strcmp (key_purpose_map
[i
].oid
, p
) )
840 es_fputs (key_purpose_map
[i
].oid
?key_purpose_map
[i
].name
:p
, fp
);
843 es_fputs (" (suggested)", fp
);
844 if ((p
= strchr (p
, '\n')))
847 es_fputs ("\n ", fp
);
855 es_fputs ("[none]\n", fp
);
858 es_fputs (" policies: ", fp
);
859 err
= ksba_cert_get_cert_policies (cert
, &string
);
860 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
863 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
867 while (p
&& (pend
=strchr (p
, ':')))
870 for (i
=0; key_purpose_map
[i
].oid
; i
++)
871 if ( !strcmp (key_purpose_map
[i
].oid
, p
) )
876 es_fputs (" (critical)", fp
);
877 if ((p
= strchr (p
, '\n')))
880 es_fputs ("\n ", fp
);
888 es_fputs ("[none]\n", fp
);
890 es_fputs (" chainLength: ", fp
);
891 err
= ksba_cert_is_ca (cert
, &is_ca
, &chainlen
);
894 if (gpg_err_code (err
) == GPG_ERR_NO_VALUE
)
895 es_fprintf (fp
, "[none]");
897 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
898 else if (chainlen
== -1)
899 es_fputs ("unlimited", fp
);
901 es_fprintf (fp
, "%d", chainlen
);
905 es_fputs ("not a CA\n", fp
);
908 /* CRL distribution point */
909 for (idx
=0; !(err
=ksba_cert_get_crl_dist_point (cert
, idx
, &name
, &name2
,
912 es_fputs (" crlDP: ", fp
);
913 print_names_raw (fp
, 15, name
);
916 es_fputs (" reason: ", fp
);
917 if ( (reason
& KSBA_CRLREASON_UNSPECIFIED
))
918 es_fputs (" unused", fp
);
919 if ( (reason
& KSBA_CRLREASON_KEY_COMPROMISE
))
920 es_fputs (" keyCompromise", fp
);
921 if ( (reason
& KSBA_CRLREASON_CA_COMPROMISE
))
922 es_fputs (" caCompromise", fp
);
923 if ( (reason
& KSBA_CRLREASON_AFFILIATION_CHANGED
))
924 es_fputs (" affiliationChanged", fp
);
925 if ( (reason
& KSBA_CRLREASON_SUPERSEDED
))
926 es_fputs (" superseded", fp
);
927 if ( (reason
& KSBA_CRLREASON_CESSATION_OF_OPERATION
))
928 es_fputs (" cessationOfOperation", fp
);
929 if ( (reason
& KSBA_CRLREASON_CERTIFICATE_HOLD
))
930 es_fputs (" certificateHold", fp
);
933 es_fputs (" issuer: ", fp
);
934 print_names_raw (fp
, 23, name2
);
935 ksba_name_release (name
);
936 ksba_name_release (name2
);
938 if (err
&& gpg_err_code (err
) != GPG_ERR_EOF
939 && gpg_err_code (err
) != GPG_ERR_NO_VALUE
)
940 es_fputs (" crlDP: [error]\n", fp
);
942 es_fputs (" crlDP: [none]\n", fp
);
945 /* authorityInfoAccess. */
946 for (idx
=0; !(err
=ksba_cert_get_authority_info_access (cert
, idx
, &string
,
949 es_fputs (" authInfo: ", fp
);
950 s
= get_oid_desc (string
, NULL
);
951 es_fprintf (fp
, "%s%s%s%s\n", string
, s
?" (":"", s
?s
:"", s
?")":"");
952 print_names_raw (fp
, -15, name
);
953 ksba_name_release (name
);
956 if (err
&& gpg_err_code (err
) != GPG_ERR_EOF
957 && gpg_err_code (err
) != GPG_ERR_NO_VALUE
)
958 es_fputs (" authInfo: [error]\n", fp
);
960 es_fputs (" authInfo: [none]\n", fp
);
962 /* subjectInfoAccess. */
963 for (idx
=0; !(err
=ksba_cert_get_subject_info_access (cert
, idx
, &string
,
966 es_fputs (" subjectInfo: ", fp
);
967 s
= get_oid_desc (string
, NULL
);
968 es_fprintf (fp
, "%s%s%s%s\n", string
, s
?" (":"", s
?s
:"", s
?")":"");
969 print_names_raw (fp
, -15, name
);
970 ksba_name_release (name
);
973 if (err
&& gpg_err_code (err
) != GPG_ERR_EOF
974 && gpg_err_code (err
) != GPG_ERR_NO_VALUE
)
975 es_fputs (" subjInfo: [error]\n", fp
);
977 es_fputs (" subjInfo: [none]\n", fp
);
980 for (idx
=0; !(err
=ksba_cert_get_extension (cert
, idx
,
981 &oid
, &i
, &off
, &len
));idx
++)
985 s
= get_oid_desc (oid
, &flag
);
986 if ((flag
& OID_FLAG_SKIP
))
989 es_fprintf (fp
, " %s: %s%s%s%s [%d octets]\n",
990 i
? "critExtn":" extn",
991 oid
, s
?" (":"", s
?s
:"", s
?")":"", (int)len
);
992 if ((flag
& OID_FLAG_UTF8
))
995 cert_der
= ksba_cert_get_image (cert
, NULL
);
997 print_utf8_extn_raw (fp
, -15, cert_der
+off
, len
);
1002 if (with_validation
)
1004 err
= gpgsm_validate_chain (ctrl
, cert
, "", NULL
, 1, fp
, 0, NULL
);
1006 es_fprintf (fp
, " [certificate is good]\n");
1008 es_fprintf (fp
, " [certificate is bad: %s]\n", gpg_strerror (err
));
1013 unsigned int blobflags
;
1015 err
= keydb_get_flags (hd
, KEYBOX_FLAG_BLOB
, 0, &blobflags
);
1017 es_fprintf (fp
, " [error getting keyflags: %s]\n",gpg_strerror (err
));
1018 else if ((blobflags
& KEYBOX_FLAG_BLOB_EPHEMERAL
))
1019 es_fprintf (fp
, " [stored as ephemeral]\n");
1027 /* List one certificate in standard mode */
1029 list_cert_std (ctrl_t ctrl
, ksba_cert_t cert
, estream_t fp
, int have_secret
,
1030 int with_validation
)
1037 int is_ca
, chainlen
;
1038 unsigned int kusage
;
1039 char *string
, *p
, *pend
;
1042 const unsigned char *cert_der
= NULL
;
1045 es_fprintf (fp
, " ID: 0x%08lX\n",
1046 gpgsm_get_short_fingerprint (cert
, NULL
));
1048 sexp
= ksba_cert_get_serial (cert
);
1049 es_fputs (" S/N: ", fp
);
1050 gpgsm_print_serial (fp
, sexp
);
1054 dn
= ksba_cert_get_issuer (cert
, 0);
1055 es_fputs (" Issuer: ", fp
);
1056 gpgsm_es_print_name (fp
, dn
);
1059 for (idx
=1; (dn
= ksba_cert_get_issuer (cert
, idx
)); idx
++)
1061 es_fputs (" aka: ", fp
);
1062 gpgsm_es_print_name (fp
, dn
);
1067 dn
= ksba_cert_get_subject (cert
, 0);
1068 es_fputs (" Subject: ", fp
);
1069 gpgsm_es_print_name (fp
, dn
);
1072 for (idx
=1; (dn
= ksba_cert_get_subject (cert
, idx
)); idx
++)
1074 es_fputs (" aka: ", fp
);
1075 gpgsm_es_print_name (fp
, dn
);
1080 ksba_cert_get_validity (cert
, 0, t
);
1081 es_fputs (" validity: ", fp
);
1082 gpgsm_print_time (fp
, t
);
1083 es_fputs (" through ", fp
);
1084 ksba_cert_get_validity (cert
, 1, t
);
1085 gpgsm_print_time (fp
, t
);
1090 const char *algoname
;
1093 algoname
= gcry_pk_algo_name (gpgsm_get_key_algo_info (cert
, &nbits
));
1094 es_fprintf (fp
, " key type: %u bit %s\n",
1095 nbits
, algoname
? algoname
:"?");
1099 err
= ksba_cert_get_key_usage (cert
, &kusage
);
1100 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
1102 es_fputs (" key usage:", fp
);
1104 es_fprintf (fp
, " [error: %s]", gpg_strerror (err
));
1107 if ( (kusage
& KSBA_KEYUSAGE_DIGITAL_SIGNATURE
))
1108 es_fputs (" digitalSignature", fp
);
1109 if ( (kusage
& KSBA_KEYUSAGE_NON_REPUDIATION
))
1110 es_fputs (" nonRepudiation", fp
);
1111 if ( (kusage
& KSBA_KEYUSAGE_KEY_ENCIPHERMENT
))
1112 es_fputs (" keyEncipherment", fp
);
1113 if ( (kusage
& KSBA_KEYUSAGE_DATA_ENCIPHERMENT
))
1114 es_fputs (" dataEncipherment", fp
);
1115 if ( (kusage
& KSBA_KEYUSAGE_KEY_AGREEMENT
))
1116 es_fputs (" keyAgreement", fp
);
1117 if ( (kusage
& KSBA_KEYUSAGE_KEY_CERT_SIGN
))
1118 es_fputs (" certSign", fp
);
1119 if ( (kusage
& KSBA_KEYUSAGE_CRL_SIGN
))
1120 es_fputs (" crlSign", fp
);
1121 if ( (kusage
& KSBA_KEYUSAGE_ENCIPHER_ONLY
))
1122 es_fputs (" encipherOnly", fp
);
1123 if ( (kusage
& KSBA_KEYUSAGE_DECIPHER_ONLY
))
1124 es_fputs (" decipherOnly", fp
);
1129 err
= ksba_cert_get_ext_key_usages (cert
, &string
);
1130 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
1132 es_fputs ("ext key usage: ", fp
);
1134 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
1138 while (p
&& (pend
=strchr (p
, ':')))
1141 for (i
=0; key_purpose_map
[i
].oid
; i
++)
1142 if ( !strcmp (key_purpose_map
[i
].oid
, p
) )
1144 es_fputs (key_purpose_map
[i
].oid
?key_purpose_map
[i
].name
:p
, fp
);
1147 es_fputs (" (suggested)", fp
);
1148 if ((p
= strchr (p
, '\n')))
1151 es_fputs (", ", fp
);
1159 /* Print restrictions. */
1160 for (idx
=0; !(err
=ksba_cert_get_extension (cert
, idx
,
1161 &oid
, NULL
, &off
, &len
));idx
++)
1163 if (!strcmp (oid
, OIDSTR_restriction
) )
1166 cert_der
= ksba_cert_get_image (cert
, NULL
);
1168 es_fputs (" restriction: ", fp
);
1169 print_utf8_extn (fp
, 15, cert_der
+off
, len
);
1173 /* Print policies. */
1174 err
= ksba_cert_get_cert_policies (cert
, &string
);
1175 if (gpg_err_code (err
) != GPG_ERR_NO_DATA
)
1177 es_fputs (" policies: ", fp
);
1179 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
1182 for (p
=string
; *p
; p
++)
1187 es_write_sanitized (fp
, string
, strlen (string
), NULL
, NULL
);
1193 err
= ksba_cert_is_ca (cert
, &is_ca
, &chainlen
);
1196 es_fputs (" chain length: ", fp
);
1197 if (gpg_err_code (err
) == GPG_ERR_NO_VALUE
)
1198 es_fprintf (fp
, "none");
1200 es_fprintf (fp
, "[error: %s]", gpg_strerror (err
));
1201 else if (chainlen
== -1)
1202 es_fputs ("unlimited", fp
);
1204 es_fprintf (fp
, "%d", chainlen
);
1208 if (opt
.with_md5_fingerprint
)
1210 dn
= gpgsm_get_fingerprint_string (cert
, GCRY_MD_MD5
);
1211 es_fprintf (fp
, " md5 fpr: %s\n", dn
?dn
:"error");
1215 dn
= gpgsm_get_fingerprint_string (cert
, 0);
1216 es_fprintf (fp
, " fingerprint: %s\n", dn
?dn
:"error");
1223 p
= gpgsm_get_keygrip_hexstring (cert
);
1224 if (!gpgsm_agent_keyinfo (ctrl
, p
, &cardsn
) && cardsn
)
1225 es_fprintf (fp
, " card s/n: %s\n", cardsn
);
1230 if (with_validation
)
1236 err
= gpgsm_validate_chain (ctrl
, cert
, "", NULL
, 1, fp
, 0, NULL
);
1237 tmperr
= ksba_cert_get_user_data (cert
, "is_qualified",
1238 &buffer
, sizeof (buffer
), &buflen
);
1239 if (!tmperr
&& buflen
)
1242 es_fputs (" [qualified]\n", fp
);
1244 else if (gpg_err_code (tmperr
) == GPG_ERR_NOT_FOUND
)
1245 ; /* Don't know - will not get marked as 'q' */
1247 log_debug ("get_user_data(is_qualified) failed: %s\n",
1248 gpg_strerror (tmperr
));
1251 es_fprintf (fp
, " [certificate is good]\n");
1253 es_fprintf (fp
, " [certificate is bad: %s]\n", gpg_strerror (err
));
1258 /* Same as standard mode mode list all certifying certs too. */
1260 list_cert_chain (ctrl_t ctrl
, KEYDB_HANDLE hd
,
1261 ksba_cert_t cert
, int raw_mode
,
1262 estream_t fp
, int with_validation
)
1264 ksba_cert_t next
= NULL
;
1267 list_cert_raw (ctrl
, hd
, cert
, fp
, 0, with_validation
);
1269 list_cert_std (ctrl
, cert
, fp
, 0, with_validation
);
1270 ksba_cert_ref (cert
);
1271 while (!gpgsm_walk_cert_chain (ctrl
, cert
, &next
))
1273 ksba_cert_release (cert
);
1274 es_fputs ("Certified by\n", fp
);
1276 list_cert_raw (ctrl
, hd
, next
, fp
, 0, with_validation
);
1278 list_cert_std (ctrl
, next
, fp
, 0, with_validation
);
1281 ksba_cert_release (cert
);
1287 /* List all internal keys or just the keys given as NAMES. MODE is a
1288 bit vector to specify what keys are to be included; see
1289 gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
1290 output mode will be used instead of the standard beautified one.
1293 list_internal_keys (ctrl_t ctrl
, strlist_t names
, estream_t fp
,
1294 unsigned int mode
, int raw_mode
)
1297 KEYDB_SEARCH_DESC
*desc
= NULL
;
1300 ksba_cert_t cert
= NULL
;
1301 ksba_cert_t lastcert
= NULL
;
1303 const char *lastresname
, *resname
;
1305 int want_ephemeral
= ctrl
->with_ephemeral_keys
;
1310 log_error ("keydb_new failed\n");
1311 rc
= gpg_error (GPG_ERR_GENERAL
);
1319 for (sl
=names
, ndesc
=0; sl
; sl
= sl
->next
, ndesc
++)
1323 desc
= xtrycalloc (ndesc
, sizeof *desc
);
1326 rc
= gpg_error_from_syserror ();
1327 log_error ("out of core\n");
1332 desc
[0].mode
= KEYDB_SEARCH_MODE_FIRST
;
1335 for (ndesc
=0, sl
=names
; sl
; sl
= sl
->next
)
1337 rc
= keydb_classify_name (sl
->d
, desc
+ndesc
);
1340 log_error ("key `%s' not found: %s\n",
1341 sl
->d
, gpg_strerror (rc
));
1350 /* If all specifications are done by fingerprint or keygrip, we
1351 switch to ephemeral mode so that _all_ currently available and
1352 matching certificates are listed. */
1353 if (!want_ephemeral
&& names
&& ndesc
)
1357 for (i
=0; (i
< ndesc
1358 && (desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR
1359 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR20
1360 || desc
[i
].mode
== KEYDB_SEARCH_MODE_FPR16
1361 || desc
[i
].mode
== KEYDB_SEARCH_MODE_KEYGRIP
)); i
++)
1368 keydb_set_ephemeral (hd
, 1);
1370 /* It would be nice to see which of the given users did actually
1371 match one in the keyring. To implement this we need to have a
1372 found flag for each entry in desc and to set this we must check
1373 all those entries after a match to mark all matched one -
1374 currently we stop at the first match. To do this we need an
1375 extra flag to enable this feature so */
1377 /* Suppress duplicates at least when they follow each other. */
1379 while (!(rc
= keydb_search (hd
, desc
, ndesc
)))
1381 unsigned int validity
;
1384 desc
[0].mode
= KEYDB_SEARCH_MODE_NEXT
;
1386 rc
= keydb_get_flags (hd
, KEYBOX_FLAG_VALIDITY
, 0, &validity
);
1389 log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc
));
1392 rc
= keydb_get_cert (hd
, &cert
);
1395 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc
));
1398 /* Skip duplicated certificates, at least if they follow each
1399 others. This works best if a single key is searched for and
1400 expected. FIXME: Non-sequential duplicates remain. */
1401 if (gpgsm_certs_identical_p (cert
, lastcert
))
1403 ksba_cert_release (cert
);
1408 resname
= keydb_get_resource_name (hd
);
1410 if (lastresname
!= resname
)
1414 if (ctrl
->no_server
)
1416 es_fprintf (fp
, "%s\n", resname
);
1417 for (i
=strlen(resname
); i
; i
-- )
1420 lastresname
= resname
;
1427 char *p
= gpgsm_get_keygrip_hexstring (cert
);
1430 rc
= gpgsm_agent_havekey (ctrl
, p
);
1433 else if ( gpg_err_code (rc
) != GPG_ERR_NO_SECKEY
)
1441 || ((mode
& 1) && !have_secret
)
1442 || ((mode
& 2) && have_secret
) )
1444 if (ctrl
->with_colons
)
1445 list_cert_colon (ctrl
, cert
, validity
, fp
, have_secret
);
1446 else if (ctrl
->with_chain
)
1447 list_cert_chain (ctrl
, hd
, cert
,
1448 raw_mode
, fp
, ctrl
->with_validation
);
1452 list_cert_raw (ctrl
, hd
, cert
, fp
, have_secret
,
1453 ctrl
->with_validation
);
1455 list_cert_std (ctrl
, cert
, fp
, have_secret
,
1456 ctrl
->with_validation
);
1461 ksba_cert_release (lastcert
);
1465 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| rc
== -1 )
1468 log_error ("keydb_search failed: %s\n", gpg_strerror (rc
));
1471 ksba_cert_release (cert
);
1472 ksba_cert_release (lastcert
);
1481 list_external_cb (void *cb_value
, ksba_cert_t cert
)
1483 struct list_external_parm_s
*parm
= cb_value
;
1485 if (keydb_store_cert (cert
, 1, NULL
))
1486 log_error ("error storing certificate as ephemeral\n");
1488 if (parm
->print_header
)
1490 const char *resname
= "[external keys]";
1493 es_fprintf (parm
->fp
, "%s\n", resname
);
1494 for (i
=strlen(resname
); i
; i
-- )
1495 es_putc('-', parm
->fp
);
1496 es_putc ('\n', parm
->fp
);
1497 parm
->print_header
= 0;
1500 if (parm
->with_colons
)
1501 list_cert_colon (parm
->ctrl
, cert
, 0, parm
->fp
, 0);
1502 else if (parm
->with_chain
)
1503 list_cert_chain (parm
->ctrl
, NULL
, cert
, parm
->raw_mode
, parm
->fp
, 0);
1507 list_cert_raw (parm
->ctrl
, NULL
, cert
, parm
->fp
, 0, 0);
1509 list_cert_std (parm
->ctrl
, cert
, parm
->fp
, 0, 0);
1510 es_putc ('\n', parm
->fp
);
1515 /* List external keys similar to internal one. Note: mode does not
1516 make sense here because it would be unwise to list external secret
1519 list_external_keys (ctrl_t ctrl
, strlist_t names
, estream_t fp
, int raw_mode
)
1522 struct list_external_parm_s parm
;
1526 parm
.print_header
= ctrl
->no_server
;
1527 parm
.with_colons
= ctrl
->with_colons
;
1528 parm
.with_chain
= ctrl
->with_chain
;
1529 parm
.raw_mode
= raw_mode
;
1531 rc
= gpgsm_dirmngr_lookup (ctrl
, names
, 0, list_external_cb
, &parm
);
1532 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| rc
== -1
1533 || gpg_err_code (rc
) == GPG_ERR_NOT_FOUND
)
1534 rc
= 0; /* "Not found" is not an error here. */
1536 log_error ("listing external keys failed: %s\n", gpg_strerror (rc
));
1540 /* List all keys or just the key given as NAMES.
1541 MODE controls the operation mode:
1543 0 = list all public keys but don't flag secret ones
1544 1 = list only public keys
1545 2 = list only secret keys
1546 3 = list secret and public keys
1547 Bit 6: list internal keys
1548 Bit 7: list external keys
1549 Bit 8: Do a raw format dump.
1552 gpgsm_list_keys (ctrl_t ctrl
, strlist_t names
, estream_t fp
,
1555 gpg_error_t err
= 0;
1557 if ((mode
& (1<<6)))
1558 err
= list_internal_keys (ctrl
, names
, fp
, (mode
& 3), (mode
&256));
1559 if (!err
&& (mode
& (1<<7)))
1560 err
= list_external_keys (ctrl
, names
, fp
, (mode
&256));