mutt stable branch with some hacks
1/*
2 * Copyright (C) 1997-2002 Thomas Roessler <roessler@does-not-exist.org>
3 *
4 * This program is free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later
8 * version.
9 *
10 * This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22/* Generally useful, pgp-related functions. */
23
24#if HAVE_CONFIG_H
25# include "config.h"
26#endif
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32#include <time.h>
33
34#include "mutt.h"
35#include "lib.h"
36#include "pgplib.h"
37
38const char *pgp_pkalgbytype (unsigned char type)
39{
40 switch (type)
41 {
42 case 1:
43 return "RSA";
44 case 2:
45 return "RSA";
46 case 3:
47 return "RSA";
48 case 16:
49 return "ElG";
50 case 17:
51 return "DSA";
52 case 20:
53 return "ElG";
54 default:
55 return "unk";
56 }
57}
58
59
60
61/* unused */
62
63#if 0
64
65static const char *hashalgbytype (unsigned char type)
66{
67 switch (type)
68 {
69 case 1:
70 return "MD5";
71 case 2:
72 return "SHA1";
73 case 3:
74 return "RIPE-MD/160";
75 case 4:
76 return "HAVAL";
77 default:
78 return "unknown";
79 }
80}
81
82#endif
83
84short pgp_canencrypt (unsigned char type)
85{
86 switch (type)
87 {
88 case 1:
89 case 2:
90 case 16:
91 case 20:
92 return 1;
93 default:
94 return 0;
95 }
96}
97
98short pgp_cansign (unsigned char type)
99{
100 switch (type)
101 {
102 case 1:
103 case 3:
104 case 17:
105 case 20:
106 return 1;
107 default:
108 return 0;
109 }
110}
111
112/* return values:
113
114 * 1 = sign only
115 * 2 = encrypt only
116 * 3 = both
117 */
118
119short pgp_get_abilities (unsigned char type)
120{
121 return (pgp_canencrypt (type) << 1) | pgp_cansign (type);
122}
123
124void pgp_free_sig (pgp_sig_t **sigp)
125{
126 pgp_sig_t *sp, *q;
127
128 if (!sigp || !*sigp)
129 return;
130
131 for (sp = *sigp; sp; sp = q)
132 {
133 q = sp->next;
134 FREE (&sp);
135 }
136
137 *sigp = NULL;
138}
139
140void pgp_free_uid (pgp_uid_t ** upp)
141{
142 pgp_uid_t *up, *q;
143
144 if (!upp || !*upp)
145 return;
146 for (up = *upp; up; up = q)
147 {
148 q = up->next;
149 pgp_free_sig (&up->sigs);
150 FREE (&up->addr);
151 FREE (&up);
152 }
153
154 *upp = NULL;
155}
156
157pgp_uid_t *pgp_copy_uids (pgp_uid_t *up, pgp_key_t parent)
158{
159 pgp_uid_t *l = NULL;
160 pgp_uid_t **lp = &l;
161
162 for (; up; up = up->next)
163 {
164 *lp = safe_calloc (1, sizeof (pgp_uid_t));
165 (*lp)->trust = up->trust;
166 (*lp)->flags = up->flags;
167 (*lp)->addr = safe_strdup (up->addr);
168 (*lp)->parent = parent;
169 lp = &(*lp)->next;
170 }
171
172 return l;
173}
174
175static void _pgp_free_key (pgp_key_t *kpp)
176{
177 pgp_key_t kp;
178
179 if (!kpp || !*kpp)
180 return;
181
182 kp = *kpp;
183
184 pgp_free_uid (&kp->address);
185 FREE (&kp->keyid);
186 FREE (&kp->fingerprint);
187 /* mutt_crypt.h: 'typedef struct pgp_keyinfo *pgp_key_t;' */
188 FREE (kpp); /* __FREE_CHECKED__ */
189}
190
191pgp_key_t pgp_remove_key (pgp_key_t *klist, pgp_key_t key)
192{
193 pgp_key_t *last;
194 pgp_key_t p, q, r;
195
196 if (!klist || !*klist || !key)
197 return NULL;
198
199 if (key->parent && key->parent != key)
200 key = key->parent;
201
202 last = klist;
203 for (p = *klist; p && p != key; p = p->next)
204 last = &p->next;
205
206 if (!p)
207 return NULL;
208
209 for (q = p->next, r = p; q && q->parent == p; q = q->next)
210 r = q;
211
212 if (r)
213 r->next = NULL;
214
215 *last = q;
216 return q;
217}
218
219void pgp_free_key (pgp_key_t *kpp)
220{
221 pgp_key_t p, q, r;
222
223 if (!kpp || !*kpp)
224 return;
225
226 if ((*kpp)->parent && (*kpp)->parent != *kpp)
227 *kpp = (*kpp)->parent;
228
229 /* Order is important here:
230 *
231 * - First free all children.
232 * - If we are an orphan (i.e., our parent was not in the key list),
233 * free our parent.
234 * - free ourselves.
235 */
236
237 for (p = *kpp; p; p = q)
238 {
239 for (q = p->next; q && q->parent == p; q = r)
240 {
241 r = q->next;
242 _pgp_free_key (&q);
243 }
244 if (p->parent)
245 _pgp_free_key (&p->parent);
246
247 _pgp_free_key (&p);
248 }
249
250 *kpp = NULL;
251}