1 /* keys.c --- Functions for reading /etc/krb5.keytab style key files.
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
25 * shishi_keys_add_keytab_mem:
26 * @handle: shishi handle as allocated by shishi_init().
27 * @data: constant memory buffer with keytab of @len size.
28 * @len: size of memory buffer with keytab data.
29 * @keys: allocated key set to store keys in.
31 * Read keys from a MIT keytab data structure, and add them to the key
34 * The format of keytab's is proprietary, and this function support
35 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
36 * Keytab Binary File Format in the Shishi manual for a description of
37 * the reverse-engineered format.
39 * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
40 * represent a valid keytab structure, and %SHISHI_OK on success.
43 shishi_keys_add_keytab_mem (Shishi
* handle
,
44 const char *data
, size_t len
,
48 uint16_t file_format_version
;
50 uint16_t num_components
; /* sub 1 if version 0x501 */
55 if (VERBOSENOISE (handle
))
57 printf ("keytab len %d (0x%x)\n", len
, len
);
58 _shishi_hexprint (data
, len
);
61 /* Check file format. */
62 file_format_version
= (data
[0] << 8) | data
[1];
64 if (VERBOSENOISE (handle
))
65 printf ("keytab file_format_version %04X\n", file_format_version
);
67 if (file_format_version
!= 0x0501 && file_format_version
!= 0x0502)
68 return SHISHI_KEYTAB_ERROR
;
70 /* Check file integrity first, to avoid error-checking below. */
72 while (entrystartpos
< len
)
74 int32_t size
= data
[entrystartpos
] << 24 | data
[entrystartpos
+1] << 16
75 | data
[entrystartpos
+2] << 8 | data
[entrystartpos
+3];
78 if (VERBOSENOISE (handle
))
80 printf ("keytab size %d (%x)\n", size
, size
);
81 printf ("keytab pos %d < %d\n", entrystartpos
+ size
, len
);
84 if (entrystartpos
+ size
> len
)
85 return SHISHI_KEYTAB_ERROR
;
87 /* Go to next entry... */
88 entrystartpos
+= size
;
90 if (entrystartpos
!= len
)
91 return SHISHI_KEYTAB_ERROR
;
93 rc
= shishi_key (handle
, &key
);
98 while (entrystartpos
< len
)
100 size_t pos
= entrystartpos
;
101 uint16_t size
= data
[pos
] << 24 | data
[pos
+1] << 16
102 | data
[pos
+2] << 8 | data
[pos
+3];
105 if (VERBOSENOISE (handle
))
106 printf ("keytab size %d (%x)\n", size
, size
);
109 num_components
= data
[pos
] << 8 | data
[pos
+1];
112 if (file_format_version
== 0x0501)
117 uint16_t realmlen
= data
[pos
] << 8 | data
[pos
+1];
118 char *realm
= xstrndup (&data
[pos
+ 2], realmlen
);;
122 shishi_key_realm_set (key
, realm
);
126 /* Principal components. */
131 for (i
= 0; i
< num_components
; i
++)
135 l
= data
[pos
] << 8 | data
[pos
+1];
138 name
= xrealloc (name
, namelen
+ l
+ 1);
139 memcpy (name
+ namelen
, &data
[pos
], l
);
140 name
[namelen
+ l
] = '/';
146 name
[namelen
- 1] = '\0';
147 shishi_key_principal_set (key
, name
);
153 uint32_t name_type
/* not present if version 0x501 */
154 = data
[pos
] << 24 | data
[pos
+1] << 16
155 | data
[pos
+2] << 8 | data
[pos
+3];
158 if (VERBOSENOISE (handle
))
159 printf ("keytab nametype %d (0x%08x)\n", name_type
, name_type
);
164 uint32_t timestamp
= data
[pos
] << 24 | data
[pos
+1] << 16
165 | data
[pos
+2] << 8 | data
[pos
+3];
168 if (VERBOSENOISE (handle
))
169 printf ("keytab timestamp %u (0x%08ux)\n", timestamp
, timestamp
);
174 uint8_t vno8
= data
[pos
++];
176 if (VERBOSENOISE (handle
))
177 printf ("keytab kvno8 %d (0x%02x)\n", vno8
, vno8
);
179 shishi_key_version_set (key
, vno8
);
184 uint32_t keytype
= data
[pos
] << 8 | data
[pos
+1];
187 if (VERBOSENOISE (handle
))
188 printf ("keytab keytype %d (0x%x)\n", keytype
, keytype
);
190 shishi_key_type_set (key
, keytype
);
193 /* key, length and data */
195 uint16_t keylen
= data
[pos
] << 8 | data
[pos
+1];
198 if (VERBOSENOISE (handle
))
199 printf ("keytab keylen %d (0x%x) eq? %d\n", keylen
, keylen
,
200 shishi_key_length (key
));
202 if (VERBOSENOISE (handle
))
203 _shishi_hexprint (data
+ pos
, keylen
);
205 shishi_key_value_set (key
, data
+ pos
);
209 if (pos
- entrystartpos
< size
+ 4)
211 uint32_t vno
/* only present if >= 4 bytes left in entry */
212 = data
[pos
] << 24 | data
[pos
+1] << 16
213 | data
[pos
+2] << 8 | data
[pos
+3];
216 if (VERBOSENOISE (handle
))
217 printf ("keytab kvno %d (0x%08x)\n", vno
, vno
);
219 shishi_key_version_set (key
, vno
);
222 if (VERBOSECRYPTONOISE (handle
))
223 shishi_key_print (handle
, stdout
, key
);
225 rc
= shishi_keys_add (keys
, key
);
229 /* Go to next entry... */
230 entrystartpos
+= size
+ 4;
236 shishi_key_done (key
);
242 * shishi_keys_add_keytab_file:
243 * @handle: shishi handle as allocated by shishi_init().
244 * @filename: name of file to read.
245 * @keys: allocated key set to store keys in.
247 * Read keys from a MIT keytab data structure from a file, and add the
248 * keys to the key set.
250 * The format of keytab's is proprietary, and this function support
251 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
252 * Keytab Binary File Format in the Shishi manual for a description of
253 * the reverse-engineered format.
255 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
256 * %SHISHI_KEYTAB_ERROR if the data cannot be parsed as a valid keytab
257 * structure, and %SHISHI_OK on success.
260 shishi_keys_add_keytab_file (Shishi
* handle
,
261 const char *filename
,
265 char *keytab
= read_file (filename
, &len
);
269 return SHISHI_IO_ERROR
;
271 rc
= shishi_keys_add_keytab_mem (handle
, keytab
, len
, keys
);
279 * shishi_keys_from_keytab_mem:
280 * @handle: shishi handle as allocated by shishi_init().
281 * @data: constant memory buffer with keytab of @len size.
282 * @len: size of memory buffer with keytab data.
283 * @outkeys: pointer to key set that will be allocated and populated,
284 * must be deallocated by caller on succes.
286 * Create a new key set populated with keys from a MIT keytab data
287 * structure read from a memory block.
289 * The format of keytab's is proprietary, and this function support
290 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
291 * Keytab Binary File Format in the Shishi manual for a description of
292 * the reverse-engineered format.
294 * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
295 * represent a valid keytab structure, and %SHISHI_OK on success.
298 shishi_keys_from_keytab_mem (Shishi
* handle
,
299 const char *data
, size_t len
,
300 Shishi_keys
**outkeys
)
304 rc
= shishi_keys (handle
, outkeys
);
308 rc
= shishi_keys_add_keytab_mem (handle
, data
, len
, *outkeys
);
311 shishi_keys_done (outkeys
);
319 * shishi_keys_from_keytab_file:
320 * @handle: shishi handle as allocated by shishi_init().
321 * @filename: name of file to read.
322 * @outkeys: pointer to key set that will be allocated and populated,
323 * must be deallocated by caller on succes.
325 * Create a new key set populated with keys from a MIT keytab data
326 * structure read from a file.
328 * The format of keytab's is proprietary, and this function support
329 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
330 * Keytab Binary File Format in the Shishi manual for a description of
331 * the reverse-engineered format.
333 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
334 * %SHISHI_KEYTAB_ERROR if the data cannot be parsed as a valid keytab
335 * structure, and %SHISHI_OK on success.
338 shishi_keys_from_keytab_file (Shishi
* handle
,
339 const char *filename
,
340 Shishi_keys
**outkeys
)
344 rc
= shishi_keys (handle
, outkeys
);
348 rc
= shishi_keys_add_keytab_file (handle
, filename
, *outkeys
);
351 shishi_keys_done (outkeys
);