Branch data Line data Source code
1 : : /* keys.c --- Functions for reading /etc/krb5.keytab style key files.
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 : : /* Get _shishi_hexprint, etc. */
26 : : #include "utils.h"
27 : :
28 : : /**
29 : : * shishi_keys_add_keytab_mem:
30 : : * @handle: shishi handle as allocated by shishi_init().
31 : : * @data: constant memory buffer with keytab of @len size.
32 : : * @len: size of memory buffer with keytab data.
33 : : * @keys: allocated key set to store keys in.
34 : : *
35 : : * Read keys from a MIT keytab data structure, and add them to the key
36 : : * set.
37 : : *
38 : : * The format of keytab's is proprietary, and this function support
39 : : * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
40 : : * Keytab Binary File Format in the Shishi manual for a description of
41 : : * the reverse-engineered format.
42 : : *
43 : : * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
44 : : * represent a valid keytab structure, and %SHISHI_OK on success.
45 : : **/
46 : : int
47 : 1 : shishi_keys_add_keytab_mem (Shishi * handle,
48 : : const char *data, size_t len, Shishi_keys * keys)
49 : : {
50 : : int rc;
51 : : uint16_t file_format_version;
52 : : size_t entrystartpos;
53 : : uint16_t num_components; /* sub 1 if version 0x501 */
54 : : size_t i;
55 : : Shishi_key *key;
56 : :
57 [ - + ]: 1 : if (VERBOSENOISE (handle))
58 : : {
59 : 0 : printf ("keytab len %d (0x%x)\n", len, len);
60 : 0 : _shishi_hexprint (data, len);
61 : : }
62 : :
63 : : /* Check file format. */
64 : 1 : file_format_version = (data[0] << 8) | data[1];
65 : :
66 [ - + ]: 1 : if (VERBOSENOISE (handle))
67 : 0 : printf ("keytab file_format_version %04X\n", file_format_version);
68 : :
69 [ + - ][ - + ]: 1 : if (file_format_version != 0x0501 && file_format_version != 0x0502)
70 : 0 : return SHISHI_KEYTAB_ERROR;
71 : :
72 : : /* Check file integrity first, to avoid error-checking below. */
73 : 1 : entrystartpos = 2;
74 [ + + ]: 7 : while (entrystartpos < len)
75 : : {
76 : 12 : int32_t size = data[entrystartpos] << 24 | data[entrystartpos + 1] << 16
77 : 12 : | data[entrystartpos + 2] << 8 | data[entrystartpos + 3];
78 : 6 : entrystartpos += 4;
79 : :
80 [ - + ]: 6 : if (VERBOSENOISE (handle))
81 : : {
82 : 0 : printf ("keytab size %d (%x)\n", size, size);
83 : 0 : printf ("keytab pos %d < %d\n", entrystartpos + size, len);
84 : : }
85 : :
86 [ - + ]: 6 : if (entrystartpos + size > len)
87 : 0 : return SHISHI_KEYTAB_ERROR;
88 : :
89 : : /* Go to next entry... */
90 : 6 : entrystartpos += size;
91 : : }
92 [ - + ]: 1 : if (entrystartpos != len)
93 : 0 : return SHISHI_KEYTAB_ERROR;
94 : :
95 : 1 : rc = shishi_key (handle, &key);
96 [ - + ]: 1 : if (rc != SHISHI_OK)
97 : 0 : return rc;
98 : :
99 : 1 : entrystartpos = 2;
100 [ + + ]: 7 : while (entrystartpos < len)
101 : : {
102 : 6 : size_t pos = entrystartpos;
103 : 12 : uint16_t size = data[pos] << 24 | data[pos + 1] << 16
104 : 12 : | data[pos + 2] << 8 | data[pos + 3];
105 : 6 : pos += 4;
106 : :
107 [ - + ]: 6 : if (VERBOSENOISE (handle))
108 : 0 : printf ("keytab size %d (%x)\n", size, size);
109 : :
110 : : /* Num_components */
111 : 6 : num_components = data[pos] << 8 | data[pos + 1];
112 : 6 : pos += 2;
113 : :
114 [ - + ]: 6 : if (file_format_version == 0x0501)
115 : 0 : num_components--;
116 : :
117 : : /* Realm */
118 : : {
119 : 6 : uint16_t realmlen = data[pos] << 8 | data[pos + 1];
120 : 6 : char *realm = xstrndup (&data[pos + 2], realmlen);;
121 : :
122 : 6 : pos += 2 + realmlen;
123 : :
124 : 6 : shishi_key_realm_set (key, realm);
125 : 6 : free (realm);
126 : : }
127 : :
128 : : /* Principal components. */
129 : : {
130 : 6 : char *name = NULL;
131 : 6 : size_t namelen = 0;
132 : :
133 [ + + ]: 18 : for (i = 0; i < num_components; i++)
134 : : {
135 : : size_t l;
136 : :
137 : 12 : l = data[pos] << 8 | data[pos + 1];
138 : 12 : pos += 2;
139 : :
140 : 12 : name = xrealloc (name, namelen + l + 1);
141 : 12 : memcpy (name + namelen, &data[pos], l);
142 : 12 : name[namelen + l] = '/';
143 : :
144 : 12 : namelen += l + 1;
145 : 12 : pos += l;
146 : :
147 : : }
148 : 6 : name[namelen - 1] = '\0';
149 : 6 : shishi_key_principal_set (key, name);
150 : 6 : free (name);
151 : : }
152 : :
153 : : /* Name_type */
154 : : {
155 : : uint32_t name_type /* not present if version 0x501 */
156 : 12 : = data[pos] << 24 | data[pos + 1] << 16
157 : 12 : | data[pos + 2] << 8 | data[pos + 3];
158 : 6 : pos += 4;
159 : :
160 [ - + ]: 6 : if (VERBOSENOISE (handle))
161 : 0 : printf ("keytab nametype %d (0x%08x)\n", name_type, name_type);
162 : : }
163 : :
164 : : /* Timestamp */
165 : : {
166 : : uint32_t timestamp =
167 : 12 : ((data[pos] << 24) & 0xFF000000)
168 : 6 : | ((data[pos + 1] << 16) & 0xFF0000)
169 : 12 : | ((data[pos + 2] << 8) & 0xFF00) | ((data[pos + 3] & 0xFF));
170 : 6 : time_t t = timestamp;
171 : 6 : pos += 4;
172 : :
173 [ - + ]: 6 : if (VERBOSENOISE (handle))
174 : 0 : printf ("keytab timestamp %u (0x%08ux)\n", timestamp, timestamp);
175 : :
176 : 6 : shishi_key_timestamp_set (key, t);
177 : : }
178 : :
179 : : /* keyvno8 */
180 : : {
181 : 6 : uint8_t vno8 = data[pos++];
182 : :
183 [ - + ]: 6 : if (VERBOSENOISE (handle))
184 : 0 : printf ("keytab kvno8 %d (0x%02x)\n", vno8, vno8);
185 : :
186 : 6 : shishi_key_version_set (key, vno8);
187 : : }
188 : :
189 : : /* key, keytype */
190 : : {
191 : 6 : uint32_t keytype = data[pos] << 8 | data[pos + 1];
192 : 6 : pos += 2;
193 : :
194 [ - + ]: 6 : if (VERBOSENOISE (handle))
195 : 0 : printf ("keytab keytype %d (0x%x)\n", keytype, keytype);
196 : :
197 : 6 : shishi_key_type_set (key, keytype);
198 : : }
199 : :
200 : : /* key, length and data */
201 : : {
202 : 6 : uint16_t keylen = data[pos] << 8 | data[pos + 1];
203 : 6 : pos += 2;
204 : :
205 [ - + ]: 6 : if (VERBOSENOISE (handle))
206 : 0 : printf ("keytab keylen %d (0x%x) eq? %d\n", keylen, keylen,
207 : : shishi_key_length (key));
208 : :
209 [ - + ]: 6 : if (VERBOSENOISE (handle))
210 : 0 : _shishi_hexprint (data + pos, keylen);
211 : :
212 : 6 : shishi_key_value_set (key, data + pos);
213 : 6 : pos += keylen;
214 : : }
215 : :
216 [ + - ]: 6 : if (pos - entrystartpos < (size_t) size + 4)
217 : : {
218 : : uint32_t vno /* only present if >= 4 bytes left in entry */
219 : 12 : = data[pos] << 24 | data[pos + 1] << 16
220 : 12 : | data[pos + 2] << 8 | data[pos + 3];
221 : 6 : pos += 4;
222 : :
223 [ - + ]: 6 : if (VERBOSENOISE (handle))
224 : 0 : printf ("keytab kvno %d (0x%08x)\n", vno, vno);
225 : :
226 : 6 : shishi_key_version_set (key, vno);
227 : : }
228 : :
229 [ - + ]: 6 : if (VERBOSECRYPTONOISE (handle))
230 : 0 : shishi_key_print (handle, stdout, key);
231 : :
232 : 6 : rc = shishi_keys_add (keys, key);
233 [ - + ]: 6 : if (rc != SHISHI_OK)
234 : 0 : goto done;
235 : :
236 : : /* Go to next entry... */
237 : 6 : entrystartpos += size + 4;
238 : : }
239 : :
240 : 1 : rc = SHISHI_OK;
241 : :
242 : : done:
243 : 1 : shishi_key_done (key);
244 : :
245 : 1 : return rc;
246 : : }
247 : :
248 : : /**
249 : : * shishi_keys_add_keytab_file:
250 : : * @handle: shishi handle as allocated by shishi_init().
251 : : * @filename: name of file to read.
252 : : * @keys: allocated key set to store keys in.
253 : : *
254 : : * Read keys from a MIT keytab data structure from a file, and add the
255 : : * keys to the key set.
256 : : *
257 : : * The format of keytab's is proprietary, and this function support
258 : : * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
259 : : * Keytab Binary File Format in the Shishi manual for a description of
260 : : * the reverse-engineered format.
261 : : *
262 : : * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
263 : : * %SHISHI_KEYTAB_ERROR if the data cannot be parsed as a valid keytab
264 : : * structure, and %SHISHI_OK on success.
265 : : **/
266 : : int
267 : 0 : shishi_keys_add_keytab_file (Shishi * handle,
268 : : const char *filename, Shishi_keys * keys)
269 : : {
270 : : size_t len;
271 : 0 : char *keytab = read_binary_file (filename, &len);
272 : : int rc;
273 : :
274 [ # # ]: 0 : if (!keytab)
275 : 0 : return SHISHI_IO_ERROR;
276 : :
277 : 0 : rc = shishi_keys_add_keytab_mem (handle, keytab, len, keys);
278 : :
279 : 0 : free (keytab);
280 : :
281 : 0 : return rc;
282 : : }
283 : :
284 : : /**
285 : : * shishi_keys_from_keytab_mem:
286 : : * @handle: shishi handle as allocated by shishi_init().
287 : : * @data: constant memory buffer with keytab of @len size.
288 : : * @len: size of memory buffer with keytab data.
289 : : * @outkeys: pointer to key set that will be allocated and populated,
290 : : * must be deallocated by caller on succes.
291 : : *
292 : : * Create a new key set populated with keys from a MIT keytab data
293 : : * structure read from a memory block.
294 : : *
295 : : * The format of keytab's is proprietary, and this function support
296 : : * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
297 : : * Keytab Binary File Format in the Shishi manual for a description of
298 : : * the reverse-engineered format.
299 : : *
300 : : * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
301 : : * represent a valid keytab structure, and %SHISHI_OK on success.
302 : : **/
303 : : int
304 : 1 : shishi_keys_from_keytab_mem (Shishi * handle,
305 : : const char *data, size_t len,
306 : : Shishi_keys ** outkeys)
307 : : {
308 : : int rc;
309 : :
310 : 1 : rc = shishi_keys (handle, outkeys);
311 [ - + ]: 1 : if (rc != SHISHI_OK)
312 : 0 : return rc;
313 : :
314 : 1 : rc = shishi_keys_add_keytab_mem (handle, data, len, *outkeys);
315 [ - + ]: 1 : if (rc != SHISHI_OK)
316 : : {
317 : 0 : shishi_keys_done (outkeys);
318 : 0 : return rc;
319 : : }
320 : :
321 : 1 : return SHISHI_OK;
322 : : }
323 : :
324 : : /**
325 : : * shishi_keys_from_keytab_file:
326 : : * @handle: shishi handle as allocated by shishi_init().
327 : : * @filename: name of file to read.
328 : : * @outkeys: pointer to key set that will be allocated and populated,
329 : : * must be deallocated by caller on succes.
330 : : *
331 : : * Create a new key set populated with keys from a MIT keytab data
332 : : * structure read from a file.
333 : : *
334 : : * The format of keytab's is proprietary, and this function support
335 : : * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
336 : : * Keytab Binary File Format in the Shishi manual for a description of
337 : : * the reverse-engineered format.
338 : : *
339 : : * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
340 : : * %SHISHI_KEYTAB_ERROR if the data cannot be parsed as a valid keytab
341 : : * structure, and %SHISHI_OK on success.
342 : : **/
343 : : int
344 : 0 : shishi_keys_from_keytab_file (Shishi * handle,
345 : : const char *filename, Shishi_keys ** outkeys)
346 : : {
347 : : int rc;
348 : :
349 : 0 : rc = shishi_keys (handle, outkeys);
350 [ # # ]: 0 : if (rc != SHISHI_OK)
351 : 0 : return rc;
352 : :
353 : 0 : rc = shishi_keys_add_keytab_file (handle, filename, *outkeys);
354 [ # # ]: 0 : if (rc != SHISHI_OK)
355 : : {
356 : 0 : shishi_keys_done (outkeys);
357 : 0 : return rc;
358 : : }
359 : :
360 : 0 : return SHISHI_OK;
361 : : }
362 : :
363 : : static int
364 : 6 : key_to_keytab_entry (Shishi * handle,
365 : : const Shishi_key * key, char **out, size_t * len)
366 : : {
367 : 6 : uint16_t num_components = 0;
368 : 6 : const char *realm = shishi_key_realm (key);
369 : 6 : size_t realmlen = strlen (realm);
370 : 6 : const char *principal = shishi_key_principal (key);
371 : 6 : uint32_t name_type = SHISHI_NT_PRINCIPAL;
372 : 6 : time_t timestamp = shishi_key_timestamp (key);
373 : 6 : uint32_t version = shishi_key_version (key);
374 : 6 : uint16_t key_type = shishi_key_type (key);
375 : 6 : size_t key_length = shishi_key_length (key);
376 : 6 : const char *key_value = shishi_key_value (key);
377 : : char *tmpname;
378 : : const char **namebuf;
379 : 6 : char *tokptr = NULL;
380 : : char *p;
381 : : size_t i;
382 : :
383 [ - + ]: 6 : if (realmlen > UINT16_MAX)
384 : 0 : return SHISHI_KEYTAB_ERROR;
385 : :
386 [ - + ]: 6 : if (key_length > UINT16_MAX)
387 : 0 : return SHISHI_KEYTAB_ERROR;
388 : :
389 : : /* Reserve room for size, num_components, realm.length, realm,
390 : : name_type, timestamp, vno8, keyblock.type, keyblock.data.length,
391 : : keyblock.data, and version. */
392 : 6 : *len = 4 + 2 + 2 + realmlen + 4 + 4 + 1 + 2 + 2 + key_length + 4;
393 : :
394 : 6 : tmpname = xstrdup (principal);
395 : 6 : namebuf = xmalloc (sizeof (*namebuf));
396 [ + + ]: 24 : for (num_components = 0; (namebuf[num_components] =
397 [ + + ]: 18 : strtok_r (num_components == 0 ? tmpname
398 : : : NULL, "/", &tokptr));
399 : 12 : num_components++)
400 : : {
401 : 12 : size_t length = strlen (namebuf[num_components]);
402 : :
403 [ - + ]: 12 : if (length > UINT16_MAX)
404 : 0 : return SHISHI_KEYTAB_ERROR;
405 : 12 : *len += 2 + length;
406 : :
407 : 12 : namebuf = xrealloc (namebuf, (num_components + 2) * sizeof (*namebuf));
408 : : }
409 : :
410 : 6 : *out = xmalloc (*len);
411 : 6 : p = *out;
412 : :
413 : : /* Write size. */
414 : 6 : p[0] = ((*len - 4) >> 24) & 0xFF;
415 : 6 : p[1] = ((*len - 4) >> 16) & 0xFF;
416 : 6 : p[2] = ((*len - 4) >> 8) & 0xFF;
417 : 6 : p[3] = (*len - 4) & 0xFF;
418 : 6 : p += 4;
419 : :
420 : : /* Write num_components. */
421 : 6 : p[0] = (num_components >> 8) & 0xFF;
422 : 6 : p[1] = num_components & 0xFF;
423 : 6 : p += 2;
424 : :
425 : : /* Write realm.length and realm.data. */
426 : 6 : p[0] = (realmlen >> 8) & 0xFF;
427 : 6 : p[1] = realmlen & 0xFF;
428 : 6 : p += 2;
429 : 6 : memcpy (p, realm, realmlen);
430 : 6 : p += realmlen;
431 : :
432 [ + + ]: 18 : for (i = 0; i < num_components; i++)
433 : : {
434 : 12 : uint16_t length = strlen (namebuf[i]);
435 : 12 : p[0] = (length >> 8) & 0xFF;
436 : 12 : p[1] = length & 0xFF;
437 : 12 : p += 2;
438 : 12 : memcpy (p, namebuf[i], length);
439 : 12 : p += length;
440 : : }
441 : :
442 : : /* Name type */
443 : 6 : p[0] = (name_type >> 24) & 0xFF;
444 : 6 : p[1] = (name_type >> 16) & 0xFF;
445 : 6 : p[2] = (name_type >> 8) & 0xFF;
446 : 6 : p[3] = name_type & 0xFF;
447 : 6 : p += 4;
448 : :
449 : : /* Timestamp */
450 : 6 : p[0] = (timestamp >> 24) & 0xFF;
451 : 6 : p[1] = (timestamp >> 16) & 0xFF;
452 : 6 : p[2] = (timestamp >> 8) & 0xFF;
453 : 6 : p[3] = timestamp & 0xFF;
454 : 6 : p += 4;
455 : :
456 : : /* Version */
457 [ + - ]: 6 : if (version < 256)
458 : 6 : p[0] = version & 0xFF;
459 : : else
460 : 0 : p[0] = 0; /* use vno */
461 : 6 : p += 1;
462 : :
463 : : /* Key */
464 : 6 : p[0] = (key_type >> 8) & 0xFF;
465 : 6 : p[1] = key_type & 0xFF;
466 : 6 : p += 2;
467 : :
468 : 6 : p[0] = (key_length >> 8) & 0xFF;
469 : 6 : p[1] = key_length & 0xFF;
470 : 6 : p += 2;
471 : 6 : memcpy (p, key_value, key_length);
472 : 6 : p += key_length;
473 : :
474 : : /* Version */
475 : 6 : p[0] = (version >> 24) & 0xFF;
476 : 6 : p[1] = (version >> 16) & 0xFF;
477 : 6 : p[2] = (version >> 8) & 0xFF;
478 : 6 : p[3] = version & 0xFF;
479 : :
480 : 6 : free (tmpname);
481 : 6 : free (namebuf);
482 : :
483 : 6 : return SHISHI_OK;
484 : : }
485 : :
486 : : /**
487 : : * shishi_keys_to_keytab_mem:
488 : : * @handle: shishi handle as allocated by shishi_init().
489 : : * @keys: key set to convert to keytab format.
490 : : * @out: constant memory buffer with keytab of @len size.
491 : : * @len: size of memory buffer with keytab data.
492 : : *
493 : : * Write keys to a MIT keytab data structure.
494 : : *
495 : : * The format of keytab's is proprietary, and this function writes the
496 : : * 0x0502 format. See the section The MIT Kerberos Keytab Binary File
497 : : * Format in the Shishi manual for a description of the
498 : : * reverse-engineered format.
499 : : *
500 : : * Returns: On success %SHISHI_OK is returned, otherwise an error
501 : : * code.
502 : : *
503 : : * Since: 0.0.42
504 : : **/
505 : : int
506 : 1 : shishi_keys_to_keytab_mem (Shishi * handle,
507 : : Shishi_keys * keys, char **out, size_t * len)
508 : : {
509 : : int rc;
510 : : const Shishi_key *key;
511 : 1 : int keyno = 0;
512 : :
513 : 1 : *out = xmalloc (2);
514 : 1 : *len = 2;
515 : :
516 : : /* Write file format version. */
517 : 1 : (*out)[0] = '\x05';
518 : 1 : (*out)[1] = '\x02';
519 : :
520 [ + + ]: 7 : while ((key = shishi_keys_nth (keys, keyno++)) != NULL)
521 : : {
522 : 6 : char *tmp = NULL;
523 : 6 : size_t tmplen = 0;
524 : :
525 : 6 : rc = key_to_keytab_entry (handle, key, &tmp, &tmplen);
526 [ - + ]: 6 : if (rc != SHISHI_OK)
527 : : {
528 : 0 : free (*out);
529 : 0 : return rc;
530 : : }
531 : :
532 : 6 : *out = xrealloc (*out, *len + tmplen);
533 : 6 : memcpy (*out + *len, tmp, tmplen);
534 : 6 : *len += tmplen;
535 : : }
536 : :
537 [ - + ]: 1 : if (VERBOSENOISE (handle))
538 : : {
539 : 0 : printf ("keys_to_keytab len %d (0x%x)\n", *len, *len);
540 : 0 : _shishi_hexprint (*out, *len);
541 : : }
542 : :
543 : 1 : return rc;
544 : : }
545 : :
546 : : static int
547 : 0 : write_binary_file (const char *filename, const char *data, size_t length)
548 : : {
549 : : FILE *fh;
550 : : size_t written;
551 : :
552 : 0 : fh = fopen (filename, "wb");
553 [ # # ]: 0 : if (!fh)
554 : 0 : return SHISHI_FOPEN_ERROR;
555 : :
556 : 0 : written = fwrite (data, 1, length, fh);
557 [ # # ]: 0 : if (written != length)
558 : 0 : return SHISHI_IO_ERROR;
559 : :
560 : 0 : return SHISHI_OK;
561 : : }
562 : :
563 : : /**
564 : : * shishi_keys_to_keytab_file:
565 : : * @handle: shishi handle as allocated by shishi_init().
566 : : * @keys: keyset to write.
567 : : * @filename: name of file to write.
568 : : *
569 : : * Write keys to a MIT keytab data structure.
570 : : *
571 : : * The format of keytab's is proprietary, and this function writes the
572 : : * 0x0502 format. See the section The MIT Kerberos Keytab Binary File
573 : : * Format in the Shishi manual for a description of the
574 : : * reverse-engineered format.
575 : : *
576 : : * Returns: %SHISHI_FOPEN_ERROR if there is a problem opening
577 : : * @filename for writing, %SHISHI_IO_ERROR if there is problem
578 : : * writing the file, and %SHISHI_OK on success.
579 : : *
580 : : * Since: 0.0.42
581 : : **/
582 : : int
583 : 0 : shishi_keys_to_keytab_file (Shishi * handle,
584 : : Shishi_keys * keys, const char *filename)
585 : : {
586 : : int rc;
587 : : char *data;
588 : : size_t len;
589 : :
590 : 0 : rc = shishi_keys_to_keytab_mem (handle, keys, &data, &len);
591 [ # # ]: 0 : if (rc != SHISHI_OK)
592 : 0 : return rc;
593 : :
594 : 0 : rc = write_binary_file (filename, data, len);
595 [ # # ]: 0 : if (rc != SHISHI_OK)
596 : 0 : return rc;
597 : :
598 : 0 : return SHISHI_OK;
599 : : }
|