1 /* keylist.c - Listing keys.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007,
4 2008, 2009 g10 Code GmbH
6 This file is part of GPGME.
8 GPGME is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as
10 published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 GPGME is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this program; if not, see <http://www.gnu.org/licenses/>.
28 #ifdef HAVE_SYS_TYPES_H
29 /* Solaris 8 needs sys/types.h before time.h. */
30 # include <sys/types.h>
37 /* Suppress warning for accessing deprecated member "class". */
38 #define _GPGME_IN_GPGME
46 struct key_queue_item_s
48 struct key_queue_item_s *next;
54 struct _gpgme_op_keylist_result result;
58 /* This points to the last uid in tmp_key. */
59 gpgme_user_id_t tmp_uid;
61 /* This points to the last sig in tmp_uid. */
62 gpgme_key_sig_t tmp_keysig;
64 /* Something new is available. */
66 struct key_queue_item_s *key_queue;
71 release_op_data (void *hook)
73 op_data_t opd = (op_data_t) hook;
74 struct key_queue_item_s *key = opd->key_queue;
77 gpgme_key_unref (opd->tmp_key);
79 /* opd->tmp_uid and opd->tmp_keysig are actually part of opd->tmp_key,
80 so we do not need to release them here. */
84 struct key_queue_item_s *next = key->next;
86 gpgme_key_unref (key->key);
92 gpgme_keylist_result_t
93 gpgme_op_keylist_result (gpgme_ctx_t ctx)
99 TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_result", ctx);
101 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
105 TRACE_SUC0 ("result=(null)");
109 TRACE_LOG1 ("truncated = %i", opd->result.truncated);
111 TRACE_SUC1 ("result=%p", &opd->result);
117 keylist_status_handler (void *priv, gpgme_status_code_t code, char *args)
119 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
124 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
131 case GPGME_STATUS_TRUNCATED:
132 opd->result.truncated = 1;
143 set_subkey_trust_info (gpgme_subkey_t subkey, const char *src)
145 while (*src && !isdigit (*src))
158 /* Note that gpg 1.3 won't print that anymore but only uses
159 the capabilities field. */
160 subkey->disabled = 1;
173 set_mainkey_trust_info (gpgme_key_t key, const char *src)
175 /* First set the trust info of the main key (the first subkey). */
176 set_subkey_trust_info (key->subkeys, src);
178 /* Now set the summarized trust info. */
179 while (*src && !isdigit (*src))
192 /* Note that gpg 1.3 won't print that anymore but only uses
193 the capabilities field. However, it is still used for
194 external key listings. */
208 set_userid_flags (gpgme_key_t key, const char *src)
210 gpgme_user_id_t uid = key->_last_uid;
213 /* Look at letters and stop at the first digit. */
214 while (*src && !isdigit (*src))
227 uid->validity = GPGME_VALIDITY_NEVER;
231 uid->validity = GPGME_VALIDITY_MARGINAL;
235 uid->validity = GPGME_VALIDITY_FULL;
239 uid->validity = GPGME_VALIDITY_ULTIMATE;
248 set_subkey_capability (gpgme_subkey_t subkey, const char *src)
255 subkey->can_encrypt = 1;
259 subkey->can_sign = 1;
263 subkey->can_certify = 1;
267 subkey->can_authenticate = 1;
271 subkey->is_qualified = 1;
275 subkey->disabled = 1;
284 set_mainkey_capability (gpgme_key_t key, const char *src)
286 /* First set the capabilities of the main key (the first subkey). */
287 set_subkey_capability (key->subkeys, src);
295 /* Note, that this flag is also set using the key validity
296 field for backward compatibility with gpg 1.2. We use d
297 and D, so that a future gpg version will be able to
298 disable certain subkeys. Currently it is expected that
299 gpg sets this for the primary key. */
305 key->can_encrypt = 1;
315 key->can_certify = 1;
320 key->can_authenticate = 1;
325 key->is_qualified = 1;
334 set_ownertrust (gpgme_key_t key, const char *src)
336 /* Look at letters and stop at the first digit. */
337 while (*src && !isdigit (*src))
342 key->owner_trust = GPGME_VALIDITY_NEVER;
346 key->owner_trust = GPGME_VALIDITY_MARGINAL;
350 key->owner_trust = GPGME_VALIDITY_FULL;
354 key->owner_trust = GPGME_VALIDITY_ULTIMATE;
358 key->owner_trust = GPGME_VALIDITY_UNKNOWN;
366 /* Parse field 15 of a secret key or subkey. This fields holds a
367 reference to smartcards. FIELD is the content of the field and we
368 are allowed to modify it. */
370 parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
374 else if (*field == '#')
376 /* This is a stub for an offline key. We reset the SECRET flag
377 of the subkey here. Note that the secret flag of the entire
378 key will be true even then. We even explicitly set
379 key->secret to make it works for GPGME_KEYLIST_MODE_WITH_SECRET. */
383 else if (strchr ("01234567890ABCDEFabcdef", *field))
385 /* Fields starts with a hex digit; thus it is a serial number. */
387 subkey->is_cardkey = 1;
388 subkey->card_number = strdup (field);
389 if (!subkey->card_number)
390 return gpg_error_from_syserror ();
392 else if (*field == '+')
406 /* We have read an entire key into tmp_key and should now finish it.
407 It is assumed that this releases tmp_key. */
409 finish_key (gpgme_ctx_t ctx, op_data_t opd)
411 gpgme_key_t key = opd->tmp_key;
415 opd->tmp_keysig = NULL;
418 _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
422 /* Note: We are allowed to modify LINE. */
424 keylist_colon_handler (void *priv, char *line)
426 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
429 RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR,
430 RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
434 char *field[NR_FIELDS];
440 gpgme_subkey_t subkey = NULL;
441 gpgme_key_sig_t keysig = NULL;
443 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
450 TRACE2 (DEBUG_CTX, "gpgme:keylist_colon_handler", ctx,
451 "key = %p, line = %s", key, line ? line : "(null)");
456 finish_key (ctx, opd);
460 while (line && fields < NR_FIELDS)
462 field[fields++] = line;
463 line = strchr (line, ':');
468 if (!strcmp (field[0], "sig"))
470 else if (!strcmp (field[0], "rev"))
472 else if (!strcmp (field[0], "pub"))
474 else if (!strcmp (field[0], "sec"))
476 else if (!strcmp (field[0], "crt"))
478 else if (!strcmp (field[0], "crs"))
480 else if (!strcmp (field[0], "fpr") && key)
482 else if (!strcmp (field[0], "uid") && key)
484 else if (!strcmp (field[0], "sub") && key)
486 else if (!strcmp (field[0], "ssb") && key)
488 else if (!strcmp (field[0], "spk") && key)
493 /* Only look at signatures immediately following a user ID. For
494 this, clear the user ID pointer when encountering anything but a
496 if (rectype != RT_SIG && rectype != RT_REV)
499 /* Only look at subpackets immediately following a signature. For
500 this, clear the signature pointer when encountering anything but
502 if (rectype != RT_SPK)
503 opd->tmp_keysig = NULL;
511 /* Start a new keyblock. */
512 err = _gpgme_key_new (&key);
515 key->keylist_mode = ctx->keylist_mode;
516 err = _gpgme_key_add_subkey (key, &subkey);
519 gpgme_key_unref (key);
523 if (rectype == RT_SEC || rectype == RT_CRS)
524 key->secret = subkey->secret = 1;
525 if (rectype == RT_CRT || rectype == RT_CRS)
526 key->protocol = GPGME_PROTOCOL_CMS;
527 finish_key (ctx, opd);
530 /* Field 2 has the trust info. */
532 set_mainkey_trust_info (key, field[1]);
534 /* Field 3 has the key length. */
537 int i = atoi (field[2]);
538 /* Ignore invalid values. */
543 /* Field 4 has the public key algorithm. */
546 int i = atoi (field[3]);
547 if (i >= 1 && i < 128)
548 subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
551 /* Field 5 has the long keyid. Allow short key IDs for the
552 output of an external keyserver listing. */
553 if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
554 strcpy (subkey->_keyid, field[4]);
556 /* Field 6 has the timestamp (seconds). */
558 subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
560 /* Field 7 has the expiration time (seconds). */
562 subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
564 /* Field 8 has the X.509 serial number. */
565 if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
567 key->issuer_serial = strdup (field[7]);
568 if (!key->issuer_serial)
569 return gpg_error_from_syserror ();
572 /* Field 9 has the ownertrust. */
574 set_ownertrust (key, field[8]);
576 /* Field 10 is not used for gpg due to --fixed-list-mode option
577 but GPGSM stores the issuer name. */
578 if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS))
579 if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0))
580 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
582 /* Field 11 has the signature class. */
584 /* Field 12 has the capabilities. */
586 set_mainkey_capability (key, field[11]);
588 /* Field 15 carries special flags of a secret key. */
591 || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
593 err = parse_sec_field15 (key, subkey, field[14]);
598 /* Field 17 has the curve name for ECC. */
599 if (fields >= 17 && *field[16])
601 subkey->curve = strdup (field[16]);
603 return gpg_error_from_syserror ();
610 /* Start a new subkey. */
611 err = _gpgme_key_add_subkey (key, &subkey);
615 if (rectype == RT_SSB)
618 /* Field 2 has the trust info. */
620 set_subkey_trust_info (subkey, field[1]);
622 /* Field 3 has the key length. */
625 int i = atoi (field[2]);
626 /* Ignore invalid values. */
631 /* Field 4 has the public key algorithm. */
634 int i = atoi (field[3]);
635 if (i >= 1 && i < 128)
636 subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
639 /* Field 5 has the long keyid. */
640 if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
641 strcpy (subkey->_keyid, field[4]);
643 /* Field 6 has the timestamp (seconds). */
645 subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
647 /* Field 7 has the expiration time (seconds). */
649 subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
651 /* Field 8 is reserved (LID). */
652 /* Field 9 has the ownertrust. */
653 /* Field 10, the user ID, is n/a for a subkey. */
655 /* Field 11 has the signature class. */
657 /* Field 12 has the capabilities. */
659 set_subkey_capability (subkey, field[11]);
661 /* Field 15 carries special flags of a secret key. */
664 || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
666 err = parse_sec_field15 (key, subkey, field[14]);
671 /* Field 17 has the curve name for ECC. */
672 if (fields >= 17 && *field[16])
674 subkey->curve = strdup (field[16]);
676 return gpg_error_from_syserror ();
682 /* Field 2 has the trust info, and field 10 has the user ID. */
685 if (_gpgme_key_append_name (key, field[9], 1))
686 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
690 set_userid_flags (key, field[1]);
691 opd->tmp_uid = key->_last_uid;
697 /* Field 10 has the fingerprint (take only the first one). */
698 if (fields >= 10 && field[9] && *field[9])
700 /* Need to apply it to the last subkey because all subkeys
701 do have fingerprints. */
702 subkey = key->_last_subkey;
705 subkey->fpr = strdup (field[9]);
707 return gpg_error_from_syserror ();
711 /* Field 13 has the gpgsm chain ID (take only the first one). */
712 if (fields >= 13 && !key->chain_id && *field[12])
714 key->chain_id = strdup (field[12]);
716 return gpg_error_from_syserror ();
725 /* Start a new (revoked) signature. */
726 assert (opd->tmp_uid == key->_last_uid);
727 keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
729 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
731 /* Field 2 has the calculated trust ('!', '-', '?', '%'). */
736 keysig->status = gpg_error (GPG_ERR_NO_ERROR);
740 keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
744 keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
748 keysig->status = gpg_error (GPG_ERR_GENERAL);
752 keysig->status = gpg_error (GPG_ERR_NO_ERROR);
756 /* Field 4 has the public key algorithm. */
759 int i = atoi (field[3]);
760 if (i >= 1 && i < 128)
761 keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
764 /* Field 5 has the long keyid. */
765 if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
766 strcpy (keysig->_keyid, field[4]);
768 /* Field 6 has the timestamp (seconds). */
770 keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
772 /* Field 7 has the expiration time (seconds). */
774 keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
776 /* Field 11 has the signature class (eg, 0x30 means revoked). */
778 if (field[10][0] && field[10][1])
780 int sig_class = _gpgme_hextobyte (field[10]);
783 keysig->sig_class = sig_class;
784 keysig->class = keysig->sig_class;
785 if (sig_class == 0x30)
788 if (field[10][2] == 'x')
789 keysig->exportable = 1;
792 opd->tmp_keysig = keysig;
796 if (!opd->tmp_keysig)
798 assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
802 /* Field 2 has the subpacket type. */
803 int type = atoi (field[1]);
805 /* Field 3 has the flags. */
806 int flags = atoi (field[2]);
808 /* Field 4 has the length. */
809 int len = atoi (field[3]);
811 /* Field 5 has the data. */
812 char *data = field[4];
814 /* Type 20: Notation data. */
815 /* Type 26: Policy URL. */
816 if (type == 20 || type == 26)
818 gpgme_sig_notation_t notation;
820 keysig = opd->tmp_keysig;
822 /* At this time, any error is serious. */
823 err = _gpgme_parse_notation (¬ation, type, flags, len, data);
827 /* Add a new notation. FIXME: Could be factored out. */
828 if (!keysig->notations)
829 keysig->notations = notation;
830 if (keysig->_last_notation)
831 keysig->_last_notation->next = notation;
832 keysig->_last_notation = notation;
837 /* Unknown record. */
845 _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
848 gpgme_ctx_t ctx = (gpgme_ctx_t) data;
849 gpgme_key_t key = (gpgme_key_t) type_data;
852 struct key_queue_item_s *q, *q2;
854 assert (type == GPGME_EVENT_NEXT_KEY);
856 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
861 q = malloc (sizeof *q);
864 gpgme_key_unref (key);
865 /* FIXME return GPGME_Out_Of_Core; */
870 /* FIXME: Use a tail pointer? */
871 if (!(q2 = opd->key_queue))
875 for (; q2->next; q2 = q2->next)
883 /* Start a keylist operation within CTX, searching for keys which
884 match PATTERN. If SECRET_ONLY is true, only secret keys are
887 gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
894 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
895 "pattern=%s, secret_only=%i", pattern, secret_only);
898 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
900 err = _gpgme_op_reset (ctx, 2);
902 return TRACE_ERR (err);
904 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
905 sizeof (*opd), release_op_data);
908 return TRACE_ERR (err);
910 _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
912 err = _gpgme_engine_set_colon_line_handler (ctx->engine,
913 keylist_colon_handler, ctx);
915 return TRACE_ERR (err);
918 flags |= GPGME_ENGINE_FLAG_OFFLINE;
920 err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
921 ctx->keylist_mode, flags);
922 return TRACE_ERR (err);
926 /* Start a keylist operation within CTX, searching for keys which
927 match PATTERN. If SECRET_ONLY is true, only secret keys are
930 gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
931 int secret_only, int reserved)
938 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
939 "secret_only=%i, reserved=0x%x", secret_only, reserved);
942 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
944 err = _gpgme_op_reset (ctx, 2);
946 return TRACE_ERR (err);
948 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
949 sizeof (*opd), release_op_data);
952 return TRACE_ERR (err);
954 _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
955 err = _gpgme_engine_set_colon_line_handler (ctx->engine,
956 keylist_colon_handler, ctx);
958 return TRACE_ERR (err);
961 flags |= GPGME_ENGINE_FLAG_OFFLINE;
963 err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
964 reserved, ctx->keylist_mode,
966 return TRACE_ERR (err);
970 /* Return the next key from the keylist in R_KEY. */
972 gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
975 struct key_queue_item_s *queue_item;
979 TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx);
982 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
985 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
987 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
990 return TRACE_ERR (err);
992 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
996 err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
998 return TRACE_ERR (err);
1001 return TRACE_ERR (gpg_error (GPG_ERR_EOF));
1004 assert (opd->key_queue);
1006 queue_item = opd->key_queue;
1007 opd->key_queue = queue_item->next;
1008 if (!opd->key_queue)
1011 *r_key = queue_item->key;
1014 return TRACE_SUC2 ("key=%p (%s)", *r_key,
1015 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1016 (*r_key)->subkeys->fpr : "invalid");
1020 /* Terminate a pending keylist operation within CTX. */
1022 gpgme_op_keylist_end (gpgme_ctx_t ctx)
1024 TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx);
1027 return gpg_error (GPG_ERR_INV_VALUE);
1033 /* Get the key with the fingerprint FPR from the crypto backend. If
1034 SECRET is true, get the secret key. */
1036 gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
1039 gpgme_ctx_t listctx;
1043 TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx,
1044 "fpr=%s, secret=%i", fpr, secret);
1046 if (!ctx || !r_key || !fpr)
1047 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1049 if (strlen (fpr) < 8) /* We have at least a key ID. */
1050 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1052 /* FIXME: We use our own context because we have to avoid the user's
1053 I/O callback handlers. */
1054 err = gpgme_new (&listctx);
1056 return TRACE_ERR (err);
1058 gpgme_protocol_t proto;
1059 gpgme_engine_info_t info;
1061 /* Clone the relevant state. */
1062 proto = gpgme_get_protocol (ctx);
1063 gpgme_set_protocol (listctx, proto);
1064 gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
1065 info = gpgme_ctx_get_engine_info (ctx);
1066 while (info && info->protocol != proto)
1069 gpgme_ctx_set_engine_info (listctx, proto,
1070 info->file_name, info->home_dir);
1073 err = gpgme_op_keylist_start (listctx, fpr, secret);
1075 err = gpgme_op_keylist_next (listctx, r_key);
1079 err = gpgme_op_keylist_next (listctx, &key);
1080 if (gpgme_err_code (err) == GPG_ERR_EOF)
1085 && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr
1086 && key && key->subkeys && key->subkeys->fpr
1087 && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr))
1089 /* The fingerprint is identical. We assume that this is
1090 the same key and don't mark it as an ambiguous. This
1091 problem may occur with corrupted keyrings and has
1092 been noticed often with gpgsm. In fact gpgsm uses a
1093 similar hack to sort out such duplicates but it can't
1094 do that while listing keys. */
1095 gpgme_key_unref (key);
1100 gpgme_key_unref (key);
1101 err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
1103 gpgme_key_unref (*r_key);
1106 gpgme_release (listctx);
1109 TRACE_LOG2 ("key=%p (%s)", *r_key,
1110 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1111 (*r_key)->subkeys->fpr : "invalid");
1113 return TRACE_ERR (err);