Branch data Line data Source code
1 : : /* key.c --- Key related functions.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2010 Simon Josefsson
3 : : *
4 : : * This file is part of Shishi.
5 : : *
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.
10 : : *
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.
15 : : *
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
20 : : *
21 : : */
22 : :
23 : : #include "internal.h"
24 : :
25 : : struct Shishi_key
26 : : {
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 */
33 : : time_t timestamp; /* Only used by keytab code. */
34 : : /* If you add anything here, check the functions shishi_key,
35 : : shishi_key_done and shishi_key_copy. */
36 : : };
37 : :
38 : : /**
39 : : * shishi_key_principal:
40 : : * @key: structure that holds key information
41 : : *
42 : : * Get the principal part of the key owner principal name, i.e.,
43 : : * except the realm.
44 : : *
45 : : * Return value: Returns the principal owning the key. (Not a copy of
46 : : * it, so don't modify or deallocate it.)
47 : : **/
48 : : const char *
49 : 34 : shishi_key_principal (const Shishi_key * key)
50 : : {
51 : 34 : return key->principal;
52 : : }
53 : :
54 : : /**
55 : : * shishi_key_principal_set:
56 : : * @key: structure that holds key information
57 : : * @principal: string with new principal name.
58 : : *
59 : : * Set the principal owning the key. The string is copied into the
60 : : * key, so you can dispose of the variable immediately after calling
61 : : * this function.
62 : : **/
63 : : void
64 : 34 : shishi_key_principal_set (Shishi_key * key, const char *principal)
65 : : {
66 : 34 : free (key->principal);
67 [ + + ]: 34 : if (principal)
68 : 12 : key->principal = xstrdup (principal);
69 : : else
70 : 22 : key->principal = NULL;
71 : 34 : }
72 : :
73 : : /**
74 : : * shishi_key_realm:
75 : : * @key: structure that holds key information
76 : : *
77 : : * Get the realm part of the key owner principal name.
78 : : *
79 : : * Return value: Returns the realm for the principal owning the key.
80 : : * (Not a copy of it, so don't modify or deallocate it.)
81 : : **/
82 : : const char *
83 : 34 : shishi_key_realm (const Shishi_key * key)
84 : : {
85 : 34 : return key->realm;
86 : : }
87 : :
88 : : /**
89 : : * shishi_key_realm_set:
90 : : * @key: structure that holds key information
91 : : * @realm: string with new realm name.
92 : : *
93 : : * Set the realm for the principal owning the key. The string is
94 : : * copied into the key, so you can dispose of the variable immediately
95 : : * after calling this function.
96 : : **/
97 : : void
98 : 34 : shishi_key_realm_set (Shishi_key * key, const char *realm)
99 : : {
100 : 34 : free (key->realm);
101 [ + + ]: 34 : if (realm)
102 : 12 : key->realm = xstrdup (realm);
103 : : else
104 : 22 : key->realm = NULL;
105 : 34 : }
106 : :
107 : : /**
108 : : * shishi_key_type:
109 : : * @key: structure that holds key information
110 : : *
111 : : * Get key type.
112 : : *
113 : : * Return value: Returns the type of key as an integer as described in
114 : : * the standard.
115 : : **/
116 : : int
117 : 10583 : shishi_key_type (const Shishi_key * key)
118 : : {
119 : 10583 : return key->type;
120 : : }
121 : :
122 : : /**
123 : : * shishi_key_type_set:
124 : : * @key: structure that holds key information
125 : : * @type: type to set in key.
126 : : *
127 : : * Set the type of key in key structure.
128 : : **/
129 : : void
130 : 2023 : shishi_key_type_set (Shishi_key * key, int32_t type)
131 : : {
132 : 2023 : key->type = type;
133 : 2023 : }
134 : :
135 : : /**
136 : : * shishi_key_value:
137 : : * @key: structure that holds key information
138 : : *
139 : : * Get the raw key bytes.
140 : : *
141 : : * Return value: Returns the key value as a pointer which is valid
142 : : * throughout the lifetime of the key structure.
143 : : **/
144 : : const char *
145 : 2148 : shishi_key_value (const Shishi_key * key)
146 : : {
147 : 2148 : return key->value;
148 : : }
149 : :
150 : : /**
151 : : * shishi_key_value_set:
152 : : * @key: structure that holds key information
153 : : * @value: input array with key data.
154 : : *
155 : : * Set the key value and length in key structure. The value is copied
156 : : * into the key (in other words, you can deallocate @value right after
157 : : * calling this function without modifying the value inside the key).
158 : : **/
159 : : void
160 : 734 : shishi_key_value_set (Shishi_key * key, const char *value)
161 : : {
162 [ + - + - + : 2202 : if (value &&
- ]
163 : 734 : shishi_cipher_keylen (key->type) > 0 &&
164 : 734 : shishi_cipher_keylen (key->type) <= MAX_KEY_LEN)
165 : 734 : memcpy (key->value, value, shishi_cipher_keylen (key->type));
166 : 734 : }
167 : :
168 : : /**
169 : : * shishi_key_version:
170 : : * @key: structure that holds key information
171 : : *
172 : : * Get the "kvno" (key version) of key. It will be UINT32_MAX if the
173 : : * key is not long-lived.
174 : : *
175 : : * Return value: Returns the version of key ("kvno").
176 : : **/
177 : : uint32_t
178 : 34 : shishi_key_version (const Shishi_key * key)
179 : : {
180 : 34 : return key->kvno;
181 : : }
182 : :
183 : : /**
184 : : * shishi_key_version_set:
185 : : * @key: structure that holds key information
186 : : * @kvno: new version integer.
187 : : *
188 : : * Set the version of key ("kvno") in key structure. Use UINT32_MAX
189 : : * for non-ptermanent keys.
190 : : **/
191 : : void
192 : 40 : shishi_key_version_set (Shishi_key * key, uint32_t kvno)
193 : : {
194 : 40 : key->kvno = kvno;
195 : 40 : }
196 : :
197 : : /**
198 : : * shishi_key_timestamp:
199 : : * @key: structure that holds key information
200 : : *
201 : : * Get the time the key was established. Typically only present when
202 : : * the key was imported from a keytab format.
203 : : *
204 : : * Return value: Returns the time the key was established, or
205 : : * (time_t)-1 if not available.
206 : : *
207 : : * Since: 0.0.42
208 : : **/
209 : : time_t
210 : 34 : shishi_key_timestamp (const Shishi_key * key)
211 : : {
212 : 34 : return key->timestamp;
213 : : }
214 : :
215 : : /**
216 : : * shishi_key_timestamp_set:
217 : : * @key: structure that holds key information
218 : : * @timestamp: new timestamp.
219 : : *
220 : : * Set the time the key was established. Typically only relevant when
221 : : * exporting the key to keytab format.
222 : : *
223 : : * Since: 0.0.42
224 : : **/
225 : : void
226 : 34 : shishi_key_timestamp_set (Shishi_key * key, time_t timestamp)
227 : : {
228 : 34 : key->timestamp = timestamp;
229 : 34 : }
230 : :
231 : : /**
232 : : * shishi_key_name:
233 : : * @key: structure that holds key information
234 : : *
235 : : * Calls shishi_cipher_name for key type.
236 : : *
237 : : * Return value: Return name of key.
238 : : **/
239 : : const char *
240 : 0 : shishi_key_name (Shishi_key * key)
241 : : {
242 : 0 : return shishi_cipher_name (key->type);
243 : : }
244 : :
245 : : /**
246 : : * shishi_key_length:
247 : : * @key: structure that holds key information
248 : : *
249 : : * Calls shishi_cipher_keylen for key type.
250 : : *
251 : : * Return value: Returns the length of the key value.
252 : : **/
253 : : size_t
254 : 3674 : shishi_key_length (const Shishi_key * key)
255 : : {
256 : 3674 : return shishi_cipher_keylen (key->type);
257 : : }
258 : :
259 : : /**
260 : : * shishi_key:
261 : : * @handle: Shishi library handle create by shishi_init().
262 : : * @key: pointer to structure that will hold newly created key information
263 : : *
264 : : * Create a new Key information structure.
265 : : *
266 : : * Return value: Returns SHISHI_OK iff successful.
267 : : **/
268 : : int
269 : 732 : shishi_key (Shishi * handle, Shishi_key ** key)
270 : : {
271 : 732 : *key = xcalloc (1, sizeof (**key));
272 : :
273 : 732 : (*key)->handle = handle;
274 : 732 : (*key)->kvno = UINT32_MAX;
275 : :
276 : 732 : return SHISHI_OK;
277 : : }
278 : :
279 : : /**
280 : : * shishi_key_done:
281 : : * @key: pointer to structure that holds key information.
282 : : *
283 : : * Deallocates key information structure.
284 : : **/
285 : : void
286 : 730 : shishi_key_done (Shishi_key * key)
287 : : {
288 : 730 : free (key->realm);
289 : 730 : free (key->principal);
290 : 730 : free (key);
291 : 730 : }
292 : :
293 : : /**
294 : : * shishi_key_copy:
295 : : * @dstkey: structure that holds destination key information
296 : : * @srckey: structure that holds source key information
297 : : *
298 : : * Copies source key into existing allocated destination key.
299 : : **/
300 : : void
301 : 28 : shishi_key_copy (Shishi_key * dstkey, Shishi_key * srckey)
302 : : {
303 : 28 : shishi_key_principal_set (dstkey, shishi_key_principal (srckey));
304 : 28 : shishi_key_realm_set (dstkey, shishi_key_realm (srckey));
305 : 28 : shishi_key_type_set (dstkey, shishi_key_type (srckey));
306 : 28 : shishi_key_value_set (dstkey, shishi_key_value (srckey));
307 : 28 : shishi_key_version_set (dstkey, shishi_key_version (srckey));
308 : 28 : shishi_key_timestamp_set (dstkey, shishi_key_timestamp (srckey));
309 : 28 : }
310 : :
311 : : /**
312 : : * shishi_key_from_value:
313 : : * @handle: Shishi library handle create by shishi_init().
314 : : * @type: type of key.
315 : : * @value: input array with key value, or NULL.
316 : : * @key: pointer to structure that will hold newly created key information
317 : : *
318 : : * Create a new Key information structure, and set the key type and
319 : : * key value. KEY contains a newly allocated structure only if this
320 : : * function is successful.
321 : : *
322 : : * Return value: Returns SHISHI_OK iff successful.
323 : : **/
324 : : int
325 : 662 : shishi_key_from_value (Shishi * handle,
326 : : int32_t type, const char *value, Shishi_key ** key)
327 : : {
328 : : int rc;
329 : :
330 : 662 : rc = shishi_key (handle, key);
331 [ - + ]: 662 : if (rc != SHISHI_OK)
332 : 0 : return rc;
333 : :
334 : 662 : shishi_key_type_set (*key, type);
335 [ + + ]: 662 : if (value)
336 : 32 : shishi_key_value_set (*key, value);
337 : :
338 : 662 : return SHISHI_OK;
339 : : }
340 : :
341 : : /**
342 : : * shishi_key_from_base64:
343 : : * @handle: Shishi library handle create by shishi_init().
344 : : * @type: type of key.
345 : : * @value: input string with base64 encoded key value, or NULL.
346 : : * @key: pointer to structure that will hold newly created key information
347 : : *
348 : : * Create a new Key information structure, and set the key type and
349 : : * key value. KEY contains a newly allocated structure only if this
350 : : * function is successful.
351 : : *
352 : : * Return value: Returns SHISHI_INVALID_KEY if the base64 encoded key
353 : : * length doesn't match the key type, and SHISHI_OK on
354 : : * success.
355 : : **/
356 : : int
357 : 1 : shishi_key_from_base64 (Shishi * handle,
358 : : int32_t type, const char *value, Shishi_key ** key)
359 : : {
360 : : int rc;
361 : :
362 : 1 : rc = shishi_key (handle, key);
363 [ - + ]: 1 : if (rc != SHISHI_OK)
364 : 0 : return rc;
365 : :
366 : 1 : shishi_key_type_set (*key, type);
367 : :
368 [ + - ]: 1 : if (value)
369 : : {
370 : 1 : size_t len = MAX_KEY_LEN;
371 : :
372 [ - + ]: 1 : if (!base64_decode (value, strlen (value), (*key)->value, &len))
373 : : {
374 : 0 : shishi_key_done (*key);
375 : 0 : return SHISHI_BASE64_ERROR;
376 : : }
377 : :
378 [ - + ]: 1 : if (len != shishi_key_length (*key))
379 : : {
380 : 0 : shishi_key_done (*key);
381 : 0 : return SHISHI_INVALID_KEY;
382 : : }
383 : : }
384 : :
385 : 1 : return SHISHI_OK;
386 : : }
387 : :
388 : : /**
389 : : * shishi_key_random
390 : : * @handle: Shishi library handle create by shishi_init().
391 : : * @type: type of key.
392 : : * @key: pointer to structure that will hold newly created key information
393 : : *
394 : : * Create a new Key information structure for the key type and some
395 : : * random data. KEY contains a newly allocated structure only if this
396 : : * function is successful.
397 : : *
398 : : * Return value: Returns SHISHI_OK iff successful.
399 : : **/
400 : : int
401 : 0 : shishi_key_random (Shishi * handle, int32_t type, Shishi_key ** key)
402 : : {
403 : : char buf[MAX_RANDOM_LEN];
404 : 0 : int len = shishi_cipher_randomlen (type);
405 : : int rc;
406 : :
407 : 0 : rc = shishi_randomize (handle, 1, buf, len);
408 [ # # ]: 0 : if (rc != SHISHI_OK)
409 : 0 : return rc;
410 : :
411 : 0 : rc = shishi_key (handle, key);
412 [ # # ]: 0 : if (rc != SHISHI_OK)
413 : 0 : return rc;
414 : :
415 : 0 : rc = shishi_random_to_key (handle, type, buf, len, *key);
416 [ # # ]: 0 : if (rc != SHISHI_OK)
417 : : {
418 : 0 : shishi_key_done (*key);
419 : 0 : return rc;
420 : : }
421 : :
422 : 0 : return SHISHI_OK;
423 : : }
424 : :
425 : : /**
426 : : * shishi_key_from_random
427 : : * @handle: Shishi library handle create by shishi_init().
428 : : * @type: type of key.
429 : : * @rnd: random data.
430 : : * @rndlen: length of random data.
431 : : * @outkey: pointer to structure that will hold newly created key information
432 : : *
433 : : * Create a new Key information structure, and set the key type and
434 : : * key value using shishi_random_to_key(). KEY contains a newly
435 : : * allocated structure only if this function is successful.
436 : : *
437 : : * Return value: Returns SHISHI_OK iff successful.
438 : : **/
439 : : int
440 : 10 : shishi_key_from_random (Shishi * handle,
441 : : int32_t type,
442 : : const char *rnd, size_t rndlen, Shishi_key ** outkey)
443 : : {
444 : : int rc;
445 : :
446 : 10 : rc = shishi_key (handle, outkey);
447 [ - + ]: 10 : if (rc != SHISHI_OK)
448 : 0 : return rc;
449 : :
450 : 10 : rc = shishi_random_to_key (handle, type, rnd, rndlen, *outkey);
451 : :
452 : 10 : return rc;
453 : : }
454 : :
455 : : /**
456 : : * shishi_key_from_string
457 : : * @handle: Shishi library handle create by shishi_init().
458 : : * @type: type of key.
459 : : * @password: input array containing password.
460 : : * @passwordlen: length of input array containing password.
461 : : * @salt: input array containing salt.
462 : : * @saltlen: length of input array containing salt.
463 : : * @parameter: input array with opaque encryption type specific information.
464 : : * @outkey: pointer to structure that will hold newly created key information
465 : : *
466 : : * Create a new Key information structure, and set the key type and
467 : : * key value using shishi_string_to_key(). KEY contains a newly
468 : : * allocated structure only if this function is successful.
469 : : *
470 : : * Return value: Returns SHISHI_OK iff successful.
471 : : **/
472 : : int
473 : 26 : shishi_key_from_string (Shishi * handle,
474 : : int32_t type,
475 : : const char *password, size_t passwordlen,
476 : : const char *salt, size_t saltlen,
477 : : const char *parameter, Shishi_key ** outkey)
478 : : {
479 : : int rc;
480 : :
481 : 26 : rc = shishi_key (handle, outkey);
482 [ - + ]: 26 : if (rc != SHISHI_OK)
483 : 0 : return rc;
484 : :
485 : 26 : rc = shishi_string_to_key (handle, type, password, passwordlen,
486 : : salt, saltlen, parameter, *outkey);
487 [ - + ]: 26 : if (rc != SHISHI_OK)
488 : : {
489 : 0 : shishi_key_done (*outkey);
490 : 0 : return rc;
491 : : }
492 : :
493 : 26 : return SHISHI_OK;
494 : : }
495 : :
496 : : /**
497 : : * shishi_key_from_name:
498 : : * @handle: Shishi library handle create by shishi_init().
499 : : * @type: type of key.
500 : : * @name: principal name of user.
501 : : * @password: input array containing password.
502 : : * @passwordlen: length of input array containing password.
503 : : * @parameter: input array with opaque encryption type specific information.
504 : : * @outkey: pointer to structure that will hold newly created key information
505 : : *
506 : : * Create a new Key information structure, and derive the key from
507 : : * principal name and password using shishi_key_from_name(). The salt
508 : : * is derived from the principal name by concatenating the decoded
509 : : * realm and principal.
510 : : *
511 : : * Return value: Returns SHISHI_OK iff successful.
512 : : **/
513 : : int
514 : 0 : shishi_key_from_name (Shishi * handle,
515 : : int32_t type,
516 : : const char *name,
517 : : const char *password, size_t passwordlen,
518 : : const char *parameter, Shishi_key ** outkey)
519 : : {
520 : : int rc;
521 : : char *salt;
522 : :
523 : 0 : rc = shishi_derive_default_salt (handle, name, &salt);
524 [ # # ]: 0 : if (rc != SHISHI_OK)
525 : 0 : return rc;
526 : :
527 : 0 : rc = shishi_key_from_string (handle, type, password, passwordlen,
528 : : salt, strlen (salt), parameter, outkey);
529 [ # # ]: 0 : if (rc == SHISHI_OK)
530 : : {
531 : : char *principal;
532 : : char *realm;
533 : :
534 : 0 : rc = shishi_parse_name (handle, name, &principal, &realm);
535 [ # # ]: 0 : if (rc == SHISHI_OK)
536 : : {
537 : 0 : shishi_key_principal_set (*outkey, principal);
538 : 0 : shishi_key_realm_set (*outkey, realm);
539 : :
540 : 0 : free (realm);
541 : 0 : free (principal);
542 : : }
543 : : }
544 : :
545 : 0 : free (salt);
546 : :
547 : 0 : return rc;
548 : : }
|