Renamed from `rsa-decrypt', since the name was no longer appropriate.
[u/mdw/catacomb] / key-attr.c
CommitLineData
d11a0bf7 1/* -*-c-*-
2 *
052b36d0 3 * $Id: key-attr.c,v 1.2 2000/02/12 18:21:02 mdw Exp $
d11a0bf7 4 *
5 * Key attribute manipulation
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: key-attr.c,v $
052b36d0 33 * Revision 1.2 2000/02/12 18:21:02 mdw
34 * Overhaul of key management (again).
35 *
d11a0bf7 36 * Revision 1.1 1999/12/22 15:47:48 mdw
37 * Major key-management revision.
38 *
39 */
40
41/*----- Header files ------------------------------------------------------*/
42
43#include <ctype.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <time.h>
48
052b36d0 49#include <mLib/dstr.h>
d11a0bf7 50#include <mLib/sym.h>
51
52#include "key.h"
53
54/*----- Main code ---------------------------------------------------------*/
55
56/* --- @key_chkident@ --- *
57 *
58 * Arguments: @const char *p@ = pointer to a type string
59 *
60 * Returns: Zero if OK, -1 on error.
61 *
62 * Use: Checks whether an identification component string is OK.
63 */
64
65int key_chkident(const char *p)
66{
67 if (!p || !*p)
68 return (-1);
69 while (*p) {
70 if (*p == ':' || *p == '.' || isspace((unsigned char)*p))
71 return (-1);
72 p++;
73 }
74 return (0);
75}
76
77/* --- @key_chkcomment@ --- *
78 *
79 * Arguments: @const char *p@ = pointer to a comment string
80 *
81 * Returns: Zero if OK, -1 on error.
82 *
83 * Use: Checks whether a comment string is OK.
84 */
85
86int key_chkcomment(const char *p)
87{
88 if (!p)
89 return (0);
90 if (!*p)
91 return (-1);
92 while (*p) {
93 if (*p == '\n')
94 return (-1);
95 p++;
96 }
97 return (0);
98}
99
100/* --- @key_mkattriter@ --- *
101 *
102 * Arguments: @key_attriter *i@ = pointer to attribute iterator
103 * @key *k@ = pointer to key
104 *
105 * Returns: ---
106 *
107 * Use: Initializes an attribute iterator. The attributes are
108 * returned by @key_nextattr@.
109 */
110
111void key_mkattriter(key_attriter *i, key *k)
112{
113 sym_mkiter(&i->i, &k->a);
114}
115
116/* --- @key_nextattr@ --- *
117 *
118 * Arguments: @key_attriter *i@ = pointer to attribute iterator
119 * @const char **n, **v@ = pointers to name and value
120 *
121 * Returns: Zero if no attribute available, or nonzero if returned OK.
122 *
123 * Use: Returns the next attribute.
124 */
125
126int key_nextattr(key_attriter *i, const char **n, const char **v)
127{
128 key_attr *a = sym_next(&i->i);
129 if (!a)
130 return (0);
131 *n = SYM_NAME(a);
132 *v = a->p;
133 return (1);
134}
135
136/* --- @key_getattr@ --- *
137 *
138 * Arguments: @key_file *f@ = pointer to file
139 * @key *k@ = pointer to key
140 * @const char *n@ = pointer to attribute name
141 *
142 * Returns: Pointer to attribute value, or null if not found.
143 *
144 * Use: Returns the value of a key attribute.
145 */
146
147const char *key_getattr(key_file *f, key *k, const char *n)
148{
149 key_attr *a;
150 if ((a = sym_find(&k->a, n, -1, 0, 0)) == 0)
151 return (0);
152 return (a->p);
153}
154
155/* --- @key_putattr@ --- *
156 *
157 * Arguments: @key_file *f@ = pointer to file
158 * @key *k@ = pointer to key
159 * @const char *n@ = pointer to attribute name
160 * @const char *v@ = pointer to attribute value or null
161 *
162 * Returns: Error code (one of the @KERR@ constants).
163 *
164 * Use: Inserts an attribute on a key. If an attribute with the same
165 * name already exists, it is deleted. Setting a null value
166 * removes the attribute.
167 */
168
169int key_putattr(key_file *f, key *k, const char *n, const char *v)
170{
171 key_attr *a;
172 unsigned found;
173
174 if (!(f->f & KF_WRITE))
175 return (KERR_READONLY);
176
177 if (v) {
178 a = sym_find(&k->a, n, -1, sizeof(*a), &found);
179 if (found)
180 free(a->p);
181 a->p = xstrdup(v);
182 } else if ((a = sym_find(&k->a, n, -1, 0, 0)) != 0) {
183 free(a->p);
184 sym_remove(&k->a, a);
185 }
186
187 f->f |= KF_MODIFIED;
188 return (0);
189}
190
191/* --- @key_setcomment@ --- *
192 *
193 * Arguments: @key_file *f@ = pointer to key file block
194 * @key *k@ = pointer to key block
195 * @const char *c@ = pointer to comment to set, or zero
196 *
197 * Returns: Error code (one of the @KERR@ constants).
198 *
199 * Use: Replaces the key's current comment with a new one.
200 */
201
202int key_setcomment(key_file *f, key *k, const char *c)
203{
204 if (!(f->f & KF_WRITE))
205 return (KERR_READONLY);
206 if (key_chkcomment(c))
207 return (KERR_BADCOMMENT);
208 if (k->c)
209 free(k->c);
210 if (c)
211 k->c = xstrdup(c);
212 else
213 k->c = 0;
214 f->f |= KF_MODIFIED;
215 return (0);
216}
217
218/* --- @key_settag@ --- *
219 *
220 * Arguments: @key_file *f@ = pointer to key file block
221 * @key *k@ = pointer to key block
222 * @const char *tag@ = pointer to comment to set, or zero
223 *
224 * Returns: Error code (one of the @KERR@ constants).
225 *
226 * Use: Replaces the key's current tag with a new one.
227 */
228
229int key_settag(key_file *f, key *k, const char *tag)
230{
231 key_ref *kr;
232 unsigned found;
233
234 if (!(f->f & KF_WRITE))
235 return (KERR_READONLY);
236
237 /* --- Make sure the tag is OK --- */
238
239 if (tag && key_chkident(tag))
240 return (KERR_BADTAG);
241
242 /* --- See if the new tag is the same as the old one --- */
243
244 if ((!tag && !k->tag) ||
245 (tag && k->tag && strcmp(tag, k->tag) == 0))
246 return (0);
247
248 /* --- Allocate an entry for the new tag --- */
249
250 if (tag) {
251 kr = sym_find(&f->bytag, tag, -1, sizeof(*kr), &found);
252 if (found)
253 return (KERR_DUPTAG);
254 kr->k = k;
255 }
256
257 /* --- Remove any existing tag --- */
258
259 if (k->tag) {
260 kr = sym_find(&f->bytag, k->tag, -1, 0, 0);
261 assert(((void)"No bytag link", kr));
262 sym_remove(&f->bytag, kr);
263 free(k->tag);
264 }
265
266 /* --- Done --- */
267
268 f->f |= KF_MODIFIED;
269 if (tag)
270 k->tag = xstrdup(tag);
271 else
272 k->tag = 0;
273 return (0);
274}
275
276/* --- @key_fulltag@ --- *
277 *
278 * Arguments: @key *k@ = pointer to key
279 * @dstr *d@ = pointer to destination string
280 *
281 * Returns: ---
282 *
283 * Use: Emits the key's full tag, which has the form
284 * `ID:TYPE[:TAG]'. This is used in the textual file format,
285 * and to identify passphrases for locked keys.
286 */
287
288void key_fulltag(key *k, dstr *d)
289{
290 dstr_putf(d, "%08lx:%s", (unsigned long)k->id, k->type);
291 if (k->tag)
292 dstr_putf(d, ":%s", k->tag);
293}
294
295/*----- That's all, folks -------------------------------------------------*/