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_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. */
381 else if (strchr ("01234567890ABCDEFabcdef", *field))
383 /* Fields starts with a hex digit; thus it is a serial number. */
384 subkey->is_cardkey = 1;
385 subkey->card_number = strdup (field);
386 if (!subkey->card_number)
387 return gpg_error_from_syserror ();
398 /* We have read an entire key into tmp_key and should now finish it.
399 It is assumed that this releases tmp_key. */
401 finish_key (gpgme_ctx_t ctx, op_data_t opd)
403 gpgme_key_t key = opd->tmp_key;
407 opd->tmp_keysig = NULL;
410 _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
414 /* Note: We are allowed to modify LINE. */
416 keylist_colon_handler (void *priv, char *line)
418 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
421 RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR,
422 RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
426 char *field[NR_FIELDS];
432 gpgme_subkey_t subkey = NULL;
433 gpgme_key_sig_t keysig = NULL;
435 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
442 TRACE2 (DEBUG_CTX, "gpgme:keylist_colon_handler", ctx,
443 "key = %p, line = %s", key, line ? line : "(null)");
448 finish_key (ctx, opd);
452 while (line && fields < NR_FIELDS)
454 field[fields++] = line;
455 line = strchr (line, ':');
460 if (!strcmp (field[0], "sig"))
462 else if (!strcmp (field[0], "rev"))
464 else if (!strcmp (field[0], "pub"))
466 else if (!strcmp (field[0], "sec"))
468 else if (!strcmp (field[0], "crt"))
470 else if (!strcmp (field[0], "crs"))
472 else if (!strcmp (field[0], "fpr") && key)
474 else if (!strcmp (field[0], "uid") && key)
476 else if (!strcmp (field[0], "sub") && key)
478 else if (!strcmp (field[0], "ssb") && key)
480 else if (!strcmp (field[0], "spk") && key)
485 /* Only look at signatures immediately following a user ID. For
486 this, clear the user ID pointer when encountering anything but a
488 if (rectype != RT_SIG && rectype != RT_REV)
491 /* Only look at subpackets immediately following a signature. For
492 this, clear the signature pointer when encountering anything but
494 if (rectype != RT_SPK)
495 opd->tmp_keysig = NULL;
503 /* Start a new keyblock. */
504 err = _gpgme_key_new (&key);
507 key->keylist_mode = ctx->keylist_mode;
508 err = _gpgme_key_add_subkey (key, &subkey);
511 gpgme_key_unref (key);
515 if (rectype == RT_SEC || rectype == RT_CRS)
516 key->secret = subkey->secret = 1;
517 if (rectype == RT_CRT || rectype == RT_CRS)
518 key->protocol = GPGME_PROTOCOL_CMS;
519 finish_key (ctx, opd);
522 /* Field 2 has the trust info. */
524 set_mainkey_trust_info (key, field[1]);
526 /* Field 3 has the key length. */
529 int i = atoi (field[2]);
530 /* Ignore invalid values. */
535 /* Field 4 has the public key algorithm. */
538 int i = atoi (field[3]);
539 if (i >= 1 && i < 128)
540 subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
543 /* Field 5 has the long keyid. Allow short key IDs for the
544 output of an external keyserver listing. */
545 if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
546 strcpy (subkey->_keyid, field[4]);
548 /* Field 6 has the timestamp (seconds). */
550 subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
552 /* Field 7 has the expiration time (seconds). */
554 subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
556 /* Field 8 has the X.509 serial number. */
557 if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
559 key->issuer_serial = strdup (field[7]);
560 if (!key->issuer_serial)
561 return gpg_error_from_syserror ();
564 /* Field 9 has the ownertrust. */
566 set_ownertrust (key, field[8]);
568 /* Field 10 is not used for gpg due to --fixed-list-mode option
569 but GPGSM stores the issuer name. */
570 if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS))
571 if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0))
572 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
574 /* Field 11 has the signature class. */
576 /* Field 12 has the capabilities. */
578 set_mainkey_capability (key, field[11]);
580 /* Field 15 carries special flags of a secret key. */
581 if (fields >= 15 && key->secret)
583 err = parse_sec_field15 (subkey, field[14]);
588 /* Field 17 has the curve name for ECC. */
589 if (fields >= 17 && *field[16])
591 subkey->curve = strdup (field[16]);
593 return gpg_error_from_syserror ();
600 /* Start a new subkey. */
601 err = _gpgme_key_add_subkey (key, &subkey);
605 if (rectype == RT_SSB)
608 /* Field 2 has the trust info. */
610 set_subkey_trust_info (subkey, field[1]);
612 /* Field 3 has the key length. */
615 int i = atoi (field[2]);
616 /* Ignore invalid values. */
621 /* Field 4 has the public key algorithm. */
624 int i = atoi (field[3]);
625 if (i >= 1 && i < 128)
626 subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
629 /* Field 5 has the long keyid. */
630 if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
631 strcpy (subkey->_keyid, field[4]);
633 /* Field 6 has the timestamp (seconds). */
635 subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
637 /* Field 7 has the expiration time (seconds). */
639 subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
641 /* Field 8 is reserved (LID). */
642 /* Field 9 has the ownertrust. */
643 /* Field 10, the user ID, is n/a for a subkey. */
645 /* Field 11 has the signature class. */
647 /* Field 12 has the capabilities. */
649 set_subkey_capability (subkey, field[11]);
651 /* Field 15 carries special flags of a secret key. */
652 if (fields >= 15 && key->secret)
654 err = parse_sec_field15 (subkey, field[14]);
659 /* Field 17 has the curve name for ECC. */
660 if (fields >= 17 && *field[16])
662 subkey->curve = strdup (field[16]);
664 return gpg_error_from_syserror ();
670 /* Field 2 has the trust info, and field 10 has the user ID. */
673 if (_gpgme_key_append_name (key, field[9], 1))
674 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
678 set_userid_flags (key, field[1]);
679 opd->tmp_uid = key->_last_uid;
685 /* Field 10 has the fingerprint (take only the first one). */
686 if (fields >= 10 && field[9] && *field[9])
688 /* Need to apply it to the last subkey because all subkeys
689 do have fingerprints. */
690 subkey = key->_last_subkey;
693 subkey->fpr = strdup (field[9]);
695 return gpg_error_from_syserror ();
699 /* Field 13 has the gpgsm chain ID (take only the first one). */
700 if (fields >= 13 && !key->chain_id && *field[12])
702 key->chain_id = strdup (field[12]);
704 return gpg_error_from_syserror ();
713 /* Start a new (revoked) signature. */
714 assert (opd->tmp_uid == key->_last_uid);
715 keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
717 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
719 /* Field 2 has the calculated trust ('!', '-', '?', '%'). */
724 keysig->status = gpg_error (GPG_ERR_NO_ERROR);
728 keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
732 keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
736 keysig->status = gpg_error (GPG_ERR_GENERAL);
740 keysig->status = gpg_error (GPG_ERR_NO_ERROR);
744 /* Field 4 has the public key algorithm. */
747 int i = atoi (field[3]);
748 if (i >= 1 && i < 128)
749 keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
752 /* Field 5 has the long keyid. */
753 if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
754 strcpy (keysig->_keyid, field[4]);
756 /* Field 6 has the timestamp (seconds). */
758 keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
760 /* Field 7 has the expiration time (seconds). */
762 keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
764 /* Field 11 has the signature class (eg, 0x30 means revoked). */
766 if (field[10][0] && field[10][1])
768 int sig_class = _gpgme_hextobyte (field[10]);
771 keysig->sig_class = sig_class;
772 keysig->class = keysig->sig_class;
773 if (sig_class == 0x30)
776 if (field[10][2] == 'x')
777 keysig->exportable = 1;
780 opd->tmp_keysig = keysig;
784 if (!opd->tmp_keysig)
786 assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
790 /* Field 2 has the subpacket type. */
791 int type = atoi (field[1]);
793 /* Field 3 has the flags. */
794 int flags = atoi (field[2]);
796 /* Field 4 has the length. */
797 int len = atoi (field[3]);
799 /* Field 5 has the data. */
800 char *data = field[4];
802 /* Type 20: Notation data. */
803 /* Type 26: Policy URL. */
804 if (type == 20 || type == 26)
806 gpgme_sig_notation_t notation;
808 keysig = opd->tmp_keysig;
810 /* At this time, any error is serious. */
811 err = _gpgme_parse_notation (¬ation, type, flags, len, data);
815 /* Add a new notation. FIXME: Could be factored out. */
816 if (!keysig->notations)
817 keysig->notations = notation;
818 if (keysig->_last_notation)
819 keysig->_last_notation->next = notation;
820 keysig->_last_notation = notation;
825 /* Unknown record. */
833 _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
836 gpgme_ctx_t ctx = (gpgme_ctx_t) data;
837 gpgme_key_t key = (gpgme_key_t) type_data;
840 struct key_queue_item_s *q, *q2;
842 assert (type == GPGME_EVENT_NEXT_KEY);
844 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
849 q = malloc (sizeof *q);
852 gpgme_key_unref (key);
853 /* FIXME return GPGME_Out_Of_Core; */
858 /* FIXME: Use a tail pointer? */
859 if (!(q2 = opd->key_queue))
863 for (; q2->next; q2 = q2->next)
871 /* Start a keylist operation within CTX, searching for keys which
872 match PATTERN. If SECRET_ONLY is true, only secret keys are
875 gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
881 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
882 "pattern=%s, secret_only=%i", pattern, secret_only);
885 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
887 err = _gpgme_op_reset (ctx, 2);
889 return TRACE_ERR (err);
891 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
892 sizeof (*opd), release_op_data);
895 return TRACE_ERR (err);
897 _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
899 err = _gpgme_engine_set_colon_line_handler (ctx->engine,
900 keylist_colon_handler, ctx);
902 return TRACE_ERR (err);
904 err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
906 return TRACE_ERR (err);
910 /* Start a keylist operation within CTX, searching for keys which
911 match PATTERN. If SECRET_ONLY is true, only secret keys are
914 gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
915 int secret_only, int reserved)
921 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
922 "secret_only=%i, reserved=0x%x", secret_only, reserved);
925 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
927 err = _gpgme_op_reset (ctx, 2);
929 return TRACE_ERR (err);
931 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
932 sizeof (*opd), release_op_data);
935 return TRACE_ERR (err);
937 _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
938 err = _gpgme_engine_set_colon_line_handler (ctx->engine,
939 keylist_colon_handler, ctx);
941 return TRACE_ERR (err);
943 err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
944 reserved, ctx->keylist_mode);
945 return TRACE_ERR (err);
949 /* Return the next key from the keylist in R_KEY. */
951 gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
954 struct key_queue_item_s *queue_item;
958 TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx);
961 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
964 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
966 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
969 return TRACE_ERR (err);
971 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
975 err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
977 return TRACE_ERR (err);
980 return TRACE_ERR (gpg_error (GPG_ERR_EOF));
983 assert (opd->key_queue);
985 queue_item = opd->key_queue;
986 opd->key_queue = queue_item->next;
990 *r_key = queue_item->key;
993 return TRACE_SUC2 ("key=%p (%s)", *r_key,
994 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
995 (*r_key)->subkeys->fpr : "invalid");
999 /* Terminate a pending keylist operation within CTX. */
1001 gpgme_op_keylist_end (gpgme_ctx_t ctx)
1003 TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx);
1006 return gpg_error (GPG_ERR_INV_VALUE);
1012 /* Get the key with the fingerprint FPR from the crypto backend. If
1013 SECRET is true, get the secret key. */
1015 gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
1018 gpgme_ctx_t listctx;
1022 TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx,
1023 "fpr=%s, secret=%i", fpr, secret);
1025 if (!ctx || !r_key || !fpr)
1026 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1028 if (strlen (fpr) < 8) /* We have at least a key ID. */
1029 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1031 /* FIXME: We use our own context because we have to avoid the user's
1032 I/O callback handlers. */
1033 err = gpgme_new (&listctx);
1035 return TRACE_ERR (err);
1037 gpgme_protocol_t proto;
1038 gpgme_engine_info_t info;
1040 /* Clone the relevant state. */
1041 proto = gpgme_get_protocol (ctx);
1042 gpgme_set_protocol (listctx, proto);
1043 gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
1044 info = gpgme_ctx_get_engine_info (ctx);
1045 while (info && info->protocol != proto)
1048 gpgme_ctx_set_engine_info (listctx, proto,
1049 info->file_name, info->home_dir);
1052 err = gpgme_op_keylist_start (listctx, fpr, secret);
1054 err = gpgme_op_keylist_next (listctx, r_key);
1058 err = gpgme_op_keylist_next (listctx, &key);
1059 if (gpgme_err_code (err) == GPG_ERR_EOF)
1064 && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr
1065 && key && key->subkeys && key->subkeys->fpr
1066 && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr))
1068 /* The fingerprint is identical. We assume that this is
1069 the same key and don't mark it as an ambiguous. This
1070 problem may occur with corrupted keyrings and has
1071 been noticed often with gpgsm. In fact gpgsm uses a
1072 similar hack to sort out such duplicates but it can't
1073 do that while listing keys. */
1074 gpgme_key_unref (key);
1079 gpgme_key_unref (key);
1080 err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
1082 gpgme_key_unref (*r_key);
1085 gpgme_release (listctx);
1088 TRACE_LOG2 ("key=%p (%s)", *r_key,
1089 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1090 (*r_key)->subkeys->fpr : "invalid");
1092 return TRACE_ERR (err);