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