3 * $Id: key-misc.c,v 1.3 2001/06/22 19:39:12 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.3 2001/06/22 19:39:12 mdw
34 * New interface to find out whether a key has expired. Also, a bug fix
35 * to @key_bytag@ so that it finds expired keys correctly.
37 * Revision 1.2 2000/02/12 18:21:02 mdw
38 * Overhaul of key management (again).
40 * Revision 1.1 1999/12/22 15:47:48 mdw
41 * Major key-management revision.
45 /*----- Header files ------------------------------------------------------*/
52 #include <mLib/bits.h>
53 #include <mLib/hash.h>
59 /*----- Useful macros -----------------------------------------------------*/
61 #define KEY_WRITE(f) do { \
62 if (!(f)->f & KF_WRITE) \
63 return (KERR_READONLY); \
66 #define KEY_MODIFY(f) do { (f)->f |= KF_MODIFIED; } while (0)
68 #define KEY_LOAD(n) ((n) * 2)
70 /*----- Iteration and iterators -------------------------------------------*/
72 /* --- @key_mkiter@ --- *
74 * Arguments: @key_iter *i@ = pointer to iterator object
75 * @key_file *f@ = pointer to file structure
79 * Use: Initializes a key iterator. The keys are returned by
83 void key_mkiter(key_iter
*i
, key_file
*f
)
85 HASH_MKITER(&i
->i
, &f
->byid
);
89 /* --- @key_next@ --- *
91 * Arguments: @key_iter *i@ = pointer to iterator object
93 * Returns: Pointer to next key, or null.
95 * Use: Returns the next key in some arbitrary sequence.
98 key
*key_next(key_iter
*i
)
105 } while (k
&& KEY_EXPIRED(i
->t
, k
->exp
) && KEY_EXPIRED(i
->t
, k
->del
));
109 /*----- Lookup ------------------------------------------------------------*/
111 /* --- @key_bytype@ --- *
113 * Arguments: @key_file *f@ = key file we want a key from
114 * @const char *type@ = type string for desired key
116 * Returns: Pointer to the best key to use, or null.
118 * Use: Looks up a key by its type. Returns the key with the latest
119 * expiry time. This function will not return an expired key.
122 key
*key_bytype(key_file
*f
, const char *type
)
124 time_t now
= time(0);
128 if ((kr
= sym_find(&f
->bytype
, type
, -1, 0, 0)) == 0)
130 for (k
= kr
->k
; k
&& KEY_EXPIRED(now
, k
->exp
); k
= k
->next
)
135 /* --- @key_byid@ --- *
137 * Arguments: @key_file *f@ = key file to find a key from
138 * @uint32 id@ = id to look for
140 * Returns: Key with matching id.
142 * Use: Returns a key given its id. This function will return an
143 * expired key, but not a deleted one.
146 key
*key_byid(key_file
*f
, uint32 id
)
151 bin
= HASH_BIN(&f
->byid
, id
);
152 for (b
= *bin
; b
; b
= b
->next
) {
155 if (KEY_EXPIRED(t
, k
->exp
) && KEY_EXPIRED(t
, k
->del
))
163 /* --- @key_bytag@ --- *
165 * Arguments: @key_file *f@ = key file to find a key from
166 * @const char *tag@ = pointer to tag string
168 * Returns: Key with matching id or tag.
170 * Use: Returns a key given its tag or id. This function will return
171 * an expired key, but not a deleted one.
174 key
*key_bytag(key_file
*f
, const char *tag
)
179 key_ref
*kr
= sym_find(&f
->bytag
, tag
, -1, 0, 0);
181 if (kr
&& !(KEY_EXPIRED(t
, kr
->k
->exp
) && KEY_EXPIRED(t
, kr
->k
->del
)))
183 id
= strtoul(tag
, &p
, 16);
185 return (key_byid(f
, id
));
186 return (key_bytype(f
, tag
));
189 /* --- @key_qtag@ --- *
191 * Arguments: @key_file *f@ = key file to find a key from
192 * @const char *tag@ = pointer to tag string
193 * @dstr *d@ = pointer to string for full tag name
194 * @key **k@ = where to store the key pointer
195 * @key_data **kd@ = where to store the key data pointer
197 * Returns: Zero if OK, nonzero if it failed.
199 * Use: Performs a full lookup on a qualified tag name. The tag is
200 * qualified by the names of subkeys, separated by dots. Hence,
201 * a qualified tag is ID|TAG[.TAG...]. The various result
202 * pointers can be null to indicate that the result isn't
206 int key_qtag(key_file
*f
, const char *tag
, dstr
*d
, key
**k
, key_data
**kd
)
213 /* --- Find the end of the base tag --- */
215 if ((q
= strchr(tag
, '.')) == 0)
218 DPUTM(&dd
, tag
, q
- tag
);
223 /* --- Look up the key tag --- */
225 if ((kk
= key_bytag(f
, dd
.buf
)) == 0) {
230 /* --- Set the various initial bits of result up --- */
238 /* --- Now dig through the rest of the tag --- */
242 /* --- Stick on the next bit of the fullqtag --- */
245 while (*q
&& *q
!= '.') {
255 /* --- Look up the subkey --- */
257 if (kkd
->e
!= KENC_STRUCT
) {
261 if ((kkd
= key_structfind(kkd
, dd
.buf
)) == 0)
265 /* --- Return the results --- */
275 /*----- Miscellaneous functions -------------------------------------------*/
277 /* --- @key_delete@ --- *
279 * Arguments: @key_file *f@ = pointer to file block
280 * @key *k@ = key to delete
282 * Returns: Error code (one of the @KERR@ constants).
284 * Use: Removes the given key from the list. The key file must be
285 * writable. (Due to the horridness of the data structures,
286 * deleted keys aren't actually removed, just marked so that
287 * they can't be looked up or iterated over. One upshot of
288 * this is that they don't get written back to the file when
292 int key_delete(key_file
*f
, key
*k
)
295 k
->exp
= KEXP_EXPIRE
;
296 k
->del
= KEXP_EXPIRE
;
301 /* --- @key_expired@ --- *
303 * Arguments: @key *k@ = pointer to key block
305 * Returns: Zero if the key is OK, nonzero if it's expired.
308 int key_expired(key
*k
)
310 time_t now
= time(0);
311 return (KEY_EXPIRED(now
, k
->exp
) || KEY_EXPIRED(now
, k
->del
));
314 /* --- @key_expire@ --- *
316 * Arguments: @key_file *f@ = pointer to file block
317 * @key *k@ = pointer to key block
319 * Returns: Error code (one of the @KERR@ constants).
321 * Use: Immediately marks the key as expired. It may be removed
322 * immediately, if it is no longer required, and will be removed
323 * by a tidy operation when it is no longer required. The key
324 * file must be writable.
327 int key_expire(key_file
*f
, key
*k
)
330 k
->exp
= KEXP_EXPIRE
;
331 if (k
->del
== KEXP_FOREVER
)
332 k
->del
= KEXP_EXPIRE
;
337 /* --- @key_used@ --- *
339 * Arguments: @key_file *f@ = pointer to key file
340 * @key *k@ = pointer to key block
341 * @time_t t@ = when key can be removed
343 * Returns: Zero if OK, nonzero on failure.
345 * Use: Marks a key as being required until a given time. Even
346 * though the key may expire before then (and won't be returned
347 * by type after that time), it will still be available when
348 * requested explicitly by id. The key file must be writable.
350 * The only (current) reason for failure is attempting to use
351 * a key which can expire for something which can't.
354 int key_used(key_file
*f
, key
*k
, time_t t
)
357 if (t
== KEXP_FOREVER
) {
358 if (k
->exp
!= KEXP_FOREVER
)
359 return (KERR_WILLEXPIRE
);
360 } else if (k
->del
>= t
)
368 /*----- That's all, folks -------------------------------------------------*/