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