1 /* kdcreq.c --- Key distribution (AS/TGS) request functions.
2 * Copyright (C) 2002-2013 Simon Josefsson
4 * This file is part of Shishi.
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.
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.
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
25 /* Get _shishi_print_armored_data, etc. */
28 #define SHISHI_KDCREQ_DEFAULT_PVNO "5"
29 #define SHISHI_KDCREQ_DEFAULT_PVNO_LEN 0
30 #define SHISHI_AS_REQ_DEFAULT_MSG_TYPE "10"
31 #define SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN 0
32 #define SHISHI_TGS_REQ_DEFAULT_MSG_TYPE "12"
33 #define SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN 0
34 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS "\x00\x00\x00\x00"
35 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN 32
36 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE "1" /* SHISHI_NT_PRINCIPAL */
37 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN 0
40 _shishi_kdcreq (Shishi * handle, int as)
44 const char *servicebuf[3];
48 node = shishi_asn1_asreq (handle);
50 node = shishi_asn1_tgsreq (handle);
54 res = shishi_asn1_write (handle, node, "pvno",
55 SHISHI_KDCREQ_DEFAULT_PVNO,
56 SHISHI_KDCREQ_DEFAULT_PVNO_LEN);
61 res = shishi_asn1_write (handle, node, "msg-type",
62 SHISHI_AS_REQ_DEFAULT_MSG_TYPE,
63 SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN);
65 res = shishi_asn1_write (handle, node, "msg-type",
66 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE,
67 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN);
71 res = shishi_asn1_write (handle, node, "req-body.kdc-options",
72 SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS,
73 SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN);
78 res = shishi_kdcreq_set_cname (handle, node, SHISHI_NT_PRINCIPAL,
79 shishi_principal_default (handle));
81 res = shishi_asn1_write (handle, node, "req-body.cname", NULL, 0);
85 res = shishi_kdcreq_set_realm (handle, node, shishi_realm_default (handle));
89 servicebuf[0] = "krbtgt";
90 servicebuf[1] = shishi_realm_default (handle);
92 res = shishi_kdcreq_set_sname (handle, node,
93 SHISHI_NT_PRINCIPAL, servicebuf);
97 res = shishi_asn1_write (handle, node, "req-body.sname.name-type",
98 SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE,
99 SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN);
100 if (res != SHISHI_OK)
103 res = shishi_asn1_write (handle, node, "req-body.till",
104 shishi_generalize_time (handle,
106 handle->ticketlife), 0);
107 if (res != SHISHI_OK)
110 shishi_randomize (handle, 0, &nonce, sizeof (nonce));
111 nonce &= 0x7FFFFFFF; /* XXX fix _libtasn1_convert_integer. */
112 res = shishi_kdcreq_nonce_set (handle, node, nonce);
113 if (res != SHISHI_OK)
116 res = shishi_kdcreq_set_etype (handle, node, handle->clientkdcetypes,
117 handle->nclientkdcetypes);
118 if (res != SHISHI_OK)
121 res = shishi_asn1_write (handle, node, "req-body.addresses", NULL, 0);
122 if (res != SHISHI_OK)
125 res = shishi_asn1_write (handle, node,
126 "req-body.enc-authorization-data", NULL, 0);
127 if (res != SHISHI_OK)
131 shishi_asn1_write (handle, node, "req-body.additional-tickets", NULL, 0);
132 if (res != SHISHI_OK)
138 shishi_asn1_done (handle, node);
144 * @handle: shishi handle as allocated by shishi_init().
146 * This function creates a new AS-REQ, populated with some default
149 * Return value: Returns the AS-REQ or NULL on failure.
152 shishi_asreq (Shishi * handle)
154 return _shishi_kdcreq (handle, 1);
159 * @handle: shishi handle as allocated by shishi_init().
161 * This function creates a new TGS-REQ, populated with some default
164 * Return value: Returns the TGS-REQ or NULL on failure.
167 shishi_tgsreq (Shishi * handle)
169 return _shishi_kdcreq (handle, 0);
173 * shishi_kdcreq_print:
174 * @handle: shishi handle as allocated by shishi_init().
175 * @fh: file handle open for writing.
176 * @kdcreq: KDC-REQ to print.
178 * Print ASCII armored DER encoding of KDC-REQ to file.
180 * Return value: Returns SHISHI_OK iff successful.
183 shishi_kdcreq_print (Shishi * handle, FILE * fh, Shishi_asn1 kdcreq)
185 return _shishi_print_armored_data (handle, fh, kdcreq, "KDC-REQ", NULL);
189 * shishi_kdcreq_save:
190 * @handle: shishi handle as allocated by shishi_init().
191 * @fh: file handle open for writing.
192 * @kdcreq: KDC-REQ to save.
194 * Print DER encoding of KDC-REQ to file.
196 * Return value: Returns SHISHI_OK iff successful.
199 shishi_kdcreq_save (Shishi * handle, FILE * fh, Shishi_asn1 kdcreq)
201 return _shishi_save_data (handle, fh, kdcreq, "KDC-REQ");
205 * shishi_kdcreq_to_file:
206 * @handle: shishi handle as allocated by shishi_init().
207 * @kdcreq: KDC-REQ to save.
208 * @filetype: input variable specifying type of file to be written,
209 * see Shishi_filetype.
210 * @filename: input variable with filename to write to.
212 * Write KDC-REQ to file in specified TYPE. The file will be truncated
215 * Return value: Returns SHISHI_OK iff successful.
218 shishi_kdcreq_to_file (Shishi * handle, Shishi_asn1 kdcreq,
219 int filetype, const char *filename)
224 if (VERBOSE (handle))
225 printf (_("Writing KDC-REQ to %s...\n"), filename);
227 fh = fopen (filename, "w");
229 return SHISHI_FOPEN_ERROR;
231 if (VERBOSE (handle))
232 printf (_("Writing KDC-REQ in %s format...\n"),
233 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
235 if (filetype == SHISHI_FILETYPE_TEXT)
236 res = shishi_kdcreq_print (handle, fh, kdcreq);
238 res = shishi_kdcreq_save (handle, fh, kdcreq);
239 if (res != SHISHI_OK)
244 return SHISHI_IO_ERROR;
246 if (VERBOSE (handle))
247 printf (_("Writing KDC-REQ to %s...done\n"), filename);
253 * shishi_kdcreq_parse:
254 * @handle: shishi handle as allocated by shishi_init().
255 * @fh: file handle open for reading.
256 * @kdcreq: output variable with newly allocated KDC-REQ.
258 * Read ASCII armored DER encoded KDC-REQ from file and populate given
261 * Return value: Returns SHISHI_OK iff successful.
264 shishi_kdcreq_parse (Shishi * handle, FILE * fh, Shishi_asn1 * kdcreq)
266 return _shishi_kdcreq_input (handle, fh, kdcreq, 0);
270 * shishi_kdcreq_read:
271 * @handle: shishi handle as allocated by shishi_init().
272 * @fh: file handle open for reading.
273 * @kdcreq: output variable with newly allocated KDC-REQ.
275 * Read DER encoded KDC-REQ from file and populate given variable.
277 * Return value: Returns SHISHI_OK iff successful.
280 shishi_kdcreq_read (Shishi * handle, FILE * fh, Shishi_asn1 * kdcreq)
282 return _shishi_kdcreq_input (handle, fh, kdcreq, 1);
286 * shishi_kdcreq_from_file:
287 * @handle: shishi handle as allocated by shishi_init().
288 * @kdcreq: output variable with newly allocated KDC-REQ.
289 * @filetype: input variable specifying type of file to be read,
290 * see Shishi_filetype.
291 * @filename: input variable with filename to read from.
293 * Read KDC-REQ from file in specified TYPE.
295 * Return value: Returns SHISHI_OK iff successful.
298 shishi_kdcreq_from_file (Shishi * handle, Shishi_asn1 * kdcreq,
299 int filetype, const char *filename)
304 if (VERBOSE (handle))
305 printf (_("Reading KDC-REQ from %s...\n"), filename);
307 fh = fopen (filename, "r");
309 return SHISHI_FOPEN_ERROR;
311 if (VERBOSE (handle))
312 printf (_("Reading KDC-REQ in %s format...\n"),
313 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
315 if (filetype == SHISHI_FILETYPE_TEXT)
316 res = shishi_kdcreq_parse (handle, fh, kdcreq);
318 res = shishi_kdcreq_read (handle, fh, kdcreq);
319 if (res != SHISHI_OK)
324 return SHISHI_IO_ERROR;
326 if (VERBOSE (handle))
327 printf (_("Reading KDC-REQ from %s...done\n"), filename);
333 shishi_kdcreq_nonce (Shishi * handle, Shishi_asn1 kdcreq, uint32_t * nonce)
337 res = shishi_asn1_read_uint32 (handle, kdcreq, "req-body.nonce", nonce);
338 if (res != SHISHI_OK)
345 * shishi_kdcreq_nonce_set:
346 * @handle: shishi handle as allocated by shishi_init().
347 * @kdcreq: KDC-REQ variable to set client name field in.
348 * @nonce: integer nonce to store in KDC-REQ.
350 * Store nonce number field in KDC-REQ.
352 * Return value: Returns %SHISHI_OK iff successful.
355 shishi_kdcreq_nonce_set (Shishi * handle, Shishi_asn1 kdcreq, uint32_t nonce)
359 res = shishi_asn1_write_uint32 (handle, kdcreq, "req-body.nonce", nonce);
360 if (res != SHISHI_OK)
367 * shishi_kdcreq_set_cname:
368 * @handle: shishi handle as allocated by shishi_init().
369 * @kdcreq: KDC-REQ variable to set client name field in.
370 * @name_type: type of principial, see Shishi_name_type, usually
372 * @principal: input array with principal name.
374 * Set the client name field in the KDC-REQ.
376 * Return value: Returns SHISHI_OK iff successful.
379 shishi_kdcreq_set_cname (Shishi * handle,
381 Shishi_name_type name_type, const char *principal)
385 res = shishi_principal_set (handle, kdcreq, "req-body.cname", principal);
386 if (res != SHISHI_OK)
393 * shishi_kdcreq_client:
394 * @handle: Shishi library handle create by shishi_init().
395 * @kdcreq: KDC-REQ variable to get client name from.
396 * @client: pointer to newly allocated zero terminated string containing
397 * principal name. May be %NULL (to only populate @clientlen).
398 * @clientlen: pointer to length of @client on output, excluding terminating
399 * zero. May be %NULL (to only populate @client).
401 * Represent client principal name in KDC-REQ as zero-terminated
402 * string. The string is allocate by this function, and it is the
403 * responsibility of the caller to deallocate it. Note that the
404 * output length @clientlen does not include the terminating zero.
406 * Return value: Returns SHISHI_OK iff successful.
409 shishi_kdcreq_client (Shishi * handle, Shishi_asn1 kdcreq,
410 char **client, size_t * clientlen)
412 return shishi_principal_name (handle, kdcreq, "req-body.cname",
417 * shishi_asreq_clientrealm:
418 * @handle: Shishi library handle create by shishi_init().
419 * @asreq: AS-REQ variable to get client name and realm from.
420 * @client: pointer to newly allocated zero terminated string containing
421 * principal name and realm. May be %NULL (to only populate @clientlen).
422 * @clientlen: pointer to length of @client on output, excluding terminating
423 * zero. May be %NULL (to only populate @client).
425 * Convert cname and realm fields from AS-REQ to printable principal
426 * name format. The string is allocate by this function, and it is
427 * the responsibility of the caller to deallocate it. Note that the
428 * output length @clientlen does not include the terminating zero.
430 * Return value: Returns SHISHI_OK iff successful.
433 shishi_asreq_clientrealm (Shishi * handle,
435 char **client, size_t * clientlen)
437 return shishi_principal_name_realm (handle,
438 asreq, "req-body.cname",
439 asreq, "req-body.realm",
444 * shishi_kdcreq_realm:
445 * @handle: Shishi library handle create by shishi_init().
446 * @kdcreq: KDC-REQ variable to get client name from.
447 * @realm: pointer to newly allocated zero terminated string containing
448 * realm. May be %NULL (to only populate @realmlen).
449 * @realmlen: pointer to length of @realm on output, excluding terminating
450 * zero. May be %NULL (to only populate @realmlen).
452 * Get realm field in KDC-REQ as zero-terminated string. The string
453 * is allocate by this function, and it is the responsibility of the
454 * caller to deallocate it. Note that the output length @realmlen
455 * does not include the terminating zero.
457 * Return value: Returns SHISHI_OK iff successful.
460 shishi_kdcreq_realm (Shishi * handle, Shishi_asn1 kdcreq,
461 char **realm, size_t * realmlen)
463 return shishi_asn1_read_optional (handle, kdcreq, "req-body.realm",
468 shishi_kdcreq_realm_get (Shishi * handle, Shishi_asn1 kdcreq,
469 char **realm, size_t * realmlen)
471 return shishi_asn1_read_optional (handle, kdcreq, "req-body.realm",
476 * shishi_kdcreq_set_realm:
477 * @handle: shishi handle as allocated by shishi_init().
478 * @kdcreq: KDC-REQ variable to set realm field in.
479 * @realm: input array with name of realm.
481 * Set the realm field in the KDC-REQ.
483 * Return value: Returns SHISHI_OK iff successful.
486 shishi_kdcreq_set_realm (Shishi * handle, Shishi_asn1 kdcreq,
491 res = shishi_asn1_write (handle, kdcreq, "req-body.realm", realm, 0);
492 if (res != SHISHI_OK)
499 * shishi_kdcreq_server:
500 * @handle: Shishi library handle create by shishi_init().
501 * @kdcreq: KDC-REQ variable to get server name from.
502 * @server: pointer to newly allocated zero terminated string containing
503 * principal name. May be %NULL (to only populate @serverlen).
504 * @serverlen: pointer to length of @server on output, excluding terminating
505 * zero. May be %NULL (to only populate @server).
507 * Represent server principal name in KDC-REQ as zero-terminated
508 * string. The string is allocate by this function, and it is the
509 * responsibility of the caller to deallocate it. Note that the
510 * output length @serverlen does not include the terminating zero.
512 * Return value: Returns SHISHI_OK iff successful.
515 shishi_kdcreq_server (Shishi * handle, Shishi_asn1 kdcreq,
516 char **server, size_t * serverlen)
518 return shishi_principal_name (handle, kdcreq, "req-body.sname",
523 * shishi_kdcreq_set_sname:
524 * @handle: shishi handle as allocated by shishi_init().
525 * @kdcreq: KDC-REQ variable to set server name field in.
526 * @name_type: type of principial, see Shishi_name_type, usually
528 * @sname: input array with principal name.
530 * Set the server name field in the KDC-REQ.
532 * Return value: Returns SHISHI_OK iff successful.
535 shishi_kdcreq_set_sname (Shishi * handle,
537 Shishi_name_type name_type, const char *sname[])
541 res = shishi_principal_name_set (handle, kdcreq, "req-body.sname",
543 if (res != SHISHI_OK)
550 shishi_kdcreq_set_server (Shishi * handle, Shishi_asn1 req,
555 res = shishi_principal_set (handle, req, "req-body.sname", server);
556 if (res != SHISHI_OK)
563 shishi_kdcreq_set_realmserver (Shishi * handle,
564 Shishi_asn1 req, char *realm, char *server)
568 res = shishi_kdcreq_set_realm (handle, req, realm);
569 if (res != SHISHI_OK)
572 res = shishi_kdcreq_set_server (handle, req, server);
573 if (res != SHISHI_OK)
580 * shishi_kdcreq_till:
581 * @handle: Shishi library handle created by shishi_init().
582 * @kdcreq: KDC-REQ variable to get endtime from.
583 * @till: pointer to newly allocated null terminated string containing
584 * "till" field with generalized time. May be passed as %NULL
585 * to only populate @tilllen.
586 * @tilllen: pointer to length of @till for output, excluding the
587 * terminating null. Set to %NULL, only @till is populated.
589 * Get "till" field, i.e., "endtime", in KDC-REQ as a null-terminated
590 * string. The string is typically 15 characters long and is
591 * allocated by this function. It is the responsibility of the
592 * caller to deallocate it. Note that the output length @tilllen
593 * does not include the terminating zero.
595 * Return value: Returns SHISHI_OK iff successful.
598 shishi_kdcreq_till (Shishi * handle, Shishi_asn1 kdcreq,
599 char **till, size_t * tilllen)
601 return shishi_asn1_read (handle, kdcreq, "req-body.till", till, tilllen);
605 * shishi_kdcreq_tillc:
606 * @handle: Shishi library handle created by shishi_init().
607 * @kdcreq: KDC-REQ variable to get "till" field from.
609 * Extract C time corresponding to the "till" field.
611 * Return value: Returns the C time interpretation of the "till"
615 shishi_kdcreq_tillc (Shishi * handle, Shishi_asn1 kdcreq)
619 time_t t = (time_t) - 1;
622 res = shishi_kdcreq_till (handle, kdcreq, &till, &tilllen);
623 if (res != SHISHI_OK)
626 if (tilllen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
627 t = shishi_generalize_ctime (handle, till);
635 * shishi_kdcreq_etype:
636 * @handle: shishi handle as allocated by shishi_init().
637 * @kdcreq: KDC-REQ variable to get etype field from.
638 * @etype: output encryption type.
639 * @netype: element number to return.
641 * Return the netype:th encryption type from KDC-REQ. The first etype
644 * Return value: Returns SHISHI_OK iff etype successful set.
647 shishi_kdcreq_etype (Shishi * handle,
648 Shishi_asn1 kdcreq, int32_t * etype, int netype)
653 asprintf (&buf, "req-body.etype.?%d", netype);
654 res = shishi_asn1_read_int32 (handle, kdcreq, buf, etype);
655 if (res != SHISHI_OK)
662 * shishi_kdcreq_set_etype:
663 * @handle: shishi handle as allocated by shishi_init().
664 * @kdcreq: KDC-REQ variable to set etype field in.
665 * @etype: input array with encryption types.
666 * @netype: number of elements in input array with encryption types.
668 * Set the list of supported or wanted encryption types in the
669 * request. The list should be sorted in priority order.
671 * Return value: Returns SHISHI_OK iff successful.
674 shishi_kdcreq_set_etype (Shishi * handle,
675 Shishi_asn1 kdcreq, int32_t * etype, int netype)
681 res = shishi_asn1_write (handle, kdcreq, "req-body.etype", NULL, 0);
682 if (res != SHISHI_OK)
685 for (i = 1; i <= netype; i++)
687 res = shishi_asn1_write (handle, kdcreq, "req-body.etype", "NEW", 1);
688 if (res != SHISHI_OK)
691 asprintf (&buf, "req-body.etype.?%d", i);
692 res = shishi_asn1_write_int32 (handle, kdcreq, buf, etype[i - 1]);
694 if (res != SHISHI_OK)
702 * shishi_kdcreq_options:
703 * @handle: shishi handle as allocated by shishi_init().
704 * @kdcreq: KDC-REQ variable to get kdc-options field from.
705 * @flags: pointer to output integer with flags.
707 * Extract KDC-Options from KDC-REQ.
709 * Return value: Returns SHISHI_OK iff successful.
712 shishi_kdcreq_options (Shishi * handle, Shishi_asn1 kdcreq, uint32_t * flags)
714 return shishi_asn1_read_bitstring (handle, kdcreq,
715 "req-body.kdc-options", flags);
719 * shishi_kdcreq_forwardable_p:
720 * @handle: shishi handle as allocated by shishi_init().
721 * @kdcreq: KDC-REQ variable to get kdc-options field from.
723 * Determine if KDC-Option forwardable flag is set.
725 * The FORWARDABLE option indicates that the ticket to be issued is to
726 * have its forwardable flag set. It may only be set on the initial
727 * request, or in a subsequent request if the ticket-granting ticket
728 * on which it is based is also forwardable.
730 * Return value: Returns non-0 iff forwardable flag is set in KDC-REQ.
733 shishi_kdcreq_forwardable_p (Shishi * handle, Shishi_asn1 kdcreq)
735 uint32_t options = 0;
737 shishi_kdcreq_options (handle, kdcreq, &options);
739 return options & SHISHI_KDCOPTIONS_FORWARDABLE;
743 * shishi_kdcreq_forwarded_p:
744 * @handle: shishi handle as allocated by shishi_init().
745 * @kdcreq: KDC-REQ variable to get kdc-options field from.
747 * Determine if KDC-Option forwarded flag is set.
749 * The FORWARDED option is only specified in a request to the
750 * ticket-granting server and will only be honored if the
751 * ticket-granting ticket in the request has its FORWARDABLE bit
752 * set. This option indicates that this is a request for
753 * forwarding. The address(es) of the host from which the resulting
754 * ticket is to be valid are included in the addresses field of the
757 * Return value: Returns non-0 iff forwarded flag is set in KDC-REQ.
760 shishi_kdcreq_forwarded_p (Shishi * handle, Shishi_asn1 kdcreq)
762 uint32_t options = 0;
764 shishi_kdcreq_options (handle, kdcreq, &options);
766 return options & SHISHI_KDCOPTIONS_FORWARDED;
770 * shishi_kdcreq_proxiable_p:
771 * @handle: shishi handle as allocated by shishi_init().
772 * @kdcreq: KDC-REQ variable to get kdc-options field from.
774 * Determine if KDC-Option proxiable flag is set.
776 * The PROXIABLE option indicates that the ticket to be issued is to
777 * have its proxiable flag set. It may only be set on the initial
778 * request, or in a subsequent request if the ticket-granting ticket
779 * on which it is based is also proxiable.
781 * Return value: Returns non-0 iff proxiable flag is set in KDC-REQ.
784 shishi_kdcreq_proxiable_p (Shishi * handle, Shishi_asn1 kdcreq)
786 uint32_t options = 0;
788 shishi_kdcreq_options (handle, kdcreq, &options);
790 return options & SHISHI_KDCOPTIONS_PROXIABLE;
794 * shishi_kdcreq_proxy_p:
795 * @handle: shishi handle as allocated by shishi_init().
796 * @kdcreq: KDC-REQ variable to get kdc-options field from.
798 * Determine if KDC-Option proxy flag is set.
800 * The PROXY option indicates that this is a request for a proxy. This
801 * option will only be honored if the ticket-granting ticket in the
802 * request has its PROXIABLE bit set. The address(es) of the host
803 * from which the resulting ticket is to be valid are included in the
804 * addresses field of the request.
806 * Return value: Returns non-0 iff proxy flag is set in KDC-REQ.
809 shishi_kdcreq_proxy_p (Shishi * handle, Shishi_asn1 kdcreq)
811 uint32_t options = 0;
813 shishi_kdcreq_options (handle, kdcreq, &options);
815 return options & SHISHI_KDCOPTIONS_PROXY;
819 * shishi_kdcreq_allow_postdate_p:
820 * @handle: shishi handle as allocated by shishi_init().
821 * @kdcreq: KDC-REQ variable to get kdc-options field from.
823 * Determine if KDC-Option allow-postdate flag is set.
825 * The ALLOW-POSTDATE option indicates that the ticket to be issued is
826 * to have its MAY-POSTDATE flag set. It may only be set on the
827 * initial request, or in a subsequent request if the ticket-granting
828 * ticket on which it is based also has its MAY-POSTDATE flag set.
830 * Return value: Returns non-0 iff allow-postdate flag is set in KDC-REQ.
833 shishi_kdcreq_allow_postdate_p (Shishi * handle, Shishi_asn1 kdcreq)
835 uint32_t options = 0;
837 shishi_kdcreq_options (handle, kdcreq, &options);
839 return options & SHISHI_KDCOPTIONS_ALLOW_POSTDATE;
843 * shishi_kdcreq_postdated_p:
844 * @handle: shishi handle as allocated by shishi_init().
845 * @kdcreq: KDC-REQ variable to get kdc-options field from.
847 * Determine if KDC-Option postdated flag is set.
849 * The POSTDATED option indicates that this is a request for a
850 * postdated ticket. This option will only be honored if the
851 * ticket-granting ticket on which it is based has its MAY-POSTDATE
852 * flag set. The resulting ticket will also have its INVALID flag set,
853 * and that flag may be reset by a subsequent request to the KDC after
854 * the starttime in the ticket has been reached.
856 * Return value: Returns non-0 iff postdated flag is set in KDC-REQ.
859 shishi_kdcreq_postdated_p (Shishi * handle, Shishi_asn1 kdcreq)
861 uint32_t options = 0;
863 shishi_kdcreq_options (handle, kdcreq, &options);
865 return options & SHISHI_KDCOPTIONS_POSTDATED;
869 * shishi_kdcreq_renewable_p:
870 * @handle: shishi handle as allocated by shishi_init().
871 * @kdcreq: KDC-REQ variable to get kdc-options field from.
873 * Determine if KDC-Option renewable flag is set.
875 * The RENEWABLE option indicates that the ticket to be issued is to
876 * have its RENEWABLE flag set. It may only be set on the initial
877 * request, or when the ticket-granting ticket on which the request is
878 * based is also renewable. If this option is requested, then the
879 * rtime field in the request contains the desired absolute expiration
880 * time for the ticket.
882 * Return value: Returns non-0 iff renewable flag is set in KDC-REQ.
885 shishi_kdcreq_renewable_p (Shishi * handle, Shishi_asn1 kdcreq)
887 uint32_t options = 0;
889 shishi_kdcreq_options (handle, kdcreq, &options);
891 return options & SHISHI_KDCOPTIONS_RENEWABLE;
895 * shishi_kdcreq_disable_transited_check_p:
896 * @handle: shishi handle as allocated by shishi_init().
897 * @kdcreq: KDC-REQ variable to get kdc-options field from.
899 * Determine if KDC-Option disable-transited-check flag is set.
901 * By default the KDC will check the transited field of a
902 * ticket-granting-ticket against the policy of the local realm before
903 * it will issue derivative tickets based on the ticket-granting
904 * ticket. If this flag is set in the request, checking of the
905 * transited field is disabled. Tickets issued without the performance
906 * of this check will be noted by the reset (0) value of the
907 * TRANSITED-POLICY-CHECKED flag, indicating to the application server
908 * that the tranisted field must be checked locally. KDCs are
909 * encouraged but not required to honor the DISABLE-TRANSITED-CHECK
912 * This flag is new since RFC 1510
914 * Return value: Returns non-0 iff disable-transited-check flag is set
918 shishi_kdcreq_disable_transited_check_p (Shishi * handle, Shishi_asn1 kdcreq)
920 uint32_t options = 0;
922 shishi_kdcreq_options (handle, kdcreq, &options);
924 return options & SHISHI_KDCOPTIONS_DISABLE_TRANSITED_CHECK;
928 * shishi_kdcreq_renewable_ok_p:
929 * @handle: shishi handle as allocated by shishi_init().
930 * @kdcreq: KDC-REQ variable to get kdc-options field from.
932 * Determine if KDC-Option renewable-ok flag is set.
934 * The RENEWABLE-OK option indicates that a renewable ticket will be
935 * acceptable if a ticket with the requested life cannot otherwise be
936 * provided. If a ticket with the requested life cannot be provided,
937 * then a renewable ticket may be issued with a renew-till equal to
938 * the requested endtime. The value of the renew-till field may still
939 * be limited by local limits, or limits selected by the individual
940 * principal or server.
942 * Return value: Returns non-0 iff renewable-ok flag is set in KDC-REQ.
945 shishi_kdcreq_renewable_ok_p (Shishi * handle, Shishi_asn1 kdcreq)
947 uint32_t options = 0;
949 shishi_kdcreq_options (handle, kdcreq, &options);
951 return options & SHISHI_KDCOPTIONS_RENEWABLE_OK;
955 * shishi_kdcreq_enc_tkt_in_skey_p:
956 * @handle: shishi handle as allocated by shishi_init().
957 * @kdcreq: KDC-REQ variable to get kdc-options field from.
959 * Determine if KDC-Option enc-tkt-in-skey flag is set.
961 * This option is used only by the ticket-granting service. The
962 * ENC-TKT-IN-SKEY option indicates that the ticket for the end server
963 * is to be encrypted in the session key from the additional
964 * ticket-granting ticket provided.
966 * Return value: Returns non-0 iff enc-tkt-in-skey flag is set in KDC-REQ.
969 shishi_kdcreq_enc_tkt_in_skey_p (Shishi * handle, Shishi_asn1 kdcreq)
971 uint32_t options = 0;
973 shishi_kdcreq_options (handle, kdcreq, &options);
975 return options & SHISHI_KDCOPTIONS_ENC_TKT_IN_SKEY;
979 * shishi_kdcreq_renew_p:
980 * @handle: shishi handle as allocated by shishi_init().
981 * @kdcreq: KDC-REQ variable to get kdc-options field from.
983 * Determine if KDC-Option renew flag is set.
985 * This option is used only by the ticket-granting service. The RENEW
986 * option indicates that the present request is for a renewal. The
987 * ticket provided is encrypted in the secret key for the server on
988 * which it is valid. This option will only be honored if the ticket
989 * to be renewed has its RENEWABLE flag set and if the time in its
990 * renew-till field has not passed. The ticket to be renewed is passed
991 * in the padata field as part of the authentication header.
993 * Return value: Returns non-0 iff renew flag is set in KDC-REQ.
996 shishi_kdcreq_renew_p (Shishi * handle, Shishi_asn1 kdcreq)
998 uint32_t options = 0;
1000 shishi_kdcreq_options (handle, kdcreq, &options);
1002 return options & SHISHI_KDCOPTIONS_RENEW;
1006 * shishi_kdcreq_validate_p:
1007 * @handle: shishi handle as allocated by shishi_init().
1008 * @kdcreq: KDC-REQ variable to get kdc-options field from.
1010 * Determine if KDC-Option validate flag is set.
1012 * This option is used only by the ticket-granting service. The
1013 * VALIDATE option indicates that the request is to validate a
1014 * postdated ticket. It will only be honored if the ticket presented
1015 * is postdated, presently has its INVALID flag set, and would be
1016 * otherwise usable at this time. A ticket cannot be validated before
1017 * its starttime. The ticket presented for validation is encrypted in
1018 * the key of the server for which it is valid and is passed in the
1019 * padata field as part of the authentication header.
1021 * Return value: Returns non-0 iff validate flag is set in KDC-REQ.
1024 shishi_kdcreq_validate_p (Shishi * handle, Shishi_asn1 kdcreq)
1026 uint32_t options = 0;
1028 shishi_kdcreq_options (handle, kdcreq, &options);
1030 return options & SHISHI_KDCOPTIONS_VALIDATE;
1034 * shishi_kdcreq_options_set:
1035 * @handle: shishi handle as allocated by shishi_init().
1036 * @kdcreq: KDC-REQ variable to set etype field in.
1037 * @options: integer with flags to store in KDC-REQ.
1039 * Set options in KDC-REQ. Note that this reset any already existing
1042 * Return value: Returns SHISHI_OK iff successful.
1045 shishi_kdcreq_options_set (Shishi * handle,
1046 Shishi_asn1 kdcreq, uint32_t options)
1050 res = shishi_asn1_write_bitstring (handle, kdcreq,
1051 "req-body.kdc-options", options);
1052 if (res != SHISHI_OK)
1059 * shishi_kdcreq_options_add:
1060 * @handle: shishi handle as allocated by shishi_init().
1061 * @kdcreq: KDC-REQ variable to set etype field in.
1062 * @option: integer with options to add in KDC-REQ.
1064 * Add KDC-Option to KDC-REQ. This preserves all existing options.
1066 * Return value: Returns SHISHI_OK iff successful.
1069 shishi_kdcreq_options_add (Shishi * handle,
1070 Shishi_asn1 kdcreq, uint32_t option)
1075 res = shishi_kdcreq_options (handle, kdcreq, &options);
1076 if (res != SHISHI_OK)
1081 res = shishi_kdcreq_options_set (handle, kdcreq, options);
1082 if (res != SHISHI_OK)
1089 * shishi_kdcreq_clear_padata:
1090 * @handle: shishi handle as allocated by shishi_init().
1091 * @kdcreq: KDC-REQ to remove PA-DATA from.
1093 * Remove the padata field from KDC-REQ.
1095 * Return value: Returns SHISHI_OK iff successful.
1098 shishi_kdcreq_clear_padata (Shishi * handle, Shishi_asn1 kdcreq)
1102 res = shishi_asn1_write (handle, kdcreq, "padata", NULL, 0);
1103 if (res != SHISHI_OK)
1110 * shishi_kdcreq_get_padata:
1111 * @handle: shishi handle as allocated by shishi_init().
1112 * @kdcreq: KDC-REQ to get PA-DATA from.
1113 * @padatatype: type of PA-DATA, see Shishi_padata_type.
1114 * @out: output array with newly allocated PA-DATA value.
1115 * @outlen: size of output array with PA-DATA value.
1117 * Get pre authentication data (PA-DATA) from KDC-REQ. Pre
1118 * authentication data is used to pass various information to KDC,
1119 * such as in case of a SHISHI_PA_TGS_REQ padatatype the AP-REQ that
1120 * authenticates the user to get the ticket.
1122 * Return value: Returns SHISHI_OK iff successful.
1125 shishi_kdcreq_get_padata (Shishi * handle,
1127 Shishi_padata_type padatatype,
1128 char **out, size_t * outlen)
1134 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n);
1135 if (res != SHISHI_OK)
1141 for (i = 1; i <= n; i++)
1145 asprintf (&format, "padata.?%d.padata-type", i);
1146 res = shishi_asn1_read_int32 (handle, kdcreq, format, &patype);
1148 if (res != SHISHI_OK)
1151 if (patype == (int32_t) padatatype)
1153 asprintf (&format, "padata.?%d.padata-value", i);
1154 res = shishi_asn1_read (handle, kdcreq, format, out, outlen);
1156 if (res != SHISHI_OK)
1166 * shishi_kdcreq_get_padata_tgs:
1167 * @handle: shishi handle as allocated by shishi_init().
1168 * @kdcreq: KDC-REQ to get PA-TGS-REQ from.
1169 * @apreq: Output variable with newly allocated AP-REQ.
1171 * Extract TGS pre-authentication data from KDC-REQ. The data is an
1172 * AP-REQ that authenticates the request. This function call
1173 * shishi_kdcreq_get_padata() with a SHISHI_PA_TGS_REQ padatatype and
1174 * DER decode the result (if any).
1176 * Return value: Returns SHISHI_OK iff successful.
1179 shishi_kdcreq_get_padata_tgs (Shishi * handle,
1180 Shishi_asn1 kdcreq, Shishi_asn1 * apreq)
1186 if (VERBOSE (handle))
1187 printf ("Extracting AP-REQ from KDC-REQ...\n");
1189 rc = shishi_kdcreq_get_padata (handle, kdcreq, SHISHI_PA_TGS_REQ,
1191 if (rc != SHISHI_OK)
1194 *apreq = shishi_der2asn1_apreq (handle, der, derlen);
1196 return SHISHI_ASN1_ERROR;
1198 if (VERBOSEASN1 (handle))
1199 shishi_apreq_print (handle, stdout, *apreq);
1205 * shishi_kdcreq_add_padata:
1206 * @handle: shishi handle as allocated by shishi_init().
1207 * @kdcreq: KDC-REQ to add PA-DATA to.
1208 * @padatatype: type of PA-DATA, see Shishi_padata_type.
1209 * @data: input array with PA-DATA value.
1210 * @datalen: size of input array with PA-DATA value.
1212 * Add new pre authentication data (PA-DATA) to KDC-REQ. This is used
1213 * to pass various information to KDC, such as in case of a
1214 * SHISHI_PA_TGS_REQ padatatype the AP-REQ that authenticates the user
1215 * to get the ticket. (But also see shishi_kdcreq_add_padata_tgs()
1216 * which takes an AP-REQ directly.)
1218 * Return value: Returns SHISHI_OK iff successful.
1221 shishi_kdcreq_add_padata (Shishi * handle,
1223 int padatatype, const char *data, size_t datalen)
1229 res = shishi_asn1_write (handle, kdcreq, "padata", "NEW", 1);
1230 if (res != SHISHI_OK)
1233 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &i);
1234 if (res != SHISHI_OK)
1237 asprintf (&format, "padata.?%d.padata-value", i);
1238 res = shishi_asn1_write (handle, kdcreq, format, data, datalen);
1240 if (res != SHISHI_OK)
1243 asprintf (&format, "padata.?%d.padata-type", i);
1244 res = shishi_asn1_write_uint32 (handle, kdcreq, format, padatatype);
1246 if (res != SHISHI_OK)
1253 * shishi_kdcreq_add_padata_tgs:
1254 * @handle: shishi handle as allocated by shishi_init().
1255 * @kdcreq: KDC-REQ to add PA-DATA to.
1256 * @apreq: AP-REQ to add as PA-DATA.
1258 * Add TGS pre-authentication data to KDC-REQ. The data is an AP-REQ
1259 * that authenticates the request. This functions simply DER encodes
1260 * the AP-REQ and calls shishi_kdcreq_add_padata() with a
1261 * SHISHI_PA_TGS_REQ padatatype.
1263 * Return value: Returns SHISHI_OK iff successful.
1266 shishi_kdcreq_add_padata_tgs (Shishi * handle,
1267 Shishi_asn1 kdcreq, Shishi_asn1 apreq)
1273 res = shishi_asn1_to_der (handle, apreq, &data, &datalen);
1274 if (res != SHISHI_OK)
1276 shishi_error_printf (handle, "Could not DER encode AP-REQ: %s\n",
1277 shishi_strerror (res));
1281 res = shishi_kdcreq_add_padata (handle, kdcreq,
1282 SHISHI_PA_TGS_REQ, data, datalen);
1284 if (res != SHISHI_OK)
1291 * shishi_kdcreq_add_padata_preauth:
1292 * @handle: shishi handle as allocated by shishi_init().
1293 * @kdcreq: KDC-REQ to add pre-authentication data to.
1294 * @key: Key used to encrypt pre-auth data.
1296 * Add pre-authentication data to KDC-REQ.
1298 * Return value: Returns SHISHI_OK iff successful.
1301 shishi_kdcreq_add_padata_preauth (Shishi * handle,
1302 Shishi_asn1 kdcreq, Shishi_key * key)
1305 size_t derlen, datalen;
1311 pa = shishi_asn1_pa_enc_ts_enc (handle);
1313 return SHISHI_ASN1_ERROR;
1315 rc = gettimeofday (&tv, NULL);
1317 return SHISHI_GETTIMEOFDAY_ERROR;
1319 rc = shishi_asn1_write (handle, pa, "patimestamp",
1320 shishi_generalize_time (handle, tv.tv_sec),
1321 SHISHI_GENERALIZEDTIME_LENGTH);
1322 if (rc != SHISHI_OK)
1325 rc = shishi_asn1_write_integer (handle, pa, "pausec", tv.tv_usec);
1326 if (rc != SHISHI_OK)
1329 rc = shishi_asn1_to_der (handle, pa, &der, &derlen);
1330 if (rc != SHISHI_OK)
1333 rc = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ASREQ_PA_ENC_TIMESTAMP,
1334 der, derlen, &data, &datalen);
1336 if (rc != SHISHI_OK)
1339 ed = shishi_asn1_encrypteddata (handle);
1341 return SHISHI_ASN1_ERROR;
1343 rc = shishi_asn1_write_integer (handle, ed, "etype", shishi_key_type (key));
1344 if (rc != SHISHI_OK)
1347 rc = shishi_asn1_write (handle, ed, "cipher", data, datalen);
1348 if (rc != SHISHI_OK)
1351 rc = shishi_asn1_write (handle, ed, "kvno", NULL, 0);
1352 if (rc != SHISHI_OK)
1355 rc = shishi_asn1_to_der (handle, ed, &der, &derlen);
1357 if (rc != SHISHI_OK)
1360 rc = shishi_kdcreq_add_padata (handle, kdcreq, SHISHI_PA_ENC_TIMESTAMP,
1363 if (rc != SHISHI_OK)
1370 shishi_kdcreq_build (Shishi * handle, Shishi_asn1 kdcreq)
1376 shishi_verbose (handle, "Building KDC-REQ...");
1378 if (shishi_asn1_empty_p (handle, kdcreq, "req-body.rtime"))
1380 res = shishi_asn1_write (handle, kdcreq, "req-body.rtime", NULL, 0);
1381 if (res != SHISHI_OK)
1383 shishi_error_printf (handle, "Could not write rtime\n");
1388 if (shishi_asn1_empty_p (handle, kdcreq, "req-body.from"))
1390 res = shishi_asn1_write (handle, kdcreq, "req-body.from", NULL, 0);
1391 if (res != SHISHI_OK)
1393 shishi_error_printf (handle, "Could not write from\n");
1398 res = shishi_asn1_read_integer (handle, kdcreq, "msg-type", &msgtype);
1399 if (res != SHISHI_OK)
1401 if (msgtype == SHISHI_MSGTYPE_AS_REQ)
1403 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n);
1404 if (res == SHISHI_OK && n == 0)
1406 res = shishi_kdcreq_clear_padata (handle, kdcreq);
1407 if (res != SHISHI_OK)
1409 shishi_error_printf (handle, "Could not write padata\n");