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