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
pgp_pkalgbytype(unsigned char type)38 const 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
65 static 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
pgp_canencrypt(unsigned char type)84 short 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
pgp_cansign(unsigned char type)98 short 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
pgp_get_abilities(unsigned char type)119 short pgp_get_abilities (unsigned char type)
120 {
121 return (pgp_canencrypt (type) << 1) | pgp_cansign (type);
122 }
123
pgp_free_sig(pgp_sig_t ** sigp)124 void 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
pgp_free_uid(pgp_uid_t ** upp)140 void 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
pgp_copy_uids(pgp_uid_t * up,pgp_key_t parent)157 pgp_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
_pgp_free_key(pgp_key_t * kpp)175 static 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 /* mutt_crypt.h: 'typedef struct pgp_keyinfo *pgp_key_t;' */
187 FREE (kpp); /* __FREE_CHECKED__ */
188 }
189
pgp_remove_key(pgp_key_t * klist,pgp_key_t key)190 pgp_key_t pgp_remove_key (pgp_key_t *klist, pgp_key_t key)
191 {
192 pgp_key_t *last;
193 pgp_key_t p, q, r;
194
195 if (!klist || !*klist || !key)
196 return NULL;
197
198 if (key->parent && key->parent != key)
199 key = key->parent;
200
201 last = klist;
202 for (p = *klist; p && p != key; p = p->next)
203 last = &p->next;
204
205 if (!p)
206 return NULL;
207
208 for (q = p->next, r = p; q && q->parent == p; q = q->next)
209 r = q;
210
211 if (r)
212 r->next = NULL;
213
214 *last = q;
215 return q;
216 }
217
pgp_free_key(pgp_key_t * kpp)218 void pgp_free_key (pgp_key_t *kpp)
219 {
220 pgp_key_t p, q, r;
221
222 if (!kpp || !*kpp)
223 return;
224
225 if ((*kpp)->parent && (*kpp)->parent != *kpp)
226 *kpp = (*kpp)->parent;
227
228 /* Order is important here:
229 *
230 * - First free all children.
231 * - If we are an orphan (i.e., our parent was not in the key list),
232 * free our parent.
233 * - free ourselves.
234 */
235
236 for (p = *kpp; p; p = q)
237 {
238 for (q = p->next; q && q->parent == p; q = r)
239 {
240 r = q->next;
241 _pgp_free_key (&q);
242 }
243 if (p->parent)
244 _pgp_free_key (&p->parent);
245
246 _pgp_free_key (&p);
247 }
248
249 *kpp = NULL;
250 }
251
252