1 /* key.c --- Key related functions.
2  * Copyright (C) 2002-2013 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 *
shishi_key_principal(const Shishi_key * key)49 shishi_key_principal (const Shishi_key * key)
50 {
51   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
shishi_key_principal_set(Shishi_key * key,const char * principal)64 shishi_key_principal_set (Shishi_key * key, const char *principal)
65 {
66   free (key->principal);
67   if (principal)
68     key->principal = xstrdup (principal);
69   else
70     key->principal = NULL;
71 }
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 *
shishi_key_realm(const Shishi_key * key)83 shishi_key_realm (const Shishi_key * key)
84 {
85   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
shishi_key_realm_set(Shishi_key * key,const char * realm)98 shishi_key_realm_set (Shishi_key * key, const char *realm)
99 {
100   free (key->realm);
101   if (realm)
102     key->realm = xstrdup (realm);
103   else
104     key->realm = NULL;
105 }
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
shishi_key_type(const Shishi_key * key)117 shishi_key_type (const Shishi_key * key)
118 {
119   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
shishi_key_type_set(Shishi_key * key,int32_t type)130 shishi_key_type_set (Shishi_key * key, int32_t type)
131 {
132   key->type = type;
133 }
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 *
shishi_key_value(const Shishi_key * key)145 shishi_key_value (const Shishi_key * key)
146 {
147   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
shishi_key_value_set(Shishi_key * key,const char * value)160 shishi_key_value_set (Shishi_key * key, const char *value)
161 {
162   if (value &&
163       shishi_cipher_keylen (key->type) > 0 &&
164       shishi_cipher_keylen (key->type) <= MAX_KEY_LEN)
165     memcpy (key->value, value, shishi_cipher_keylen (key->type));
166 }
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
shishi_key_version(const Shishi_key * key)178 shishi_key_version (const Shishi_key * key)
179 {
180   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
shishi_key_version_set(Shishi_key * key,uint32_t kvno)192 shishi_key_version_set (Shishi_key * key, uint32_t kvno)
193 {
194   key->kvno = kvno;
195 }
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
shishi_key_timestamp(const Shishi_key * key)210 shishi_key_timestamp (const Shishi_key * key)
211 {
212   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
shishi_key_timestamp_set(Shishi_key * key,time_t timestamp)226 shishi_key_timestamp_set (Shishi_key * key, time_t timestamp)
227 {
228   key->timestamp = timestamp;
229 }
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 *
shishi_key_name(Shishi_key * key)240 shishi_key_name (Shishi_key * key)
241 {
242   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
shishi_key_length(const Shishi_key * key)254 shishi_key_length (const Shishi_key * key)
255 {
256   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
shishi_key(Shishi * handle,Shishi_key ** key)269 shishi_key (Shishi * handle, Shishi_key ** key)
270 {
271   *key = xcalloc (1, sizeof (**key));
272 
273   (*key)->handle = handle;
274   (*key)->kvno = UINT32_MAX;
275 
276   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
shishi_key_done(Shishi_key * key)286 shishi_key_done (Shishi_key * key)
287 {
288   free (key->realm);
289   free (key->principal);
290   free (key);
291 }
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
shishi_key_copy(Shishi_key * dstkey,Shishi_key * srckey)301 shishi_key_copy (Shishi_key * dstkey, Shishi_key * srckey)
302 {
303   shishi_key_principal_set (dstkey, shishi_key_principal (srckey));
304   shishi_key_realm_set (dstkey, shishi_key_realm (srckey));
305   shishi_key_type_set (dstkey, shishi_key_type (srckey));
306   shishi_key_value_set (dstkey, shishi_key_value (srckey));
307   shishi_key_version_set (dstkey, shishi_key_version (srckey));
308   shishi_key_timestamp_set (dstkey, shishi_key_timestamp (srckey));
309 }
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
shishi_key_from_value(Shishi * handle,int32_t type,const char * value,Shishi_key ** key)325 shishi_key_from_value (Shishi * handle,
326 		       int32_t type, const char *value, Shishi_key ** key)
327 {
328   int rc;
329 
330   rc = shishi_key (handle, key);
331   if (rc != SHISHI_OK)
332     return rc;
333 
334   shishi_key_type_set (*key, type);
335   if (value)
336     shishi_key_value_set (*key, value);
337 
338   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
shishi_key_from_base64(Shishi * handle,int32_t type,const char * value,Shishi_key ** key)357 shishi_key_from_base64 (Shishi * handle,
358 			int32_t type, const char *value, Shishi_key ** key)
359 {
360   int rc;
361 
362   rc = shishi_key (handle, key);
363   if (rc != SHISHI_OK)
364     return rc;
365 
366   shishi_key_type_set (*key, type);
367 
368   if (value)
369     {
370       size_t len = MAX_KEY_LEN;
371 
372       if (!base64_decode (value, strlen (value), (*key)->value, &len))
373 	{
374 	  shishi_key_done (*key);
375 	  return SHISHI_BASE64_ERROR;
376 	}
377 
378       if (len != shishi_key_length (*key))
379 	{
380 	  shishi_key_done (*key);
381 	  return SHISHI_INVALID_KEY;
382 	}
383     }
384 
385   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
shishi_key_random(Shishi * handle,int32_t type,Shishi_key ** key)401 shishi_key_random (Shishi * handle, int32_t type, Shishi_key ** key)
402 {
403   char buf[MAX_RANDOM_LEN];
404   int len = shishi_cipher_randomlen (type);
405   int rc;
406 
407   rc = shishi_randomize (handle, 1, buf, len);
408   if (rc != SHISHI_OK)
409     return rc;
410 
411   rc = shishi_key (handle, key);
412   if (rc != SHISHI_OK)
413     return rc;
414 
415   rc = shishi_random_to_key (handle, type, buf, len, *key);
416   if (rc != SHISHI_OK)
417     {
418       shishi_key_done (*key);
419       return rc;
420     }
421 
422   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
shishi_key_from_random(Shishi * handle,int32_t type,const char * rnd,size_t rndlen,Shishi_key ** outkey)440 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   rc = shishi_key (handle, outkey);
447   if (rc != SHISHI_OK)
448     return rc;
449 
450   rc = shishi_random_to_key (handle, type, rnd, rndlen, *outkey);
451 
452   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
shishi_key_from_string(Shishi * handle,int32_t type,const char * password,size_t passwordlen,const char * salt,size_t saltlen,const char * parameter,Shishi_key ** outkey)473 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   rc = shishi_key (handle, outkey);
482   if (rc != SHISHI_OK)
483     return rc;
484 
485   rc = shishi_string_to_key (handle, type, password, passwordlen,
486 			     salt, saltlen, parameter, *outkey);
487   if (rc != SHISHI_OK)
488     {
489       shishi_key_done (*outkey);
490       return rc;
491     }
492 
493   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
shishi_key_from_name(Shishi * handle,int32_t type,const char * name,const char * password,size_t passwordlen,const char * parameter,Shishi_key ** outkey)514 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   rc = shishi_derive_default_salt (handle, name, &salt);
524   if (rc != SHISHI_OK)
525     return rc;
526 
527   rc = shishi_key_from_string (handle, type, password, passwordlen,
528 			       salt, strlen (salt), parameter, outkey);
529   if (rc == SHISHI_OK)
530     {
531       char *principal;
532       char *realm;
533 
534       rc = shishi_parse_name (handle, name, &principal, &realm);
535       if (rc == SHISHI_OK)
536 	{
537 	  shishi_key_principal_set (*outkey, principal);
538 	  shishi_key_realm_set (*outkey, realm);
539 
540 	  free (realm);
541 	  free (principal);
542 	}
543     }
544 
545   free (salt);
546 
547   return rc;
548 }
549