Branch data Line data Source code
1 : : /* apreq.c --- AP-REQ functions.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
3 : : *
4 : : * This file is part of Shishi.
5 : : *
6 : : * Shishi is free software; you can redistribute it and/or modify it 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 but
12 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * 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_print_armored_data, etc. */
26 : : #include "diskio.h"
27 : :
28 : : #define SHISHI_APREQ_DEFAULT_PVNO "5"
29 : : #define SHISHI_APREQ_DEFAULT_PVNO_LEN 0
30 : : #define SHISHI_APREQ_DEFAULT_MSG_TYPE "14" /* KRB_AP_REQ */
31 : : #define SHISHI_APREQ_DEFAULT_MSG_TYPE_LEN 0
32 : : #define SHISHI_APREQ_DEFAULT_AP_OPTIONS "\x00\x00\x00\x00"
33 : : #define SHISHI_APREQ_DEFAULT_AP_OPTIONS_LEN 32
34 : : #define SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO "5"
35 : : #define SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO_LEN 0
36 : : #define SHISHI_APREQ_DEFAULT_TICKET_REALM ""
37 : : #define SHISHI_APREQ_DEFAULT_TICKET_REALM_LEN 0
38 : : #define SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE "1" /* SHISHI_NT_PRINCIPAL */
39 : : #define SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE_LEN 0
40 : : #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE "0"
41 : : #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE_LEN 0
42 : : #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO "0"
43 : : #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO_LEN 0
44 : : #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER ""
45 : : #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER_LEN 0
46 : : #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE "0"
47 : : #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE_LEN 0
48 : : #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO "1"
49 : : #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO_LEN 0
50 : : #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER ""
51 : : #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER_LEN 0
52 : :
53 : : /**
54 : : * shishi_apreq:
55 : : * @handle: shishi handle as allocated by shishi_init().
56 : : *
57 : : * This function creates a new AP-REQ, populated with some default
58 : : * values.
59 : : *
60 : : * Return value: Returns the AP-REQ or NULL on failure.
61 : : **/
62 : : Shishi_asn1
63 : 0 : shishi_apreq (Shishi * handle)
64 : : {
65 : : Shishi_asn1 node;
66 : : int res;
67 : :
68 : 0 : node = shishi_asn1_apreq (handle);
69 [ # # ]: 0 : if (!node)
70 : 0 : goto error;
71 : :
72 : 0 : res = shishi_asn1_write (handle, node, "pvno",
73 : : SHISHI_APREQ_DEFAULT_PVNO,
74 : : SHISHI_APREQ_DEFAULT_PVNO_LEN);
75 [ # # ]: 0 : if (res != SHISHI_OK)
76 : 0 : goto error;
77 : :
78 : 0 : res = shishi_asn1_write (handle, node, "msg-type",
79 : : SHISHI_APREQ_DEFAULT_MSG_TYPE,
80 : : SHISHI_APREQ_DEFAULT_MSG_TYPE_LEN);
81 [ # # ]: 0 : if (res != SHISHI_OK)
82 : 0 : goto error;
83 : :
84 : 0 : res = shishi_asn1_write (handle, node, "ap-options",
85 : : SHISHI_APREQ_DEFAULT_AP_OPTIONS,
86 : : SHISHI_APREQ_DEFAULT_AP_OPTIONS_LEN);
87 [ # # ]: 0 : if (res != SHISHI_OK)
88 : 0 : goto error;
89 : :
90 : 0 : res = shishi_asn1_write (handle, node, "ticket.tkt-vno",
91 : : SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO,
92 : : SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO_LEN);
93 [ # # ]: 0 : if (res != SHISHI_OK)
94 : 0 : goto error;
95 : :
96 : 0 : res = shishi_asn1_write (handle, node, "ticket.realm",
97 : : SHISHI_APREQ_DEFAULT_TICKET_REALM,
98 : : SHISHI_APREQ_DEFAULT_TICKET_REALM_LEN);
99 [ # # ]: 0 : if (res != SHISHI_OK)
100 : 0 : goto error;
101 : :
102 : 0 : res = shishi_asn1_write (handle, node, "ticket.realm",
103 : : SHISHI_APREQ_DEFAULT_TICKET_REALM,
104 : : SHISHI_APREQ_DEFAULT_TICKET_REALM_LEN);
105 [ # # ]: 0 : if (res != SHISHI_OK)
106 : 0 : goto error;
107 : :
108 : 0 : res = shishi_asn1_write (handle, node, "ticket.sname.name-type",
109 : : SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE,
110 : : SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE_LEN);
111 [ # # ]: 0 : if (res != SHISHI_OK)
112 : 0 : goto error;
113 : :
114 : 0 : res = shishi_asn1_write (handle, node, "ticket.enc-part.etype",
115 : : SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE,
116 : : SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE_LEN);
117 [ # # ]: 0 : if (res != SHISHI_OK)
118 : 0 : goto error;
119 : :
120 : 0 : res = shishi_asn1_write (handle, node, "ticket.enc-part.kvno",
121 : : SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO,
122 : : SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO_LEN);
123 [ # # ]: 0 : if (res != SHISHI_OK)
124 : 0 : goto error;
125 : :
126 : 0 : res = shishi_asn1_write (handle, node, "ticket.enc-part.cipher",
127 : : SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER,
128 : : SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER_LEN);
129 [ # # ]: 0 : if (res != SHISHI_OK)
130 : 0 : goto error;
131 : :
132 : 0 : res = shishi_asn1_write (handle, node, "authenticator.etype",
133 : : SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE,
134 : : SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE_LEN);
135 [ # # ]: 0 : if (res != SHISHI_OK)
136 : 0 : goto error;
137 : :
138 : 0 : res = shishi_asn1_write (handle, node, "authenticator.kvno",
139 : : SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO,
140 : : SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO_LEN);
141 [ # # ]: 0 : if (res != SHISHI_OK)
142 : 0 : goto error;
143 : :
144 : 0 : res = shishi_asn1_write (handle, node, "authenticator.cipher",
145 : : SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER,
146 : : SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER_LEN);
147 [ # # ]: 0 : if (res != SHISHI_OK)
148 : 0 : goto error;
149 : :
150 : 0 : return node;
151 : :
152 : : error:
153 [ # # ]: 0 : if (node)
154 : 0 : shishi_asn1_done (handle, node);
155 : 0 : return NULL;
156 : : }
157 : :
158 : : /**
159 : : * shishi_apreq_print:
160 : : * @handle: shishi handle as allocated by shishi_init().
161 : : * @fh: file handle open for writing.
162 : : * @apreq: AP-REQ to print.
163 : : *
164 : : * Print ASCII armored DER encoding of AP-REQ to file.
165 : : *
166 : : * Return value: Returns SHISHI_OK iff successful.
167 : : **/
168 : : int
169 : 0 : shishi_apreq_print (Shishi * handle, FILE * fh, Shishi_asn1 apreq)
170 : : {
171 : 0 : return _shishi_print_armored_data (handle, fh, apreq, "AP-REQ", NULL);
172 : : }
173 : :
174 : : /**
175 : : * shishi_apreq_save:
176 : : * @handle: shishi handle as allocated by shishi_init().
177 : : * @fh: file handle open for writing.
178 : : * @apreq: AP-REQ to save.
179 : : *
180 : : * Save DER encoding of AP-REQ to file.
181 : : *
182 : : * Return value: Returns SHISHI_OK iff successful.
183 : : **/
184 : : int
185 : 0 : shishi_apreq_save (Shishi * handle, FILE * fh, Shishi_asn1 apreq)
186 : : {
187 : 0 : return _shishi_save_data (handle, fh, apreq, "AP-REQ");
188 : : }
189 : :
190 : : /**
191 : : * shishi_apreq_to_file:
192 : : * @handle: shishi handle as allocated by shishi_init().
193 : : * @apreq: AP-REQ to save.
194 : : * @filetype: input variable specifying type of file to be written,
195 : : * see Shishi_filetype.
196 : : * @filename: input variable with filename to write to.
197 : : *
198 : : * Write AP-REQ to file in specified TYPE. The file will be
199 : : * truncated if it exists.
200 : : *
201 : : * Return value: Returns SHISHI_OK iff successful.
202 : : **/
203 : : int
204 : 0 : shishi_apreq_to_file (Shishi * handle, Shishi_asn1 apreq,
205 : : int filetype, const char *filename)
206 : : {
207 : : FILE *fh;
208 : : int res;
209 : :
210 [ # # ]: 0 : if (VERBOSE (handle))
211 : 0 : printf (_("Writing AP-REQ to %s...\n"), filename);
212 : :
213 : 0 : fh = fopen (filename, "w");
214 [ # # ]: 0 : if (fh == NULL)
215 : 0 : return SHISHI_FOPEN_ERROR;
216 : :
217 [ # # ]: 0 : if (VERBOSE (handle))
218 [ # # ]: 0 : printf (_("Writing AP-REQ in %s format...\n"),
219 : : filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
220 : :
221 [ # # ]: 0 : if (filetype == SHISHI_FILETYPE_TEXT)
222 : 0 : res = shishi_apreq_print (handle, fh, apreq);
223 : : else
224 : 0 : res = shishi_apreq_save (handle, fh, apreq);
225 [ # # ]: 0 : if (res != SHISHI_OK)
226 : 0 : return res;
227 : :
228 : 0 : res = fclose (fh);
229 [ # # ]: 0 : if (res != 0)
230 : 0 : return SHISHI_IO_ERROR;
231 : :
232 [ # # ]: 0 : if (VERBOSE (handle))
233 : 0 : printf (_("Writing AP-REQ to %s...done\n"), filename);
234 : :
235 : 0 : return SHISHI_OK;
236 : : }
237 : :
238 : : /**
239 : : * shishi_apreq_parse:
240 : : * @handle: shishi handle as allocated by shishi_init().
241 : : * @fh: file handle open for reading.
242 : : * @apreq: output variable with newly allocated AP-REQ.
243 : : *
244 : : * Read ASCII armored DER encoded AP-REQ from file and populate given
245 : : * variable.
246 : : *
247 : : * Return value: Returns SHISHI_OK iff successful.
248 : : **/
249 : : int
250 : 0 : shishi_apreq_parse (Shishi * handle, FILE * fh, Shishi_asn1 * apreq)
251 : : {
252 : 0 : return _shishi_apreq_input (handle, fh, apreq, 0);
253 : : }
254 : :
255 : : /**
256 : : * shishi_apreq_read:
257 : : * @handle: shishi handle as allocated by shishi_init().
258 : : * @fh: file handle open for reading.
259 : : * @apreq: output variable with newly allocated AP-REQ.
260 : : *
261 : : * Read DER encoded AP-REQ from file and populate given variable.
262 : : *
263 : : * Return value: Returns SHISHI_OK iff successful.
264 : : **/
265 : : int
266 : 0 : shishi_apreq_read (Shishi * handle, FILE * fh, Shishi_asn1 * apreq)
267 : : {
268 : 0 : return _shishi_apreq_input (handle, fh, apreq, 1);
269 : : }
270 : :
271 : : /**
272 : : * shishi_apreq_from_file:
273 : : * @handle: shishi handle as allocated by shishi_init().
274 : : * @apreq: output variable with newly allocated AP-REQ.
275 : : * @filetype: input variable specifying type of file to be read,
276 : : * see Shishi_filetype.
277 : : * @filename: input variable with filename to read from.
278 : : *
279 : : * Read AP-REQ from file in specified TYPE.
280 : : *
281 : : * Return value: Returns SHISHI_OK iff successful.
282 : : **/
283 : : int
284 : 0 : shishi_apreq_from_file (Shishi * handle, Shishi_asn1 * apreq,
285 : : int filetype, const char *filename)
286 : : {
287 : : int res;
288 : : FILE *fh;
289 : :
290 [ # # ]: 0 : if (VERBOSE (handle))
291 : 0 : printf (_("Reading AP-REQ from %s...\n"), filename);
292 : :
293 : 0 : fh = fopen (filename, "r");
294 [ # # ]: 0 : if (fh == NULL)
295 : 0 : return SHISHI_FOPEN_ERROR;
296 : :
297 [ # # ]: 0 : if (VERBOSE (handle))
298 [ # # ]: 0 : printf (_("Reading AP-REQ in %s format...\n"),
299 : : filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
300 : :
301 [ # # ]: 0 : if (filetype == SHISHI_FILETYPE_TEXT)
302 : 0 : res = shishi_apreq_parse (handle, fh, apreq);
303 : : else
304 : 0 : res = shishi_apreq_read (handle, fh, apreq);
305 [ # # ]: 0 : if (res != SHISHI_OK)
306 : 0 : return res;
307 : :
308 : 0 : res = fclose (fh);
309 [ # # ]: 0 : if (res != 0)
310 : 0 : return SHISHI_IO_ERROR;
311 : :
312 [ # # ]: 0 : if (VERBOSE (handle))
313 : 0 : printf (_("Reading AP-REQ from %s...done\n"), filename);
314 : :
315 : 0 : return SHISHI_OK;
316 : : }
317 : :
318 : : /**
319 : : * shishi_apreq_set_authenticator:
320 : : * @handle: shishi handle as allocated by shishi_init().
321 : : * @apreq: AP-REQ to add authenticator field to.
322 : : * @etype: encryption type used to encrypt authenticator.
323 : : * @kvno: version of the key used to encrypt authenticator.
324 : : * @buf: input array with encrypted authenticator.
325 : : * @buflen: size of input array with encrypted authenticator.
326 : : *
327 : : * Set the encrypted authenticator field in the AP-REP. The encrypted
328 : : * data is usually created by calling shishi_encrypt() on the DER
329 : : * encoded authenticator. To save time, you may want to use
330 : : * shishi_apreq_add_authenticator() instead, which calculates the
331 : : * encrypted data and calls this function in one step.
332 : : *
333 : : * Return value: Returns SHISHI_OK on success.
334 : : **/
335 : : int
336 : 0 : shishi_apreq_set_authenticator (Shishi * handle,
337 : : Shishi_asn1 apreq,
338 : : int32_t etype, uint32_t kvno,
339 : : const char *buf, size_t buflen)
340 : : {
341 : : int res;
342 : :
343 : 0 : res = shishi_asn1_write (handle, apreq, "authenticator.cipher",
344 : : buf, buflen);
345 [ # # ]: 0 : if (res != SHISHI_OK)
346 : 0 : return res;
347 : :
348 [ # # ]: 0 : if (kvno == UINT32_MAX)
349 : 0 : res = shishi_asn1_write (handle, apreq, "authenticator.kvno", NULL, 0);
350 : : else
351 : 0 : res = shishi_asn1_write_int32 (handle, apreq, "authenticator.kvno", kvno);
352 [ # # ]: 0 : if (res != SHISHI_OK)
353 : 0 : return res;
354 : :
355 : 0 : res = shishi_asn1_write_int32 (handle, apreq, "authenticator.etype", etype);
356 [ # # ]: 0 : if (res != SHISHI_OK)
357 : 0 : return res;
358 : :
359 : 0 : return SHISHI_OK;
360 : : }
361 : :
362 : : /**
363 : : * shishi_apreq_add_authenticator:
364 : : * @handle: shishi handle as allocated by shishi_init().
365 : : * @apreq: AP-REQ to add authenticator field to.
366 : : * @key: key to to use for encryption.
367 : : * @keyusage: cryptographic key usage value to use in encryption.
368 : : * @authenticator: authenticator as allocated by shishi_authenticator().
369 : : *
370 : : * Encrypts DER encoded authenticator using key and store it in the
371 : : * AP-REQ.
372 : : *
373 : : * Return value: Returns SHISHI_OK iff successful.
374 : : **/
375 : : int
376 : 0 : shishi_apreq_add_authenticator (Shishi * handle,
377 : : Shishi_asn1 apreq,
378 : : Shishi_key * key,
379 : : int keyusage, Shishi_asn1 authenticator)
380 : : {
381 : : int res;
382 : : char *buf;
383 : : size_t buflen;
384 : : char *der;
385 : : size_t derlen;
386 : :
387 : 0 : res = shishi_asn1_to_der (handle, authenticator, &der, &derlen);
388 [ # # ]: 0 : if (res != SHISHI_OK)
389 : : {
390 : 0 : shishi_error_printf (handle, "Could not DER encode authenticator: %s\n",
391 : : shishi_strerror (res));
392 : 0 : return res;
393 : : }
394 : :
395 : 0 : res = shishi_encrypt (handle, key, keyusage, der, derlen, &buf, &buflen);
396 : :
397 : 0 : free (der);
398 : :
399 [ # # ]: 0 : if (res != SHISHI_OK)
400 : : {
401 : 0 : shishi_error_printf (handle, "Cannot encrypt authenticator.\n");
402 : 0 : return res;
403 : : }
404 : :
405 : 0 : res = shishi_apreq_set_authenticator (handle, apreq, shishi_key_type (key),
406 : : shishi_key_version (key),
407 : : buf, buflen);
408 : :
409 : 0 : return res;
410 : : }
411 : :
412 : : /**
413 : : * shishi_apreq_set_ticket:
414 : : * @handle: shishi handle as allocated by shishi_init().
415 : : * @apreq: AP-REQ to add ticket field to.
416 : : * @ticket: input ticket to copy into AP-REQ ticket field.
417 : : *
418 : : * Copy ticket into AP-REQ.
419 : : *
420 : : * Return value: Returns SHISHI_OK iff successful.
421 : : **/
422 : : int
423 : 0 : shishi_apreq_set_ticket (Shishi * handle, Shishi_asn1 apreq,
424 : : Shishi_asn1 ticket)
425 : : {
426 : : int res;
427 : : char *format;
428 : : char *buf;
429 : : size_t buflen, i, n;
430 : :
431 : 0 : res = shishi_asn1_read (handle, ticket, "tkt-vno", &buf, &buflen);
432 [ # # ]: 0 : if (res != SHISHI_OK)
433 : 0 : return res;
434 : :
435 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.tkt-vno", buf, buflen);
436 : 0 : free (buf);
437 [ # # ]: 0 : if (res != SHISHI_OK)
438 : 0 : return res;
439 : :
440 : 0 : res = shishi_asn1_read (handle, ticket, "realm", &buf, &buflen);
441 [ # # ]: 0 : if (res != SHISHI_OK)
442 : 0 : return res;
443 : :
444 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.realm", buf, buflen);
445 : 0 : free (buf);
446 [ # # ]: 0 : if (res != SHISHI_OK)
447 : 0 : return res;
448 : :
449 : 0 : res = shishi_asn1_read (handle, ticket, "sname.name-type", &buf, &buflen);
450 [ # # ]: 0 : if (res != SHISHI_OK)
451 : 0 : return res;
452 : :
453 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.sname.name-type",
454 : : buf, buflen);
455 : 0 : free (buf);
456 [ # # ]: 0 : if (res != SHISHI_OK)
457 : 0 : return res;
458 : :
459 : 0 : res = shishi_asn1_number_of_elements (handle, ticket,
460 : : "sname.name-string", &n);
461 [ # # ]: 0 : if (res != SHISHI_OK)
462 : 0 : return res;
463 : :
464 [ # # ]: 0 : for (i = 1; i <= n; i++)
465 : : {
466 : 0 : res = shishi_asn1_write (handle, apreq,
467 : : "ticket.sname.name-string", "NEW", 1);
468 [ # # ]: 0 : if (res != SHISHI_OK)
469 : 0 : return res;
470 : :
471 : 0 : asprintf (&format, "sname.name-string.?%d", i);
472 : 0 : res = shishi_asn1_read (handle, ticket, format, &buf, &buflen);
473 : 0 : free (format);
474 [ # # ]: 0 : if (res != SHISHI_OK)
475 : 0 : return res;
476 : :
477 : 0 : asprintf (&format, "ticket.sname.name-string.?%d", i);
478 : 0 : res = shishi_asn1_write (handle, apreq, format, buf, buflen);
479 : 0 : free (format);
480 : 0 : free (buf);
481 [ # # ]: 0 : if (res != SHISHI_OK)
482 : 0 : return res;
483 : : }
484 : :
485 : 0 : res = shishi_asn1_read (handle, ticket, "enc-part.etype", &buf, &buflen);
486 [ # # ]: 0 : if (res != SHISHI_OK)
487 : 0 : return res;
488 : :
489 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.enc-part.etype",
490 : : buf, buflen);
491 : 0 : free (buf);
492 [ # # ]: 0 : if (res != SHISHI_OK)
493 : 0 : return res;
494 : :
495 : 0 : res = shishi_asn1_read (handle, ticket, "enc-part.kvno", &buf, &buflen);
496 [ # # # # ]: 0 : if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT)
497 : 0 : return res;
498 : :
499 [ # # ]: 0 : if (res == SHISHI_ASN1_NO_ELEMENT)
500 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.enc-part.kvno", NULL, 0);
501 : : else
502 : : {
503 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.enc-part.kvno",
504 : : buf, buflen);
505 : 0 : free (buf);
506 : : }
507 [ # # ]: 0 : if (res != SHISHI_OK)
508 : 0 : return res;
509 : :
510 : 0 : res = shishi_asn1_read (handle, ticket, "enc-part.cipher", &buf, &buflen);
511 [ # # ]: 0 : if (res != SHISHI_OK)
512 : 0 : return res;
513 : :
514 : 0 : res = shishi_asn1_write (handle, apreq, "ticket.enc-part.cipher",
515 : : buf, buflen);
516 : 0 : free (buf);
517 [ # # ]: 0 : if (res != SHISHI_OK)
518 : 0 : return res;
519 : :
520 : 0 : return SHISHI_OK;
521 : : }
522 : :
523 : : /**
524 : : * shishi_apreq_options:
525 : : * @handle: shishi handle as allocated by shishi_init().
526 : : * @apreq: AP-REQ to get options from.
527 : : * @flags: Output integer containing options from AP-REQ.
528 : : *
529 : : * Extract the AP-Options from AP-REQ into output integer.
530 : : *
531 : : * Return value: Returns SHISHI_OK iff successful.
532 : : **/
533 : : int
534 : 0 : shishi_apreq_options (Shishi * handle, Shishi_asn1 apreq, uint32_t * flags)
535 : : {
536 : 0 : return shishi_asn1_read_bitstring (handle, apreq, "ap-options", flags);
537 : : }
538 : :
539 : : /**
540 : : * shishi_apreq_use_session_key_p:
541 : : * @handle: shishi handle as allocated by shishi_init().
542 : : * @apreq: AP-REQ as allocated by shishi_apreq().
543 : : *
544 : : * Return non-0 iff the "Use session key" option is set in the AP-REQ.
545 : : *
546 : : * Return value: Returns SHISHI_OK iff successful.
547 : : **/
548 : : int
549 : 0 : shishi_apreq_use_session_key_p (Shishi * handle, Shishi_asn1 apreq)
550 : : {
551 : 0 : uint32_t options = 0;
552 : :
553 : 0 : shishi_apreq_options (handle, apreq, &options);
554 : :
555 : 0 : return options & SHISHI_APOPTIONS_USE_SESSION_KEY;
556 : : }
557 : :
558 : : /**
559 : : * shishi_apreq_mutual_required_p:
560 : : * @handle: shishi handle as allocated by shishi_init().
561 : : * @apreq: AP-REQ as allocated by shishi_apreq().
562 : : *
563 : : * Return non-0 iff the "Mutual required" option is set in the AP-REQ.
564 : : *
565 : : * Return value: Returns SHISHI_OK iff successful.
566 : : **/
567 : : int
568 : 0 : shishi_apreq_mutual_required_p (Shishi * handle, Shishi_asn1 apreq)
569 : : {
570 : 0 : uint32_t options = 0;
571 : :
572 : 0 : shishi_apreq_options (handle, apreq, &options);
573 : :
574 : 0 : return options & SHISHI_APOPTIONS_MUTUAL_REQUIRED;
575 : : }
576 : :
577 : : /**
578 : : * shishi_apreq_options_set:
579 : : * @handle: shishi handle as allocated by shishi_init().
580 : : * @apreq: AP-REQ as allocated by shishi_apreq().
581 : : * @options: Options to set in AP-REQ.
582 : : *
583 : : * Set the AP-Options in AP-REQ to indicate integer.
584 : : *
585 : : * Return value: Returns SHISHI_OK iff successful.
586 : : **/
587 : : int
588 : 0 : shishi_apreq_options_set (Shishi * handle, Shishi_asn1 apreq,
589 : : uint32_t options)
590 : : {
591 : : int res;
592 : :
593 : 0 : res = shishi_asn1_write_bitstring (handle, apreq, "ap-options", options);
594 [ # # ]: 0 : if (res != SHISHI_OK)
595 : 0 : return res;
596 : :
597 : 0 : return SHISHI_OK;
598 : : }
599 : :
600 : : /**
601 : : * shishi_apreq_options_add:
602 : : * @handle: shishi handle as allocated by shishi_init().
603 : : * @apreq: AP-REQ as allocated by shishi_apreq().
604 : : * @option: Options to add in AP-REQ.
605 : : *
606 : : * Add the AP-Options in AP-REQ. Options not set in input parameter
607 : : * @option are preserved in the AP-REQ.
608 : : *
609 : : * Return value: Returns SHISHI_OK iff successful.
610 : : **/
611 : : int
612 : 0 : shishi_apreq_options_add (Shishi * handle, Shishi_asn1 apreq, uint32_t option)
613 : : {
614 : : uint32_t options;
615 : : int res;
616 : :
617 : 0 : res = shishi_apreq_options (handle, apreq, &options);
618 [ # # ]: 0 : if (res != SHISHI_OK)
619 : 0 : return res;
620 : :
621 : 0 : options |= option;
622 : :
623 : 0 : res = shishi_apreq_options_set (handle, apreq, options);
624 [ # # ]: 0 : if (res != SHISHI_OK)
625 : 0 : return res;
626 : :
627 : 0 : return SHISHI_OK;
628 : : }
629 : :
630 : : /**
631 : : * shishi_apreq_options_remove:
632 : : * @handle: shishi handle as allocated by shishi_init().
633 : : * @apreq: AP-REQ as allocated by shishi_apreq().
634 : : * @option: Options to remove from AP-REQ.
635 : : *
636 : : * Remove the AP-Options from AP-REQ. Options not set in input
637 : : * parameter @option are preserved in the AP-REQ.
638 : : *
639 : : * Return value: Returns SHISHI_OK iff successful.
640 : : **/
641 : : int
642 : 0 : shishi_apreq_options_remove (Shishi * handle,
643 : : Shishi_asn1 apreq, uint32_t option)
644 : : {
645 : : uint32_t options;
646 : : int res;
647 : :
648 : 0 : res = shishi_apreq_options (handle, apreq, &options);
649 [ # # ]: 0 : if (res != SHISHI_OK)
650 : 0 : return res;
651 : :
652 : 0 : options &= ~(options & option);
653 : :
654 : 0 : res = shishi_apreq_options_set (handle, apreq, options);
655 [ # # ]: 0 : if (res != SHISHI_OK)
656 : 0 : return res;
657 : :
658 : 0 : return SHISHI_OK;
659 : : }
660 : :
661 : : /**
662 : : * shishi_apreq_get_authenticator_etype:
663 : : * @handle: shishi handle as allocated by shishi_init().
664 : : * @apreq: AP-REQ variable to get value from.
665 : : * @etype: output variable that holds the value.
666 : : *
667 : : * Extract AP-REQ.authenticator.etype.
668 : : *
669 : : * Return value: Returns SHISHI_OK iff successful.
670 : : **/
671 : : int
672 : 0 : shishi_apreq_get_authenticator_etype (Shishi * handle,
673 : : Shishi_asn1 apreq, int32_t * etype)
674 : : {
675 : 0 : return shishi_asn1_read_int32 (handle, apreq, "authenticator.etype", etype);
676 : : }
677 : :
678 : : /**
679 : : * shishi_apreq_get_ticket:
680 : : * @handle: shishi handle as allocated by shishi_init().
681 : : * @apreq: AP-REQ variable to get ticket from.
682 : : * @ticket: output variable to hold extracted ticket.
683 : : *
684 : : * Extract ticket from AP-REQ.
685 : : *
686 : : * Return value: Returns SHISHI_OK iff successful.
687 : : **/
688 : : int
689 : 0 : shishi_apreq_get_ticket (Shishi * handle,
690 : : Shishi_asn1 apreq, Shishi_asn1 * ticket)
691 : : {
692 : : char *buf;
693 : : char *format;
694 : : size_t buflen, i, n;
695 : : int res;
696 : :
697 : : /* there's GOT to be an easier way to do this */
698 : :
699 : 0 : *ticket = shishi_ticket (handle);
700 [ # # ]: 0 : if (!*ticket)
701 : 0 : return SHISHI_ASN1_ERROR;
702 : :
703 : 0 : res = shishi_asn1_read (handle, apreq, "ticket.tkt-vno", &buf, &buflen);
704 [ # # ]: 0 : if (res != SHISHI_OK)
705 : 0 : goto error;
706 : :
707 : 0 : res = shishi_asn1_write (handle, *ticket, "tkt-vno", buf, buflen);
708 : 0 : free (buf);
709 [ # # ]: 0 : if (res != SHISHI_OK)
710 : 0 : goto error;
711 : :
712 : 0 : res = shishi_asn1_read (handle, apreq, "ticket.realm", &buf, &buflen);
713 [ # # ]: 0 : if (res != SHISHI_OK)
714 : 0 : goto error;
715 : :
716 : 0 : res = shishi_asn1_write (handle, *ticket, "realm", buf, buflen);
717 : 0 : free (buf);
718 [ # # ]: 0 : if (res != SHISHI_OK)
719 : 0 : goto error;
720 : :
721 : 0 : res = shishi_asn1_read (handle, apreq, "ticket.sname.name-type",
722 : : &buf, &buflen);
723 [ # # ]: 0 : if (res != SHISHI_OK)
724 : 0 : goto error;
725 : :
726 : 0 : res = shishi_asn1_write (handle, *ticket, "sname.name-type", buf, buflen);
727 : 0 : free (buf);
728 [ # # ]: 0 : if (res != SHISHI_OK)
729 : 0 : goto error;
730 : :
731 : 0 : res = shishi_asn1_number_of_elements (handle, apreq,
732 : : "ticket.sname.name-string", &n);
733 [ # # ]: 0 : if (res != SHISHI_OK)
734 : 0 : goto error;
735 : :
736 [ # # ]: 0 : for (i = 1; i <= n; i++)
737 : : {
738 : 0 : res = shishi_asn1_write (handle, *ticket, "sname.name-string",
739 : : "NEW", 1);
740 [ # # ]: 0 : if (res != SHISHI_OK)
741 : 0 : goto error;
742 : :
743 : 0 : asprintf (&format, "ticket.sname.name-string.?%d", i);
744 : 0 : res = shishi_asn1_read (handle, apreq, format, &buf, &buflen);
745 : 0 : free (format);
746 [ # # ]: 0 : if (res != SHISHI_OK)
747 : 0 : goto error;
748 : :
749 : 0 : asprintf (&format, "sname.name-string.?%d", i);
750 : 0 : res = shishi_asn1_write (handle, *ticket, format, buf, buflen);
751 : 0 : free (format);
752 : 0 : free (buf);
753 [ # # ]: 0 : if (res != SHISHI_OK)
754 : 0 : goto error;
755 : : }
756 : :
757 : 0 : res = shishi_asn1_read (handle, apreq, "ticket.enc-part.etype",
758 : : &buf, &buflen);
759 [ # # ]: 0 : if (res != SHISHI_OK)
760 : 0 : goto error;
761 : :
762 : 0 : res = shishi_asn1_write (handle, *ticket, "enc-part.etype", buf, buflen);
763 : 0 : free (buf);
764 [ # # ]: 0 : if (res != SHISHI_OK)
765 : 0 : goto error;
766 : :
767 : 0 : res = shishi_asn1_read (handle, apreq, "ticket.enc-part.kvno",
768 : : &buf, &buflen);
769 [ # # # # ]: 0 : if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT)
770 : 0 : goto error;
771 : :
772 [ # # ]: 0 : if (res == SHISHI_ASN1_NO_ELEMENT)
773 : 0 : res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", NULL, 0);
774 : : else
775 : : {
776 : 0 : res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", buf, buflen);
777 : 0 : free (buf);
778 : : }
779 [ # # ]: 0 : if (res != SHISHI_OK)
780 : 0 : goto error;
781 : :
782 : 0 : res = shishi_asn1_read (handle, apreq, "ticket.enc-part.cipher",
783 : : &buf, &buflen);
784 [ # # ]: 0 : if (res != SHISHI_OK)
785 : 0 : goto error;
786 : :
787 : 0 : res = shishi_asn1_write (handle, *ticket, "enc-part.cipher", buf, buflen);
788 : 0 : free (buf);
789 [ # # ]: 0 : if (res != SHISHI_OK)
790 : 0 : goto error;
791 : :
792 : 0 : return SHISHI_OK;
793 : :
794 : : error:
795 : 0 : shishi_asn1_done (handle, *ticket);
796 : 0 : return res;
797 : : }
798 : :
799 : : int
800 : 0 : shishi_apreq_decrypt (Shishi * handle,
801 : : Shishi_asn1 apreq,
802 : : Shishi_key * key,
803 : : int keyusage, Shishi_asn1 * authenticator)
804 : : {
805 : : int res;
806 : : int i;
807 : : char *buf;
808 : : size_t buflen;
809 : : char *cipher;
810 : : size_t cipherlen;
811 : : int etype;
812 : :
813 : 0 : res = shishi_apreq_get_authenticator_etype (handle, apreq, &etype);
814 [ # # ]: 0 : if (res != SHISHI_OK)
815 : 0 : return res;
816 : :
817 [ # # ]: 0 : if (etype != shishi_key_type (key))
818 : 0 : return SHISHI_APREQ_BAD_KEYTYPE;
819 : :
820 : 0 : res = shishi_asn1_read (handle, apreq, "authenticator.cipher",
821 : : &cipher, &cipherlen);
822 [ # # ]: 0 : if (res != SHISHI_OK)
823 : 0 : return res;
824 : :
825 : 0 : res = shishi_decrypt (handle, key, keyusage,
826 : : cipher, cipherlen, &buf, &buflen);
827 : 0 : free (cipher);
828 [ # # ]: 0 : if (res != SHISHI_OK)
829 : : {
830 : 0 : shishi_error_printf (handle,
831 : : "decrypt fail, most likely wrong password\n");
832 : 0 : return SHISHI_APREQ_DECRYPT_FAILED;
833 : : }
834 : :
835 : : /* The crypto is so 1980; no length indicator. Trim off pad bytes
836 : : until we can parse it. */
837 [ # # ]: 0 : for (i = 0; i < 8; i++)
838 : : {
839 [ # # ]: 0 : if (VERBOSEASN1 (handle))
840 : 0 : printf ("Trying with %d pad in enckdcrep...\n", i);
841 : :
842 : 0 : *authenticator = shishi_der2asn1_authenticator (handle, &buf[0],
843 : : buflen - i);
844 [ # # ]: 0 : if (*authenticator != NULL)
845 : 0 : break;
846 : : }
847 : :
848 [ # # ]: 0 : if (*authenticator == NULL)
849 : : {
850 : 0 : shishi_error_printf (handle, "Could not DER decode Authenticator. "
851 : : "Password probably correct (decrypt ok) though\n");
852 : 0 : return SHISHI_ASN1_ERROR;
853 : : }
854 : :
855 : 0 : return SHISHI_OK;
856 : : }
|