Trace the use of GPG_ERR_INV_ENGINE.
[gpgme.git] / src / key.c
1 /* key.c - Key objects.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
4
5    This file is part of GPGME.
6
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11
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    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <errno.h>
29
30 #include "util.h"
31 #include "ops.h"
32 #include "sema.h"
33 #include "debug.h"
34
35 \f
36 /* Protects all reference counters in keys.  All other accesses to a
37    key are read only.  */
38 DEFINE_STATIC_LOCK (key_ref_lock);
39
40
41 /* Create a new key.  */
42 gpgme_error_t
43 _gpgme_key_new (gpgme_key_t *r_key)
44 {
45   gpgme_key_t key;
46
47   key = calloc (1, sizeof *key);
48   if (!key)
49     return gpg_error_from_errno (errno);
50   key->_refs = 1;
51
52   *r_key = key;
53   return 0;
54 }
55
56
57 gpgme_error_t
58 _gpgme_key_add_subkey (gpgme_key_t key, gpgme_subkey_t *r_subkey)
59 {
60   gpgme_subkey_t subkey;
61
62   subkey = calloc (1, sizeof *subkey);
63   if (!subkey)
64     return gpg_error_from_errno (errno);
65   subkey->keyid = subkey->_keyid;
66   subkey->_keyid[16] = '\0';
67
68   if (!key->subkeys)
69     key->subkeys = subkey;
70   if (key->_last_subkey)
71     key->_last_subkey->next = subkey;
72   key->_last_subkey = subkey;
73
74   *r_subkey = subkey;
75   return 0;
76 }
77
78
79 static char *
80 set_user_id_part (char *tail, const char *buf, size_t len)
81 {
82   while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t'))
83     len--;
84   for (; len; len--)
85     *tail++ = *buf++;
86   *tail++ = 0;
87   return tail;
88 }
89
90
91 static void
92 parse_user_id (char *src, char **name, char **email,
93                char **comment, char *tail)
94 {
95   const char *start = NULL;
96   int in_name = 0;
97   int in_email = 0;
98   int in_comment = 0;
99
100   while (*src)
101     {
102       if (in_email)
103         {
104           if (*src == '<')
105             /* Not legal but anyway.  */
106             in_email++;
107           else if (*src == '>')
108             {
109               if (!--in_email && !*email)
110                 {
111                   *email = tail;
112                   tail = set_user_id_part (tail, start, src - start);
113                 }
114             }
115         }
116       else if (in_comment)
117         {
118           if (*src == '(')
119             in_comment++;
120           else if (*src == ')')
121             {
122               if (!--in_comment && !*comment)
123                 {
124                   *comment = tail;
125                   tail = set_user_id_part (tail, start, src - start);
126                 }
127             }
128         }
129       else if (*src == '<')
130         {
131           if (in_name)
132             {
133               if (!*name)
134                 {
135                   *name = tail;
136                   tail = set_user_id_part (tail, start, src - start);
137                 }
138               in_name = 0;
139             }
140           in_email = 1;
141           start = src + 1;
142         }
143       else if (*src == '(')
144         {
145           if (in_name)
146             {
147               if (!*name)
148                 {
149                   *name = tail;
150                   tail = set_user_id_part (tail, start, src - start);
151                 }
152               in_name = 0;
153             }
154           in_comment = 1;
155           start = src + 1;
156         }
157       else if (!in_name && *src != ' ' && *src != '\t')
158         {
159           in_name = 1;
160           start = src;
161         }
162       src++;
163     }
164
165   if (in_name)
166     {
167       if (!*name)
168         {
169           *name = tail;
170           tail = set_user_id_part (tail, start, src - start);
171         }
172     }
173
174   /* Let unused parts point to an EOS.  */
175   tail--;
176   if (!*name)
177     *name = tail;
178   if (!*email)
179     *email = tail;
180   if (!*comment)
181     *comment = tail;
182 }
183
184
185 static void
186 parse_x509_user_id (char *src, char **name, char **email,
187                     char **comment, char *tail)
188 {
189   if (*src == '<' && src[strlen (src) - 1] == '>')
190     *email = src;
191
192   /* Let unused parts point to an EOS.  */
193   tail--;
194   if (!*name)
195     *name = tail;
196   if (!*email)
197     *email = tail;
198   if (!*comment)
199     *comment = tail;
200 }
201
202
203 /* Take a name from the --with-colon listing, remove certain escape
204    sequences sequences and put it into the list of UIDs.  */
205 gpgme_error_t
206 _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert)
207 {
208   gpgme_user_id_t uid;
209   char *dst;
210   int src_len = strlen (src);
211
212   assert (key);
213   /* We can malloc a buffer of the same length, because the converted
214      string will never be larger. Actually we allocate it twice the
215      size, so that we are able to store the parsed stuff there too.  */
216   uid = malloc (sizeof (*uid) + 2 * src_len + 3);
217   if (!uid)
218     return gpg_error_from_errno (errno);
219   memset (uid, 0, sizeof *uid);
220
221   uid->uid = ((char *) uid) + sizeof (*uid);
222   dst = uid->uid;
223   if (convert)
224     _gpgme_decode_c_string (src, &dst, src_len + 1);
225   else
226     memcpy (dst, src, src_len + 1);
227
228   dst += strlen (dst) + 1;
229   if (key->protocol == GPGME_PROTOCOL_CMS)
230     parse_x509_user_id (uid->uid, &uid->name, &uid->email,
231                         &uid->comment, dst);
232   else
233     parse_user_id (uid->uid, &uid->name, &uid->email,
234                    &uid->comment, dst);
235
236   if (!key->uids)
237     key->uids = uid;
238   if (key->_last_uid)
239     key->_last_uid->next = uid;
240   key->_last_uid = uid;
241
242   return 0;
243 }
244
245
246 gpgme_key_sig_t
247 _gpgme_key_add_sig (gpgme_key_t key, char *src)
248 {
249   int src_len = src ? strlen (src) : 0;
250   gpgme_user_id_t uid;
251   gpgme_key_sig_t sig;
252
253   assert (key); /* XXX */
254
255   uid = key->_last_uid;
256   assert (uid); /* XXX */
257
258   /* We can malloc a buffer of the same length, because the converted
259      string will never be larger.  Actually we allocate it twice the
260      size, so that we are able to store the parsed stuff there too.  */
261   sig = malloc (sizeof (*sig) + 2 * src_len + 3);
262   if (!sig)
263     return NULL;
264   memset (sig, 0, sizeof *sig);
265
266   sig->keyid = sig->_keyid;
267   sig->_keyid[16] = '\0';
268   sig->uid = ((char *) sig) + sizeof (*sig);
269
270   if (src)
271     {
272       char *dst = sig->uid;
273       _gpgme_decode_c_string (src, &dst, src_len + 1);
274       dst += strlen (dst) + 1;
275       if (key->protocol == GPGME_PROTOCOL_CMS)
276         parse_x509_user_id (sig->uid, &sig->name, &sig->email,
277                             &sig->comment, dst);
278       else
279         parse_user_id (sig->uid, &sig->name, &sig->email,
280                        &sig->comment, dst);
281     }
282   else
283     sig->uid = '\0';
284
285   if (!uid->signatures)
286     uid->signatures = sig;
287   if (uid->_last_keysig)
288     uid->_last_keysig->next = sig;
289   uid->_last_keysig = sig;
290
291   return sig;
292 }
293
294 \f
295 /* Acquire a reference to KEY.  */
296 void
297 gpgme_key_ref (gpgme_key_t key)
298 {
299   LOCK (key_ref_lock);
300   key->_refs++;
301   UNLOCK (key_ref_lock);
302 }
303
304
305 /* gpgme_key_unref releases the key object.  Note, that this function
306    may not do an actual release if there are other shallow copies of
307    the objects.  You have to call this function for every newly
308    created key object as well as for every gpgme_key_ref() done on the
309    key object.  */
310 void
311 gpgme_key_unref (gpgme_key_t key)
312 {
313   gpgme_user_id_t uid;
314   gpgme_subkey_t subkey;
315
316   if (!key)
317     return;
318
319   LOCK (key_ref_lock);
320   assert (key->_refs > 0);
321   if (--key->_refs)
322     {
323       UNLOCK (key_ref_lock);
324       return;
325     }
326   UNLOCK (key_ref_lock);
327
328   subkey = key->subkeys;
329   while (subkey)
330     {
331       gpgme_subkey_t next = subkey->next;
332       if (subkey->fpr)
333         free (subkey->fpr);
334       if (subkey->card_number)
335         free (subkey->card_number);
336       free (subkey);
337       subkey = next;
338     }
339
340   uid = key->uids;
341   while (uid)
342     {
343       gpgme_user_id_t next_uid = uid->next;
344       gpgme_key_sig_t keysig = uid->signatures;
345
346       while (keysig)
347         {
348           gpgme_key_sig_t next_keysig = keysig->next;
349           gpgme_sig_notation_t notation = keysig->notations;
350
351           while (notation)
352             {
353               gpgme_sig_notation_t next_notation = notation->next;
354
355               _gpgme_sig_notation_free (notation);
356               notation = next_notation;
357             }
358
359           free (keysig);
360           keysig = next_keysig;
361         }
362       free (uid);
363       uid = next_uid;
364     }
365
366   if (key->issuer_serial)
367     free (key->issuer_serial);
368   if (key->issuer_name)
369     free (key->issuer_name);
370
371   if (key->chain_id)
372     free (key->chain_id);
373
374   free (key);
375 }
376
377 \f
378 /* Support functions.  */
379
380 /* Create a dummy key to specify an email address.  */
381 gpgme_error_t
382 gpgme_key_from_uid (gpgme_key_t *r_key, const char *name)
383 {
384   gpgme_error_t err;
385   gpgme_key_t key;
386
387   *r_key = NULL;
388   err = _gpgme_key_new (&key);
389   if (err)
390     return err;
391
392   /* Note: protocol doesn't matter if only email is provided.  */
393   err = _gpgme_key_append_name (key, name, 0);
394   if (err)
395     gpgme_key_unref (key);
396   else
397     *r_key = key;
398
399   return err;
400 }
401
402
403 \f
404 /* Compatibility interfaces.  */
405
406 void
407 gpgme_key_release (gpgme_key_t key)
408 {
409   gpgme_key_unref (key);
410 }
411
412
413 static const char *
414 otrust_to_string (int otrust)
415 {
416   switch (otrust)
417     {
418     case GPGME_VALIDITY_NEVER:
419       return "n";
420
421     case GPGME_VALIDITY_MARGINAL:
422       return "m";
423
424     case GPGME_VALIDITY_FULL:
425       return "f";
426
427     case GPGME_VALIDITY_ULTIMATE:
428       return "u";
429
430     default:
431       return "?";
432     }
433 }
434
435
436 static const char *
437 validity_to_string (int validity)
438 {
439   switch (validity)
440     {
441     case GPGME_VALIDITY_UNDEFINED:
442       return "q";
443
444     case GPGME_VALIDITY_NEVER:
445       return "n";
446
447     case GPGME_VALIDITY_MARGINAL:
448       return "m";
449
450     case GPGME_VALIDITY_FULL:
451       return "f";
452
453     case GPGME_VALIDITY_ULTIMATE:
454       return "u";
455
456     case GPGME_VALIDITY_UNKNOWN:
457     default:
458       return "?";
459     }
460 }
461
462
463 static const char *
464 capabilities_to_string (gpgme_subkey_t subkey)
465 {
466   static const char *const strings[8] =
467     {
468       "",
469       "c",
470       "s",
471       "sc",
472       "e",
473       "ec",
474       "es",
475       "esc"
476     };
477   return strings[(!!subkey->can_encrypt << 2)
478                  | (!!subkey->can_sign << 1)
479                  | (!!subkey->can_certify)];
480 }
481
482
483 /* Return the value of the attribute WHAT of ITEM, which has to be
484    representable by a string.  */
485 const char *
486 gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
487                            const void *reserved, int idx)
488 {
489   gpgme_subkey_t subkey;
490   gpgme_user_id_t uid;
491   int i;
492
493   if (!key || reserved || idx < 0)
494     return NULL;
495
496   /* Select IDXth subkey.  */
497   subkey = key->subkeys;
498   for (i = 0; i < idx; i++)
499     {
500       subkey = subkey->next;
501       if (!subkey)
502         break;
503     }
504
505   /* Select the IDXth user ID.  */
506   uid = key->uids;
507   for (i = 0; i < idx; i++)
508     {
509       uid = uid->next;
510       if (!uid)
511         break;
512     }
513
514   switch (what)
515     {
516     case GPGME_ATTR_KEYID:
517       return subkey ? subkey->keyid : NULL;
518
519     case GPGME_ATTR_FPR:
520       return subkey ? subkey->fpr : NULL;
521
522     case GPGME_ATTR_ALGO:
523       return subkey ? gpgme_pubkey_algo_name (subkey->pubkey_algo) : NULL;
524
525     case GPGME_ATTR_TYPE:
526       return key->protocol == GPGME_PROTOCOL_CMS ? "X.509" : "PGP";
527
528     case GPGME_ATTR_OTRUST:
529       return otrust_to_string (key->owner_trust);
530
531     case GPGME_ATTR_USERID:
532       return uid ? uid->uid : NULL;
533
534     case GPGME_ATTR_NAME:
535       return uid ? uid->name : NULL;
536
537     case GPGME_ATTR_EMAIL:
538       return uid ? uid->email : NULL;
539
540     case GPGME_ATTR_COMMENT:
541       return uid ? uid->comment : NULL;
542
543     case GPGME_ATTR_VALIDITY:
544       return uid ? validity_to_string (uid->validity) : NULL;
545
546     case GPGME_ATTR_KEY_CAPS:
547       return subkey ? capabilities_to_string (subkey) : NULL;
548
549     case GPGME_ATTR_SERIAL:
550       return key->issuer_serial;
551
552     case GPGME_ATTR_ISSUER:
553       return idx ? NULL : key->issuer_name;
554
555     case GPGME_ATTR_CHAINID:
556       return key->chain_id;
557
558     default:
559       return NULL;
560     }
561 }
562
563
564 unsigned long
565 gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
566                           const void *reserved, int idx)
567 {
568   gpgme_subkey_t subkey;
569   gpgme_user_id_t uid;
570   int i;
571
572   if (!key || reserved || idx < 0)
573     return 0;
574
575   /* Select IDXth subkey.  */
576   subkey = key->subkeys;
577   for (i = 0; i < idx; i++)
578     {
579       subkey = subkey->next;
580       if (!subkey)
581         break;
582     }
583
584   /* Select the IDXth user ID.  */
585   uid = key->uids;
586   for (i = 0; i < idx; i++)
587     {
588       uid = uid->next;
589       if (!uid)
590         break;
591     }
592
593   switch (what)
594     {
595     case GPGME_ATTR_ALGO:
596       return subkey ? (unsigned long) subkey->pubkey_algo : 0;
597
598     case GPGME_ATTR_LEN:
599       return subkey ? (unsigned long) subkey->length : 0;
600
601     case GPGME_ATTR_TYPE:
602       return key->protocol == GPGME_PROTOCOL_CMS ? 1 : 0;
603
604     case GPGME_ATTR_CREATED:
605       return (subkey && subkey->timestamp >= 0)
606         ? (unsigned long) subkey->timestamp : 0;
607
608     case GPGME_ATTR_EXPIRE:
609       return (subkey && subkey->expires >= 0)
610         ? (unsigned long) subkey->expires : 0;
611
612     case GPGME_ATTR_VALIDITY:
613       return uid ? uid->validity : 0;
614
615     case GPGME_ATTR_OTRUST:
616       return key->owner_trust;
617
618     case GPGME_ATTR_IS_SECRET:
619       return !!key->secret;
620
621     case GPGME_ATTR_KEY_REVOKED:
622       return subkey ? subkey->revoked : 0;
623
624     case GPGME_ATTR_KEY_INVALID:
625       return subkey ? subkey->invalid : 0;
626
627     case GPGME_ATTR_KEY_EXPIRED:
628       return subkey ? subkey->expired : 0;
629
630     case GPGME_ATTR_KEY_DISABLED:
631       return subkey ? subkey->disabled : 0;
632
633     case GPGME_ATTR_UID_REVOKED:
634       return uid ? uid->revoked : 0;
635
636     case GPGME_ATTR_UID_INVALID:
637       return uid ? uid->invalid : 0;
638
639     case GPGME_ATTR_CAN_ENCRYPT:
640       return key->can_encrypt;
641
642     case GPGME_ATTR_CAN_SIGN:
643       return key->can_sign;
644
645     case GPGME_ATTR_CAN_CERTIFY:
646       return key->can_certify;
647
648     default:
649       return 0;
650     }
651 }
652
653
654 static gpgme_key_sig_t
655 get_keysig (gpgme_key_t key, int uid_idx, int idx)
656 {
657   gpgme_user_id_t uid;
658   gpgme_key_sig_t sig;
659
660   if (!key || uid_idx < 0 || idx < 0)
661     return NULL;
662
663   uid = key->uids;
664   while (uid && uid_idx > 0)
665     {
666       uid = uid->next;
667       uid_idx--;
668     }
669   if (!uid)
670     return NULL;
671
672   sig = uid->signatures;
673   while (sig && idx > 0)
674     {
675       sig = sig->next;
676       idx--;
677     }
678   return sig;
679 }
680
681
682 const char *
683 gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
684                                _gpgme_attr_t what,
685                                const void *reserved, int idx)
686 {
687   gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
688
689   if (!certsig || reserved)
690     return NULL;
691
692   switch (what)
693     {
694     case GPGME_ATTR_KEYID:
695       return certsig->keyid;
696
697     case GPGME_ATTR_ALGO:
698       return gpgme_pubkey_algo_name (certsig->pubkey_algo);
699
700     case GPGME_ATTR_USERID:
701       return certsig->uid;
702
703     case GPGME_ATTR_NAME:
704       return certsig->name;
705
706     case GPGME_ATTR_EMAIL:
707       return certsig->email;
708
709     case GPGME_ATTR_COMMENT:
710       return certsig->comment;
711
712     default:
713       return NULL;
714     }
715 }
716
717
718 unsigned long
719 gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, _gpgme_attr_t what,
720                               const void *reserved, int idx)
721 {
722   gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
723
724   if (!certsig || reserved)
725     return 0;
726
727   switch (what)
728     {
729     case GPGME_ATTR_ALGO:
730       return (unsigned long) certsig->pubkey_algo;
731
732     case GPGME_ATTR_CREATED:
733       return certsig->timestamp < 0 ? 0L : (unsigned long) certsig->timestamp;
734
735     case GPGME_ATTR_EXPIRE:
736       return certsig->expires < 0 ? 0L : (unsigned long) certsig->expires;
737
738     case GPGME_ATTR_KEY_REVOKED:
739       return certsig->revoked;
740
741     case GPGME_ATTR_KEY_INVALID:
742       return certsig->invalid;
743
744     case GPGME_ATTR_KEY_EXPIRED:
745       return certsig->expired;
746
747     case GPGME_ATTR_SIG_CLASS:
748       return certsig->sig_class;
749
750     case GPGME_ATTR_SIG_STATUS:
751       return certsig->status;
752
753     default:
754       return 0;
755     }
756 }