warning fixes
[apps/madmutt.git] / pgplib.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1997-2000 Thomas Roessler <roessler@does-not-exist.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 /* Generally useful, pgp-related functions. */
11
12 #if HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <time.h>
21
22 #include "mutt.h"
23 #include "lib.h"
24 #include "pgplib.h"
25
26 #include "lib/mem.h"
27
28 const char *pgp_pkalgbytype (unsigned char type)
29 {
30   switch (type) {
31   case 1:
32     return "RSA";
33   case 2:
34     return "RSA";
35   case 3:
36     return "RSA";
37   case 16:
38     return "ElG";
39   case 17:
40     return "DSA";
41   case 20:
42     return "ElG";
43   default:
44     return "unk";
45   }
46 }
47
48
49
50 /* unused */
51
52 #if 0
53
54 static const char *hashalgbytype (unsigned char type)
55 {
56   switch (type) {
57   case 1:
58     return "MD5";
59   case 2:
60     return "SHA1";
61   case 3:
62     return "RIPE-MD/160";
63   case 4:
64     return "HAVAL";
65   default:
66     return "unknown";
67   }
68 }
69
70 #endif
71
72 short pgp_canencrypt (unsigned char type)
73 {
74   switch (type) {
75   case 1:
76   case 2:
77   case 16:
78   case 20:
79     return 1;
80   default:
81     return 0;
82   }
83 }
84
85 short pgp_cansign (unsigned char type)
86 {
87   switch (type) {
88   case 1:
89   case 3:
90   case 17:
91   case 20:
92     return 1;
93   default:
94     return 0;
95   }
96 }
97
98 /* return values: 
99
100  * 1 = sign only
101  * 2 = encrypt only
102  * 3 = both
103  */
104
105 short pgp_get_abilities (unsigned char type)
106 {
107   return (pgp_canencrypt (type) << 1) | pgp_cansign (type);
108 }
109
110 void pgp_free_sig (pgp_sig_t ** sigp)
111 {
112   pgp_sig_t *sp, *q;
113
114   if (!sigp || !*sigp)
115     return;
116
117   for (sp = *sigp; sp; sp = q) {
118     q = sp->next;
119     mem_free (&sp);
120   }
121
122   *sigp = NULL;
123 }
124
125 void pgp_free_uid (pgp_uid_t ** upp)
126 {
127   pgp_uid_t *up, *q;
128
129   if (!upp || !*upp)
130     return;
131   for (up = *upp; up; up = q) {
132     q = up->next;
133     pgp_free_sig (&up->sigs);
134     mem_free (&up->addr);
135     mem_free (&up);
136   }
137
138   *upp = NULL;
139 }
140
141 pgp_uid_t *pgp_copy_uids (pgp_uid_t * up, pgp_key_t parent)
142 {
143   pgp_uid_t *l = NULL;
144   pgp_uid_t **lp = &l;
145
146   for (; up; up = up->next) {
147     *lp = mem_calloc (1, sizeof (pgp_uid_t));
148     (*lp)->trust = up->trust;
149     (*lp)->flags = up->flags;
150     (*lp)->addr = str_dup (up->addr);
151     (*lp)->parent = parent;
152     lp = &(*lp)->next;
153   }
154
155   return l;
156 }
157
158 static void _pgp_free_key (pgp_key_t * kpp)
159 {
160   pgp_key_t kp;
161
162   if (!kpp || !*kpp)
163     return;
164
165   kp = *kpp;
166
167   pgp_free_uid (&kp->address);
168   mem_free (&kp->keyid);
169   mem_free (kpp);
170 }
171
172 pgp_key_t pgp_remove_key (pgp_key_t * klist, pgp_key_t key)
173 {
174   pgp_key_t *last;
175   pgp_key_t p, q, r;
176
177   if (!klist || !*klist || !key)
178     return NULL;
179
180   if (key->parent && key->parent != key)
181     key = key->parent;
182
183   last = klist;
184   for (p = *klist; p && p != key; p = p->next)
185     last = &p->next;
186
187   if (!p)
188     return NULL;
189
190   for (q = p->next, r = p; q && q->parent == p; q = q->next)
191     r = q;
192
193   if (r)
194     r->next = NULL;
195
196   *last = q;
197   return q;
198 }
199
200 void pgp_free_key (pgp_key_t * kpp)
201 {
202   pgp_key_t p, q, r;
203
204   if (!kpp || !*kpp)
205     return;
206
207   if ((*kpp)->parent && (*kpp)->parent != *kpp)
208     *kpp = (*kpp)->parent;
209
210   /* Order is important here:
211    *
212    * - First free all children.
213    * - If we are an orphan (i.e., our parent was not in the key list),
214    *   free our parent.
215    * - free ourselves.
216    */
217
218   for (p = *kpp; p; p = q) {
219     for (q = p->next; q && q->parent == p; q = r) {
220       r = q->next;
221       _pgp_free_key (&q);
222     }
223     if (p->parent)
224       _pgp_free_key (&p->parent);
225
226     _pgp_free_key (&p);
227   }
228
229   *kpp = NULL;
230 }