python: Fix error handling.
[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_syserror ();
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_syserror ();
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_syserror ();
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->curve)
335         free (subkey->curve);
336       if (subkey->card_number)
337         free (subkey->card_number);
338       free (subkey);
339       subkey = next;
340     }
341
342   uid = key->uids;
343   while (uid)
344     {
345       gpgme_user_id_t next_uid = uid->next;
346       gpgme_key_sig_t keysig = uid->signatures;
347
348       while (keysig)
349         {
350           gpgme_key_sig_t next_keysig = keysig->next;
351           gpgme_sig_notation_t notation = keysig->notations;
352
353           while (notation)
354             {
355               gpgme_sig_notation_t next_notation = notation->next;
356
357               _gpgme_sig_notation_free (notation);
358               notation = next_notation;
359             }
360
361           free (keysig);
362           keysig = next_keysig;
363         }
364       free (uid);
365       uid = next_uid;
366     }
367
368   if (key->issuer_serial)
369     free (key->issuer_serial);
370   if (key->issuer_name)
371     free (key->issuer_name);
372
373   if (key->chain_id)
374     free (key->chain_id);
375
376   free (key);
377 }
378
379 \f
380 /* Support functions.  */
381
382 /* Create a dummy key to specify an email address.  */
383 gpgme_error_t
384 gpgme_key_from_uid (gpgme_key_t *r_key, const char *name)
385 {
386   gpgme_error_t err;
387   gpgme_key_t key;
388
389   *r_key = NULL;
390   err = _gpgme_key_new (&key);
391   if (err)
392     return err;
393
394   /* Note: protocol doesn't matter if only email is provided.  */
395   err = _gpgme_key_append_name (key, name, 0);
396   if (err)
397     gpgme_key_unref (key);
398   else
399     *r_key = key;
400
401   return err;
402 }
403
404
405 \f
406 /* Compatibility interfaces.  */
407
408 void
409 gpgme_key_release (gpgme_key_t key)
410 {
411   gpgme_key_unref (key);
412 }
413
414
415 static const char *
416 otrust_to_string (int otrust)
417 {
418   switch (otrust)
419     {
420     case GPGME_VALIDITY_NEVER:
421       return "n";
422
423     case GPGME_VALIDITY_MARGINAL:
424       return "m";
425
426     case GPGME_VALIDITY_FULL:
427       return "f";
428
429     case GPGME_VALIDITY_ULTIMATE:
430       return "u";
431
432     default:
433       return "?";
434     }
435 }
436
437
438 static const char *
439 validity_to_string (int validity)
440 {
441   switch (validity)
442     {
443     case GPGME_VALIDITY_UNDEFINED:
444       return "q";
445
446     case GPGME_VALIDITY_NEVER:
447       return "n";
448
449     case GPGME_VALIDITY_MARGINAL:
450       return "m";
451
452     case GPGME_VALIDITY_FULL:
453       return "f";
454
455     case GPGME_VALIDITY_ULTIMATE:
456       return "u";
457
458     case GPGME_VALIDITY_UNKNOWN:
459     default:
460       return "?";
461     }
462 }
463
464
465 static const char *
466 capabilities_to_string (gpgme_subkey_t subkey)
467 {
468   static const char *const strings[8] =
469     {
470       "",
471       "c",
472       "s",
473       "sc",
474       "e",
475       "ec",
476       "es",
477       "esc"
478     };
479   return strings[(!!subkey->can_encrypt << 2)
480                  | (!!subkey->can_sign << 1)
481                  | (!!subkey->can_certify)];
482 }
483
484
485 /* Return the value of the attribute WHAT of ITEM, which has to be
486    representable by a string.  */
487 const char *
488 gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
489                            const void *reserved, int idx)
490 {
491   gpgme_subkey_t subkey;
492   gpgme_user_id_t uid;
493   int i;
494
495   if (!key || reserved || idx < 0)
496     return NULL;
497
498   /* Select IDXth subkey.  */
499   subkey = key->subkeys;
500   for (i = 0; i < idx; i++)
501     {
502       subkey = subkey->next;
503       if (!subkey)
504         break;
505     }
506
507   /* Select the IDXth user ID.  */
508   uid = key->uids;
509   for (i = 0; i < idx; i++)
510     {
511       uid = uid->next;
512       if (!uid)
513         break;
514     }
515
516   switch (what)
517     {
518     case GPGME_ATTR_KEYID:
519       return subkey ? subkey->keyid : NULL;
520
521     case GPGME_ATTR_FPR:
522       return subkey ? subkey->fpr : NULL;
523
524     case GPGME_ATTR_ALGO:
525       return subkey ? gpgme_pubkey_algo_name (subkey->pubkey_algo) : NULL;
526
527     case GPGME_ATTR_TYPE:
528       return key->protocol == GPGME_PROTOCOL_CMS ? "X.509" : "PGP";
529
530     case GPGME_ATTR_OTRUST:
531       return otrust_to_string (key->owner_trust);
532
533     case GPGME_ATTR_USERID:
534       return uid ? uid->uid : NULL;
535
536     case GPGME_ATTR_NAME:
537       return uid ? uid->name : NULL;
538
539     case GPGME_ATTR_EMAIL:
540       return uid ? uid->email : NULL;
541
542     case GPGME_ATTR_COMMENT:
543       return uid ? uid->comment : NULL;
544
545     case GPGME_ATTR_VALIDITY:
546       return uid ? validity_to_string (uid->validity) : NULL;
547
548     case GPGME_ATTR_KEY_CAPS:
549       return subkey ? capabilities_to_string (subkey) : NULL;
550
551     case GPGME_ATTR_SERIAL:
552       return key->issuer_serial;
553
554     case GPGME_ATTR_ISSUER:
555       return idx ? NULL : key->issuer_name;
556
557     case GPGME_ATTR_CHAINID:
558       return key->chain_id;
559
560     default:
561       return NULL;
562     }
563 }
564
565
566 unsigned long
567 gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
568                           const void *reserved, int idx)
569 {
570   gpgme_subkey_t subkey;
571   gpgme_user_id_t uid;
572   int i;
573
574   if (!key || reserved || idx < 0)
575     return 0;
576
577   /* Select IDXth subkey.  */
578   subkey = key->subkeys;
579   for (i = 0; i < idx; i++)
580     {
581       subkey = subkey->next;
582       if (!subkey)
583         break;
584     }
585
586   /* Select the IDXth user ID.  */
587   uid = key->uids;
588   for (i = 0; i < idx; i++)
589     {
590       uid = uid->next;
591       if (!uid)
592         break;
593     }
594
595   switch (what)
596     {
597     case GPGME_ATTR_ALGO:
598       return subkey ? (unsigned long) subkey->pubkey_algo : 0;
599
600     case GPGME_ATTR_LEN:
601       return subkey ? (unsigned long) subkey->length : 0;
602
603     case GPGME_ATTR_TYPE:
604       return key->protocol == GPGME_PROTOCOL_CMS ? 1 : 0;
605
606     case GPGME_ATTR_CREATED:
607       return (subkey && subkey->timestamp >= 0)
608         ? (unsigned long) subkey->timestamp : 0;
609
610     case GPGME_ATTR_EXPIRE:
611       return (subkey && subkey->expires >= 0)
612         ? (unsigned long) subkey->expires : 0;
613
614     case GPGME_ATTR_VALIDITY:
615       return uid ? uid->validity : 0;
616
617     case GPGME_ATTR_OTRUST:
618       return key->owner_trust;
619
620     case GPGME_ATTR_IS_SECRET:
621       return !!key->secret;
622
623     case GPGME_ATTR_KEY_REVOKED:
624       return subkey ? subkey->revoked : 0;
625
626     case GPGME_ATTR_KEY_INVALID:
627       return subkey ? subkey->invalid : 0;
628
629     case GPGME_ATTR_KEY_EXPIRED:
630       return subkey ? subkey->expired : 0;
631
632     case GPGME_ATTR_KEY_DISABLED:
633       return subkey ? subkey->disabled : 0;
634
635     case GPGME_ATTR_UID_REVOKED:
636       return uid ? uid->revoked : 0;
637
638     case GPGME_ATTR_UID_INVALID:
639       return uid ? uid->invalid : 0;
640
641     case GPGME_ATTR_CAN_ENCRYPT:
642       return key->can_encrypt;
643
644     case GPGME_ATTR_CAN_SIGN:
645       return key->can_sign;
646
647     case GPGME_ATTR_CAN_CERTIFY:
648       return key->can_certify;
649
650     default:
651       return 0;
652     }
653 }
654
655
656 static gpgme_key_sig_t
657 get_keysig (gpgme_key_t key, int uid_idx, int idx)
658 {
659   gpgme_user_id_t uid;
660   gpgme_key_sig_t sig;
661
662   if (!key || uid_idx < 0 || idx < 0)
663     return NULL;
664
665   uid = key->uids;
666   while (uid && uid_idx > 0)
667     {
668       uid = uid->next;
669       uid_idx--;
670     }
671   if (!uid)
672     return NULL;
673
674   sig = uid->signatures;
675   while (sig && idx > 0)
676     {
677       sig = sig->next;
678       idx--;
679     }
680   return sig;
681 }
682
683
684 const char *
685 gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
686                                _gpgme_attr_t what,
687                                const void *reserved, int idx)
688 {
689   gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
690
691   if (!certsig || reserved)
692     return NULL;
693
694   switch (what)
695     {
696     case GPGME_ATTR_KEYID:
697       return certsig->keyid;
698
699     case GPGME_ATTR_ALGO:
700       return gpgme_pubkey_algo_name (certsig->pubkey_algo);
701
702     case GPGME_ATTR_USERID:
703       return certsig->uid;
704
705     case GPGME_ATTR_NAME:
706       return certsig->name;
707
708     case GPGME_ATTR_EMAIL:
709       return certsig->email;
710
711     case GPGME_ATTR_COMMENT:
712       return certsig->comment;
713
714     default:
715       return NULL;
716     }
717 }
718
719
720 unsigned long
721 gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, _gpgme_attr_t what,
722                               const void *reserved, int idx)
723 {
724   gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
725
726   if (!certsig || reserved)
727     return 0;
728
729   switch (what)
730     {
731     case GPGME_ATTR_ALGO:
732       return (unsigned long) certsig->pubkey_algo;
733
734     case GPGME_ATTR_CREATED:
735       return certsig->timestamp < 0 ? 0L : (unsigned long) certsig->timestamp;
736
737     case GPGME_ATTR_EXPIRE:
738       return certsig->expires < 0 ? 0L : (unsigned long) certsig->expires;
739
740     case GPGME_ATTR_KEY_REVOKED:
741       return certsig->revoked;
742
743     case GPGME_ATTR_KEY_INVALID:
744       return certsig->invalid;
745
746     case GPGME_ATTR_KEY_EXPIRED:
747       return certsig->expired;
748
749     case GPGME_ATTR_SIG_CLASS:
750       return certsig->sig_class;
751
752     case GPGME_ATTR_SIG_STATUS:
753       return certsig->status;
754
755     default:
756       return 0;
757     }
758 }