Change GPLv2+ to GPLv3+.
[shishi.git] / lib / key.c
blobb7152dbc5e0678ae8a6a4fff81380b63c9b906a3
1 /* key.c --- Key related functions.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
23 #include "internal.h"
25 struct Shishi_key
27 Shishi *handle;
28 char *principal;
29 char *realm;
30 int type;
31 char value[MAX_KEY_LEN];
32 uint32_t kvno; /* UINT32_MAX means undefined kvno */
35 /**
36 * shishi_key_principal:
37 * @key: structure that holds key information
39 * Get the principal part of the key owner principal name, i.e.,
40 * except the realm.
42 * Return value: Returns the principal owning the key. (Not a copy of
43 * it, so don't modify or deallocate it.)
44 **/
45 const char *
46 shishi_key_principal (Shishi_key * key)
48 return key->principal;
51 /**
52 * shishi_key_principal_set:
53 * @key: structure that holds key information
54 * @principal: string with new principal name.
56 * Set the principal owning the key. The string is copied into the
57 * key, so you can dispose of the variable immediately after calling
58 * this function.
59 **/
60 void
61 shishi_key_principal_set (Shishi_key * key, const char *principal)
63 if (key->principal)
64 free (key->principal);
65 if (principal)
66 key->principal = xstrdup (principal);
67 else
68 key->principal = NULL;
71 /**
72 * shishi_key_realm:
73 * @key: structure that holds key information
75 * Get the realm part of the key owner principal name.
77 * Return value: Returns the realm for the principal owning the key.
78 * (Not a copy of it, so don't modify or deallocate it.)
79 **/
80 const char *
81 shishi_key_realm (Shishi_key * key)
83 return key->realm;
86 /**
87 * shishi_key_realm_set:
88 * @key: structure that holds key information
89 * @realm: string with new realm name.
91 * Set the realm for the principal owning the key. The string is
92 * copied into the key, so you can dispose of the variable immediately
93 * after calling this function.
94 **/
95 void
96 shishi_key_realm_set (Shishi_key * key, const char *realm)
98 if (key->realm)
99 free (key->realm);
100 if (realm)
101 key->realm = xstrdup (realm);
102 else
103 key->realm = NULL;
107 * shishi_key_type:
108 * @key: structure that holds key information
110 * Get key type.
112 * Return value: Returns the type of key as an integer as described in
113 * the standard.
116 shishi_key_type (Shishi_key * key)
118 return key->type;
122 * shishi_key_type_set:
123 * @key: structure that holds key information
124 * @type: type to set in key.
126 * Set the type of key in key structure.
128 void
129 shishi_key_type_set (Shishi_key * key, int32_t type)
131 key->type = type;
135 * shishi_key_value:
136 * @key: structure that holds key information
138 * Get the raw key bytes.
140 * Return value: Returns the key value as a pointer which is valid
141 * throughout the lifetime of the key structure.
143 char *
144 shishi_key_value (Shishi_key * key)
146 return key->value;
150 * shishi_key_value_set:
151 * @key: structure that holds key information
152 * @value: input array with key data.
154 * Set the key value and length in key structure. The value is copied
155 * into the key (in other words, you can deallocate @value right after
156 * calling this function without modifying the value inside the key).
158 void
159 shishi_key_value_set (Shishi_key * key, const char *value)
161 if (value &&
162 shishi_cipher_keylen (key->type) > 0 &&
163 shishi_cipher_keylen (key->type) <= MAX_KEY_LEN)
164 memcpy (key->value, value, shishi_cipher_keylen (key->type));
168 * shishi_key_version:
169 * @key: structure that holds key information
171 * Get the "kvno" (key version) of key. It will be UINT32_MAX if the
172 * key is not long-lived.
174 * Return value: Returns the version of key ("kvno").
176 uint32_t
177 shishi_key_version (Shishi_key * key)
179 return key->kvno;
183 * shishi_key_version_set:
184 * @key: structure that holds key information
185 * @kvno: new version integer.
187 * Set the version of key ("kvno") in key structure. Use UINT32_MAX
188 * for non-ptermanent keys.
190 void
191 shishi_key_version_set (Shishi_key * key, uint32_t kvno)
193 key->kvno = kvno;
197 * shishi_key_name:
198 * @key: structure that holds key information
200 * Calls shishi_cipher_name for key type.
202 * Return value: Return name of key.
204 const char *
205 shishi_key_name (Shishi_key * key)
207 return shishi_cipher_name (key->type);
211 * shishi_key_length:
212 * @key: structure that holds key information
214 * Calls shishi_cipher_keylen for key type.
216 * Return value: Returns the length of the key value.
218 size_t
219 shishi_key_length (Shishi_key * key)
221 return shishi_cipher_keylen (key->type);
225 * shishi_key:
226 * @handle: Shishi library handle create by shishi_init().
227 * @key: pointer to structure that will hold newly created key information
229 * Create a new Key information structure.
231 * Return value: Returns SHISHI_OK iff successful.
234 shishi_key (Shishi * handle, Shishi_key ** key)
236 *key = xcalloc (1, sizeof (**key));
238 (*key)->handle = handle;
239 (*key)->kvno = UINT32_MAX;
241 return SHISHI_OK;
245 * shishi_key_done:
246 * @key: pointer to structure that holds key information.
248 * Deallocates key information structure.
250 void
251 shishi_key_done (Shishi_key * key)
253 if (key->realm)
254 free (key->realm);
255 if (key->principal)
256 free (key->principal);
257 free (key);
261 * shishi_key_copy:
262 * @dstkey: structure that holds destination key information
263 * @srckey: structure that holds source key information
265 * Copies source key into existing allocated destination key.
267 void
268 shishi_key_copy (Shishi_key * dstkey, Shishi_key * srckey)
270 shishi_key_principal_set (dstkey, shishi_key_principal (srckey));
271 shishi_key_realm_set (dstkey, shishi_key_realm (srckey));
272 shishi_key_type_set (dstkey, shishi_key_type (srckey));
273 shishi_key_value_set (dstkey, shishi_key_value (srckey));
274 shishi_key_version_set (dstkey, shishi_key_version (srckey));
278 * shishi_key_from_value:
279 * @handle: Shishi library handle create by shishi_init().
280 * @type: type of key.
281 * @value: input array with key value, or NULL.
282 * @key: pointer to structure that will hold newly created key information
284 * Create a new Key information structure, and set the key type and
285 * key value. KEY contains a newly allocated structure only if this
286 * function is successful.
288 * Return value: Returns SHISHI_OK iff successful.
291 shishi_key_from_value (Shishi * handle,
292 int32_t type, const char *value, Shishi_key ** key)
294 int rc;
296 rc = shishi_key (handle, key);
297 if (rc != SHISHI_OK)
298 return rc;
300 shishi_key_type_set (*key, type);
301 if (value)
302 shishi_key_value_set (*key, value);
304 return SHISHI_OK;
308 * shishi_key_from_base64:
309 * @handle: Shishi library handle create by shishi_init().
310 * @type: type of key.
311 * @value: input string with base64 encoded key value, or NULL.
312 * @key: pointer to structure that will hold newly created key information
314 * Create a new Key information structure, and set the key type and
315 * key value. KEY contains a newly allocated structure only if this
316 * function is successful.
318 * Return value: Returns SHISHI_INVALID_KEY if the base64 encoded key
319 * length doesn't match the key type, and SHISHI_OK on
320 * success.
323 shishi_key_from_base64 (Shishi * handle,
324 int32_t type, const char *value, Shishi_key ** key)
326 int rc;
328 rc = shishi_key (handle, key);
329 if (rc != SHISHI_OK)
330 return rc;
332 shishi_key_type_set (*key, type);
334 if (value)
336 size_t len = MAX_KEY_LEN;
338 if (!base64_decode (value, strlen (value), (*key)->value, &len))
340 shishi_key_done (*key);
341 return SHISHI_BASE64_ERROR;
344 if (len != shishi_key_length (*key))
346 shishi_key_done (*key);
347 return SHISHI_INVALID_KEY;
351 return SHISHI_OK;
355 * shishi_key_random
356 * @handle: Shishi library handle create by shishi_init().
357 * @type: type of key.
358 * @key: pointer to structure that will hold newly created key information
360 * Create a new Key information structure for the key type and some
361 * random data. KEY contains a newly allocated structure only if this
362 * function is successful.
364 * Return value: Returns SHISHI_OK iff successful.
367 shishi_key_random (Shishi * handle, int32_t type, Shishi_key ** key)
369 char buf[MAX_RANDOM_LEN];
370 int len = shishi_cipher_randomlen (type);
371 int rc;
373 rc = shishi_randomize (handle, 1, buf, len);
374 if (rc != SHISHI_OK)
375 return rc;
377 rc = shishi_key (handle, key);
378 if (rc != SHISHI_OK)
379 return rc;
381 rc = shishi_random_to_key (handle, type, buf, len, *key);
382 if (rc != SHISHI_OK)
384 shishi_key_done (*key);
385 return rc;
388 return SHISHI_OK;
392 * shishi_key_from_random
393 * @handle: Shishi library handle create by shishi_init().
394 * @type: type of key.
395 * @rnd: random data.
396 * @rndlen: length of random data.
397 * @outkey: pointer to structure that will hold newly created key information
399 * Create a new Key information structure, and set the key type and
400 * key value using shishi_random_to_key(). KEY contains a newly
401 * allocated structure only if this function is successful.
403 * Return value: Returns SHISHI_OK iff successful.
406 shishi_key_from_random (Shishi * handle,
407 int32_t type,
408 const char *rnd, size_t rndlen, Shishi_key ** outkey)
410 int rc;
412 rc = shishi_key (handle, outkey);
413 if (rc != SHISHI_OK)
414 return rc;
416 rc = shishi_random_to_key (handle, type, rnd, rndlen, *outkey);
418 return rc;
422 * shishi_key_from_string
423 * @handle: Shishi library handle create by shishi_init().
424 * @type: type of key.
425 * @password: input array containing password.
426 * @passwordlen: length of input array containing password.
427 * @salt: input array containing salt.
428 * @saltlen: length of input array containing salt.
429 * @parameter: input array with opaque encryption type specific information.
430 * @outkey: pointer to structure that will hold newly created key information
432 * Create a new Key information structure, and set the key type and
433 * key value using shishi_string_to_key(). KEY contains a newly
434 * allocated structure only if this function is successful.
436 * Return value: Returns SHISHI_OK iff successful.
439 shishi_key_from_string (Shishi * handle,
440 int32_t type,
441 const char *password, size_t passwordlen,
442 const char *salt, size_t saltlen,
443 const char *parameter, Shishi_key ** outkey)
445 int rc;
447 rc = shishi_key (handle, outkey);
448 if (rc != SHISHI_OK)
449 return rc;
451 rc = shishi_string_to_key (handle, type, password, passwordlen,
452 salt, saltlen, parameter, *outkey);
453 if (rc != SHISHI_OK)
455 shishi_key_done (*outkey);
456 return rc;
459 return SHISHI_OK;
463 * shishi_key_from_name:
464 * @handle: Shishi library handle create by shishi_init().
465 * @type: type of key.
466 * @name: principal name of user.
467 * @password: input array containing password.
468 * @passwordlen: length of input array containing password.
469 * @parameter: input array with opaque encryption type specific information.
470 * @outkey: pointer to structure that will hold newly created key information
472 * Create a new Key information structure, and derive the key from
473 * principal name and password using shishi_key_from_name(). The salt
474 * is derived from the principal name by concatenating the decoded
475 * realm and principal.
477 * Return value: Returns SHISHI_OK iff successful.
480 shishi_key_from_name (Shishi * handle,
481 int32_t type,
482 const char *name,
483 const char *password, size_t passwordlen,
484 const char *parameter, Shishi_key ** outkey)
486 int rc;
487 char *salt;
489 rc = shishi_derive_default_salt (handle, name, &salt);
490 if (rc != SHISHI_OK)
491 return rc;
493 rc = shishi_key_from_string (handle, type, password, passwordlen,
494 salt, strlen (salt), parameter, outkey);
495 if (rc == SHISHI_OK)
497 char *principal;
498 char *realm;
500 rc = shishi_parse_name (handle, name, &principal, &realm);
501 if (rc == SHISHI_OK)
503 shishi_key_principal_set (*outkey, principal);
504 shishi_key_realm_set (*outkey, realm);
506 free (realm);
507 free (principal);
511 free (salt);
513 return rc;