Fix.
[shishi.git] / lib / kdcreq.c
blobd6534df97dc9bf85fbd733736312122a55090119
1 /* kdcreq.c Key distribution (AS/TGS) request functions
2 * Copyright (C) 2002, 2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 #define SHISHI_KDCREQ_DEFAULT_PVNO "5"
25 #define SHISHI_KDCREQ_DEFAULT_PVNO_LEN 0
26 #define SHISHI_AS_REQ_DEFAULT_MSG_TYPE "10"
27 #define SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN 0
28 #define SHISHI_TGS_REQ_DEFAULT_MSG_TYPE "12"
29 #define SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN 0
30 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS "\x00\x00\x00\x00"
31 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN 32
32 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE "1" /* SHISHI_NT_PRINCIPAL */
33 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN 0
34 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_TILL ""
35 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_TILL_LEN 1
37 static Shishi_asn1
38 _shishi_kdcreq (Shishi * handle, int as)
40 int res;
41 Shishi_asn1 node;
42 const char *servicebuf[3];
43 char noncebuf[4];
45 if (as)
46 node = shishi_asn1_asreq (handle);
47 else
48 node = shishi_asn1_tgsreq (handle);
49 if (!node)
50 return NULL;
52 res = shishi_asn1_write (handle, node, "pvno",
53 SHISHI_KDCREQ_DEFAULT_PVNO,
54 SHISHI_KDCREQ_DEFAULT_PVNO_LEN);
55 if (res != SHISHI_OK)
56 goto error;
58 if (as)
59 res = shishi_asn1_write (handle, node, "msg-type",
60 SHISHI_AS_REQ_DEFAULT_MSG_TYPE,
61 SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN);
62 else
63 res = shishi_asn1_write (handle, node, "msg-type",
64 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE,
65 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN);
66 if (res != SHISHI_OK)
67 goto error;
69 res = shishi_asn1_write (handle, node, "req-body.kdc-options",
70 SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS,
71 SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN);
72 if (res != SHISHI_OK)
73 goto error;
75 if (as)
76 res = shishi_kdcreq_set_cname (handle, node, SHISHI_NT_PRINCIPAL,
77 shishi_principal_default (handle));
78 else
79 res = shishi_asn1_write (handle, node, "req-body.cname", NULL, 0);
80 if (res != SHISHI_OK)
81 goto error;
83 res = shishi_kdcreq_set_realm (handle, node, shishi_realm_default (handle));
84 if (res != SHISHI_OK)
85 goto error;
87 servicebuf[0] = "krbtgt";
88 servicebuf[1] = shishi_realm_default (handle);
89 servicebuf[2] = NULL;
90 res = shishi_kdcreq_set_sname (handle, node,
91 SHISHI_NT_PRINCIPAL, servicebuf);
92 if (res != SHISHI_OK)
93 goto error;
95 res = shishi_asn1_write (handle, node, "req-body.sname.name-type",
96 SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE,
97 SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN);
98 if (res != SHISHI_OK)
99 goto error;
101 res = shishi_asn1_write (handle, node, "req-body.till",
102 shishi_generalize_time (handle,
103 time (NULL) +
104 handle->ticketlife), 0);
105 if (res != SHISHI_OK)
106 goto error;
108 shishi_randomize (handle, &noncebuf[0], sizeof (noncebuf));
109 res = shishi_asn1_write (handle, node, "req-body.nonce", noncebuf,
110 sizeof (noncebuf));
111 if (res != SHISHI_OK)
112 goto error;
114 res = shishi_kdcreq_set_etype (handle, node, handle->clientkdcetypes,
115 handle->nclientkdcetypes);
116 if (res != SHISHI_OK)
117 goto error;
119 res = shishi_asn1_write (handle, node, "req-body.addresses", NULL, 0);
120 if (res != SHISHI_OK)
121 goto error;
123 res = shishi_asn1_write (handle, node,
124 "req-body.enc-authorization-data", NULL, 0);
125 if (res != SHISHI_OK)
126 goto error;
128 res =
129 shishi_asn1_write (handle, node, "req-body.additional-tickets", NULL, 0);
130 if (res != SHISHI_OK)
131 goto error;
133 return node;
135 error:
136 shishi_asn1_done (handle, node);
137 return NULL;
141 * shishi_asreq:
142 * @handle: shishi handle as allocated by shishi_init().
144 * This function creates a new AS-REQ, populated with some default
145 * values.
147 * Return value: Returns the AS-REQ or NULL on failure.
149 Shishi_asn1
150 shishi_asreq (Shishi * handle)
152 return _shishi_kdcreq (handle, 1);
156 * shishi_tgsreq:
157 * @handle: shishi handle as allocated by shishi_init().
159 * This function creates a new TGS-REQ, populated with some default
160 * values.
162 * Return value: Returns the TGS-REQ or NULL on failure.
164 Shishi_asn1
165 shishi_tgsreq (Shishi * handle)
167 return _shishi_kdcreq (handle, 0);
171 * shishi_kdcreq_print:
172 * @handle: shishi handle as allocated by shishi_init().
173 * @fh: file handle open for writing.
174 * @kdcreq: KDC-REQ to print.
176 * Print ASCII armored DER encoding of KDC-REQ to file.
178 * Return value: Returns SHISHI_OK iff successful.
181 shishi_kdcreq_print (Shishi * handle, FILE * fh, Shishi_asn1 kdcreq)
183 return _shishi_print_armored_data (handle, fh, kdcreq, "KDC-REQ", NULL);
187 * shishi_kdcreq_save:
188 * @handle: shishi handle as allocated by shishi_init().
189 * @fh: file handle open for writing.
190 * @kdcreq: KDC-REQ to save.
192 * Print DER encoding of KDC-REQ to file.
194 * Return value: Returns SHISHI_OK iff successful.
197 shishi_kdcreq_save (Shishi * handle, FILE * fh, Shishi_asn1 kdcreq)
199 return _shishi_save_data (handle, fh, kdcreq, "KDC-REQ");
203 * shishi_kdcreq_to_file:
204 * @handle: shishi handle as allocated by shishi_init().
205 * @kdcreq: KDC-REQ to save.
206 * @filetype: input variable specifying type of file to be written,
207 * see Shishi_filetype.
208 * @filename: input variable with filename to write to.
210 * Write KDC-REQ to file in specified TYPE. The file will be truncated
211 * if it exists.
213 * Return value: Returns SHISHI_OK iff successful.
216 shishi_kdcreq_to_file (Shishi * handle, Shishi_asn1 kdcreq,
217 int filetype, char *filename)
219 FILE *fh;
220 int res;
222 if (VERBOSE (handle))
223 printf (_("Writing KDC-REQ to %s...\n"), filename);
225 fh = fopen (filename, "w");
226 if (fh == NULL)
227 return SHISHI_FOPEN_ERROR;
229 if (VERBOSE (handle))
230 printf (_("Writing KDC-REQ in %s format...\n"),
231 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
233 if (filetype == SHISHI_FILETYPE_TEXT)
234 res = shishi_kdcreq_print (handle, fh, kdcreq);
235 else
236 res = shishi_kdcreq_save (handle, fh, kdcreq);
237 if (res != SHISHI_OK)
238 return res;
240 res = fclose (fh);
241 if (res != 0)
242 return SHISHI_FCLOSE_ERROR;
244 if (VERBOSE (handle))
245 printf (_("Writing KDC-REQ to %s...done\n"), filename);
247 return SHISHI_OK;
251 * shishi_kdcreq_parse:
252 * @handle: shishi handle as allocated by shishi_init().
253 * @fh: file handle open for reading.
254 * @kdcreq: output variable with newly allocated KDC-REQ.
256 * Read ASCII armored DER encoded KDC-REQ from file and populate given
257 * variable.
259 * Return value: Returns SHISHI_OK iff successful.
262 shishi_kdcreq_parse (Shishi * handle, FILE * fh, Shishi_asn1 * kdcreq)
264 return _shishi_kdcreq_input (handle, fh, kdcreq, 0);
268 * shishi_kdcreq_read:
269 * @handle: shishi handle as allocated by shishi_init().
270 * @fh: file handle open for reading.
271 * @kdcreq: output variable with newly allocated KDC-REQ.
273 * Read DER encoded KDC-REQ from file and populate given variable.
275 * Return value: Returns SHISHI_OK iff successful.
278 shishi_kdcreq_read (Shishi * handle, FILE * fh, Shishi_asn1 * kdcreq)
280 return _shishi_kdcreq_input (handle, fh, kdcreq, 1);
284 * shishi_kdcreq_from_file:
285 * @handle: shishi handle as allocated by shishi_init().
286 * @kdcreq: output variable with newly allocated KDC-REQ.
287 * @filetype: input variable specifying type of file to be read,
288 * see Shishi_filetype.
289 * @filename: input variable with filename to read from.
291 * Read KDC-REQ from file in specified TYPE.
293 * Return value: Returns SHISHI_OK iff successful.
296 shishi_kdcreq_from_file (Shishi * handle, Shishi_asn1 * kdcreq,
297 int filetype, char *filename)
299 int res;
300 FILE *fh;
302 if (VERBOSE (handle))
303 printf (_("Reading KDC-REQ from %s...\n"), filename);
305 fh = fopen (filename, "r");
306 if (fh == NULL)
307 return SHISHI_FOPEN_ERROR;
309 if (VERBOSE (handle))
310 printf (_("Reading KDC-REQ in %s format...\n"),
311 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
313 if (filetype == SHISHI_FILETYPE_TEXT)
314 res = shishi_kdcreq_parse (handle, fh, kdcreq);
315 else
316 res = shishi_kdcreq_read (handle, fh, kdcreq);
317 if (res != SHISHI_OK)
318 return res;
320 res = fclose (fh);
321 if (res != 0)
322 return SHISHI_FCLOSE_ERROR;
324 if (VERBOSE (handle))
325 printf (_("Reading KDC-REQ from %s...done\n"), filename);
327 return SHISHI_OK;
331 shishi_kdcreq_nonce (Shishi * handle, Shishi_asn1 kdcreq, uint32_t * nonce)
333 int res;
335 res = shishi_asn1_read_uint32 (handle, kdcreq, "req-body.nonce", nonce);
336 if (res != SHISHI_OK)
337 return res;
339 return SHISHI_OK;
343 * shishi_kdcreq_set_cname:
344 * @handle: shishi handle as allocated by shishi_init().
345 * @kdcreq: KDC-REQ variable to set client name field in.
346 * @name_type: type of principial, see Shishi_name_type, usually
347 * SHISHI_NT_UNKNOWN.
348 * @principal: input array with principal name.
350 * Set the client name field in the KDC-REQ.
352 * Return value: Returns SHISHI_OK iff successful.
355 shishi_kdcreq_set_cname (Shishi * handle,
356 Shishi_asn1 kdcreq,
357 Shishi_name_type name_type, const char *principal)
359 int res;
361 res = shishi_principal_set (handle, kdcreq, "req-body.cname", principal);
362 if (res != SHISHI_OK)
363 return res;
365 return SHISHI_OK;
369 shishi_kdcreq_cname_get (Shishi * handle,
370 Shishi_asn1 kdcreq, char *cname, size_t * cnamelen)
372 return shishi_principal_name_get (handle, kdcreq,
373 "req-body.cname", cname, cnamelen);
377 shishi_asreq_cnamerealm_get (Shishi * handle,
378 Shishi_asn1 asreq,
379 char *cnamerealm, size_t * cnamerealmlen)
381 return shishi_principal_name_realm_get (handle, asreq,
382 "req-body.cname", asreq,
383 "req-body.realm",
384 cnamerealm, cnamerealmlen);
388 shishi_kdcreq_realm_get (Shishi * handle, Shishi_asn1 kdcreq,
389 char *realm, size_t * realmlen)
391 return shishi_asn1_read_optional (handle, kdcreq, "req-body.realm",
392 realm, realmlen);
396 * shishi_kdcreq_set_realm:
397 * @handle: shishi handle as allocated by shishi_init().
398 * @kdcreq: KDC-REQ variable to set realm field in.
399 * @realm: input array with name of realm.
401 * Set the realm field in the KDC-REQ.
403 * Return value: Returns SHISHI_OK iff successful.
406 shishi_kdcreq_set_realm (Shishi * handle, Shishi_asn1 kdcreq,
407 const char *realm)
409 int res;
411 res = shishi_asn1_write (handle, kdcreq, "req-body.realm", realm, 0);
412 if (res != SHISHI_OK)
413 return res;
415 return SHISHI_OK;
419 shishi_kdcreq_sname_get (Shishi * handle,
420 Shishi_asn1 kdcreq, char *sname, size_t * snamelen)
422 return shishi_principal_name_get (handle, kdcreq,
423 "req-body.sname", sname, snamelen);
427 shishi_kdcreq_snamerealm_get (Shishi * handle,
428 Shishi_asn1 kdcreq,
429 char *snamerealm, size_t * snamerealmlen)
431 return shishi_principal_name_realm_get (handle, kdcreq,
432 "req-body.sname", kdcreq,
433 "req-body.realm",
434 snamerealm, snamerealmlen);
438 * shishi_kdcreq_set_sname:
439 * @handle: shishi handle as allocated by shishi_init().
440 * @kdcreq: KDC-REQ variable to set server name field in.
441 * @name_type: type of principial, see Shishi_name_type, usually
442 * SHISHI_NT_UNKNOWN.
443 * @sname: input array with principal name.
445 * Set the server name field in the KDC-REQ.
447 * Return value: Returns SHISHI_OK iff successful.
450 shishi_kdcreq_set_sname (Shishi * handle,
451 Shishi_asn1 kdcreq,
452 Shishi_name_type name_type, const char *sname[])
454 int res;
456 res = shishi_principal_name_set (handle, kdcreq, "req-body.sname",
457 name_type, sname);
458 if (res != SHISHI_OK)
459 return res;
461 return SHISHI_OK;
465 shishi_kdcreq_set_server (Shishi * handle, Shishi_asn1 req,
466 const char *server)
468 int res;
470 res = shishi_principal_set (handle, req, "req-body.sname", server);
471 if (res != SHISHI_OK)
472 return res;
474 return SHISHI_OK;
478 shishi_kdcreq_set_realmserver (Shishi * handle,
479 Shishi_asn1 req, char *realm, char *server)
481 int res;
483 res = shishi_kdcreq_set_realm (handle, req, realm);
484 if (res != SHISHI_OK)
485 return res;
487 res = shishi_kdcreq_set_server (handle, req, server);
488 if (res != SHISHI_OK)
489 return res;
491 return SHISHI_OK;
495 * shishi_kdcreq_etype:
496 * @handle: shishi handle as allocated by shishi_init().
497 * @kdcreq: KDC-REQ variable to get etype field from.
498 * @etype: output encryption type.
499 * @netype: element number to return.
501 * Return the netype:th encryption type from KDC-REQ. The first etype
502 * is number 1.
504 * Return value: Returns SHISHI_OK iff etype successful set.
507 shishi_kdcreq_etype (Shishi * handle,
508 Shishi_asn1 kdcreq, int32_t * etype, int netype)
510 char *buf;
511 int res;
513 asprintf (&buf, "req-body.etype.?%d", netype);
514 res = shishi_asn1_read_int32 (handle, kdcreq, buf, etype);
515 if (res != SHISHI_OK)
516 return res;
518 return SHISHI_OK;
522 * shishi_kdcreq_set_etype:
523 * @handle: shishi handle as allocated by shishi_init().
524 * @kdcreq: KDC-REQ variable to set etype field in.
525 * @etype: input array with encryption types.
526 * @netype: number of elements in input array with encryption types.
528 * Set the list of supported or wanted encryption types in the
529 * request. The list should be sorted in priority order.
531 * Return value: Returns SHISHI_OK iff successful.
534 shishi_kdcreq_set_etype (Shishi * handle,
535 Shishi_asn1 kdcreq, int32_t * etype, int netype)
537 int res;
538 char *buf;
539 int i;
541 res = shishi_asn1_write (handle, kdcreq, "req-body.etype", NULL, 0);
542 if (res != SHISHI_OK)
543 return res;
545 for (i = 1; i <= netype; i++)
547 res = shishi_asn1_write (handle, kdcreq, "req-body.etype", "NEW", 1);
548 if (res != SHISHI_OK)
549 return res;
551 asprintf (&buf, "req-body.etype.?%d", i);
552 res = shishi_asn1_write_int32 (handle, kdcreq, buf, etype[i - 1]);
553 free (buf);
554 if (res != SHISHI_OK)
555 return res;
558 return SHISHI_OK;
562 * shishi_kdcreq_options:
563 * @handle: shishi handle as allocated by shishi_init().
564 * @kdcreq: KDC-REQ variable to set etype field in.
565 * @flags: pointer to output integer with flags.
567 * Extract KDC-Options from KDC-REQ.
569 * Return value: Returns SHISHI_OK iff successful.
572 shishi_kdcreq_options (Shishi * handle, Shishi_asn1 kdcreq, uint32_t *flags)
574 return shishi_asn1_read_bitstring (handle, kdcreq,
575 "req-body.kdc-options", flags);
579 * shishi_kdcreq_renewable_p:
580 * @handle: shishi handle as allocated by shishi_init().
581 * @kdcreq: KDC-REQ variable to set etype field in.
583 * Determine if KDC-Option renewable flag is set.
585 * The RENEWABLE option indicates that the ticket to be issued is to
586 * have its RENEWABLE flag set. It may only be set on the initial
587 * request, or when the ticket-granting ticket on which the request is
588 * based is also renewable. If this option is requested, then the
589 * rtime field in the request contains the desired absolute expiration
590 * time for the ticket.
592 * Return value: Returns non-0 iff renewable flag is set in KDC-REQ.
595 shishi_kdcreq_renewable_p (Shishi * handle, Shishi_asn1 kdcreq)
597 int options = 0;
599 shishi_kdcreq_options (handle, kdcreq, &options);
601 return options & SHISHI_KDCOPTIONS_RENEWABLE;
605 * shishi_kdcreq_options_set:
606 * @handle: shishi handle as allocated by shishi_init().
607 * @kdcreq: KDC-REQ variable to set etype field in.
608 * @options: integer with flags to store in KDC-REQ.
610 * Set options in KDC-REQ. Note that this reset any already existing
611 * flags.
613 * Return value: Returns SHISHI_OK iff successful.
616 shishi_kdcreq_options_set (Shishi * handle,
617 Shishi_asn1 kdcreq,
618 uint32_t options)
620 int res;
622 res = shishi_asn1_write_bitstring (handle, kdcreq,
623 "req-body.kdc-options", options);
624 if (res != SHISHI_OK)
625 return res;
627 return SHISHI_OK;
631 * shishi_kdcreq_options_add:
632 * @handle: shishi handle as allocated by shishi_init().
633 * @kdcreq: KDC-REQ variable to set etype field in.
634 * @option: integer with options to add in KDC-REQ.
636 * Add KDC-Option to KDC-REQ. This preserves all existing options.
638 * Return value: Returns SHISHI_OK iff successful.
641 shishi_kdcreq_options_add (Shishi * handle,
642 Shishi_asn1 kdcreq,
643 uint32_t option)
645 int options;
646 int res;
648 res = shishi_kdcreq_options (handle, kdcreq, &options);
649 if (res != SHISHI_OK)
650 return res;
652 options |= option;
654 res = shishi_kdcreq_options_set (handle, kdcreq, options);
655 if (res != SHISHI_OK)
656 return res;
658 return SHISHI_OK;
662 * shishi_kdcreq_clear_padata:
663 * @handle: shishi handle as allocated by shishi_init().
664 * @kdcreq: KDC-REQ to remove PA-DATA from.
666 * Remove the padata field from KDC-REQ.
668 * Return value: Returns SHISHI_OK iff successful.
671 shishi_kdcreq_clear_padata (Shishi * handle, Shishi_asn1 kdcreq)
673 int res;
675 res = shishi_asn1_write (handle, kdcreq, "padata", NULL, 0);
676 if (res != SHISHI_OK)
677 return res;
679 return SHISHI_OK;
683 * shishi_kdcreq_get_padata:
684 * @handle: shishi handle as allocated by shishi_init().
685 * @kdcreq: KDC-REQ to get PA-DATA from.
686 * @padatatype: type of PA-DATA, see Shishi_padata_type.
687 * @out: output array with newly allocated PA-DATA value.
688 * @outlen: size of output array with PA-DATA value.
690 * Get pre authentication data (PA-DATA) from KDC-REQ. Pre
691 * authentication data is used to pass various information to KDC,
692 * such as in case of a SHISHI_PA_TGS_REQ padatatype the AP-REQ that
693 * authenticates the user to get the ticket.
695 * Return value: Returns SHISHI_OK iff successful.
698 shishi_kdcreq_get_padata (Shishi * handle,
699 Shishi_asn1 kdcreq,
700 Shishi_padata_type padatatype,
701 char **out, size_t * outlen)
703 char *format;
704 int res;
705 size_t i, n;
707 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n);
708 if (res != SHISHI_OK)
709 return res;
711 *out = NULL;
712 *outlen = 0;
714 for (i = 1; i <= n; i++)
716 int32_t patype;
718 asprintf (&format, "padata.?%d.padata-type", i);
719 res = shishi_asn1_read_int32 (handle, kdcreq, format, &patype);
720 free (format);
721 if (res != SHISHI_OK)
722 return res;
724 if (patype == (int32_t) padatatype)
726 asprintf (&format, "padata.?%d.padata-value", i);
727 res = shishi_asn1_read2 (handle, kdcreq, format, out, outlen);
728 free (format);
729 if (res != SHISHI_OK)
730 return res;
731 break;
735 return SHISHI_OK;
739 * shishi_kdcreq_get_padata_tgs:
740 * @handle: shishi handle as allocated by shishi_init().
741 * @kdcreq: KDC-REQ to get PA-TGS-REQ from.
742 * @apreq: Output variable with newly allocated AP-REQ.
744 * Extract TGS pre-authentication data from KDC-REQ. The data is an
745 * AP-REQ that authenticates the request. This function call
746 * shishi_kdcreq_get_padata() with a SHISHI_PA_TGS_REQ padatatype and
747 * DER decode the result (if any).
749 * Return value: Returns SHISHI_OK iff successful.
752 shishi_kdcreq_get_padata_tgs (Shishi * handle,
753 Shishi_asn1 kdcreq, Shishi_asn1 * apreq)
755 char *der;
756 size_t derlen;
757 int rc;
759 if (VERBOSE (handle))
760 printf ("Extracting AP-REQ from KDC-REQ...\n");
762 rc = shishi_kdcreq_get_padata (handle, kdcreq, SHISHI_PA_TGS_REQ,
763 &der, &derlen);
764 if (rc != SHISHI_OK)
765 return rc;
767 *apreq = shishi_der2asn1_apreq (handle, der, derlen);
768 if (!*apreq)
769 return SHISHI_ASN1_ERROR;
771 if (VERBOSEASN1 (handle))
772 shishi_apreq_print (handle, stdout, *apreq);
774 return SHISHI_OK;
778 * shishi_kdcreq_add_padata:
779 * @handle: shishi handle as allocated by shishi_init().
780 * @kdcreq: KDC-REQ to add PA-DATA to.
781 * @padatatype: type of PA-DATA, see Shishi_padata_type.
782 * @data: input array with PA-DATA value.
783 * @datalen: size of input array with PA-DATA value.
785 * Add new pre authentication data (PA-DATA) to KDC-REQ. This is used
786 * to pass various information to KDC, such as in case of a
787 * SHISHI_PA_TGS_REQ padatatype the AP-REQ that authenticates the user
788 * to get the ticket. (But also see shishi_kdcreq_add_padata_tgs()
789 * which takes an AP-REQ directly.)
791 * Return value: Returns SHISHI_OK iff successful.
794 shishi_kdcreq_add_padata (Shishi * handle,
795 Shishi_asn1 kdcreq,
796 int padatatype, const char *data, size_t datalen)
798 char *format;
799 int res;
800 int i;
802 res = shishi_asn1_write (handle, kdcreq, "padata", "NEW", 1);
803 if (res != SHISHI_OK)
804 return res;
806 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &i);
807 if (res != SHISHI_OK)
808 return res;
810 asprintf (&format, "padata.?%d.padata-value", i);
811 res = shishi_asn1_write (handle, kdcreq, format, data, datalen);
812 free (format);
813 if (res != SHISHI_OK)
814 return res;
816 asprintf (&format, "padata.?%d.padata-type", i);
817 res = shishi_asn1_write_uint32 (handle, kdcreq, format, padatatype);
818 free (format);
819 if (res != SHISHI_OK)
820 return res;
822 return SHISHI_OK;
826 * shishi_kdcreq_add_padata_tgs:
827 * @handle: shishi handle as allocated by shishi_init().
828 * @kdcreq: KDC-REQ to add PA-DATA to.
829 * @apreq: AP-REQ to add as PA-DATA.
831 * Add TGS pre-authentication data to KDC-REQ. The data is an AP-REQ
832 * that authenticates the request. This functions simply DER encodes
833 * the AP-REQ and calls shishi_kdcreq_add_padata() with a
834 * SHISHI_PA_TGS_REQ padatatype.
836 * Return value: Returns SHISHI_OK iff successful.
839 shishi_kdcreq_add_padata_tgs (Shishi * handle,
840 Shishi_asn1 kdcreq, Shishi_asn1 apreq)
842 int res;
843 char *data;
844 size_t datalen;
846 res = shishi_new_a2d (handle, apreq, &data, &datalen);
847 if (res != SHISHI_OK)
849 shishi_error_printf (handle, "Could not DER encode AP-REQ: %s\n",
850 shishi_strerror (res));
851 return res;
854 res = shishi_kdcreq_add_padata (handle, kdcreq,
855 SHISHI_PA_TGS_REQ, data, datalen);
856 free (data);
857 if (res != SHISHI_OK)
858 return res;
860 return res;
864 shishi_kdcreq_build (Shishi * handle, Shishi_asn1 kdcreq)
866 int res;
868 if (VERBOSE (handle))
869 printf ("Building KDC-REQ...\n");
871 if (shishi_asn1_empty_p (handle, kdcreq, "req-body.rtime"))
873 res = shishi_asn1_write (handle, kdcreq, "req-body.rtime", NULL, 0);
874 if (res != SHISHI_OK)
876 shishi_error_printf (handle, "Could not write rtime\n");
877 return res;
881 if (shishi_asn1_empty_p (handle, kdcreq, "req-body.from"))
883 res = shishi_asn1_write (handle, kdcreq, "req-body.from", NULL, 0);
884 if (res != SHISHI_OK)
886 shishi_error_printf (handle, "Could not write from\n");
887 return res;
891 return SHISHI_OK;