Fix last commit.
[shishi.git] / lib / key.c
blobc1a3c0ef487eab33e428d8abcfcecf67520d4179
1 /* key.c --- Key related functions.
2 * Copyright (C) 2002, 2003, 2004, 2006 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "internal.h"
24 struct Shishi_key
26 Shishi *handle;
27 char *principal;
28 char *realm;
29 int type;
30 char value[MAX_KEY_LEN];
31 uint32_t kvno; /* UINT32_MAX means undefined kvno */
34 /**
35 * shishi_key_principal:
36 * @key: structure that holds key information
38 * Get the principal part of the key owner principal name, i.e.,
39 * except the realm.
41 * Return value: Returns the principal owning the key. (Not a copy of
42 * it, so don't modify or deallocate it.)
43 **/
44 const char *
45 shishi_key_principal (Shishi_key * key)
47 return key->principal;
50 /**
51 * shishi_key_principal_set:
52 * @key: structure that holds key information
53 * @principal: string with new principal name.
55 * Set the principal owning the key. The string is copied into the
56 * key, so you can dispose of the variable immediately after calling
57 * this function.
58 **/
59 void
60 shishi_key_principal_set (Shishi_key * key, const char *principal)
62 if (key->principal)
63 free (key->principal);
64 if (principal)
65 key->principal = xstrdup (principal);
66 else
67 key->principal = NULL;
70 /**
71 * shishi_key_realm:
72 * @key: structure that holds key information
74 * Get the realm part of the key owner principal name.
76 * Return value: Returns the realm for the principal owning the key.
77 * (Not a copy of it, so don't modify or deallocate it.)
78 **/
79 const char *
80 shishi_key_realm (Shishi_key * key)
82 return key->realm;
85 /**
86 * shishi_key_realm_set:
87 * @key: structure that holds key information
88 * @realm: string with new realm name.
90 * Set the realm for the principal owning the key. The string is
91 * copied into the key, so you can dispose of the variable immediately
92 * after calling this function.
93 **/
94 void
95 shishi_key_realm_set (Shishi_key * key, const char *realm)
97 if (key->realm)
98 free (key->realm);
99 if (realm)
100 key->realm = xstrdup (realm);
101 else
102 key->realm = NULL;
106 * shishi_key_type:
107 * @key: structure that holds key information
109 * Get key type.
111 * Return value: Returns the type of key as an integer as described in
112 * the standard.
115 shishi_key_type (Shishi_key * key)
117 return key->type;
121 * shishi_key_type_set:
122 * @key: structure that holds key information
123 * @type: type to set in key.
125 * Set the type of key in key structure.
127 void
128 shishi_key_type_set (Shishi_key * key, int32_t type)
130 key->type = type;
134 * shishi_key_value:
135 * @key: structure that holds key information
137 * Get the raw key bytes.
139 * Return value: Returns the key value as a pointer which is valid
140 * throughout the lifetime of the key structure.
142 char *
143 shishi_key_value (Shishi_key * key)
145 return key->value;
149 * shishi_key_value_set:
150 * @key: structure that holds key information
151 * @value: input array with key data.
153 * Set the key value and length in key structure. The value is copied
154 * into the key (in other words, you can deallocate @value right after
155 * calling this function without modifying the value inside the key).
157 void
158 shishi_key_value_set (Shishi_key * key, const char *value)
160 if (value &&
161 shishi_cipher_keylen (key->type) > 0 &&
162 shishi_cipher_keylen (key->type) <= MAX_KEY_LEN)
163 memcpy (key->value, value, shishi_cipher_keylen (key->type));
167 * shishi_key_version:
168 * @key: structure that holds key information
170 * Get the "kvno" (key version) of key. It will be UINT32_MAX if the
171 * key is not long-lived.
173 * Return value: Returns the version of key ("kvno").
175 uint32_t
176 shishi_key_version (Shishi_key * key)
178 return key->kvno;
182 * shishi_key_version_set:
183 * @key: structure that holds key information
184 * @kvno: new version integer.
186 * Set the version of key ("kvno") in key structure. Use UINT32_MAX
187 * for non-ptermanent keys.
189 void
190 shishi_key_version_set (Shishi_key * key, uint32_t kvno)
192 key->kvno = kvno;
196 * shishi_key_name:
197 * @key: structure that holds key information
199 * Calls shishi_cipher_name for key type.
201 * Return value: Return name of key.
203 const char *
204 shishi_key_name (Shishi_key * key)
206 return shishi_cipher_name (key->type);
210 * shishi_key_length:
211 * @key: structure that holds key information
213 * Calls shishi_cipher_keylen for key type.
215 * Return value: Returns the length of the key value.
217 size_t
218 shishi_key_length (Shishi_key * key)
220 return shishi_cipher_keylen (key->type);
224 * shishi_key:
225 * @handle: Shishi library handle create by shishi_init().
226 * @key: pointer to structure that will hold newly created key information
228 * Create a new Key information structure.
230 * Return value: Returns SHISHI_OK iff successful.
233 shishi_key (Shishi * handle, Shishi_key ** key)
235 *key = xcalloc (1, sizeof (**key));
237 (*key)->handle = handle;
238 (*key)->kvno = UINT32_MAX;
240 return SHISHI_OK;
244 * shishi_key_done:
245 * @key: pointer to structure that holds key information.
247 * Deallocates key information structure.
249 void
250 shishi_key_done (Shishi_key * key)
252 if (key->realm)
253 free (key->realm);
254 if (key->principal)
255 free (key->principal);
256 free (key);
260 * shishi_key_copy:
261 * @dstkey: structure that holds destination key information
262 * @srckey: structure that holds source key information
264 * Copies source key into existing allocated destination key.
266 void
267 shishi_key_copy (Shishi_key * dstkey, Shishi_key * srckey)
269 shishi_key_principal_set (dstkey, shishi_key_principal (srckey));
270 shishi_key_realm_set (dstkey, shishi_key_realm (srckey));
271 shishi_key_type_set (dstkey, shishi_key_type (srckey));
272 shishi_key_value_set (dstkey, shishi_key_value (srckey));
273 shishi_key_version_set (dstkey, shishi_key_version (srckey));
277 * shishi_key_from_value:
278 * @handle: Shishi library handle create by shishi_init().
279 * @type: type of key.
280 * @value: input array with key value, or NULL.
281 * @key: pointer to structure that will hold newly created key information
283 * Create a new Key information structure, and set the key type and
284 * key value. KEY contains a newly allocated structure only if this
285 * function is successful.
287 * Return value: Returns SHISHI_OK iff successful.
290 shishi_key_from_value (Shishi * handle,
291 int32_t type, const char *value, Shishi_key ** key)
293 int rc;
295 rc = shishi_key (handle, key);
296 if (rc != SHISHI_OK)
297 return rc;
299 shishi_key_type_set (*key, type);
300 if (value)
301 shishi_key_value_set (*key, value);
303 return SHISHI_OK;
307 * shishi_key_from_base64:
308 * @handle: Shishi library handle create by shishi_init().
309 * @type: type of key.
310 * @value: input string with base64 encoded key value, or NULL.
311 * @key: pointer to structure that will hold newly created key information
313 * Create a new Key information structure, and set the key type and
314 * key value. KEY contains a newly allocated structure only if this
315 * function is successful.
317 * Return value: Returns SHISHI_INVALID_KEY if the base64 encoded key
318 * length doesn't match the key type, and SHISHI_OK on
319 * success.
322 shishi_key_from_base64 (Shishi * handle,
323 int32_t type, const char *value, Shishi_key ** key)
325 int rc;
327 rc = shishi_key (handle, key);
328 if (rc != SHISHI_OK)
329 return rc;
331 shishi_key_type_set (*key, type);
333 if (value)
335 size_t len = MAX_KEY_LEN;
337 if (!base64_decode (value, strlen (value), (*key)->value, &len))
339 shishi_key_done (*key);
340 return SHISHI_BASE64_ERROR;
343 if (len != shishi_key_length (*key))
345 shishi_key_done (*key);
346 return SHISHI_INVALID_KEY;
350 return SHISHI_OK;
354 * shishi_key_random
355 * @handle: Shishi library handle create by shishi_init().
356 * @type: type of key.
357 * @key: pointer to structure that will hold newly created key information
359 * Create a new Key information structure for the key type and some
360 * random data. KEY contains a newly allocated structure only if this
361 * function is successful.
363 * Return value: Returns SHISHI_OK iff successful.
366 shishi_key_random (Shishi * handle, int32_t type, Shishi_key ** key)
368 char buf[MAX_RANDOM_LEN];
369 int len = shishi_cipher_randomlen (type);
370 int rc;
372 rc = shishi_randomize (handle, 1, buf, len);
373 if (rc != SHISHI_OK)
374 return rc;
376 rc = shishi_key (handle, key);
377 if (rc != SHISHI_OK)
378 return rc;
380 rc = shishi_random_to_key (handle, type, buf, len, *key);
381 if (rc != SHISHI_OK)
383 shishi_key_done (*key);
384 return rc;
387 return SHISHI_OK;
391 * shishi_key_from_random
392 * @handle: Shishi library handle create by shishi_init().
393 * @type: type of key.
394 * @rnd: random data.
395 * @rndlen: length of random data.
396 * @outkey: pointer to structure that will hold newly created key information
398 * Create a new Key information structure, and set the key type and
399 * key value using shishi_random_to_key(). KEY contains a newly
400 * allocated structure only if this function is successful.
402 * Return value: Returns SHISHI_OK iff successful.
405 shishi_key_from_random (Shishi * handle,
406 int32_t type,
407 const char *rnd, size_t rndlen, Shishi_key ** outkey)
409 int rc;
411 rc = shishi_key (handle, outkey);
412 if (rc != SHISHI_OK)
413 return rc;
415 rc = shishi_random_to_key (handle, type, rnd, rndlen, *outkey);
417 return rc;
421 * shishi_key_from_string
422 * @handle: Shishi library handle create by shishi_init().
423 * @type: type of key.
424 * @password: input array containing password.
425 * @passwordlen: length of input array containing password.
426 * @salt: input array containing salt.
427 * @saltlen: length of input array containing salt.
428 * @parameter: input array with opaque encryption type specific information.
429 * @outkey: pointer to structure that will hold newly created key information
431 * Create a new Key information structure, and set the key type and
432 * key value using shishi_string_to_key(). KEY contains a newly
433 * allocated structure only if this function is successful.
435 * Return value: Returns SHISHI_OK iff successful.
438 shishi_key_from_string (Shishi * handle,
439 int32_t type,
440 const char *password, size_t passwordlen,
441 const char *salt, size_t saltlen,
442 const char *parameter, Shishi_key ** outkey)
444 int rc;
446 rc = shishi_key (handle, outkey);
447 if (rc != SHISHI_OK)
448 return rc;
450 rc = shishi_string_to_key (handle, type, password, passwordlen,
451 salt, saltlen, parameter, *outkey);
452 if (rc != SHISHI_OK)
454 shishi_key_done (*outkey);
455 return rc;
458 return SHISHI_OK;
462 * shishi_key_from_name:
463 * @handle: Shishi library handle create by shishi_init().
464 * @type: type of key.
465 * @name: principal name of user.
466 * @password: input array containing password.
467 * @passwordlen: length of input array containing password.
468 * @parameter: input array with opaque encryption type specific information.
469 * @outkey: pointer to structure that will hold newly created key information
471 * Create a new Key information structure, and derive the key from
472 * principal name and password using shishi_key_from_name(). The salt
473 * is derived from the principal name by concatenating the decoded
474 * realm and principal.
476 * Return value: Returns SHISHI_OK iff successful.
479 shishi_key_from_name (Shishi * handle,
480 int32_t type,
481 const char *name,
482 const char *password, size_t passwordlen,
483 const char *parameter, Shishi_key ** outkey)
485 int rc;
486 char *salt;
488 rc = shishi_derive_default_salt (handle, name, &salt);
489 if (rc != SHISHI_OK)
490 return rc;
492 rc = shishi_key_from_string (handle, type, password, passwordlen,
493 salt, strlen (salt), parameter, outkey);
494 if (rc == SHISHI_OK)
496 char *principal;
497 char *realm;
499 rc = shishi_parse_name (handle, name, &principal, &realm);
500 if (rc == SHISHI_OK)
502 shishi_key_principal_set (*outkey, principal);
503 shishi_key_realm_set (*outkey, realm);
505 free (realm);
506 free (principal);
510 free (salt);
512 return rc;