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