1 /* authenticator.c functions for authenticators
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
25 * shishi_authenticator:
26 * @handle: shishi handle as allocated by shishi_init().
28 * This function creates a new Authenticator, populated with some
29 * default values. It uses the current time as returned by the system
30 * for the ctime and cusec fields.
32 * Return value: Returns the authenticator or NULL on
36 shishi_authenticator (Shishi
* handle
)
39 Shishi_asn1 node
= NULL
;
43 node
= shishi_asn1_authenticator (handle
);
47 res
= shishi_asn1_write (handle
, node
, "authenticator-vno", "5", 0);
51 res
= shishi_authenticator_set_crealm (handle
, node
,
52 shishi_realm_default (handle
));
56 res
= shishi_authenticator_client_set (handle
, node
,
57 shishi_principal_default (handle
));
61 gettimeofday (&tv
, &tz
);
62 res
= shishi_authenticator_cusec_set (handle
, node
, tv
.tv_usec
% 1000000);
66 res
= shishi_asn1_write (handle
, node
, "ctime",
67 shishi_generalize_time (handle
, time (NULL
)), 0);
71 res
= shishi_asn1_write (handle
, node
, "seq-number", NULL
, 0);
78 shishi_asn1_done (handle
, node
);
83 * shishi_authenticator_subkey:
84 * @handle: shishi handle as allocated by shishi_init().
86 * This function creates a new Authenticator, populated with some
87 * default values. It uses the current time as returned by the system
88 * for the ctime and cusec fields. It adds a random subkey.
90 * Return value: Returns the authenticator or NULL on
94 shishi_authenticator_subkey (Shishi
* handle
)
99 node
= shishi_authenticator (handle
);
103 res
= shishi_authenticator_add_random_subkey (handle
, node
);
104 if (res
!= SHISHI_OK
)
111 * shishi_authenticator_print:
112 * @handle: shishi handle as allocated by shishi_init().
113 * @fh: file handle open for writing.
114 * @authenticator: authenticator as allocated by shishi_authenticator().
116 * Print ASCII armored DER encoding of authenticator to file.
118 * Return value: Returns SHISHI_OK iff successful.
121 shishi_authenticator_print (Shishi
* handle
,
122 FILE * fh
, Shishi_asn1 authenticator
)
124 return _shishi_print_armored_data (handle
, fh
, authenticator
,
125 "Authenticator", NULL
);
129 * shishi_authenticator_save:
130 * @handle: shishi handle as allocated by shishi_init().
131 * @fh: file handle open for writing.
132 * @authenticator: authenticator as allocated by shishi_authenticator().
134 * Save DER encoding of authenticator to file.
136 * Return value: Returns SHISHI_OK iff successful.
139 shishi_authenticator_save (Shishi
* handle
,
140 FILE * fh
, Shishi_asn1 authenticator
)
142 return _shishi_save_data (handle
, fh
, authenticator
, "Authenticator");
146 * shishi_authenticator_to_file:
147 * @handle: shishi handle as allocated by shishi_init().
148 * @authenticator: Authenticator to save.
149 * @filetype: input variable specifying type of file to be written,
150 * see Shishi_filetype.
151 * @filename: input variable with filename to write to.
153 * Write Authenticator to file in specified TYPE. The file will be
154 * truncated if it exists.
156 * Return value: Returns SHISHI_OK iff successful.
159 shishi_authenticator_to_file (Shishi
* handle
, Shishi_asn1 authenticator
,
160 int filetype
, char *filename
)
165 if (VERBOSE (handle
))
166 printf (_("Writing Authenticator to %s...\n"), filename
);
168 fh
= fopen (filename
, "w");
170 return SHISHI_FOPEN_ERROR
;
172 if (VERBOSE (handle
))
173 printf (_("Writing Authenticator in %s format...\n"),
174 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
176 if (filetype
== SHISHI_FILETYPE_TEXT
)
177 res
= shishi_authenticator_print (handle
, fh
, authenticator
);
179 res
= shishi_authenticator_save (handle
, fh
, authenticator
);
180 if (res
!= SHISHI_OK
)
185 return SHISHI_FCLOSE_ERROR
;
187 if (VERBOSE (handle
))
188 printf (_("Writing Authenticator to %s...done\n"), filename
);
194 * shishi_authenticator_parse:
195 * @handle: shishi handle as allocated by shishi_init().
196 * @fh: file handle open for reading.
197 * @authenticator: output variable with newly allocated authenticator.
199 * Read ASCII armored DER encoded authenticator from file and populate
200 * given authenticator variable.
202 * Return value: Returns SHISHI_OK iff successful.
205 shishi_authenticator_parse (Shishi
* handle
,
206 FILE * fh
, Shishi_asn1
* authenticator
)
208 return _shishi_authenticator_input (handle
, fh
, authenticator
, 0);
212 * shishi_authenticator_read:
213 * @handle: shishi handle as allocated by shishi_init().
214 * @fh: file handle open for reading.
215 * @authenticator: output variable with newly allocated authenticator.
217 * Read DER encoded authenticator from file and populate given
218 * authenticator variable.
220 * Return value: Returns SHISHI_OK iff successful.
223 shishi_authenticator_read (Shishi
* handle
,
224 FILE * fh
, Shishi_asn1
* authenticator
)
226 return _shishi_authenticator_input (handle
, fh
, authenticator
, 1);
230 * shishi_authenticator_from_file:
231 * @handle: shishi handle as allocated by shishi_init().
232 * @authenticator: output variable with newly allocated Authenticator.
233 * @filetype: input variable specifying type of file to be read,
234 * see Shishi_filetype.
235 * @filename: input variable with filename to read from.
237 * Read Authenticator from file in specified TYPE.
239 * Return value: Returns SHISHI_OK iff successful.
242 shishi_authenticator_from_file (Shishi
* handle
, Shishi_asn1
* authenticator
,
243 int filetype
, char *filename
)
248 if (VERBOSE (handle
))
249 printf (_("Reading Authenticator from %s...\n"), filename
);
251 fh
= fopen (filename
, "r");
253 return SHISHI_FOPEN_ERROR
;
255 if (VERBOSE (handle
))
256 printf (_("Reading Authenticator in %s format...\n"),
257 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
259 if (filetype
== SHISHI_FILETYPE_TEXT
)
260 res
= shishi_authenticator_parse (handle
, fh
, authenticator
);
262 res
= shishi_authenticator_read (handle
, fh
, authenticator
);
263 if (res
!= SHISHI_OK
)
268 return SHISHI_FCLOSE_ERROR
;
270 if (VERBOSE (handle
))
271 printf (_("Reading Authenticator from %s...done\n"), filename
);
277 * shishi_authenticator_set_crealm:
278 * @handle: shishi handle as allocated by shishi_init().
279 * @authenticator: authenticator as allocated by shishi_authenticator().
280 * @crealm: input array with realm.
282 * Set realm field in authenticator to specified value.
284 * Return value: Returns SHISHI_OK iff successful.
287 shishi_authenticator_set_crealm (Shishi
* handle
,
288 Shishi_asn1 authenticator
,
293 res
= shishi_asn1_write (handle
, authenticator
, "crealm", crealm
, 0);
294 if (res
!= SHISHI_OK
)
301 * shishi_authenticator_set_cname:
302 * @handle: shishi handle as allocated by shishi_init().
303 * @authenticator: authenticator as allocated by shishi_authenticator().
304 * @name_type: type of principial, see Shishi_name_type, usually
306 * @cname: input array with principal name.
308 * Set principal field in authenticator to specified value.
310 * Return value: Returns SHISHI_OK iff successful.
313 shishi_authenticator_set_cname (Shishi
* handle
,
314 Shishi_asn1 authenticator
,
315 Shishi_name_type name_type
,
320 res
= shishi_principal_name_set (handle
, authenticator
, "cname",
322 if (res
!= SHISHI_OK
)
329 * shishi_authenticator_client_set:
330 * @handle: shishi handle as allocated by shishi_init().
331 * @authenticator: Authenticator to set client name field in.
332 * @client: zero-terminated string with principal name on RFC 1964 form.
334 * Set the client name field in the Authenticator.
336 * Return value: Returns SHISHI_OK iff successful.
339 shishi_authenticator_client_set (Shishi
* handle
,
340 Shishi_asn1 authenticator
,
345 res
= shishi_principal_set (handle
, authenticator
, "cname", client
);
346 if (res
!= SHISHI_OK
)
353 * shishi_authenticator_ctime:
354 * @handle: shishi handle as allocated by shishi_init().
355 * @authenticator: Authenticator as allocated by shishi_authenticator().
356 * @ctime: newly allocated zero-terminated character array with client time.
358 * Extract client time from Authenticator.
360 * Return value: Returns SHISHI_OK iff successful.
363 shishi_authenticator_ctime (Shishi
* handle
,
364 Shishi_asn1 authenticator
, char **ctime
)
366 return shishi_time (handle
, authenticator
, "ctime", ctime
);
370 * shishi_authenticator_ctime_set:
371 * @handle: shishi handle as allocated by shishi_init().
372 * @authenticator: Authenticator as allocated by shishi_authenticator().
373 * @ctime: string with generalized time value to store in Authenticator.
375 * Store client time in Authenticator.
377 * Return value: Returns SHISHI_OK iff successful.
380 shishi_authenticator_ctime_set (Shishi
* handle
,
381 Shishi_asn1 authenticator
, char *ctime
)
385 res
= shishi_asn1_write (handle
, authenticator
, "ctime",
386 ctime
, GENERALIZEDTIME_TIME_LEN
);
387 if (res
!= SHISHI_OK
)
394 * shishi_authenticator_cusec_get:
395 * @handle: shishi handle as allocated by shishi_init().
396 * @authenticator: Authenticator as allocated by shishi_authenticator().
397 * @cusec: output integer with client microseconds field.
399 * Extract client microseconds field from Authenticator.
401 * Return value: Returns SHISHI_OK iff successful.
404 shishi_authenticator_cusec_get (Shishi
* handle
,
405 Shishi_asn1 authenticator
, int *cusec
)
409 res
= shishi_asn1_read_uint32 (handle
, authenticator
, "cusec", cusec
);
410 if (res
!= SHISHI_OK
)
417 * shishi_authenticator_cusec_set:
418 * @handle: shishi handle as allocated by shishi_init().
419 * @authenticator: authenticator as allocated by shishi_authenticator().
420 * @cusec: client microseconds to set in authenticator, 0-999999.
422 * Set the cusec field in the Authenticator.
424 * Return value: Returns SHISHI_OK iff successful.
427 shishi_authenticator_cusec_set (Shishi
* handle
,
428 Shishi_asn1 authenticator
, int cusec
)
432 res
= shishi_asn1_write_uint32 (handle
, authenticator
, "cusec", cusec
);
433 if (res
!= SHISHI_OK
)
440 shishi_authenticator_cname_get (Shishi
* handle
,
441 Shishi_asn1 authenticator
,
442 char *cname
, size_t * cnamelen
)
444 return shishi_principal_name_get (handle
, authenticator
,
445 "cname", cname
, cnamelen
);
449 shishi_authenticator_cnamerealm_get (Shishi
* handle
,
450 Shishi_asn1 authenticator
,
451 char *cnamerealm
, size_t * cnamerealmlen
)
453 return shishi_principal_name_realm_get (handle
, authenticator
,
457 cnamerealm
, cnamerealmlen
);
461 shishi_authenticator_remove_cksum (Shishi
* handle
, Shishi_asn1 authenticator
)
465 /* XXX remove this function */
467 res
= shishi_asn1_write (handle
, authenticator
, "cksum", NULL
, 0);
468 if (res
!= SHISHI_OK
)
475 * shishi_authenticator_cksum:
476 * @handle: shishi handle as allocated by shishi_init().
477 * @authenticator: authenticator as allocated by shishi_authenticator().
478 * @cksumtype: output checksum type.
479 * @cksum: output checksum data from authenticator.
480 * @cksumlen: on input, maximum size of output checksum data buffer,
481 * on output, actual size of output checksum data buffer.
483 * Read checksum value from authenticator.
485 * Return value: Returns SHISHI_OK iff successful.
488 shishi_authenticator_cksum (Shishi
* handle
,
489 Shishi_asn1 authenticator
,
491 char *cksum
, size_t * cksumlen
)
495 res
= shishi_asn1_read_int32 (handle
, authenticator
,
496 "cksum.cksumtype", cksumtype
);
497 if (res
!= SHISHI_OK
)
500 res
= shishi_asn1_read (handle
, authenticator
, "cksum.checksum",
502 if (res
!= SHISHI_OK
)
509 * shishi_authenticator_set_cksum:
510 * @handle: shishi handle as allocated by shishi_init().
511 * @authenticator: authenticator as allocated by shishi_authenticator().
512 * @cksumtype: input checksum type to store in authenticator.
513 * @cksum: input checksum data to store in authenticator.
514 * @cksumlen: size of input checksum data to store in authenticator.
516 * Store checksum value in authenticator. A checksum is usually created
517 * by calling shishi_checksum() on some application specific data using
518 * the key from the ticket that is being used. To save time, you may
519 * want to use shishi_authenticator_add_cksum() instead, which calculates
520 * the checksum and calls this function in one step.
522 * Return value: Returns SHISHI_OK iff successful.
525 shishi_authenticator_set_cksum (Shishi
* handle
,
526 Shishi_asn1 authenticator
,
528 char *cksum
, size_t cksumlen
)
532 res
= shishi_asn1_write_int32 (handle
, authenticator
,
533 "cksum.cksumtype", cksumtype
);
534 if (res
!= SHISHI_OK
)
537 res
= shishi_asn1_write (handle
, authenticator
, "cksum.checksum",
539 if (res
!= SHISHI_OK
)
546 * shishi_authenticator_add_cksum:
547 * @handle: shishi handle as allocated by shishi_init().
548 * @authenticator: authenticator as allocated by shishi_authenticator().
549 * @key: key to to use for encryption.
550 * @keyusage: kerberos key usage value to use in encryption.
551 * @data: input array with data to calculate checksum on.
552 * @datalen: size of input array with data to calculate checksum on.
554 * Calculate checksum for data and store it in the authenticator.
556 * Return value: Returns SHISHI_OK iff successful.
559 shishi_authenticator_add_cksum (Shishi
* handle
,
560 Shishi_asn1 authenticator
,
562 int keyusage
, char *data
, size_t datalen
)
564 return shishi_authenticator_add_cksum_type (handle
, authenticator
, key
,
566 shishi_cipher_defaultcksumtype
567 (shishi_key_type (key
)),
572 * shishi_authenticator_add_cksum_type:
573 * @handle: shishi handle as allocated by shishi_init().
574 * @authenticator: authenticator as allocated by shishi_authenticator().
575 * @key: key to to use for encryption.
576 * @keyusage: kerberos key usage value to use in encryption.
577 * @cksumtype: checksum to type to calculate checksum.
578 * @data: input array with data to calculate checksum on.
579 * @datalen: size of input array with data to calculate checksum on.
581 * Calculate checksum for data and store it in the authenticator.
583 * Return value: Returns SHISHI_OK iff successful.
586 shishi_authenticator_add_cksum_type (Shishi
* handle
,
587 Shishi_asn1 authenticator
,
589 int keyusage
, int cksumtype
,
590 char *data
, size_t datalen
)
594 if (data
&& datalen
> 0)
599 res
= shishi_checksum (handle
, key
, keyusage
, cksumtype
,
600 data
, datalen
, &cksum
, &cksumlen
);
601 if (res
!= SHISHI_OK
)
604 res
= shishi_authenticator_set_cksum (handle
, authenticator
,
605 cksumtype
, cksum
, cksumlen
);
609 res
= shishi_authenticator_remove_cksum (handle
, authenticator
);
615 * shishi_authenticator_clear_authorizationdata:
616 * @handle: shishi handle as allocated by shishi_init().
617 * @authenticator: Authenticator as allocated by shishi_authenticator().
619 * Remove the authorization-data field from Authenticator.
621 * Return value: Returns SHISHI_OK iff successful.
624 shishi_authenticator_clear_authorizationdata (Shishi
* handle
,
625 Shishi_asn1 authenticator
)
629 res
= shishi_asn1_write (handle
, authenticator
,
630 "authorization-data", NULL
, 0);
631 if (res
!= SHISHI_OK
)
632 return SHISHI_ASN1_ERROR
;
638 * shishi_authenticator_add_authorizationdata:
639 * @handle: shishi handle as allocated by shishi_init().
640 * @authenticator: authenticator as allocated by shishi_authenticator().
641 * @adtype: input authorization data type to add.
642 * @addata: input authorization data to add.
643 * @addatalen: size of input authorization data to add.
645 * Add authorization data to authenticator.
647 * Return value: Returns SHISHI_OK iff successful.
650 shishi_authenticator_add_authorizationdata (Shishi
* handle
,
651 Shishi_asn1 authenticator
,
653 char *addata
, size_t addatalen
)
659 res
= shishi_asn1_write (handle
, authenticator
,
660 "authorization-data", "NEW", 1);
661 if (res
!= SHISHI_OK
)
664 res
= shishi_asn1_number_of_elements (handle
, authenticator
,
665 "authorization-data", &i
);
666 if (res
!= SHISHI_OK
)
669 asprintf (&format
, "authorization-data.?%d.ad-type", i
);
670 res
= shishi_asn1_write_integer (handle
, authenticator
, format
, adtype
);
671 if (res
!= SHISHI_OK
)
677 sprintf (format
, "authorization-data.?%d.ad-data", i
);
678 res
= shishi_asn1_write (handle
, authenticator
, format
, addata
, addatalen
);
680 if (res
!= SHISHI_OK
)
687 * shishi_authenticator_authorizationdata:
688 * @handle: shishi handle as allocated by shishi_init().
689 * @authenticator: authenticator as allocated by shishi_authenticator().
690 * @adtype: output authorization data type.
691 * @addata: output authorization data.
692 * @addatalen: on input, maximum size of output authorization data,
693 * on output, actual size of authorization data.
694 * @nth: element number of authorization-data to extract.
696 * Extract n:th authorization data from authenticator. The first
699 * Return value: Returns SHISHI_OK iff successful.
702 shishi_authenticator_authorizationdata (Shishi
* handle
,
703 Shishi_asn1 authenticator
,
705 char *addata
, size_t * addatalen
,
712 res
= shishi_asn1_number_of_elements (handle
, authenticator
,
713 "authorization-data", &i
);
714 if (res
!= SHISHI_OK
)
715 return SHISHI_ASN1_ERROR
;
718 return SHISHI_OUT_OF_RANGE
;
720 asprintf (&format
, "authorization-data.?%d.ad-type", nth
);
721 res
= shishi_asn1_read_int32 (handle
, authenticator
, format
, adtype
);
723 if (res
!= SHISHI_OK
)
726 asprintf (&format
, "authorization-data.?%d.ad-data", i
);
727 res
= shishi_asn1_read (handle
, authenticator
, format
, addata
, addatalen
);
729 if (res
!= SHISHI_OK
)
736 * shishi_authenticator_remove_subkey:
737 * @handle: shishi handle as allocated by shishi_init().
738 * @authenticator: authenticator as allocated by shishi_authenticator().
740 * Remove subkey from the authenticator.
742 * Return value: Returns SHISHI_OK iff successful.
745 shishi_authenticator_remove_subkey (Shishi
* handle
,
746 Shishi_asn1 authenticator
)
750 res
= shishi_asn1_write (handle
, authenticator
, "subkey", NULL
, 0);
751 if (res
!= SHISHI_OK
)
758 * shishi_authenticator_get_subkey:
759 * @handle: shishi handle as allocated by shishi_init().
760 * @authenticator: authenticator as allocated by shishi_authenticator().
761 * @subkey: output newly allocated subkey from authenticator.
763 * Read subkey value from authenticator.
765 * Return value: Returns SHISHI_OK if successful or SHISHI_ASN1_NO_ELEMENT
766 * if subkey is not present.
769 shishi_authenticator_get_subkey (Shishi
* handle
,
770 Shishi_asn1 authenticator
,
771 Shishi_key
** subkey
)
779 res
= shishi_asn1_number_of_elements (handle
, authenticator
, "subkey", &n
);
780 if (res
!= SHISHI_OK
)
783 res
= shishi_asn1_read_int32 (handle
, authenticator
,
784 "subkey.keytype", &subkeytype
);
785 if (res
!= SHISHI_OK
)
788 res
= shishi_asn1_read2 (handle
, authenticator
, "subkey.keyvalue",
789 &subkeyvalue
, &subkeylen
);
790 if (res
!= SHISHI_OK
)
793 res
= shishi_key (handle
, subkey
);
794 if (res
!= SHISHI_OK
)
797 shishi_key_type_set (*subkey
, subkeytype
);
798 shishi_key_value_set (*subkey
, subkeyvalue
);
804 * shishi_authenticator_set_subkey:
805 * @handle: shishi handle as allocated by shishi_init().
806 * @authenticator: authenticator as allocated by shishi_authenticator().
807 * @subkeytype: input subkey type to store in authenticator.
808 * @subkey: input subkey data to store in authenticator.
809 * @subkeylen: size of input subkey data to store in authenticator.
811 * Store subkey value in authenticator. A subkey is usually created
812 * by calling shishi_key_random() using the default encryption type of
813 * the key from the ticket that is being used. To save time, you may
814 * want to use shishi_authenticator_add_subkey() instead, which calculates
815 * the subkey and calls this function in one step.
817 * Return value: Returns SHISHI_OK iff successful.
820 shishi_authenticator_set_subkey (Shishi
* handle
,
821 Shishi_asn1 authenticator
,
823 char *subkey
, size_t subkeylen
)
827 res
= shishi_asn1_write_int32 (handle
, authenticator
,
828 "subkey.keytype", subkeytype
);
829 if (res
!= SHISHI_OK
)
832 res
= shishi_asn1_write (handle
, authenticator
, "subkey.keyvalue",
834 if (res
!= SHISHI_OK
)
841 * shishi_authenticator_add_random_subkey:
842 * @handle: shishi handle as allocated by shishi_init().
843 * @authenticator: authenticator as allocated by shishi_authenticator().
845 * Generate random subkey and store it in the authenticator.
847 * Return value: Returns SHISHI_OK iff successful.
850 shishi_authenticator_add_random_subkey (Shishi
* handle
,
851 Shishi_asn1 authenticator
)
857 res
= shishi_cfg_clientkdcetype (handle
, &etypes
);
861 res
= shishi_key_random (handle
, etypes
[0], &subkey
);
862 if (res
!= SHISHI_OK
)
865 res
= shishi_authenticator_set_subkey (handle
, authenticator
,
866 shishi_key_type (subkey
),
867 shishi_key_value (subkey
),
868 shishi_key_length (subkey
));
870 shishi_key_done (subkey
);
876 * shishi_authenticator_add_subkey:
877 * @handle: shishi handle as allocated by shishi_init().
878 * @authenticator: authenticator as allocated by shishi_authenticator().
879 * @subkey: subkey to add to authenticator.
881 * Store subkey in the authenticator.
883 * Return value: Returns SHISHI_OK iff successful.
886 shishi_authenticator_add_subkey (Shishi
* handle
,
887 Shishi_asn1 authenticator
,
893 res
= shishi_cfg_clientkdcetype (handle
, &etypes
);
894 if (res
!= SHISHI_OK
)
897 res
= shishi_authenticator_set_subkey (handle
, authenticator
,
898 shishi_key_type (subkey
),
899 shishi_key_value (subkey
),
900 shishi_key_length (subkey
));