12a5f2176dd5c00448c5391116b81b2ad9d2e0fe
3 * $Id: key-misc.c,v 1.2 2000/02/12 18:21:02 mdw Exp $
5 * Simple key management
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Revision history --------------------------------------------------*
32 * $Log: key-misc.c,v $
33 * Revision 1.2 2000/02/12 18:21:02 mdw
34 * Overhaul of key management (again).
36 * Revision 1.1 1999/12/22 15:47:48 mdw
37 * Major key-management revision.
41 /*----- Header files ------------------------------------------------------*/
48 #include <mLib/bits.h>
49 #include <mLib/hash.h>
55 /*----- Useful macros -----------------------------------------------------*/
57 #define KEY_WRITE(f) do { \
58 if (!(f)->f & KF_WRITE) \
59 return (KERR_READONLY); \
62 #define KEY_MODIFY(f) do { (f)->f |= KF_MODIFIED; } while (0)
64 #define KEY_LOAD(n) ((n) * 2)
66 /*----- Iteration and iterators -------------------------------------------*/
68 /* --- @key_mkiter@ --- *
70 * Arguments: @key_iter *i@ = pointer to iterator object
71 * @key_file *f@ = pointer to file structure
75 * Use: Initializes a key iterator. The keys are returned by
79 void key_mkiter(key_iter
*i
, key_file
*f
)
81 HASH_MKITER(&i
->i
, &f
->byid
);
85 /* --- @key_next@ --- *
87 * Arguments: @key_iter *i@ = pointer to iterator object
89 * Returns: Pointer to next key, or null.
91 * Use: Returns the next key in some arbitrary sequence.
94 key
*key_next(key_iter
*i
)
101 } while (k
&& KEY_EXPIRED(i
->t
, k
->exp
) && KEY_EXPIRED(i
->t
, k
->del
));
105 /*----- Lookup ------------------------------------------------------------*/
107 /* --- @key_bytype@ --- *
109 * Arguments: @key_file *f@ = key file we want a key from
110 * @const char *type@ = type string for desired key
112 * Returns: Pointer to the best key to use, or null.
114 * Use: Looks up a key by its type. Returns the key with the latest
115 * expiry time. This function will not return an expired key.
118 key
*key_bytype(key_file
*f
, const char *type
)
120 time_t now
= time(0);
124 if ((kr
= sym_find(&f
->bytype
, type
, -1, 0, 0)) == 0)
126 for (k
= kr
->k
; k
&& KEY_EXPIRED(now
, k
->exp
); k
= k
->next
)
131 /* --- @key_byid@ --- *
133 * Arguments: @key_file *f@ = key file to find a key from
134 * @uint32 id@ = id to look for
136 * Returns: Key with matching id.
138 * Use: Returns a key given its id. This function will return an
139 * expired key, but not a deleted one.
142 key
*key_byid(key_file
*f
, uint32 id
)
147 bin
= HASH_BIN(&f
->byid
, id
);
148 for (b
= *bin
; b
; b
= b
->next
) {
151 if (KEY_EXPIRED(t
, k
->exp
) && KEY_EXPIRED(t
, k
->del
))
159 /* --- @key_bytag@ --- *
161 * Arguments: @key_file *f@ = key file to find a key from
162 * @const char *tag@ = pointer to tag string
164 * Returns: Key with matching id or tag.
166 * Use: Returns a key given its tag or id. This function will return
167 * an expired key, but not a deleted one.
170 key
*key_bytag(key_file
*f
, const char *tag
)
175 key_ref
*kr
= sym_find(&f
->bytag
, tag
, -1, 0, 0);
177 if (kr
&& !(KEY_EXPIRED(t
, kr
->k
->exp
) && KEY_EXPIRED(t
, kr
->k
->exp
)))
179 id
= strtoul(tag
, &p
, 16);
181 return (key_byid(f
, id
));
182 return (key_bytype(f
, tag
));
185 /* --- @key_qtag@ --- *
187 * Arguments: @key_file *f@ = key file to find a key from
188 * @const char *tag@ = pointer to tag string
189 * @dstr *d@ = pointer to string for full tag name
190 * @key **k@ = where to store the key pointer
191 * @key_data **kd@ = where to store the key data pointer
193 * Returns: Zero if OK, nonzero if it failed.
195 * Use: Performs a full lookup on a qualified tag name. The tag is
196 * qualified by the names of subkeys, separated by dots. Hence,
197 * a qualified tag is ID|TAG[.TAG...]. The various result
198 * pointers can be null to indicate that the result isn't
202 int key_qtag(key_file
*f
, const char *tag
, dstr
*d
, key
**k
, key_data
**kd
)
209 /* --- Find the end of the base tag --- */
211 if ((q
= strchr(tag
, '.')) == 0)
214 DPUTM(&dd
, tag
, q
- tag
);
219 /* --- Look up the key tag --- */
221 if ((kk
= key_bytag(f
, dd
.buf
)) == 0) {
226 /* --- Set the various initial bits of result up --- */
234 /* --- Now dig through the rest of the tag --- */
238 /* --- Stick on the next bit of the fullqtag --- */
241 while (*q
&& *q
!= '.') {
251 /* --- Look up the subkey --- */
253 if (kkd
->e
!= KENC_STRUCT
) {
257 if ((kkd
= key_structfind(kkd
, dd
.buf
)) == 0)
261 /* --- Return the results --- */
271 /*----- Miscellaneous functions -------------------------------------------*/
273 /* --- @key_delete@ --- *
275 * Arguments: @key_file *f@ = pointer to file block
276 * @key *k@ = key to delete
278 * Returns: Error code (one of the @KERR@ constants).
280 * Use: Removes the given key from the list. The key file must be
281 * writable. (Due to the horridness of the data structures,
282 * deleted keys aren't actually removed, just marked so that
283 * they can't be looked up or iterated over. One upshot of
284 * this is that they don't get written back to the file when
288 int key_delete(key_file
*f
, key
*k
)
291 k
->exp
= KEXP_EXPIRE
;
292 k
->del
= KEXP_EXPIRE
;
297 /* --- @key_expire@ --- *
299 * Arguments: @key_file *f@ = pointer to file block
300 * @key *k@ = pointer to key block
302 * Returns: Error code (one of the @KERR@ constants).
304 * Use: Immediately marks the key as expired. It may be removed
305 * immediately, if it is no longer required, and will be removed
306 * by a tidy operation when it is no longer required. The key
307 * file must be writable.
310 int key_expire(key_file
*f
, key
*k
)
313 k
->exp
= KEXP_EXPIRE
;
314 if (k
->del
== KEXP_FOREVER
)
315 k
->del
= KEXP_EXPIRE
;
320 /* --- @key_used@ --- *
322 * Arguments: @key_file *f@ = pointer to key file
323 * @key *k@ = pointer to key block
324 * @time_t t@ = when key can be removed
326 * Returns: Zero if OK, nonzero on failure.
328 * Use: Marks a key as being required until a given time. Even
329 * though the key may expire before then (and won't be returned
330 * by type after that time), it will still be available when
331 * requested explicitly by id. The key file must be writable.
333 * The only (current) reason for failure is attempting to use
334 * a key which can expire for something which can't.
337 int key_used(key_file
*f
, key
*k
, time_t t
)
340 if (t
== KEXP_FOREVER
) {
341 if (k
->exp
!= KEXP_FOREVER
)
342 return (KERR_WILLEXPIRE
);
343 } else if (k
->del
>= t
)
351 /*----- That's all, folks -------------------------------------------------*/