1 /* keylist.c - Print certificates in various formats.
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2008, 2009,
3 * 2010, 2011 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 <https://www.gnu.org/licenses/>.
36 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
37 #include "../common/i18n.h"
38 #include "../common/tlv.h"
39 #include "../common/compliance.h"
41 struct list_external_parm_s
52 /* This table is to map Extended Key Usage OIDs to human readable
58 } key_purpose_map[] = {
59 { "1.3.6.1.5.5.7.3.1", "serverAuth" },
60 { "1.3.6.1.5.5.7.3.2", "clientAuth" },
61 { "1.3.6.1.5.5.7.3.3", "codeSigning" },
62 { "1.3.6.1.5.5.7.3.4", "emailProtection" },
63 { "1.3.6.1.5.5.7.3.5", "ipsecEndSystem" },
64 { "1.3.6.1.5.5.7.3.6", "ipsecTunnel" },
65 { "1.3.6.1.5.5.7.3.7", "ipsecUser" },
66 { "1.3.6.1.5.5.7.3.8", "timeStamping" },
67 { "1.3.6.1.5.5.7.3.9", "ocspSigning" },
68 { "1.3.6.1.5.5.7.3.10", "dvcs" },
69 { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
70 { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
71 { "1.3.6.1.5.5.7.3.14", "wlanSSID" },
73 { "2.16.840.1.113730.4.1", "serverGatedCrypto.ns" }, /* Netscape. */
74 { "1.3.6.1.4.1.311.10.3.3", "serverGatedCrypto.ms"}, /* Microsoft. */
76 { "1.3.6.1.5.5.7.48.1.5", "ocspNoCheck" },
82 /* Do not print this extension in the list of extensions. This is set
83 for oids which are already available via ksba functions. */
84 #define OID_FLAG_SKIP 1
85 /* The extension is a simple UTF8String and should be printed. */
86 #define OID_FLAG_UTF8 2
87 /* The extension can be trnted as a hex string. */
88 #define OID_FLAG_HEX 4
90 /* A table mapping OIDs to a descriptive string. */
95 unsigned int flag; /* A flag as described above. */
99 { "1.2.840.10040.4.1", "dsa" },
100 { "1.2.840.10040.4.3", "dsaWithSha1" },
102 { "1.2.840.113549.1.1.1", "rsaEncryption" },
103 { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
104 { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
105 { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
106 { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
107 { "1.2.840.113549.1.1.7", "rsaOAEP" },
108 { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
109 { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
110 { "1.2.840.113549.1.1.10", "rsaPSS" },
111 { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
112 { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
113 { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
115 { "1.3.14.3.2.26", "sha1" },
116 { "1.3.14.3.2.29", "sha-1WithRSAEncryption" },
117 { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
120 /* Telesec extensions. */
121 { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
122 { "0.2.262.1.10.12.1", "telesecCertIdExt" },
123 { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
124 { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
125 { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
126 { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
127 { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
128 #define OIDSTR_restriction \
130 { OIDSTR_restriction, "restriction", OID_FLAG_UTF8 },
133 /* PKIX private extensions. */
134 { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
135 { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
136 { "1.3.6.1.5.5.7.1.3", "qcStatements" },
137 { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
138 { "1.3.6.1.5.5.7.1.5", "acTargeting" },
139 { "1.3.6.1.5.5.7.1.6", "acAaControls" },
140 { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
141 { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
142 { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
143 { "1.3.6.1.5.5.7.1.10", "acProxying" },
144 { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
146 { "1.3.6.1.5.5.7.48.1", "ocsp" },
147 { "1.3.6.1.5.5.7.48.2", "caIssuers" },
148 { "1.3.6.1.5.5.7.48.3", "timeStamping" },
149 { "1.3.6.1.5.5.7.48.5", "caRepository" },
152 { "2.5.29.14", "subjectKeyIdentifier", OID_FLAG_SKIP},
153 { "2.5.29.15", "keyUsage", OID_FLAG_SKIP},
154 { "2.5.29.16", "privateKeyUsagePeriod" },
155 { "2.5.29.17", "subjectAltName", OID_FLAG_SKIP},
156 { "2.5.29.18", "issuerAltName", OID_FLAG_SKIP},
157 { "2.5.29.19", "basicConstraints", OID_FLAG_SKIP},
158 { "2.5.29.20", "cRLNumber" },
159 { "2.5.29.21", "cRLReason" },
160 { "2.5.29.22", "expirationDate" },
161 { "2.5.29.23", "instructionCode" },
162 { "2.5.29.24", "invalidityDate" },
163 { "2.5.29.27", "deltaCRLIndicator" },
164 { "2.5.29.28", "issuingDistributionPoint" },
165 { "2.5.29.29", "certificateIssuer" },
166 { "2.5.29.30", "nameConstraints" },
167 { "2.5.29.31", "cRLDistributionPoints", OID_FLAG_SKIP},
168 { "2.5.29.32", "certificatePolicies", OID_FLAG_SKIP},
169 { "2.5.29.32.0", "anyPolicy" },
170 { "2.5.29.33", "policyMappings" },
171 { "2.5.29.35", "authorityKeyIdentifier", OID_FLAG_SKIP},
172 { "2.5.29.36", "policyConstraints" },
173 { "2.5.29.37", "extKeyUsage", OID_FLAG_SKIP},
174 { "2.5.29.46", "freshestCRL" },
175 { "2.5.29.54", "inhibitAnyPolicy" },
177 /* Netscape certificate extensions. */
178 { "2.16.840.1.113730.1.1", "netscape-cert-type" },
179 { "2.16.840.1.113730.1.2", "netscape-base-url" },
180 { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
181 { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
182 { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
183 { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
184 { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
185 { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
186 { "2.16.840.1.113730.1.11", "netscape-userPicture" },
187 { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
188 { "2.16.840.1.113730.1.13", "netscape-comment" },
190 /* GnuPG extensions */
191 { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
192 { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" },
193 { "1.3.6.1.4.1.11591.2.2.2", "wellKnownPrivateKey" },
195 /* Extensions used by the Bundesnetzagentur. */
196 { "1.3.6.1.4.1.8301.3.5", "validityModel" },
198 /* Yubikey extensions for attestation certificates. */
199 { "1.3.6.1.4.1.41482.3.3", "yubikey-firmware-version", OID_FLAG_HEX },
200 { "1.3.6.1.4.1.41482.3.7", "yubikey-serial-number", OID_FLAG_HEX },
201 { "1.3.6.1.4.1.41482.3.8", "yubikey-pin-touch-policy", OID_FLAG_HEX },
202 { "1.3.6.1.4.1.41482.3.9", "yubikey-formfactor", OID_FLAG_HEX },
208 /* Return the description for OID; if no description is available
211 get_oid_desc (const char *oid, unsigned int *flag)
216 for (i=0; oidtranstbl[i].oid; i++)
217 if (!strcmp (oidtranstbl[i].oid, oid))
220 *flag = oidtranstbl[i].flag;
221 return oidtranstbl[i].name;
230 print_key_data (ksba_cert_t cert, estream_t fp)
233 int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
236 for(i=0; i < n; i++ )
238 es_fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
239 mpi_print(stdout, pk->pkey[i], 1 );
250 print_capabilities (ksba_cert_t cert, estream_t fp)
254 unsigned int is_encr, is_sign, is_cert;
259 err = ksba_cert_get_user_data (cert, "is_qualified",
260 &buffer, sizeof (buffer), &buflen);
266 else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
267 ; /* Don't know - will not get marked as 'q' */
269 log_debug ("get_user_data(is_qualified) failed: %s\n",
272 err = ksba_cert_get_key_usage (cert, &use);
273 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
285 log_error (_("error getting key usage information: %s\n"),
290 is_encr = is_sign = is_cert = 0;
292 if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
294 if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
296 if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
299 /* We need to returned the faked key usage to frontends so that they
300 * can select the right key. Note that we don't do this for the
301 * human readable keyUsage. */
302 if ((opt.compat_flags & COMPAT_ALLOW_KA_TO_ENCR)
303 && (use & KSBA_KEYUSAGE_KEY_AGREEMENT))
322 print_time (gnupg_isotime_t t, estream_t fp)
331 /* Return an allocated string with the email address extracted from a
332 DN. Note hat we use this code also in ../kbx/keybox-blob.c. */
334 email_kludge (const char *name)
336 const char *p, *string;
343 p = strstr (string, "1.2.840.113549.1.9.1=#");
346 if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
355 /* This looks pretty much like an email address in the subject's DN
356 we use this to add an additional user ID entry. This way,
357 OpenSSL generated keys get a nicer and usable listing. */
358 for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
362 buf = xtrymalloc (n+3);
364 return NULL; /* oops, out of core */
366 for (n=1, p=name; hexdigitp (p); p +=2, n++)
374 /* Print the compliance flags to field 18. ALGO is the gcrypt algo
375 * number. NBITS is the length of the key in bits. */
377 print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits,
382 /* Note that we do not need to test for PK_ALGO_FLAG_RSAPSS because
383 * that is not a property of the key but one of the created
385 if (gnupg_pk_is_compliant (CO_DE_VS, algo, 0, NULL, nbits, NULL))
387 hashalgo = gcry_md_map_name (ksba_cert_get_digest_algo (cert));
388 if (gnupg_digest_is_compliant (CO_DE_VS, hashalgo))
390 es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
396 /* List one certificate in colon mode */
398 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
399 estream_t fp, int have_secret)
411 const char *chain_id;
412 char *chain_id_buffer = NULL;
416 if (ctrl->with_validation)
417 valerr = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, NULL, 0, NULL);
422 /* We need to get the fingerprint and the chaining ID in advance. */
423 fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
427 rc = gpgsm_walk_cert_chain (ctrl, cert, &next);
428 if (!rc) /* We known the issuer's certificate. */
430 p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
432 chain_id = chain_id_buffer;
433 ksba_cert_release (next);
435 else if (rc == -1) /* We have reached the root certificate. */
445 es_fputs (have_secret? "crs:":"crt:", fp);
447 /* Note: We can't use multiple flags, like "ei", because the
448 validation check does only return one error. */
451 if ((validity & VALIDITY_REVOKED)
452 || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
454 else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
458 /* Lets also check whether the certificate under question
459 expired. This is merely a hack until we found a proper way
460 to store the expiration flag in the keybox. */
461 ksba_isotime_t current_time, not_after;
463 gnupg_get_isotime (current_time);
464 if (!opt.ignore_expiration
465 && !ksba_cert_get_validity (cert, 1, not_after)
466 && *not_after && strcmp (current_time, not_after) > 0 )
470 if (gpgsm_cert_has_well_known_private_key (cert))
471 *truststring = 'w'; /* Well, this is dummy CA. */
475 else if (ctrl->with_validation && !is_root)
479 /* If we have no truststring yet (i.e. the certificate might be
480 good) and this is a root certificate, we ask the agent whether
481 this is a trusted root certificate. */
482 if (!*truststring && is_root)
484 struct rootca_flags_s dummy_flags;
486 if (gpgsm_cert_has_well_known_private_key (cert))
487 *truststring = 'w'; /* Well, this is dummy CA. */
490 rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
492 *truststring = 'u'; /* Yes, we trust this one (ultimately). */
493 else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
494 *truststring = 'n'; /* No, we do not trust this one. */
495 /* (in case of an error we can't tell anything.) */
500 es_fputs (truststring, fp);
502 algo = gpgsm_get_key_algo_info (cert, &nbits);
503 es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
505 ksba_cert_get_validity (cert, 0, t);
508 ksba_cert_get_validity (cert, 1, t);
511 /* Field 8, serial number: */
512 if ((sexp = ksba_cert_get_serial (cert)))
515 const unsigned char *s = sexp;
520 for (len=0; *s && *s != ':' && digitp (s); s++)
521 len = len*10 + atoi_1 (s);
523 for (s++; len; len--, s++)
524 es_fprintf (fp,"%02X", *s);
529 /* Field 9, ownertrust - not used here */
531 /* field 10, old user ID - we use it here for the issuer DN */
532 if ((p = ksba_cert_get_issuer (cert,0)))
534 es_write_sanitized (fp, p, strlen (p), ":", NULL);
538 /* Field 11, signature class - not used */
540 /* Field 12, capabilities: */
541 print_capabilities (cert, fp);
543 /* Field 13, not used: */
545 /* Field 14, not used: */
547 if (have_secret || ctrl->with_secret)
551 p = gpgsm_get_keygrip_hexstring (cert);
552 if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn)
553 && (cardsn || ctrl->with_secret))
555 /* Field 15: Token serial number or secret key indicator. */
557 es_fputs (cardsn, fp);
558 else if (ctrl->with_secret)
564 es_putc (':', fp); /* End of field 15. */
565 es_putc (':', fp); /* End of field 16. */
566 es_putc (':', fp); /* End of field 17. */
567 print_compliance_flags (cert, algo, nbits, fp);
568 es_putc (':', fp); /* End of field 18. */
572 es_fprintf (fp, "fpr:::::::::%s:::", fpr);
573 /* Print chaining ID (field 13)*/
575 es_fputs (chain_id, fp);
578 xfree (fpr); fpr = NULL; chain_id = NULL;
579 xfree (chain_id_buffer); chain_id_buffer = NULL;
580 /* SHA256 FPR record */
581 fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA256);
582 es_fprintf (fp, "fp2:::::::::%s::::\n", fpr);
583 xfree (fpr); fpr = NULL;
585 /* Always print the keygrip. */
586 if ( (p = gpgsm_get_keygrip_hexstring (cert)))
588 es_fprintf (fp, "grp:::::::::%s:\n", p);
592 if (opt.with_key_data)
593 print_key_data (cert, fp);
596 for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
598 /* In the case that the same email address is in the subject DN
599 as well as in an alternate subject name we avoid printing it
601 if (kludge_uid && !strcmp (kludge_uid, p))
604 es_fprintf (fp, "uid:%s::::::::", truststring);
605 es_write_sanitized (fp, p, strlen (p), ":", NULL);
611 /* It would be better to get the faked email address from
612 the keydb. But as long as we don't have a way to pass
613 the meta data back, we just check it the same way as the
614 code used to create the keybox meta data does */
615 kludge_uid = email_kludge (p);
618 es_fprintf (fp, "uid:%s::::::::", truststring);
619 es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
633 print_name_raw (estream_t fp, const char *string)
636 es_fputs ("[error]", fp);
638 es_write_sanitized (fp, string, strlen (string), NULL, NULL);
642 print_names_raw (estream_t fp, int indent, ksba_name_t name)
648 if ((indent_all = (indent < 0)))
653 es_fputs ("none\n", fp);
657 for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
659 char *p = ksba_name_get_uri (name, idx);
660 es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
661 es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
669 print_utf8_extn_raw (estream_t fp, int indent,
670 const unsigned char *der, size_t derlen)
673 int class, tag, constructed, ndef;
674 size_t objlen, hdrlen;
679 err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
680 &ndef, &objlen, &hdrlen);
681 if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
682 err = gpg_error (GPG_ERR_INV_OBJ);
685 es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
688 es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
693 print_utf8_extn (estream_t fp, int indent,
694 const unsigned char *der, size_t derlen)
697 int class, tag, constructed, ndef;
698 size_t objlen, hdrlen;
701 if ((indent_all = (indent < 0)))
704 err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
705 &ndef, &objlen, &hdrlen);
706 if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
707 err = gpg_error (GPG_ERR_INV_OBJ);
710 es_fprintf (fp, "%*s[%s%s]\n",
711 indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
714 es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
715 /* Fixme: we should implement word wrapping */
716 es_write_sanitized (fp, der, objlen, "\"", NULL);
717 es_fputs ("\"\n", fp);
721 /* Print the extension described by (DER,DERLEN) in hex. */
723 print_hex_extn (estream_t fp, int indent,
724 const unsigned char *der, size_t derlen)
729 es_fprintf (fp, "%*s(", indent, "");
730 for (; derlen; der++, derlen--)
731 es_fprintf (fp, "%02X%s", *der, derlen > 1? " ":"");
732 es_fprintf (fp, ")\n");
736 /* List one certificate in raw mode useful to have a closer look at
737 the certificate. This one does no beautification and only minimal
738 output sanitation. It is mainly useful for debugging. */
740 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
741 ksba_cert_t cert, estream_t fp, int have_secret,
746 ksba_sexp_t sexp, keyid;
752 char *string, *p, *pend;
754 ksba_name_t name, name2;
756 const unsigned char *cert_der = NULL;
760 es_fprintf (fp, " ID: 0x%08lX\n",
761 gpgsm_get_short_fingerprint (cert, NULL));
763 sexp = ksba_cert_get_serial (cert);
764 es_fputs (" S/N: ", fp);
765 gpgsm_print_serial (fp, sexp);
767 es_fputs (" (dec): ", fp);
768 gpgsm_print_serial_decimal (fp, sexp);
772 dn = ksba_cert_get_issuer (cert, 0);
773 es_fputs (" Issuer: ", fp);
774 print_name_raw (fp, dn);
777 for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
779 es_fputs (" aka: ", fp);
780 print_name_raw (fp, dn);
785 dn = ksba_cert_get_subject (cert, 0);
786 es_fputs (" Subject: ", fp);
787 print_name_raw (fp, dn);
790 for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
792 es_fputs (" aka: ", fp);
793 print_name_raw (fp, dn);
798 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA256);
799 es_fprintf (fp, " sha2_fpr: %s\n", dn?dn:"error");
802 dn = gpgsm_get_fingerprint_string (cert, 0);
803 es_fprintf (fp, " sha1_fpr: %s\n", dn?dn:"error");
806 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
807 es_fprintf (fp, " md5_fpr: %s\n", dn?dn:"error");
810 dn = gpgsm_get_certid (cert);
811 es_fprintf (fp, " certid: %s\n", dn?dn:"error");
814 dn = gpgsm_get_keygrip_hexstring (cert);
815 es_fprintf (fp, " keygrip: %s\n", dn?dn:"error");
818 ksba_cert_get_validity (cert, 0, t);
819 es_fputs (" notBefore: ", fp);
820 gpgsm_print_time (fp, t);
822 es_fputs (" notAfter: ", fp);
823 ksba_cert_get_validity (cert, 1, t);
824 gpgsm_print_time (fp, t);
827 oid = ksba_cert_get_digest_algo (cert);
828 s = get_oid_desc (oid, NULL);
829 es_fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
832 const char *algoname;
835 algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
836 es_fprintf (fp, " keyType: %u bit %s\n",
837 nbits, algoname? algoname:"?");
840 /* subjectKeyIdentifier */
841 es_fputs (" subjKeyId: ", fp);
842 err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
843 if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
845 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
846 es_fputs ("[none]\n", fp);
849 gpgsm_print_serial (fp, keyid);
855 es_fputs ("[?]\n", fp);
858 /* authorityKeyIdentifier */
859 es_fputs (" authKeyId: ", fp);
860 err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
861 if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
863 if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
864 es_fputs ("[none]\n", fp);
867 gpgsm_print_serial (fp, sexp);
870 print_names_raw (fp, -15, name);
871 ksba_name_release (name);
875 es_fputs (" authKeyId.ki: ", fp);
876 gpgsm_print_serial (fp, keyid);
882 es_fputs ("[?]\n", fp);
884 es_fputs (" keyUsage:", fp);
885 err = ksba_cert_get_key_usage (cert, &kusage);
886 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
889 es_fprintf (fp, " [error: %s]", gpg_strerror (err));
892 if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
893 es_fputs (" digitalSignature", fp);
894 if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
895 es_fputs (" nonRepudiation", fp);
896 if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
897 es_fputs (" keyEncipherment", fp);
898 if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
899 es_fputs (" dataEncipherment", fp);
900 if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
901 es_fputs (" keyAgreement", fp);
902 if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
903 es_fputs (" certSign", fp);
904 if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
905 es_fputs (" crlSign", fp);
906 if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
907 es_fputs (" encipherOnly", fp);
908 if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
909 es_fputs (" decipherOnly", fp);
914 es_fputs (" [none]\n", fp);
916 es_fputs (" extKeyUsage: ", fp);
917 err = ksba_cert_get_ext_key_usages (cert, &string);
918 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
921 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
925 while (p && (pend=strchr (p, ':')))
928 for (i=0; key_purpose_map[i].oid; i++)
929 if ( !strcmp (key_purpose_map[i].oid, p) )
931 es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
934 es_fputs (" (suggested)", fp);
935 if ((p = strchr (p, '\n')))
938 es_fputs ("\n ", fp);
946 es_fputs ("[none]\n", fp);
949 es_fputs (" policies: ", fp);
950 err = ksba_cert_get_cert_policies (cert, &string);
951 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
954 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
958 while (p && (pend=strchr (p, ':')))
961 for (i=0; key_purpose_map[i].oid; i++)
962 if ( !strcmp (key_purpose_map[i].oid, p) )
967 es_fputs (" (critical)", fp);
968 if ((p = strchr (p, '\n')))
971 es_fputs ("\n ", fp);
979 es_fputs ("[none]\n", fp);
981 es_fputs (" chainLength: ", fp);
982 err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
985 if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
986 es_fprintf (fp, "[none]");
988 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
989 else if (chainlen == -1)
990 es_fputs ("unlimited", fp);
992 es_fprintf (fp, "%d", chainlen);
996 es_fputs ("not a CA\n", fp);
999 /* CRL distribution point */
1000 for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
1003 es_fputs (" crlDP: ", fp);
1004 print_names_raw (fp, 15, name);
1007 es_fputs (" reason: ", fp);
1008 if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
1009 es_fputs (" unused", fp);
1010 if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
1011 es_fputs (" keyCompromise", fp);
1012 if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
1013 es_fputs (" caCompromise", fp);
1014 if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
1015 es_fputs (" affiliationChanged", fp);
1016 if ( (reason & KSBA_CRLREASON_SUPERSEDED))
1017 es_fputs (" superseded", fp);
1018 if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
1019 es_fputs (" cessationOfOperation", fp);
1020 if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
1021 es_fputs (" certificateHold", fp);
1024 es_fputs (" issuer: ", fp);
1025 print_names_raw (fp, 23, name2);
1026 ksba_name_release (name);
1027 ksba_name_release (name2);
1029 if (err && gpg_err_code (err) != GPG_ERR_EOF
1030 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
1031 es_fputs (" crlDP: [error]\n", fp);
1033 es_fputs (" crlDP: [none]\n", fp);
1036 /* authorityInfoAccess. */
1037 for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
1040 es_fputs (" authInfo: ", fp);
1041 s = get_oid_desc (string, NULL);
1042 es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
1043 print_names_raw (fp, -15, name);
1044 ksba_name_release (name);
1047 if (err && gpg_err_code (err) != GPG_ERR_EOF
1048 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
1049 es_fputs (" authInfo: [error]\n", fp);
1051 es_fputs (" authInfo: [none]\n", fp);
1053 /* subjectInfoAccess. */
1054 for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
1057 es_fputs (" subjectInfo: ", fp);
1058 s = get_oid_desc (string, NULL);
1059 es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
1060 print_names_raw (fp, -15, name);
1061 ksba_name_release (name);
1064 if (err && gpg_err_code (err) != GPG_ERR_EOF
1065 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
1066 es_fputs (" subjInfo: [error]\n", fp);
1068 es_fputs (" subjInfo: [none]\n", fp);
1071 for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1072 &oid, &i, &off, &len));idx++)
1076 s = get_oid_desc (oid, &flag);
1077 if ((flag & OID_FLAG_SKIP))
1080 es_fprintf (fp, " %s: %s%s%s%s",
1081 i? "critExtn":" extn",
1082 oid, s?" (":"", s?s:"", s?")":"");
1083 if ((flag & OID_FLAG_UTF8))
1086 cert_der = ksba_cert_get_image (cert, NULL);
1087 log_assert (cert_der);
1088 es_fprintf (fp, "\n");
1089 print_utf8_extn_raw (fp, -15, cert_der+off, len);
1091 else if ((flag & OID_FLAG_HEX))
1094 cert_der = ksba_cert_get_image (cert, NULL);
1095 log_assert (cert_der);
1096 es_fprintf (fp, "\n");
1097 print_hex_extn (fp, -15, cert_der+off, len);
1100 es_fprintf (fp, " [%d octets]\n", (int)len);
1104 if (with_validation)
1106 err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1108 es_fprintf (fp, " [certificate is good]\n");
1110 es_fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
1115 unsigned int blobflags;
1117 err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
1119 es_fprintf (fp, " [error getting keyflags: %s]\n",gpg_strerror (err));
1120 else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1121 es_fprintf (fp, " [stored as ephemeral]\n");
1129 /* List one certificate in standard mode */
1131 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1132 int with_validation)
1139 int is_ca, chainlen;
1140 unsigned int kusage;
1141 char *string, *p, *pend;
1144 const unsigned char *cert_der = NULL;
1147 es_fprintf (fp, " ID: 0x%08lX\n",
1148 gpgsm_get_short_fingerprint (cert, NULL));
1150 sexp = ksba_cert_get_serial (cert);
1151 es_fputs (" S/N: ", fp);
1152 gpgsm_print_serial (fp, sexp);
1154 es_fputs (" (dec): ", fp);
1155 gpgsm_print_serial_decimal (fp, sexp);
1159 dn = ksba_cert_get_issuer (cert, 0);
1160 es_fputs (" Issuer: ", fp);
1161 gpgsm_es_print_name (fp, dn);
1164 for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1166 es_fputs (" aka: ", fp);
1167 gpgsm_es_print_name (fp, dn);
1172 dn = ksba_cert_get_subject (cert, 0);
1173 es_fputs (" Subject: ", fp);
1174 gpgsm_es_print_name (fp, dn);
1177 for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1179 es_fputs (" aka: ", fp);
1180 gpgsm_es_print_name (fp, dn);
1185 ksba_cert_get_validity (cert, 0, t);
1186 es_fputs (" validity: ", fp);
1187 gpgsm_print_time (fp, t);
1188 es_fputs (" through ", fp);
1189 ksba_cert_get_validity (cert, 1, t);
1190 gpgsm_print_time (fp, t);
1195 const char *algoname;
1198 algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1199 es_fprintf (fp, " key type: %u bit %s\n",
1200 nbits, algoname? algoname:"?");
1204 err = ksba_cert_get_key_usage (cert, &kusage);
1205 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1207 es_fputs (" key usage:", fp);
1209 es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1212 if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1213 es_fputs (" digitalSignature", fp);
1214 if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
1215 es_fputs (" nonRepudiation", fp);
1216 if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
1217 es_fputs (" keyEncipherment", fp);
1218 if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1219 es_fputs (" dataEncipherment", fp);
1220 if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
1221 es_fputs (" keyAgreement", fp);
1222 if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1223 es_fputs (" certSign", fp);
1224 if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
1225 es_fputs (" crlSign", fp);
1226 if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1227 es_fputs (" encipherOnly", fp);
1228 if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
1229 es_fputs (" decipherOnly", fp);
1234 err = ksba_cert_get_ext_key_usages (cert, &string);
1235 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1237 es_fputs ("ext key usage: ", fp);
1239 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1243 while (p && (pend=strchr (p, ':')))
1246 for (i=0; key_purpose_map[i].oid; i++)
1247 if ( !strcmp (key_purpose_map[i].oid, p) )
1249 es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1252 es_fputs (" (suggested)", fp);
1253 if ((p = strchr (p, '\n')))
1256 es_fputs (", ", fp);
1264 /* Print restrictions. */
1265 for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1266 &oid, NULL, &off, &len));idx++)
1268 if (!strcmp (oid, OIDSTR_restriction) )
1271 cert_der = ksba_cert_get_image (cert, NULL);
1273 es_fputs (" restriction: ", fp);
1274 print_utf8_extn (fp, 15, cert_der+off, len);
1278 /* Print policies. */
1279 err = ksba_cert_get_cert_policies (cert, &string);
1280 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1282 es_fputs (" policies: ", fp);
1284 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1287 for (p=string; *p; p++)
1292 es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1298 err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1301 es_fputs (" chain length: ", fp);
1302 if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1303 es_fprintf (fp, "none");
1305 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1306 else if (chainlen == -1)
1307 es_fputs ("unlimited", fp);
1309 es_fprintf (fp, "%d", chainlen);
1313 if (opt.with_md5_fingerprint)
1315 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1316 es_fprintf (fp, " md5 fpr: %s\n", dn?dn:"error");
1320 dn = gpgsm_get_fingerprint_string (cert, 0);
1321 es_fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
1324 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA256);
1325 es_fprintf (fp, " sha2 fpr: %s\n", dn?dn:"error");
1328 if (opt.with_keygrip)
1330 dn = gpgsm_get_keygrip_hexstring (cert);
1333 es_fprintf (fp, " keygrip: %s\n", dn);
1342 p = gpgsm_get_keygrip_hexstring (cert);
1343 if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
1344 es_fprintf (fp, " card s/n: %s\n", cardsn);
1349 if (with_validation)
1355 err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1356 tmperr = ksba_cert_get_user_data (cert, "is_qualified",
1357 &buffer, sizeof (buffer), &buflen);
1358 if (!tmperr && buflen)
1361 es_fputs (" [qualified]\n", fp);
1363 else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1364 ; /* Don't know - will not get marked as 'q' */
1366 log_debug ("get_user_data(is_qualified) failed: %s\n",
1367 gpg_strerror (tmperr));
1370 es_fprintf (fp, " [certificate is good]\n");
1372 es_fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
1377 /* Same as standard mode list all certifying certs too. */
1379 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1380 ksba_cert_t cert, int raw_mode,
1381 estream_t fp, int with_validation)
1383 ksba_cert_t next = NULL;
1387 list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1389 list_cert_std (ctrl, cert, fp, 0, with_validation);
1390 ksba_cert_ref (cert);
1391 while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1393 es_fputs ("Certified by\n", fp);
1396 es_fputs (_("certificate chain too long\n"), fp);
1399 ksba_cert_release (cert);
1401 list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1403 list_cert_std (ctrl, next, fp, 0, with_validation);
1406 ksba_cert_release (cert);
1412 /* List all internal keys or just the keys given as NAMES. MODE is a
1413 bit vector to specify what keys are to be included; see
1414 gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
1415 output mode will be used instead of the standard beautified one.
1418 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1419 unsigned int mode, int raw_mode)
1422 KEYDB_SEARCH_DESC *desc = NULL;
1425 ksba_cert_t cert = NULL;
1426 ksba_cert_t lastcert = NULL;
1428 const char *lastresname, *resname;
1430 int want_ephemeral = ctrl->with_ephemeral_keys;
1435 log_error ("keydb_new failed\n");
1436 rc = gpg_error (GPG_ERR_GENERAL);
1444 for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1448 desc = xtrycalloc (ndesc, sizeof *desc);
1451 rc = gpg_error_from_syserror ();
1452 log_error ("out of core\n");
1457 desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1460 for (ndesc=0, sl=names; sl; sl = sl->next)
1462 rc = classify_user_id (sl->d, desc+ndesc, 0);
1465 log_error ("key '%s' not found: %s\n",
1466 sl->d, gpg_strerror (rc));
1475 /* If all specifications are done by fingerprint or keygrip, we
1476 switch to ephemeral mode so that _all_ currently available and
1477 matching certificates are listed. */
1478 if (!want_ephemeral && names && ndesc)
1482 for (i=0; (i < ndesc
1483 && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
1484 || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
1485 || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
1486 || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
1493 keydb_set_ephemeral (hd, 1);
1495 /* It would be nice to see which of the given users did actually
1496 match one in the keyring. To implement this we need to have a
1497 found flag for each entry in desc and to set this we must check
1498 all those entries after a match to mark all matched one -
1499 currently we stop at the first match. To do this we need an
1500 extra flag to enable this feature so */
1502 /* Suppress duplicates at least when they follow each other. */
1504 while (!(rc = keydb_search (ctrl, hd, desc, ndesc)))
1506 unsigned int validity;
1509 desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1511 rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1514 log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1517 rc = keydb_get_cert (hd, &cert);
1520 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1523 /* Skip duplicated certificates, at least if they follow each
1524 others. This works best if a single key is searched for and
1525 expected. FIXME: Non-sequential duplicates remain. */
1526 if (gpgsm_certs_identical_p (cert, lastcert))
1528 ksba_cert_release (cert);
1533 resname = keydb_get_resource_name (hd);
1535 if (lastresname != resname )
1539 if (ctrl->no_server)
1541 es_fprintf (fp, "%s\n", resname );
1542 for (i=strlen(resname); i; i-- )
1545 lastresname = resname;
1552 char *p = gpgsm_get_keygrip_hexstring (cert);
1555 rc = gpgsm_agent_havekey (ctrl, p);
1558 else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1565 if (!mode || ((mode & 1) && !have_secret)
1566 || ((mode & 2) && have_secret) )
1568 if (ctrl->with_colons)
1569 list_cert_colon (ctrl, cert, validity, fp, have_secret);
1570 else if (ctrl->with_chain)
1571 list_cert_chain (ctrl, hd, cert,
1572 raw_mode, fp, ctrl->with_validation);
1576 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1577 ctrl->with_validation);
1579 list_cert_std (ctrl, cert, fp, have_secret,
1580 ctrl->with_validation);
1585 ksba_cert_release (lastcert);
1589 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1592 log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1595 ksba_cert_release (cert);
1596 ksba_cert_release (lastcert);
1605 list_external_cb (void *cb_value, ksba_cert_t cert)
1607 struct list_external_parm_s *parm = cb_value;
1609 if (keydb_store_cert (parm->ctrl, cert, 1, NULL))
1610 log_error ("error storing certificate as ephemeral\n");
1612 if (parm->print_header)
1614 const char *resname = "[external keys]";
1617 es_fprintf (parm->fp, "%s\n", resname );
1618 for (i=strlen(resname); i; i-- )
1619 es_putc('-', parm->fp);
1620 es_putc ('\n', parm->fp);
1621 parm->print_header = 0;
1624 if (parm->with_colons)
1625 list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1626 else if (parm->with_chain)
1627 list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1631 list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1633 list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1634 es_putc ('\n', parm->fp);
1639 /* List external keys similar to internal one. Note: mode does not
1640 make sense here because it would be unwise to list external secret
1643 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1646 struct list_external_parm_s parm;
1650 parm.print_header = ctrl->no_server;
1651 parm.with_colons = ctrl->with_colons;
1652 parm.with_chain = ctrl->with_chain;
1653 parm.raw_mode = raw_mode;
1655 rc = gpgsm_dirmngr_lookup (ctrl, names, NULL, 0, list_external_cb, &parm);
1656 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
1657 || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1658 rc = 0; /* "Not found" is not an error here. */
1660 log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1664 /* List all keys or just the key given as NAMES.
1665 MODE controls the operation mode:
1667 0 = list all public keys but don't flag secret ones
1668 1 = list only public keys
1669 2 = list only secret keys
1670 3 = list secret and public keys
1671 Bit 6: list internal keys
1672 Bit 7: list external keys
1673 Bit 8: Do a raw format dump.
1676 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1679 gpg_error_t err = 0;
1681 if ((mode & (1<<6)))
1682 err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1683 if (!err && (mode & (1<<7)))
1684 err = list_external_keys (ctrl, names, fp, (mode&256));