1 /* key.c - Key objects.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003 g10 Code GmbH
5 This file is part of GPGME.
7 GPGME is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GPGME is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GPGME; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
34 /* Protects all reference counters in keys. All other accesses to a
36 DEFINE_STATIC_LOCK (key_ref_lock);
39 /* Create a new key. */
41 _gpgme_key_new (gpgme_key_t *r_key)
45 key = calloc (1, sizeof *key);
47 return gpg_error_from_errno (errno);
56 _gpgme_key_add_subkey (gpgme_key_t key, gpgme_subkey_t *r_subkey)
58 gpgme_subkey_t subkey;
60 subkey = calloc (1, sizeof *subkey);
62 return gpg_error_from_errno (errno);
63 subkey->keyid = subkey->_keyid;
64 subkey->_keyid[16] = '\0';
67 key->subkeys = subkey;
68 if (key->_last_subkey)
69 key->_last_subkey->next = subkey;
70 key->_last_subkey = subkey;
78 set_user_id_part (char *tail, const char *buf, size_t len)
80 while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t'))
90 parse_user_id (char *src, char **name, char **email,
91 char **comment, char *tail)
93 const char *start = NULL;
103 /* Not legal but anyway. */
105 else if (*src == '>')
107 if (!--in_email && !*email)
110 tail = set_user_id_part (tail, start, src - start);
118 else if (*src == ')')
120 if (!--in_comment && !*comment)
123 tail = set_user_id_part (tail, start, src - start);
127 else if (*src == '<')
134 tail = set_user_id_part (tail, start, src - start);
141 else if (*src == '(')
148 tail = set_user_id_part (tail, start, src - start);
155 else if (!in_name && *src != ' ' && *src != '\t')
168 tail = set_user_id_part (tail, start, src - start);
172 /* Let unused parts point to an EOS. */
184 parse_x509_user_id (char *src, char **name, char **email,
185 char **comment, char *tail)
187 if (*src == '<' && src[strlen (src) - 1] == '>')
190 /* Let unused parts point to an EOS. */
201 /* Take a name from the --with-colon listing, remove certain escape
202 sequences sequences and put it into the list of UIDs. */
204 _gpgme_key_append_name (gpgme_key_t key, char *src)
208 int src_len = strlen (src);
211 /* We can malloc a buffer of the same length, because the converted
212 string will never be larger. Actually we allocate it twice the
213 size, so that we are able to store the parsed stuff there too. */
214 uid = malloc (sizeof (*uid) + 2 * src_len + 3);
216 return gpg_error_from_errno (errno);
217 memset (uid, 0, sizeof *uid);
219 uid->uid = ((char *) uid) + sizeof (*uid);
221 _gpgme_decode_c_string (src, &dst, src_len + 1);
224 if (key->protocol == GPGME_PROTOCOL_CMS)
225 parse_x509_user_id (uid->uid, &uid->name, &uid->email,
228 parse_user_id (uid->uid, &uid->name, &uid->email,
234 key->_last_uid->next = uid;
235 key->_last_uid = uid;
242 _gpgme_key_add_sig (gpgme_key_t key, char *src)
244 int src_len = src ? strlen (src) : 0;
248 assert (key); /* XXX */
250 uid = key->_last_uid;
251 assert (uid); /* XXX */
253 /* We can malloc a buffer of the same length, because the converted
254 string will never be larger. Actually we allocate it twice the
255 size, so that we are able to store the parsed stuff there too. */
256 sig = calloc (1, sizeof (*sig) + 2 * src_len + 3);
259 sig->keyid = sig->_keyid;
260 sig->_keyid[16] = '\0';
261 sig->uid = ((char *) sig) + sizeof (*sig);
265 char *dst = sig->uid;
266 _gpgme_decode_c_string (src, &dst, src_len + 1);
268 if (key->protocol == GPGME_PROTOCOL_CMS)
269 parse_x509_user_id (sig->uid, &sig->name, &sig->email,
272 parse_user_id (sig->uid, &sig->name, &sig->email,
276 if (!uid->signatures)
277 uid->signatures = sig;
278 if (uid->_last_keysig)
279 uid->_last_keysig->next = sig;
280 uid->_last_keysig = sig;
286 /* Acquire a reference to KEY. */
288 gpgme_key_ref (gpgme_key_t key)
292 UNLOCK (key_ref_lock);
296 /* gpgme_key_unref releases the key object. Note, that this function
297 may not do an actual release if there are other shallow copies of
298 the objects. You have to call this function for every newly
299 created key object as well as for every gpgme_key_ref() done on the
302 gpgme_key_unref (gpgme_key_t key)
305 gpgme_subkey_t subkey;
308 assert (key->_refs > 0);
311 UNLOCK (key_ref_lock);
314 UNLOCK (key_ref_lock);
316 subkey = key->subkeys;
319 gpgme_subkey_t next = subkey->next;
329 gpgme_user_id_t next_uid = uid->next;
330 gpgme_key_sig_t keysig = uid->signatures;
334 gpgme_key_sig_t next = keysig->next;
342 if (key->issuer_serial)
343 free (key->issuer_serial);
344 if (key->issuer_name)
345 free (key->issuer_name);
348 free (key->chain_id);
354 /* Compatibility interfaces. */
357 gpgme_key_release (gpgme_key_t key)
359 gpgme_key_unref (key);
364 otrust_to_string (int otrust)
368 case GPGME_VALIDITY_NEVER:
371 case GPGME_VALIDITY_MARGINAL:
374 case GPGME_VALIDITY_FULL:
377 case GPGME_VALIDITY_ULTIMATE:
387 validity_to_string (int validity)
391 case GPGME_VALIDITY_UNDEFINED:
394 case GPGME_VALIDITY_NEVER:
397 case GPGME_VALIDITY_MARGINAL:
400 case GPGME_VALIDITY_FULL:
403 case GPGME_VALIDITY_ULTIMATE:
406 case GPGME_VALIDITY_UNKNOWN:
414 capabilities_to_string (gpgme_subkey_t subkey)
416 static const char *const strings[8] =
427 return strings[(!!subkey->can_encrypt << 2)
428 | (!!subkey->can_sign << 1)
429 | (!!subkey->can_certify)];
433 /* Return the value of the attribute WHAT of ITEM, which has to be
434 representable by a string. */
436 gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
437 const void *reserved, int idx)
439 gpgme_subkey_t subkey;
443 if (!key || reserved || idx < 0)
446 /* Select IDXth subkey. */
447 subkey = key->subkeys;
448 for (i = 0; i < idx; i++)
450 subkey = subkey->next;
455 /* Select the IDXth user ID. */
457 for (i = 0; i < idx; i++)
466 case GPGME_ATTR_KEYID:
467 return subkey ? subkey->keyid : NULL;
470 return subkey ? subkey->fpr : NULL;
472 case GPGME_ATTR_ALGO:
473 return subkey ? gpgme_pubkey_algo_name (subkey->pubkey_algo) : NULL;
475 case GPGME_ATTR_TYPE:
476 return key->protocol == GPGME_PROTOCOL_CMS ? "X.509" : "PGP";
478 case GPGME_ATTR_OTRUST:
479 return otrust_to_string (key->owner_trust);
481 case GPGME_ATTR_USERID:
482 return uid ? uid->uid : NULL;
484 case GPGME_ATTR_NAME:
485 return uid ? uid->name : NULL;
487 case GPGME_ATTR_EMAIL:
488 return uid ? uid->email : NULL;
490 case GPGME_ATTR_COMMENT:
491 return uid ? uid->comment : NULL;
493 case GPGME_ATTR_VALIDITY:
494 return uid ? validity_to_string (uid->validity) : NULL;
496 case GPGME_ATTR_KEY_CAPS:
497 return subkey ? capabilities_to_string (subkey) : NULL;
499 case GPGME_ATTR_SERIAL:
500 return key->issuer_serial;
502 case GPGME_ATTR_ISSUER:
503 return idx ? NULL : key->issuer_name;
505 case GPGME_ATTR_CHAINID:
506 return key->chain_id;
515 gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
516 const void *reserved, int idx)
518 gpgme_subkey_t subkey;
522 if (!key || reserved || idx < 0)
525 /* Select IDXth subkey. */
526 subkey = key->subkeys;
527 for (i = 0; i < idx; i++)
529 subkey = subkey->next;
534 /* Select the IDXth user ID. */
536 for (i = 0; i < idx; i++)
545 case GPGME_ATTR_ALGO:
546 return subkey ? (unsigned long) subkey->pubkey_algo : 0;
549 return subkey ? (unsigned long) subkey->length : 0;
551 case GPGME_ATTR_TYPE:
552 return key->protocol == GPGME_PROTOCOL_CMS ? 1 : 0;
554 case GPGME_ATTR_CREATED:
555 return (subkey && subkey->timestamp >= 0)
556 ? (unsigned long) subkey->timestamp : 0;
558 case GPGME_ATTR_EXPIRE:
559 return (subkey && subkey->expires >= 0)
560 ? (unsigned long) subkey->expires : 0;
562 case GPGME_ATTR_VALIDITY:
563 return uid ? uid->validity : 0;
565 case GPGME_ATTR_OTRUST:
566 return key->owner_trust;
568 case GPGME_ATTR_IS_SECRET:
569 return !!key->secret;
571 case GPGME_ATTR_KEY_REVOKED:
572 return subkey ? subkey->revoked : 0;
574 case GPGME_ATTR_KEY_INVALID:
575 return subkey ? subkey->invalid : 0;
577 case GPGME_ATTR_KEY_EXPIRED:
578 return subkey ? subkey->expired : 0;
580 case GPGME_ATTR_KEY_DISABLED:
581 return subkey ? subkey->disabled : 0;
583 case GPGME_ATTR_UID_REVOKED:
584 return uid ? uid->revoked : 0;
586 case GPGME_ATTR_UID_INVALID:
587 return uid ? uid->invalid : 0;
589 case GPGME_ATTR_CAN_ENCRYPT:
590 return key->can_encrypt;
592 case GPGME_ATTR_CAN_SIGN:
593 return key->can_sign;
595 case GPGME_ATTR_CAN_CERTIFY:
596 return key->can_certify;
604 static gpgme_key_sig_t
605 get_keysig (gpgme_key_t key, int uid_idx, int idx)
610 if (!key || uid_idx < 0 || idx < 0)
614 while (uid && uid_idx > 0)
622 sig = uid->signatures;
623 while (sig && idx > 0)
633 gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
635 const void *reserved, int idx)
637 gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
639 if (!certsig || reserved)
644 case GPGME_ATTR_KEYID:
645 return certsig->keyid;
647 case GPGME_ATTR_ALGO:
648 return gpgme_pubkey_algo_name (certsig->pubkey_algo);
650 case GPGME_ATTR_USERID:
653 case GPGME_ATTR_NAME:
654 return certsig->name;
656 case GPGME_ATTR_EMAIL:
657 return certsig->email;
659 case GPGME_ATTR_COMMENT:
660 return certsig->comment;
669 gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, _gpgme_attr_t what,
670 const void *reserved, int idx)
672 gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
674 if (!certsig || reserved)
679 case GPGME_ATTR_ALGO:
680 return (unsigned long) certsig->pubkey_algo;
682 case GPGME_ATTR_CREATED:
683 return certsig->timestamp < 0 ? 0L : (unsigned long) certsig->timestamp;
685 case GPGME_ATTR_EXPIRE:
686 return certsig->expires < 0 ? 0L : (unsigned long) certsig->expires;
688 case GPGME_ATTR_KEY_REVOKED:
689 return certsig->revoked;
691 case GPGME_ATTR_KEY_INVALID:
692 return certsig->invalid;
694 case GPGME_ATTR_KEY_EXPIRED:
695 return certsig->expired;
697 case GPGME_ATTR_SIG_CLASS:
698 return certsig->class;
700 case GPGME_ATTR_SIG_STATUS:
701 return certsig->status;