No need for getline.h.
[shishi.git] / lib / authenticator.c
blob80ea5cc801384b4ad08637ae55cb9346a484bfa0
1 /* authenticator.c --- Functions for authenticators.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 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
23 #include "internal.h"
25 /* Get _shishi_print_armored_data, etc. */
26 #include "diskio.h"
28 /**
29 * shishi_authenticator:
30 * @handle: shishi handle as allocated by shishi_init().
32 * This function creates a new Authenticator, populated with some
33 * default values. It uses the current time as returned by the system
34 * for the ctime and cusec fields.
36 * Return value: Returns the authenticator or NULL on
37 * failure.
38 **/
39 Shishi_asn1
40 shishi_authenticator (Shishi * handle)
42 int res;
43 Shishi_asn1 node = NULL;
44 struct timeval tv;
45 uint32_t seqnr;
47 res = gettimeofday (&tv, NULL);
48 if (res != 0)
49 return NULL;
51 node = shishi_asn1_authenticator (handle);
52 if (!node)
53 return NULL;
55 res = shishi_asn1_write (handle, node, "authenticator-vno", "5", 0);
56 if (res != SHISHI_OK)
57 goto error;
59 res = shishi_authenticator_set_crealm (handle, node,
60 shishi_realm_default (handle));
61 if (res != SHISHI_OK)
62 goto error;
64 res = shishi_authenticator_client_set (handle, node,
65 shishi_principal_default (handle));
66 if (res != SHISHI_OK)
67 goto error;
69 res = shishi_authenticator_cusec_set (handle, node, tv.tv_usec % 1000000);
70 if (res != SHISHI_OK)
71 goto error;
73 res = shishi_asn1_write (handle, node, "ctime",
74 shishi_generalize_time (handle, time (NULL)), 0);
75 if (res != SHISHI_OK)
76 goto error;
79 * For sequence numbers to adequately support the detection of
80 * replays they SHOULD be non-repeating, even across connection
81 * boundaries. The initial sequence number SHOULD be random and
82 * uniformly distributed across the full space of possible sequence
83 * numbers, so that it cannot be guessed by an attacker and so that
84 * it and the successive sequence numbers do not repeat other
85 * sequences.
87 shishi_randomize (handle, 0, &seqnr, sizeof (seqnr));
89 /* XXX remove once libtasn1 _asn1_convert_integer is fixed. */
90 seqnr &= 0x7FFFFFFF;
93 * Implementation note: as noted before, some implementations omit
94 * the optional sequence number when its value would be zero.
95 * Implementations MAY accept an omitted sequence number when
96 * expecting a value of zero, and SHOULD NOT transmit an
97 * Authenticator with a initial sequence number of zero.
99 if (seqnr == 0)
100 seqnr++;
102 res = shishi_authenticator_seqnumber_set (handle, node, seqnr);
103 if (res != SHISHI_OK)
104 goto error;
106 return node;
108 error:
109 shishi_asn1_done (handle, node);
110 return NULL;
114 * shishi_authenticator_subkey:
115 * @handle: shishi handle as allocated by shishi_init().
117 * This function creates a new Authenticator, populated with some
118 * default values. It uses the current time as returned by the system
119 * for the ctime and cusec fields. It adds a random subkey.
121 * Return value: Returns the authenticator or NULL on
122 * failure.
124 Shishi_asn1
125 shishi_authenticator_subkey (Shishi * handle)
127 Shishi_asn1 node;
128 int res;
130 node = shishi_authenticator (handle);
131 if (node == NULL)
132 return NULL;
134 res = shishi_authenticator_add_random_subkey (handle, node);
135 if (res != SHISHI_OK)
136 return NULL;
138 return node;
142 * shishi_authenticator_print:
143 * @handle: shishi handle as allocated by shishi_init().
144 * @fh: file handle open for writing.
145 * @authenticator: authenticator as allocated by shishi_authenticator().
147 * Print ASCII armored DER encoding of authenticator to file.
149 * Return value: Returns SHISHI_OK iff successful.
152 shishi_authenticator_print (Shishi * handle,
153 FILE * fh, Shishi_asn1 authenticator)
155 return _shishi_print_armored_data (handle, fh, authenticator,
156 "Authenticator", NULL);
160 * shishi_authenticator_save:
161 * @handle: shishi handle as allocated by shishi_init().
162 * @fh: file handle open for writing.
163 * @authenticator: authenticator as allocated by shishi_authenticator().
165 * Save DER encoding of authenticator to file.
167 * Return value: Returns SHISHI_OK iff successful.
170 shishi_authenticator_save (Shishi * handle,
171 FILE * fh, Shishi_asn1 authenticator)
173 return _shishi_save_data (handle, fh, authenticator, "Authenticator");
177 * shishi_authenticator_to_file:
178 * @handle: shishi handle as allocated by shishi_init().
179 * @authenticator: Authenticator to save.
180 * @filetype: input variable specifying type of file to be written,
181 * see Shishi_filetype.
182 * @filename: input variable with filename to write to.
184 * Write Authenticator to file in specified TYPE. The file will be
185 * truncated if it exists.
187 * Return value: Returns SHISHI_OK iff successful.
190 shishi_authenticator_to_file (Shishi * handle, Shishi_asn1 authenticator,
191 int filetype, const char *filename)
193 FILE *fh;
194 int res;
196 if (VERBOSE (handle))
197 printf (_("Writing Authenticator to %s...\n"), filename);
199 fh = fopen (filename, "w");
200 if (fh == NULL)
201 return SHISHI_FOPEN_ERROR;
203 if (VERBOSE (handle))
204 printf (_("Writing Authenticator in %s format...\n"),
205 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
207 if (filetype == SHISHI_FILETYPE_TEXT)
208 res = shishi_authenticator_print (handle, fh, authenticator);
209 else
210 res = shishi_authenticator_save (handle, fh, authenticator);
211 if (res != SHISHI_OK)
212 return res;
214 res = fclose (fh);
215 if (res != 0)
216 return SHISHI_IO_ERROR;
218 if (VERBOSE (handle))
219 printf (_("Writing Authenticator to %s...done\n"), filename);
221 return SHISHI_OK;
225 * shishi_authenticator_parse:
226 * @handle: shishi handle as allocated by shishi_init().
227 * @fh: file handle open for reading.
228 * @authenticator: output variable with newly allocated authenticator.
230 * Read ASCII armored DER encoded authenticator from file and populate
231 * given authenticator variable.
233 * Return value: Returns SHISHI_OK iff successful.
236 shishi_authenticator_parse (Shishi * handle,
237 FILE * fh, Shishi_asn1 * authenticator)
239 return _shishi_authenticator_input (handle, fh, authenticator, 0);
243 * shishi_authenticator_read:
244 * @handle: shishi handle as allocated by shishi_init().
245 * @fh: file handle open for reading.
246 * @authenticator: output variable with newly allocated authenticator.
248 * Read DER encoded authenticator from file and populate given
249 * authenticator variable.
251 * Return value: Returns SHISHI_OK iff successful.
254 shishi_authenticator_read (Shishi * handle,
255 FILE * fh, Shishi_asn1 * authenticator)
257 return _shishi_authenticator_input (handle, fh, authenticator, 1);
261 * shishi_authenticator_from_file:
262 * @handle: shishi handle as allocated by shishi_init().
263 * @authenticator: output variable with newly allocated Authenticator.
264 * @filetype: input variable specifying type of file to be read,
265 * see Shishi_filetype.
266 * @filename: input variable with filename to read from.
268 * Read Authenticator from file in specified TYPE.
270 * Return value: Returns SHISHI_OK iff successful.
273 shishi_authenticator_from_file (Shishi * handle, Shishi_asn1 * authenticator,
274 int filetype, const char *filename)
276 int res;
277 FILE *fh;
279 if (VERBOSE (handle))
280 printf (_("Reading Authenticator from %s...\n"), filename);
282 fh = fopen (filename, "r");
283 if (fh == NULL)
284 return SHISHI_FOPEN_ERROR;
286 if (VERBOSE (handle))
287 printf (_("Reading Authenticator in %s format...\n"),
288 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
290 if (filetype == SHISHI_FILETYPE_TEXT)
291 res = shishi_authenticator_parse (handle, fh, authenticator);
292 else
293 res = shishi_authenticator_read (handle, fh, authenticator);
294 if (res != SHISHI_OK)
295 return res;
297 res = fclose (fh);
298 if (res != 0)
299 return SHISHI_IO_ERROR;
301 if (VERBOSE (handle))
302 printf (_("Reading Authenticator from %s...done\n"), filename);
304 return SHISHI_OK;
308 * shishi_authenticator_set_crealm:
309 * @handle: shishi handle as allocated by shishi_init().
310 * @authenticator: authenticator as allocated by shishi_authenticator().
311 * @crealm: input array with realm.
313 * Set realm field in authenticator to specified value.
315 * Return value: Returns SHISHI_OK iff successful.
318 shishi_authenticator_set_crealm (Shishi * handle,
319 Shishi_asn1 authenticator,
320 const char *crealm)
322 int res;
324 res = shishi_asn1_write (handle, authenticator, "crealm", crealm, 0);
325 if (res != SHISHI_OK)
326 return res;
328 return SHISHI_OK;
332 * shishi_authenticator_set_cname:
333 * @handle: shishi handle as allocated by shishi_init().
334 * @authenticator: authenticator as allocated by shishi_authenticator().
335 * @name_type: type of principial, see Shishi_name_type, usually
336 * SHISHI_NT_UNKNOWN.
337 * @cname: input array with principal name.
339 * Set principal field in authenticator to specified value.
341 * Return value: Returns SHISHI_OK iff successful.
344 shishi_authenticator_set_cname (Shishi * handle,
345 Shishi_asn1 authenticator,
346 Shishi_name_type name_type,
347 const char *cname[])
349 int res;
351 res = shishi_principal_name_set (handle, authenticator, "cname",
352 name_type, cname);
353 if (res != SHISHI_OK)
354 return res;
356 return SHISHI_OK;
360 * shishi_authenticator_client_set:
361 * @handle: shishi handle as allocated by shishi_init().
362 * @authenticator: Authenticator to set client name field in.
363 * @client: zero-terminated string with principal name on RFC 1964 form.
365 * Set the client name field in the Authenticator.
367 * Return value: Returns SHISHI_OK iff successful.
370 shishi_authenticator_client_set (Shishi * handle,
371 Shishi_asn1 authenticator,
372 const char *client)
374 int res;
376 res = shishi_principal_set (handle, authenticator, "cname", client);
377 if (res != SHISHI_OK)
378 return res;
380 return SHISHI_OK;
384 * shishi_authenticator_ctime:
385 * @handle: shishi handle as allocated by shishi_init().
386 * @authenticator: Authenticator as allocated by shishi_authenticator().
387 * @t: newly allocated zero-terminated character array with client time.
389 * Extract client time from Authenticator.
391 * Return value: Returns SHISHI_OK iff successful.
394 shishi_authenticator_ctime (Shishi * handle,
395 Shishi_asn1 authenticator, char **t)
397 return shishi_time (handle, authenticator, "ctime", t);
401 * shishi_authenticator_ctime_set:
402 * @handle: shishi handle as allocated by shishi_init().
403 * @authenticator: Authenticator as allocated by shishi_authenticator().
404 * @t: string with generalized time value to store in Authenticator.
406 * Store client time in Authenticator.
408 * Return value: Returns SHISHI_OK iff successful.
411 shishi_authenticator_ctime_set (Shishi * handle,
412 Shishi_asn1 authenticator, const char *t)
414 int res;
416 res = shishi_asn1_write (handle, authenticator, "ctime",
417 t, SHISHI_GENERALIZEDTIME_LENGTH);
418 if (res != SHISHI_OK)
419 return res;
421 return SHISHI_OK;
425 * shishi_authenticator_cusec_get:
426 * @handle: shishi handle as allocated by shishi_init().
427 * @authenticator: Authenticator as allocated by shishi_authenticator().
428 * @cusec: output integer with client microseconds field.
430 * Extract client microseconds field from Authenticator.
432 * Return value: Returns SHISHI_OK iff successful.
435 shishi_authenticator_cusec_get (Shishi * handle,
436 Shishi_asn1 authenticator, uint32_t * cusec)
438 int res;
440 res = shishi_asn1_read_uint32 (handle, authenticator, "cusec", cusec);
441 if (res != SHISHI_OK)
442 return res;
444 return SHISHI_OK;
448 * shishi_authenticator_cusec_set:
449 * @handle: shishi handle as allocated by shishi_init().
450 * @authenticator: authenticator as allocated by shishi_authenticator().
451 * @cusec: client microseconds to set in authenticator, 0-999999.
453 * Set the cusec field in the Authenticator.
455 * Return value: Returns SHISHI_OK iff successful.
458 shishi_authenticator_cusec_set (Shishi * handle,
459 Shishi_asn1 authenticator, uint32_t cusec)
461 int res;
463 res = shishi_asn1_write_uint32 (handle, authenticator, "cusec", cusec);
464 if (res != SHISHI_OK)
465 return res;
467 return SHISHI_OK;
471 * shishi_authenticator_seqnumber_get:
472 * @handle: shishi handle as allocated by shishi_init().
473 * @authenticator: authenticator as allocated by shishi_authenticator().
474 * @seqnumber: output integer with sequence number field.
476 * Extract sequence number field from Authenticator.
478 * Return value: Returns %SHISHI_OK iff successful.
481 shishi_authenticator_seqnumber_get (Shishi * handle,
482 Shishi_asn1 authenticator,
483 uint32_t * seqnumber)
485 int res;
487 res = shishi_asn1_read_uint32 (handle, authenticator,
488 "seq-number", seqnumber);
489 if (res != SHISHI_OK)
490 return res;
492 return res;
496 * shishi_authenticator_seqnumber_remove:
497 * @handle: shishi handle as allocated by shishi_init().
498 * @authenticator: authenticator as allocated by shishi_authenticator().
500 * Remove sequence number field in Authenticator.
502 * Return value: Returns %SHISHI_OK iff successful.
505 shishi_authenticator_seqnumber_remove (Shishi * handle,
506 Shishi_asn1 authenticator)
508 int res;
510 res = shishi_asn1_write (handle, authenticator, "seq-number", NULL, 0);
511 if (res != SHISHI_OK)
512 return res;
514 return SHISHI_OK;
518 * shishi_authenticator_seqnumber_set:
519 * @handle: shishi handle as allocated by shishi_init().
520 * @authenticator: authenticator as allocated by shishi_authenticator().
521 * @seqnumber: integer with sequence number field to store in Authenticator.
523 * Store sequence number field in Authenticator.
525 * Return value: Returns %SHISHI_OK iff successful.
528 shishi_authenticator_seqnumber_set (Shishi * handle,
529 Shishi_asn1 authenticator,
530 uint32_t seqnumber)
532 int res;
534 res = shishi_asn1_write_uint32 (handle, authenticator,
535 "seq-number", seqnumber);
536 if (res != SHISHI_OK)
537 return res;
539 return SHISHI_OK;
543 * shishi_authenticator_client:
544 * @handle: Shishi library handle create by shishi_init().
545 * @authenticator: Authenticator variable to get client name from.
546 * @client: pointer to newly allocated zero terminated string containing
547 * principal name. May be %NULL (to only populate @clientlen).
548 * @clientlen: pointer to length of @client on output, excluding terminating
549 * zero. May be %NULL (to only populate @client).
551 * Represent client principal name in Authenticator as zero-terminated
552 * string. The string is allocate by this function, and it is the
553 * responsibility of the caller to deallocate it. Note that the
554 * output length @clientlen does not include the terminating zero.
556 * Return value: Returns SHISHI_OK iff successful.
559 shishi_authenticator_client (Shishi * handle,
560 Shishi_asn1 authenticator,
561 char **client, size_t * clientlen)
563 return shishi_principal_name (handle, authenticator,
564 "cname", client, clientlen);
568 * shishi_authenticator_clientrealm:
569 * @handle: Shishi library handle create by shishi_init().
570 * @authenticator: Authenticator variable to get client name and realm from.
571 * @client: pointer to newly allocated zero terminated string containing
572 * principal name and realm. May be %NULL (to only populate @clientlen).
573 * @clientlen: pointer to length of @client on output, excluding terminating
574 * zero. May be %NULL (to only populate @client).
576 * Convert cname and realm fields from Authenticator to printable
577 * principal name format. The string is allocate by this function,
578 * and it is the responsibility of the caller to deallocate it. Note
579 * that the output length @clientlen does not include the terminating
580 * zero.
582 * Return value: Returns SHISHI_OK iff successful.
585 shishi_authenticator_clientrealm (Shishi * handle,
586 Shishi_asn1 authenticator,
587 char **client, size_t * clientlen)
589 return shishi_principal_name_realm (handle,
590 authenticator, "cname",
591 authenticator, "crealm",
592 client, clientlen);
596 shishi_authenticator_remove_cksum (Shishi * handle, Shishi_asn1 authenticator)
598 int res;
600 /* XXX remove this function */
602 res = shishi_asn1_write (handle, authenticator, "cksum", NULL, 0);
603 if (res != SHISHI_OK)
604 return res;
606 return SHISHI_OK;
610 * shishi_authenticator_cksum:
611 * @handle: shishi handle as allocated by shishi_init().
612 * @authenticator: authenticator as allocated by shishi_authenticator().
613 * @cksumtype: output checksum type.
614 * @cksum: newly allocated output checksum data from authenticator.
615 * @cksumlen: on output, actual size of allocated output checksum data buffer.
617 * Read checksum value from authenticator. @cksum is allocated by
618 * this function, and it is the responsibility of caller to deallocate
619 * it.
621 * Return value: Returns SHISHI_OK iff successful.
624 shishi_authenticator_cksum (Shishi * handle,
625 Shishi_asn1 authenticator,
626 int32_t * cksumtype,
627 char **cksum, size_t * cksumlen)
629 int res;
631 res = shishi_asn1_read_int32 (handle, authenticator,
632 "cksum.cksumtype", cksumtype);
633 if (res != SHISHI_OK)
634 return res;
636 res = shishi_asn1_read (handle, authenticator, "cksum.checksum",
637 cksum, cksumlen);
638 if (res != SHISHI_OK)
639 return res;
641 return SHISHI_OK;
645 * shishi_authenticator_set_cksum:
646 * @handle: shishi handle as allocated by shishi_init().
647 * @authenticator: authenticator as allocated by shishi_authenticator().
648 * @cksumtype: input checksum type to store in authenticator.
649 * @cksum: input checksum data to store in authenticator.
650 * @cksumlen: size of input checksum data to store in authenticator.
652 * Store checksum value in authenticator. A checksum is usually created
653 * by calling shishi_checksum() on some application specific data using
654 * the key from the ticket that is being used. To save time, you may
655 * want to use shishi_authenticator_add_cksum() instead, which calculates
656 * the checksum and calls this function in one step.
658 * Return value: Returns SHISHI_OK iff successful.
661 shishi_authenticator_set_cksum (Shishi * handle,
662 Shishi_asn1 authenticator,
663 int32_t cksumtype,
664 char *cksum, size_t cksumlen)
666 int res;
668 res = shishi_asn1_write_int32 (handle, authenticator,
669 "cksum.cksumtype", cksumtype);
670 if (res != SHISHI_OK)
671 return res;
673 res = shishi_asn1_write (handle, authenticator, "cksum.checksum",
674 cksum, cksumlen);
675 if (res != SHISHI_OK)
676 return res;
678 return SHISHI_OK;
682 * shishi_authenticator_add_cksum:
683 * @handle: shishi handle as allocated by shishi_init().
684 * @authenticator: authenticator as allocated by shishi_authenticator().
685 * @key: key to to use for encryption.
686 * @keyusage: cryptographic key usage value to use in encryption.
687 * @data: input array with data to calculate checksum on.
688 * @datalen: size of input array with data to calculate checksum on.
690 * Calculate checksum for data and store it in the authenticator.
692 * Return value: Returns SHISHI_OK iff successful.
695 shishi_authenticator_add_cksum (Shishi * handle,
696 Shishi_asn1 authenticator,
697 Shishi_key * key,
698 int keyusage, char *data, size_t datalen)
700 return shishi_authenticator_add_cksum_type (handle, authenticator, key,
701 keyusage,
702 shishi_cipher_defaultcksumtype
703 (shishi_key_type (key)),
704 data, datalen);
708 * shishi_authenticator_add_cksum_type:
709 * @handle: shishi handle as allocated by shishi_init().
710 * @authenticator: authenticator as allocated by shishi_authenticator().
711 * @key: key to to use for encryption.
712 * @keyusage: cryptographic key usage value to use in encryption.
713 * @cksumtype: checksum to type to calculate checksum.
714 * @data: input array with data to calculate checksum on.
715 * @datalen: size of input array with data to calculate checksum on.
717 * Calculate checksum for data and store it in the authenticator.
719 * Return value: Returns SHISHI_OK iff successful.
722 shishi_authenticator_add_cksum_type (Shishi * handle,
723 Shishi_asn1 authenticator,
724 Shishi_key * key,
725 int keyusage, int cksumtype,
726 char *data, size_t datalen)
728 int res;
730 if (data && datalen > 0)
732 char *cksum;
733 size_t cksumlen;
735 res = shishi_checksum (handle, key, keyusage, cksumtype,
736 data, datalen, &cksum, &cksumlen);
737 if (res != SHISHI_OK)
738 return res;
740 res = shishi_authenticator_set_cksum (handle, authenticator,
741 cksumtype, cksum, cksumlen);
742 free (cksum);
744 else
745 res = shishi_authenticator_remove_cksum (handle, authenticator);
747 return res;
751 * shishi_authenticator_clear_authorizationdata:
752 * @handle: shishi handle as allocated by shishi_init().
753 * @authenticator: Authenticator as allocated by shishi_authenticator().
755 * Remove the authorization-data field from Authenticator.
757 * Return value: Returns SHISHI_OK iff successful.
760 shishi_authenticator_clear_authorizationdata (Shishi * handle,
761 Shishi_asn1 authenticator)
763 int res;
765 res = shishi_asn1_write (handle, authenticator,
766 "authorization-data", NULL, 0);
767 if (res != SHISHI_OK)
768 return SHISHI_ASN1_ERROR;
770 return SHISHI_OK;
774 * shishi_authenticator_add_authorizationdata:
775 * @handle: shishi handle as allocated by shishi_init().
776 * @authenticator: authenticator as allocated by shishi_authenticator().
777 * @adtype: input authorization data type to add.
778 * @addata: input authorization data to add.
779 * @addatalen: size of input authorization data to add.
781 * Add authorization data to authenticator.
783 * Return value: Returns SHISHI_OK iff successful.
786 shishi_authenticator_add_authorizationdata (Shishi * handle,
787 Shishi_asn1 authenticator,
788 int32_t adtype,
789 const char *addata,
790 size_t addatalen)
792 char *format;
793 int res;
794 size_t i;
796 res = shishi_asn1_write (handle, authenticator,
797 "authorization-data", "NEW", 1);
798 if (res != SHISHI_OK)
799 return res;
801 res = shishi_asn1_number_of_elements (handle, authenticator,
802 "authorization-data", &i);
803 if (res != SHISHI_OK)
804 return res;
806 asprintf (&format, "authorization-data.?%d.ad-type", i);
807 res = shishi_asn1_write_integer (handle, authenticator, format, adtype);
808 if (res != SHISHI_OK)
810 free (format);
811 return res;
814 sprintf (format, "authorization-data.?%d.ad-data", i);
815 res = shishi_asn1_write (handle, authenticator, format, addata, addatalen);
816 free (format);
817 if (res != SHISHI_OK)
818 return res;
820 return SHISHI_OK;
824 * shishi_authenticator_authorizationdata:
825 * @handle: shishi handle as allocated by shishi_init().
826 * @authenticator: authenticator as allocated by shishi_authenticator().
827 * @adtype: output authorization data type.
828 * @addata: newly allocated output authorization data.
829 * @addatalen: on output, actual size of newly allocated authorization data.
830 * @nth: element number of authorization-data to extract.
832 * Extract n:th authorization data from authenticator. The first
833 * field is 1.
835 * Return value: Returns SHISHI_OK iff successful.
838 shishi_authenticator_authorizationdata (Shishi * handle,
839 Shishi_asn1 authenticator,
840 int32_t * adtype,
841 char **addata, size_t * addatalen,
842 size_t nth)
844 char *format;
845 int res;
846 size_t i;
848 res = shishi_asn1_number_of_elements (handle, authenticator,
849 "authorization-data", &i);
850 if (res != SHISHI_OK)
851 return SHISHI_ASN1_ERROR;
853 if (nth > i)
854 return SHISHI_OUT_OF_RANGE;
856 asprintf (&format, "authorization-data.?%d.ad-type", nth);
857 res = shishi_asn1_read_int32 (handle, authenticator, format, adtype);
858 free (format);
859 if (res != SHISHI_OK)
860 return res;
862 asprintf (&format, "authorization-data.?%d.ad-data", i);
863 res = shishi_asn1_read (handle, authenticator, format, addata, addatalen);
864 free (format);
865 if (res != SHISHI_OK)
866 return res;
868 return SHISHI_OK;
872 * shishi_authenticator_remove_subkey:
873 * @handle: shishi handle as allocated by shishi_init().
874 * @authenticator: authenticator as allocated by shishi_authenticator().
876 * Remove subkey from the authenticator.
878 * Return value: Returns SHISHI_OK iff successful.
881 shishi_authenticator_remove_subkey (Shishi * handle,
882 Shishi_asn1 authenticator)
884 int res;
886 res = shishi_asn1_write (handle, authenticator, "subkey", NULL, 0);
887 if (res != SHISHI_OK)
888 return res;
890 return SHISHI_OK;
894 * shishi_authenticator_get_subkey:
895 * @handle: shishi handle as allocated by shishi_init().
896 * @authenticator: authenticator as allocated by shishi_authenticator().
897 * @subkey: output newly allocated subkey from authenticator.
899 * Read subkey value from authenticator.
901 * Return value: Returns SHISHI_OK if successful or SHISHI_ASN1_NO_ELEMENT
902 * if subkey is not present.
905 shishi_authenticator_get_subkey (Shishi * handle,
906 Shishi_asn1 authenticator,
907 Shishi_key ** subkey)
909 int res;
910 int subkeytype;
911 char *subkeyvalue;
912 size_t subkeylen;
914 res = shishi_asn1_read_int32 (handle, authenticator,
915 "subkey.keytype", &subkeytype);
916 if (res != SHISHI_OK)
917 return res;
919 res = shishi_asn1_read (handle, authenticator, "subkey.keyvalue",
920 &subkeyvalue, &subkeylen);
921 if (res != SHISHI_OK)
922 return res;
924 res = shishi_key (handle, subkey);
925 if (res != SHISHI_OK)
926 return res;
928 shishi_key_type_set (*subkey, subkeytype);
929 shishi_key_value_set (*subkey, subkeyvalue);
931 return SHISHI_OK;
935 * shishi_authenticator_set_subkey:
936 * @handle: shishi handle as allocated by shishi_init().
937 * @authenticator: authenticator as allocated by shishi_authenticator().
938 * @subkeytype: input subkey type to store in authenticator.
939 * @subkey: input subkey data to store in authenticator.
940 * @subkeylen: size of input subkey data to store in authenticator.
942 * Store subkey value in authenticator. A subkey is usually created
943 * by calling shishi_key_random() using the default encryption type of
944 * the key from the ticket that is being used. To save time, you may
945 * want to use shishi_authenticator_add_subkey() instead, which calculates
946 * the subkey and calls this function in one step.
948 * Return value: Returns SHISHI_OK iff successful.
951 shishi_authenticator_set_subkey (Shishi * handle,
952 Shishi_asn1 authenticator,
953 int32_t subkeytype,
954 char *subkey, size_t subkeylen)
956 int res;
958 res = shishi_asn1_write_int32 (handle, authenticator,
959 "subkey.keytype", subkeytype);
960 if (res != SHISHI_OK)
961 return res;
963 res = shishi_asn1_write (handle, authenticator, "subkey.keyvalue",
964 subkey, subkeylen);
965 if (res != SHISHI_OK)
966 return res;
968 return SHISHI_OK;
972 * shishi_authenticator_add_random_subkey:
973 * @handle: shishi handle as allocated by shishi_init().
974 * @authenticator: authenticator as allocated by shishi_authenticator().
976 * Generate random subkey, of the default encryption type from
977 * configuration, and store it in the authenticator.
979 * Return value: Returns SHISHI_OK iff successful.
982 shishi_authenticator_add_random_subkey (Shishi * handle,
983 Shishi_asn1 authenticator)
985 int n;
986 int res;
987 int *etypes;
989 n = shishi_cfg_clientkdcetype (handle, &etypes);
990 if (n <= 0)
991 return SHISHI_TICKET_BAD_KEYTYPE; /* XXX */
993 res = shishi_authenticator_add_random_subkey_etype (handle, authenticator,
994 etypes[0]);
995 if (res != SHISHI_OK)
996 return res;
998 return res;
1002 * shishi_authenticator_add_random_subkey_etype:
1003 * @handle: shishi handle as allocated by shishi_init().
1004 * @authenticator: authenticator as allocated by shishi_authenticator().
1005 * @etype: encryption type of random key to generate.
1007 * Generate random subkey of indicated encryption type, and store it
1008 * in the authenticator.
1010 * Return value: Returns SHISHI_OK iff successful.
1013 shishi_authenticator_add_random_subkey_etype (Shishi * handle,
1014 Shishi_asn1 authenticator,
1015 int etype)
1017 int res;
1018 Shishi_key *subkey;
1020 res = shishi_key_random (handle, etype, &subkey);
1021 if (res != SHISHI_OK)
1022 return res;
1024 res = shishi_authenticator_add_subkey (handle, authenticator, subkey);
1026 shishi_key_done (subkey);
1028 return res;
1032 * shishi_authenticator_add_subkey:
1033 * @handle: shishi handle as allocated by shishi_init().
1034 * @authenticator: authenticator as allocated by shishi_authenticator().
1035 * @subkey: subkey to add to authenticator.
1037 * Store subkey in the authenticator.
1039 * Return value: Returns SHISHI_OK iff successful.
1042 shishi_authenticator_add_subkey (Shishi * handle,
1043 Shishi_asn1 authenticator,
1044 Shishi_key * subkey)
1046 int res;
1048 res = shishi_authenticator_set_subkey (handle, authenticator,
1049 shishi_key_type (subkey),
1050 shishi_key_value (subkey),
1051 shishi_key_length (subkey));
1052 if (res != SHISHI_OK)
1053 return res;
1055 return SHISHI_OK;