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 = i;
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_errno (errno);
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]);
591 /* Start a new subkey. */
592 err = _gpgme_key_add_subkey (key, &subkey);
596 if (rectype == RT_SSB)
599 /* Field 2 has the trust info. */
601 set_subkey_trust_info (subkey, field[1]);
603 /* Field 3 has the key length. */
606 int i = atoi (field[2]);
607 /* Ignore invalid values. */
612 /* Field 4 has the public key algorithm. */
615 int i = atoi (field[3]);
616 if (i >= 1 && i < 128)
617 subkey->pubkey_algo = i;
620 /* Field 5 has the long keyid. */
621 if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
622 strcpy (subkey->_keyid, field[4]);
624 /* Field 6 has the timestamp (seconds). */
626 subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
628 /* Field 7 has the expiration time (seconds). */
630 subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
632 /* Field 8 is reserved (LID). */
633 /* Field 9 has the ownertrust. */
634 /* Field 10, the user ID, is n/a for a subkey. */
636 /* Field 11 has the signature class. */
638 /* Field 12 has the capabilities. */
640 set_subkey_capability (subkey, field[11]);
642 /* Field 15 carries special flags of a secret key. */
643 if (fields >= 15 && key->secret)
645 err = parse_sec_field15 (subkey, field[14]);
652 /* Field 2 has the trust info, and field 10 has the user ID. */
655 if (_gpgme_key_append_name (key, field[9], 1))
656 return gpg_error_from_errno (GPG_ERR_ENOMEM); /* FIXME */
660 set_userid_flags (key, field[1]);
661 opd->tmp_uid = key->_last_uid;
667 /* Field 10 has the fingerprint (take only the first one). */
668 if (fields >= 10 && field[9] && *field[9])
670 /* Need to apply it to the last subkey because all subkeys
671 do have fingerprints. */
672 subkey = key->_last_subkey;
675 subkey->fpr = strdup (field[9]);
677 return gpg_error_from_errno (errno);
681 /* Field 13 has the gpgsm chain ID (take only the first one). */
682 if (fields >= 13 && !key->chain_id && *field[12])
684 key->chain_id = strdup (field[12]);
686 return gpg_error_from_errno (errno);
695 /* Start a new (revoked) signature. */
696 assert (opd->tmp_uid == key->_last_uid);
697 keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
699 return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
701 /* Field 2 has the calculated trust ('!', '-', '?', '%'). */
706 keysig->status = gpg_error (GPG_ERR_NO_ERROR);
710 keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
714 keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
718 keysig->status = gpg_error (GPG_ERR_GENERAL);
722 keysig->status = gpg_error (GPG_ERR_NO_ERROR);
726 /* Field 4 has the public key algorithm. */
729 int i = atoi (field[3]);
730 if (i >= 1 && i < 128)
731 keysig->pubkey_algo = i;
734 /* Field 5 has the long keyid. */
735 if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
736 strcpy (keysig->_keyid, field[4]);
738 /* Field 6 has the timestamp (seconds). */
740 keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
742 /* Field 7 has the expiration time (seconds). */
744 keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
746 /* Field 11 has the signature class (eg, 0x30 means revoked). */
748 if (field[10][0] && field[10][1])
750 int sig_class = _gpgme_hextobyte (field[10]);
753 keysig->sig_class = sig_class;
754 keysig->class = keysig->sig_class;
755 if (sig_class == 0x30)
758 if (field[10][2] == 'x')
759 keysig->exportable = 1;
762 opd->tmp_keysig = keysig;
766 if (!opd->tmp_keysig)
768 assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
772 /* Field 2 has the subpacket type. */
773 int type = atoi (field[1]);
775 /* Field 3 has the flags. */
776 int flags = atoi (field[2]);
778 /* Field 4 has the length. */
779 int len = atoi (field[3]);
781 /* Field 5 has the data. */
782 char *data = field[4];
784 /* Type 20: Notation data. */
785 /* Type 26: Policy URL. */
786 if (type == 20 || type == 26)
788 gpgme_sig_notation_t notation;
790 keysig = opd->tmp_keysig;
792 /* At this time, any error is serious. */
793 err = _gpgme_parse_notation (¬ation, type, flags, len, data);
797 /* Add a new notation. FIXME: Could be factored out. */
798 if (!keysig->notations)
799 keysig->notations = notation;
800 if (keysig->_last_notation)
801 keysig->_last_notation->next = notation;
802 keysig->_last_notation = notation;
807 /* Unknown record. */
815 _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
818 gpgme_ctx_t ctx = (gpgme_ctx_t) data;
819 gpgme_key_t key = (gpgme_key_t) type_data;
822 struct key_queue_item_s *q, *q2;
824 assert (type == GPGME_EVENT_NEXT_KEY);
826 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
831 q = malloc (sizeof *q);
834 gpgme_key_unref (key);
835 /* FIXME return GPGME_Out_Of_Core; */
840 /* FIXME: Use a tail pointer? */
841 if (!(q2 = opd->key_queue))
845 for (; q2->next; q2 = q2->next)
853 /* Start a keylist operation within CTX, searching for keys which
854 match PATTERN. If SECRET_ONLY is true, only secret keys are
857 gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
863 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
864 "pattern=%s, secret_only=%i", pattern, secret_only);
867 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
869 err = _gpgme_op_reset (ctx, 2);
871 return TRACE_ERR (err);
873 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
874 sizeof (*opd), release_op_data);
877 return TRACE_ERR (err);
879 _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
881 err = _gpgme_engine_set_colon_line_handler (ctx->engine,
882 keylist_colon_handler, ctx);
884 return TRACE_ERR (err);
886 err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
888 return TRACE_ERR (err);
892 /* Start a keylist operation within CTX, searching for keys which
893 match PATTERN. If SECRET_ONLY is true, only secret keys are
896 gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
897 int secret_only, int reserved)
903 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
904 "secret_only=%i, reserved=0x%x", secret_only, reserved);
907 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
909 err = _gpgme_op_reset (ctx, 2);
911 return TRACE_ERR (err);
913 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
914 sizeof (*opd), release_op_data);
917 return TRACE_ERR (err);
919 _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
920 err = _gpgme_engine_set_colon_line_handler (ctx->engine,
921 keylist_colon_handler, ctx);
923 return TRACE_ERR (err);
925 err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
926 reserved, ctx->keylist_mode);
927 return TRACE_ERR (err);
931 /* Return the next key from the keylist in R_KEY. */
933 gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
936 struct key_queue_item_s *queue_item;
940 TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx);
943 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
946 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
948 err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
951 return TRACE_ERR (err);
953 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
957 err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
959 return TRACE_ERR (err);
962 return TRACE_ERR (gpg_error (GPG_ERR_EOF));
965 assert (opd->key_queue);
967 queue_item = opd->key_queue;
968 opd->key_queue = queue_item->next;
972 *r_key = queue_item->key;
975 return TRACE_SUC2 ("key=%p (%s)", *r_key,
976 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
977 (*r_key)->subkeys->fpr : "invalid");
981 /* Terminate a pending keylist operation within CTX. */
983 gpgme_op_keylist_end (gpgme_ctx_t ctx)
985 TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx);
988 return gpg_error (GPG_ERR_INV_VALUE);
994 /* Get the key with the fingerprint FPR from the crypto backend. If
995 SECRET is true, get the secret key. */
997 gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
1000 gpgme_ctx_t listctx;
1004 TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx,
1005 "fpr=%s, secret=%i", fpr, secret);
1007 if (!ctx || !r_key || !fpr)
1008 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1010 if (strlen (fpr) < 8) /* We have at least a key ID. */
1011 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1013 /* FIXME: We use our own context because we have to avoid the user's
1014 I/O callback handlers. */
1015 err = gpgme_new (&listctx);
1017 return TRACE_ERR (err);
1019 gpgme_protocol_t proto;
1020 gpgme_engine_info_t info;
1022 /* Clone the relevant state. */
1023 proto = gpgme_get_protocol (ctx);
1024 gpgme_set_protocol (listctx, proto);
1025 gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
1026 info = gpgme_ctx_get_engine_info (ctx);
1027 while (info && info->protocol != proto)
1030 gpgme_ctx_set_engine_info (listctx, proto,
1031 info->file_name, info->home_dir);
1034 err = gpgme_op_keylist_start (listctx, fpr, secret);
1036 err = gpgme_op_keylist_next (listctx, r_key);
1040 err = gpgme_op_keylist_next (listctx, &key);
1041 if (gpgme_err_code (err) == GPG_ERR_EOF)
1046 && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr
1047 && key && key->subkeys && key->subkeys->fpr
1048 && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr))
1050 /* The fingerprint is identical. We assume that this is
1051 the same key and don't mark it as an ambiguous. This
1052 problem may occur with corrupted keyrings and has
1053 been noticed often with gpgsm. In fact gpgsm uses a
1054 similar hack to sort out such duplicates but it can't
1055 do that while listing keys. */
1056 gpgme_key_unref (key);
1061 gpgme_key_unref (key);
1062 err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
1064 gpgme_key_unref (*r_key);
1067 gpgme_release (listctx);
1070 TRACE_LOG2 ("key=%p (%s)", *r_key,
1071 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1072 (*r_key)->subkeys->fpr : "invalid");
1074 return TRACE_ERR (err);