Change GPLv2+ to GPLv3+.
[shishi.git] / lib / apreq.c
blob3c2a530b590ac689a45418deea44a226ba63f736
1 /* apreq.c --- AP-REQ functions.
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 3 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
22 #include "internal.h"
24 /* Get _shishi_print_armored_data, etc. */
25 #include "diskio.h"
27 #define SHISHI_APREQ_DEFAULT_PVNO "5"
28 #define SHISHI_APREQ_DEFAULT_PVNO_LEN 0
29 #define SHISHI_APREQ_DEFAULT_MSG_TYPE "14" /* KRB_AP_REQ */
30 #define SHISHI_APREQ_DEFAULT_MSG_TYPE_LEN 0
31 #define SHISHI_APREQ_DEFAULT_AP_OPTIONS "\x00\x00\x00\x00"
32 #define SHISHI_APREQ_DEFAULT_AP_OPTIONS_LEN 32
33 #define SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO "5"
34 #define SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO_LEN 0
35 #define SHISHI_APREQ_DEFAULT_TICKET_REALM ""
36 #define SHISHI_APREQ_DEFAULT_TICKET_REALM_LEN 0
37 #define SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE "1" /* SHISHI_NT_PRINCIPAL */
38 #define SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE_LEN 0
39 #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE "0"
40 #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE_LEN 0
41 #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO "0"
42 #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO_LEN 0
43 #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER ""
44 #define SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER_LEN 0
45 #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE "0"
46 #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE_LEN 0
47 #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO "1"
48 #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO_LEN 0
49 #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER ""
50 #define SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER_LEN 0
52 /**
53 * shishi_apreq:
54 * @handle: shishi handle as allocated by shishi_init().
56 * This function creates a new AP-REQ, populated with some default
57 * values.
59 * Return value: Returns the AP-REQ or NULL on failure.
60 **/
61 Shishi_asn1
62 shishi_apreq (Shishi * handle)
64 Shishi_asn1 node;
65 int res;
67 node = shishi_asn1_apreq (handle);
68 if (!node)
69 goto error;
71 res = shishi_asn1_write (handle, node, "pvno",
72 SHISHI_APREQ_DEFAULT_PVNO,
73 SHISHI_APREQ_DEFAULT_PVNO_LEN);
74 if (res != SHISHI_OK)
75 goto error;
77 res = shishi_asn1_write (handle, node, "msg-type",
78 SHISHI_APREQ_DEFAULT_MSG_TYPE,
79 SHISHI_APREQ_DEFAULT_MSG_TYPE_LEN);
80 if (res != SHISHI_OK)
81 goto error;
83 res = shishi_asn1_write (handle, node, "ap-options",
84 SHISHI_APREQ_DEFAULT_AP_OPTIONS,
85 SHISHI_APREQ_DEFAULT_AP_OPTIONS_LEN);
86 if (res != SHISHI_OK)
87 goto error;
89 res = shishi_asn1_write (handle, node, "ticket.tkt-vno",
90 SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO,
91 SHISHI_APREQ_DEFAULT_TICKET_TKT_VNO_LEN);
92 if (res != SHISHI_OK)
93 goto error;
95 res = shishi_asn1_write (handle, node, "ticket.realm",
96 SHISHI_APREQ_DEFAULT_TICKET_REALM,
97 SHISHI_APREQ_DEFAULT_TICKET_REALM_LEN);
98 if (res != SHISHI_OK)
99 goto error;
101 res = shishi_asn1_write (handle, node, "ticket.realm",
102 SHISHI_APREQ_DEFAULT_TICKET_REALM,
103 SHISHI_APREQ_DEFAULT_TICKET_REALM_LEN);
104 if (res != SHISHI_OK)
105 goto error;
107 res = shishi_asn1_write (handle, node, "ticket.sname.name-type",
108 SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE,
109 SHISHI_APREQ_DEFAULT_TICKET_SNAME_NAME_TYPE_LEN);
110 if (res != SHISHI_OK)
111 goto error;
113 res = shishi_asn1_write (handle, node, "ticket.enc-part.etype",
114 SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE,
115 SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_ETYPE_LEN);
116 if (res != SHISHI_OK)
117 goto error;
119 res = shishi_asn1_write (handle, node, "ticket.enc-part.kvno",
120 SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO,
121 SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_KVNO_LEN);
122 if (res != SHISHI_OK)
123 goto error;
125 res = shishi_asn1_write (handle, node, "ticket.enc-part.cipher",
126 SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER,
127 SHISHI_APREQ_DEFAULT_TICKET_ENC_PART_CIPHER_LEN);
128 if (res != SHISHI_OK)
129 goto error;
131 res = shishi_asn1_write (handle, node, "authenticator.etype",
132 SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE,
133 SHISHI_APREQ_DEFAULT_AUTHENTICATOR_ETYPE_LEN);
134 if (res != SHISHI_OK)
135 goto error;
137 res = shishi_asn1_write (handle, node, "authenticator.kvno",
138 SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO,
139 SHISHI_APREQ_DEFAULT_AUTHENTICATOR_KVNO_LEN);
140 if (res != SHISHI_OK)
141 goto error;
143 res = shishi_asn1_write (handle, node, "authenticator.cipher",
144 SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER,
145 SHISHI_APREQ_DEFAULT_AUTHENTICATOR_CIPHER_LEN);
146 if (res != SHISHI_OK)
147 goto error;
149 return node;
151 error:
152 if (node)
153 shishi_asn1_done (handle, node);
154 return NULL;
158 * shishi_apreq_print:
159 * @handle: shishi handle as allocated by shishi_init().
160 * @fh: file handle open for writing.
161 * @apreq: AP-REQ to print.
163 * Print ASCII armored DER encoding of AP-REQ to file.
165 * Return value: Returns SHISHI_OK iff successful.
168 shishi_apreq_print (Shishi * handle, FILE * fh, Shishi_asn1 apreq)
170 return _shishi_print_armored_data (handle, fh, apreq, "AP-REQ", NULL);
174 * shishi_apreq_save:
175 * @handle: shishi handle as allocated by shishi_init().
176 * @fh: file handle open for writing.
177 * @apreq: AP-REQ to save.
179 * Save DER encoding of AP-REQ to file.
181 * Return value: Returns SHISHI_OK iff successful.
184 shishi_apreq_save (Shishi * handle, FILE * fh, Shishi_asn1 apreq)
186 return _shishi_save_data (handle, fh, apreq, "AP-REQ");
190 * shishi_apreq_to_file:
191 * @handle: shishi handle as allocated by shishi_init().
192 * @apreq: AP-REQ to save.
193 * @filetype: input variable specifying type of file to be written,
194 * see Shishi_filetype.
195 * @filename: input variable with filename to write to.
197 * Write AP-REQ to file in specified TYPE. The file will be
198 * truncated if it exists.
200 * Return value: Returns SHISHI_OK iff successful.
203 shishi_apreq_to_file (Shishi * handle, Shishi_asn1 apreq,
204 int filetype, const char *filename)
206 FILE *fh;
207 int res;
209 if (VERBOSE (handle))
210 printf (_("Writing AP-REQ to %s...\n"), filename);
212 fh = fopen (filename, "w");
213 if (fh == NULL)
214 return SHISHI_FOPEN_ERROR;
216 if (VERBOSE (handle))
217 printf (_("Writing AP-REQ in %s format...\n"),
218 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
220 if (filetype == SHISHI_FILETYPE_TEXT)
221 res = shishi_apreq_print (handle, fh, apreq);
222 else
223 res = shishi_apreq_save (handle, fh, apreq);
224 if (res != SHISHI_OK)
225 return res;
227 res = fclose (fh);
228 if (res != 0)
229 return SHISHI_IO_ERROR;
231 if (VERBOSE (handle))
232 printf (_("Writing AP-REQ to %s...done\n"), filename);
234 return SHISHI_OK;
238 * shishi_apreq_parse:
239 * @handle: shishi handle as allocated by shishi_init().
240 * @fh: file handle open for reading.
241 * @apreq: output variable with newly allocated AP-REQ.
243 * Read ASCII armored DER encoded AP-REQ from file and populate given
244 * variable.
246 * Return value: Returns SHISHI_OK iff successful.
249 shishi_apreq_parse (Shishi * handle, FILE * fh, Shishi_asn1 * apreq)
251 return _shishi_apreq_input (handle, fh, apreq, 0);
255 * shishi_apreq_read:
256 * @handle: shishi handle as allocated by shishi_init().
257 * @fh: file handle open for reading.
258 * @apreq: output variable with newly allocated AP-REQ.
260 * Read DER encoded AP-REQ from file and populate given variable.
262 * Return value: Returns SHISHI_OK iff successful.
265 shishi_apreq_read (Shishi * handle, FILE * fh, Shishi_asn1 * apreq)
267 return _shishi_apreq_input (handle, fh, apreq, 1);
271 * shishi_apreq_from_file:
272 * @handle: shishi handle as allocated by shishi_init().
273 * @apreq: output variable with newly allocated AP-REQ.
274 * @filetype: input variable specifying type of file to be read,
275 * see Shishi_filetype.
276 * @filename: input variable with filename to read from.
278 * Read AP-REQ from file in specified TYPE.
280 * Return value: Returns SHISHI_OK iff successful.
283 shishi_apreq_from_file (Shishi * handle, Shishi_asn1 * apreq,
284 int filetype, const char *filename)
286 int res;
287 FILE *fh;
289 if (VERBOSE (handle))
290 printf (_("Reading AP-REQ from %s...\n"), filename);
292 fh = fopen (filename, "r");
293 if (fh == NULL)
294 return SHISHI_FOPEN_ERROR;
296 if (VERBOSE (handle))
297 printf (_("Reading AP-REQ in %s format...\n"),
298 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
300 if (filetype == SHISHI_FILETYPE_TEXT)
301 res = shishi_apreq_parse (handle, fh, apreq);
302 else
303 res = shishi_apreq_read (handle, fh, apreq);
304 if (res != SHISHI_OK)
305 return res;
307 res = fclose (fh);
308 if (res != 0)
309 return SHISHI_IO_ERROR;
311 if (VERBOSE (handle))
312 printf (_("Reading AP-REQ from %s...done\n"), filename);
314 return SHISHI_OK;
318 * shishi_apreq_set_authenticator:
319 * @handle: shishi handle as allocated by shishi_init().
320 * @apreq: AP-REQ to add authenticator field to.
321 * @etype: encryption type used to encrypt authenticator.
322 * @kvno: version of the key used to encrypt authenticator.
323 * @buf: input array with encrypted authenticator.
324 * @buflen: size of input array with encrypted authenticator.
326 * Set the encrypted authenticator field in the AP-REP. The encrypted
327 * data is usually created by calling shishi_encrypt() on the DER
328 * encoded authenticator. To save time, you may want to use
329 * shishi_apreq_add_authenticator() instead, which calculates the
330 * encrypted data and calls this function in one step.
332 * Return value: Returns SHISHI_OK on success.
335 shishi_apreq_set_authenticator (Shishi * handle,
336 Shishi_asn1 apreq,
337 int32_t etype, uint32_t kvno,
338 const char *buf, size_t buflen)
340 int res;
342 res = shishi_asn1_write (handle, apreq, "authenticator.cipher",
343 buf, buflen);
344 if (res != SHISHI_OK)
345 return res;
347 if (kvno == UINT32_MAX)
348 res = shishi_asn1_write (handle, apreq, "authenticator.kvno", NULL, 0);
349 else
350 res = shishi_asn1_write_int32 (handle, apreq, "authenticator.kvno", kvno);
351 if (res != SHISHI_OK)
352 return res;
354 res = shishi_asn1_write_int32 (handle, apreq, "authenticator.etype", etype);
355 if (res != SHISHI_OK)
356 return res;
358 return SHISHI_OK;
362 * shishi_apreq_add_authenticator:
363 * @handle: shishi handle as allocated by shishi_init().
364 * @apreq: AP-REQ to add authenticator field to.
365 * @key: key to to use for encryption.
366 * @keyusage: cryptographic key usage value to use in encryption.
367 * @authenticator: authenticator as allocated by shishi_authenticator().
369 * Encrypts DER encoded authenticator using key and store it in the
370 * AP-REQ.
372 * Return value: Returns SHISHI_OK iff successful.
375 shishi_apreq_add_authenticator (Shishi * handle,
376 Shishi_asn1 apreq,
377 Shishi_key * key,
378 int keyusage, Shishi_asn1 authenticator)
380 int res;
381 char *buf;
382 size_t buflen;
383 char *der;
384 size_t derlen;
386 res = shishi_asn1_to_der (handle, authenticator, &der, &derlen);
387 if (res != SHISHI_OK)
389 shishi_error_printf (handle, "Could not DER encode authenticator: %s\n",
390 shishi_strerror (res));
391 return res;
394 res = shishi_encrypt (handle, key, keyusage, der, derlen, &buf, &buflen);
396 free (der);
398 if (res != SHISHI_OK)
400 shishi_error_printf (handle, "Cannot encrypt authenticator.\n");
401 return res;
404 res = shishi_apreq_set_authenticator (handle, apreq, shishi_key_type (key),
405 shishi_key_version (key),
406 buf, buflen);
408 return res;
412 * shishi_apreq_set_ticket:
413 * @handle: shishi handle as allocated by shishi_init().
414 * @apreq: AP-REQ to add ticket field to.
415 * @ticket: input ticket to copy into AP-REQ ticket field.
417 * Copy ticket into AP-REQ.
419 * Return value: Returns SHISHI_OK iff successful.
422 shishi_apreq_set_ticket (Shishi * handle, Shishi_asn1 apreq,
423 Shishi_asn1 ticket)
425 int res;
426 char *format;
427 char *buf;
428 size_t buflen, i, n;
430 res = shishi_asn1_read (handle, ticket, "tkt-vno", &buf, &buflen);
431 if (res != SHISHI_OK)
432 return res;
434 res = shishi_asn1_write (handle, apreq, "ticket.tkt-vno", buf, buflen);
435 free (buf);
436 if (res != SHISHI_OK)
437 return res;
439 res = shishi_asn1_read (handle, ticket, "realm", &buf, &buflen);
440 if (res != SHISHI_OK)
441 return res;
443 res = shishi_asn1_write (handle, apreq, "ticket.realm", buf, buflen);
444 free (buf);
445 if (res != SHISHI_OK)
446 return res;
448 res = shishi_asn1_read (handle, ticket, "sname.name-type", &buf, &buflen);
449 if (res != SHISHI_OK)
450 return res;
452 res = shishi_asn1_write (handle, apreq, "ticket.sname.name-type",
453 buf, buflen);
454 free (buf);
455 if (res != SHISHI_OK)
456 return res;
458 res = shishi_asn1_number_of_elements (handle, ticket,
459 "sname.name-string", &n);
460 if (res != SHISHI_OK)
461 return res;
463 for (i = 1; i <= n; i++)
465 res = shishi_asn1_write (handle, apreq,
466 "ticket.sname.name-string", "NEW", 1);
467 if (res != SHISHI_OK)
468 return res;
470 asprintf (&format, "sname.name-string.?%d", i);
471 res = shishi_asn1_read (handle, ticket, format, &buf, &buflen);
472 free (format);
473 if (res != SHISHI_OK)
474 return res;
476 asprintf (&format, "ticket.sname.name-string.?%d", i);
477 res = shishi_asn1_write (handle, apreq, format, buf, buflen);
478 free (format);
479 free (buf);
480 if (res != SHISHI_OK)
481 return res;
484 res = shishi_asn1_read (handle, ticket, "enc-part.etype", &buf, &buflen);
485 if (res != SHISHI_OK)
486 return res;
488 res = shishi_asn1_write (handle, apreq, "ticket.enc-part.etype",
489 buf, buflen);
490 free (buf);
491 if (res != SHISHI_OK)
492 return res;
494 res = shishi_asn1_read (handle, ticket, "enc-part.kvno", &buf, &buflen);
495 if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT)
496 return res;
498 if (res == SHISHI_ASN1_NO_ELEMENT)
499 res = shishi_asn1_write (handle, apreq, "ticket.enc-part.kvno", NULL, 0);
500 else
502 res = shishi_asn1_write (handle, apreq, "ticket.enc-part.kvno",
503 buf, buflen);
504 free (buf);
506 if (res != SHISHI_OK)
507 return res;
509 res = shishi_asn1_read (handle, ticket, "enc-part.cipher", &buf, &buflen);
510 if (res != SHISHI_OK)
511 return res;
513 res = shishi_asn1_write (handle, apreq, "ticket.enc-part.cipher",
514 buf, buflen);
515 free (buf);
516 if (res != SHISHI_OK)
517 return res;
519 return SHISHI_OK;
523 * shishi_apreq_options:
524 * @handle: shishi handle as allocated by shishi_init().
525 * @apreq: AP-REQ to get options from.
526 * @flags: Output integer containing options from AP-REQ.
528 * Extract the AP-Options from AP-REQ into output integer.
530 * Return value: Returns SHISHI_OK iff successful.
533 shishi_apreq_options (Shishi * handle, Shishi_asn1 apreq, uint32_t * flags)
535 return shishi_asn1_read_bitstring (handle, apreq, "ap-options", flags);
539 * shishi_apreq_use_session_key_p:
540 * @handle: shishi handle as allocated by shishi_init().
541 * @apreq: AP-REQ as allocated by shishi_apreq().
543 * Return non-0 iff the "Use session key" option is set in the AP-REQ.
545 * Return value: Returns SHISHI_OK iff successful.
548 shishi_apreq_use_session_key_p (Shishi * handle, Shishi_asn1 apreq)
550 uint32_t options = 0;
552 shishi_apreq_options (handle, apreq, &options);
554 return options & SHISHI_APOPTIONS_USE_SESSION_KEY;
558 * shishi_apreq_mutual_required_p:
559 * @handle: shishi handle as allocated by shishi_init().
560 * @apreq: AP-REQ as allocated by shishi_apreq().
562 * Return non-0 iff the "Mutual required" option is set in the AP-REQ.
564 * Return value: Returns SHISHI_OK iff successful.
567 shishi_apreq_mutual_required_p (Shishi * handle, Shishi_asn1 apreq)
569 uint32_t options = 0;
571 shishi_apreq_options (handle, apreq, &options);
573 return options & SHISHI_APOPTIONS_MUTUAL_REQUIRED;
577 * shishi_apreq_options_set:
578 * @handle: shishi handle as allocated by shishi_init().
579 * @apreq: AP-REQ as allocated by shishi_apreq().
580 * @options: Options to set in AP-REQ.
582 * Set the AP-Options in AP-REQ to indicate integer.
584 * Return value: Returns SHISHI_OK iff successful.
587 shishi_apreq_options_set (Shishi * handle, Shishi_asn1 apreq,
588 uint32_t options)
590 int res;
592 res = shishi_asn1_write_bitstring (handle, apreq, "ap-options", options);
593 if (res != SHISHI_OK)
594 return res;
596 return SHISHI_OK;
600 * shishi_apreq_options_add:
601 * @handle: shishi handle as allocated by shishi_init().
602 * @apreq: AP-REQ as allocated by shishi_apreq().
603 * @option: Options to add in AP-REQ.
605 * Add the AP-Options in AP-REQ. Options not set in input parameter
606 * @option are preserved in the AP-REQ.
608 * Return value: Returns SHISHI_OK iff successful.
611 shishi_apreq_options_add (Shishi * handle, Shishi_asn1 apreq, uint32_t option)
613 uint32_t options;
614 int res;
616 res = shishi_apreq_options (handle, apreq, &options);
617 if (res != SHISHI_OK)
618 return res;
620 options |= option;
622 res = shishi_apreq_options_set (handle, apreq, options);
623 if (res != SHISHI_OK)
624 return res;
626 return SHISHI_OK;
630 * shishi_apreq_options_remove:
631 * @handle: shishi handle as allocated by shishi_init().
632 * @apreq: AP-REQ as allocated by shishi_apreq().
633 * @option: Options to remove from AP-REQ.
635 * Remove the AP-Options from AP-REQ. Options not set in input
636 * parameter @option are preserved in the AP-REQ.
638 * Return value: Returns SHISHI_OK iff successful.
641 shishi_apreq_options_remove (Shishi * handle,
642 Shishi_asn1 apreq, uint32_t option)
644 uint32_t options;
645 int res;
647 res = shishi_apreq_options (handle, apreq, &options);
648 if (res != SHISHI_OK)
649 return res;
651 options &= ~(options & option);
653 res = shishi_apreq_options_set (handle, apreq, options);
654 if (res != SHISHI_OK)
655 return res;
657 return SHISHI_OK;
661 * shishi_apreq_get_authenticator_etype:
662 * @handle: shishi handle as allocated by shishi_init().
663 * @apreq: AP-REQ variable to get value from.
664 * @etype: output variable that holds the value.
666 * Extract AP-REQ.authenticator.etype.
668 * Return value: Returns SHISHI_OK iff successful.
671 shishi_apreq_get_authenticator_etype (Shishi * handle,
672 Shishi_asn1 apreq, int32_t * etype)
674 return shishi_asn1_read_int32 (handle, apreq, "authenticator.etype", etype);
678 * shishi_apreq_get_ticket:
679 * @handle: shishi handle as allocated by shishi_init().
680 * @apreq: AP-REQ variable to get ticket from.
681 * @ticket: output variable to hold extracted ticket.
683 * Extract ticket from AP-REQ.
685 * Return value: Returns SHISHI_OK iff successful.
688 shishi_apreq_get_ticket (Shishi * handle,
689 Shishi_asn1 apreq, Shishi_asn1 * ticket)
691 char *buf;
692 char *format;
693 size_t buflen, i, n;
694 int res;
696 /* there's GOT to be an easier way to do this */
698 *ticket = shishi_ticket (handle);
699 if (!*ticket)
700 return SHISHI_ASN1_ERROR;
702 res = shishi_asn1_read (handle, apreq, "ticket.tkt-vno", &buf, &buflen);
703 if (res != SHISHI_OK)
704 goto error;
706 res = shishi_asn1_write (handle, *ticket, "tkt-vno", buf, buflen);
707 free (buf);
708 if (res != SHISHI_OK)
709 goto error;
711 res = shishi_asn1_read (handle, apreq, "ticket.realm", &buf, &buflen);
712 if (res != SHISHI_OK)
713 goto error;
715 res = shishi_asn1_write (handle, *ticket, "realm", buf, buflen);
716 free (buf);
717 if (res != SHISHI_OK)
718 goto error;
720 res = shishi_asn1_read (handle, apreq, "ticket.sname.name-type",
721 &buf, &buflen);
722 if (res != SHISHI_OK)
723 goto error;
725 res = shishi_asn1_write (handle, *ticket, "sname.name-type", buf, buflen);
726 free (buf);
727 if (res != SHISHI_OK)
728 goto error;
730 res = shishi_asn1_number_of_elements (handle, apreq,
731 "ticket.sname.name-string", &n);
732 if (res != SHISHI_OK)
733 goto error;
735 for (i = 1; i <= n; i++)
737 res = shishi_asn1_write (handle, *ticket, "sname.name-string",
738 "NEW", 1);
739 if (res != SHISHI_OK)
740 goto error;
742 asprintf (&format, "ticket.sname.name-string.?%d", i);
743 res = shishi_asn1_read (handle, apreq, format, &buf, &buflen);
744 free (format);
745 if (res != SHISHI_OK)
746 goto error;
748 asprintf (&format, "sname.name-string.?%d", i);
749 res = shishi_asn1_write (handle, *ticket, format, buf, buflen);
750 free (format);
751 free (buf);
752 if (res != SHISHI_OK)
753 goto error;
756 res = shishi_asn1_read (handle, apreq, "ticket.enc-part.etype",
757 &buf, &buflen);
758 if (res != SHISHI_OK)
759 goto error;
761 res = shishi_asn1_write (handle, *ticket, "enc-part.etype", buf, buflen);
762 free (buf);
763 if (res != SHISHI_OK)
764 goto error;
766 res = shishi_asn1_read (handle, apreq, "ticket.enc-part.kvno",
767 &buf, &buflen);
768 if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT)
769 goto error;
771 if (res == SHISHI_ASN1_NO_ELEMENT)
772 res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", NULL, 0);
773 else
775 res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", buf, buflen);
776 free (buf);
778 if (res != SHISHI_OK)
779 goto error;
781 res = shishi_asn1_read (handle, apreq, "ticket.enc-part.cipher",
782 &buf, &buflen);
783 if (res != SHISHI_OK)
784 goto error;
786 res = shishi_asn1_write (handle, *ticket, "enc-part.cipher", buf, buflen);
787 free (buf);
788 if (res != SHISHI_OK)
789 goto error;
791 return SHISHI_OK;
793 error:
794 shishi_asn1_done (handle, *ticket);
795 return res;
799 shishi_apreq_decrypt (Shishi * handle,
800 Shishi_asn1 apreq,
801 Shishi_key * key,
802 int keyusage, Shishi_asn1 * authenticator)
804 int res;
805 int i;
806 char *buf;
807 size_t buflen;
808 char *cipher;
809 size_t cipherlen;
810 int etype;
812 res = shishi_apreq_get_authenticator_etype (handle, apreq, &etype);
813 if (res != SHISHI_OK)
814 return res;
816 if (etype != shishi_key_type (key))
817 return SHISHI_APREQ_BAD_KEYTYPE;
819 res = shishi_asn1_read (handle, apreq, "authenticator.cipher",
820 &cipher, &cipherlen);
821 if (res != SHISHI_OK)
822 return res;
824 res = shishi_decrypt (handle, key, keyusage,
825 cipher, cipherlen, &buf, &buflen);
826 free (cipher);
827 if (res != SHISHI_OK)
829 shishi_error_printf (handle,
830 "decrypt fail, most likely wrong password\n");
831 return SHISHI_APREQ_DECRYPT_FAILED;
834 /* The crypto is so 1980; no length indicator. Trim off pad bytes
835 until we can parse it. */
836 for (i = 0; i < 8; i++)
838 if (VERBOSEASN1 (handle))
839 printf ("Trying with %d pad in enckdcrep...\n", i);
841 *authenticator = shishi_der2asn1_authenticator (handle, &buf[0],
842 buflen - i);
843 if (*authenticator != NULL)
844 break;
847 if (*authenticator == NULL)
849 shishi_error_printf (handle, "Could not DER decode Authenticator. "
850 "Password probably correct (decrypt ok) though\n");
851 return SHISHI_ASN1_ERROR;
854 return SHISHI_OK;