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
, "subkey", NULL
, 0);
75 res
= shishi_asn1_write (handle
, node
, "seq-number", NULL
, 0);
82 shishi_asn1_done (handle
, node
);
87 * shishi_authenticator_print:
88 * @handle: shishi handle as allocated by shishi_init().
89 * @fh: file handle open for writing.
90 * @authenticator: authenticator as allocated by shishi_authenticator().
92 * Print ASCII armored DER encoding of authenticator to file.
94 * Return value: Returns SHISHI_OK iff successful.
97 shishi_authenticator_print (Shishi
* handle
,
98 FILE * fh
, Shishi_asn1 authenticator
)
100 return _shishi_print_armored_data (handle
, fh
, authenticator
,
101 "Authenticator", NULL
);
105 * shishi_authenticator_save:
106 * @handle: shishi handle as allocated by shishi_init().
107 * @fh: file handle open for writing.
108 * @authenticator: authenticator as allocated by shishi_authenticator().
110 * Save DER encoding of authenticator to file.
112 * Return value: Returns SHISHI_OK iff successful.
115 shishi_authenticator_save (Shishi
* handle
,
116 FILE * fh
, Shishi_asn1 authenticator
)
118 return _shishi_save_data (handle
, fh
, authenticator
, "Authenticator");
122 * shishi_authenticator_to_file:
123 * @handle: shishi handle as allocated by shishi_init().
124 * @authenticator: Authenticator to save.
125 * @filetype: input variable specifying type of file to be written,
126 * see Shishi_filetype.
127 * @filename: input variable with filename to write to.
129 * Write Authenticator to file in specified TYPE. The file will be
130 * truncated if it exists.
132 * Return value: Returns SHISHI_OK iff successful.
135 shishi_authenticator_to_file (Shishi
* handle
, Shishi_asn1 authenticator
,
136 int filetype
, char *filename
)
141 if (VERBOSE (handle
))
142 printf (_("Writing Authenticator to %s...\n"), filename
);
144 fh
= fopen (filename
, "w");
146 return SHISHI_FOPEN_ERROR
;
148 if (VERBOSE (handle
))
149 printf (_("Writing Authenticator in %s format...\n"),
150 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
152 if (filetype
== SHISHI_FILETYPE_TEXT
)
153 res
= shishi_authenticator_print (handle
, fh
, authenticator
);
155 res
= shishi_authenticator_save (handle
, fh
, authenticator
);
156 if (res
!= SHISHI_OK
)
161 return SHISHI_FCLOSE_ERROR
;
163 if (VERBOSE (handle
))
164 printf (_("Writing Authenticator to %s...done\n"), filename
);
170 * shishi_authenticator_parse:
171 * @handle: shishi handle as allocated by shishi_init().
172 * @fh: file handle open for reading.
173 * @authenticator: output variable with newly allocated authenticator.
175 * Read ASCII armored DER encoded authenticator from file and populate
176 * given authenticator variable.
178 * Return value: Returns SHISHI_OK iff successful.
181 shishi_authenticator_parse (Shishi
* handle
,
182 FILE * fh
, Shishi_asn1
* authenticator
)
184 return _shishi_authenticator_input (handle
, fh
, authenticator
, 0);
188 * shishi_authenticator_read:
189 * @handle: shishi handle as allocated by shishi_init().
190 * @fh: file handle open for reading.
191 * @authenticator: output variable with newly allocated authenticator.
193 * Read DER encoded authenticator from file and populate given
194 * authenticator variable.
196 * Return value: Returns SHISHI_OK iff successful.
199 shishi_authenticator_read (Shishi
* handle
,
200 FILE * fh
, Shishi_asn1
* authenticator
)
202 return _shishi_authenticator_input (handle
, fh
, authenticator
, 1);
206 * shishi_authenticator_from_file:
207 * @handle: shishi handle as allocated by shishi_init().
208 * @authenticator: output variable with newly allocated Authenticator.
209 * @filetype: input variable specifying type of file to be read,
210 * see Shishi_filetype.
211 * @filename: input variable with filename to read from.
213 * Read Authenticator from file in specified TYPE.
215 * Return value: Returns SHISHI_OK iff successful.
218 shishi_authenticator_from_file (Shishi
* handle
, Shishi_asn1
* authenticator
,
219 int filetype
, char *filename
)
224 if (VERBOSE (handle
))
225 printf (_("Reading Authenticator from %s...\n"), filename
);
227 fh
= fopen (filename
, "r");
229 return SHISHI_FOPEN_ERROR
;
231 if (VERBOSE (handle
))
232 printf (_("Reading Authenticator in %s format...\n"),
233 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
235 if (filetype
== SHISHI_FILETYPE_TEXT
)
236 res
= shishi_authenticator_parse (handle
, fh
, authenticator
);
238 res
= shishi_authenticator_read (handle
, fh
, authenticator
);
239 if (res
!= SHISHI_OK
)
244 return SHISHI_FCLOSE_ERROR
;
246 if (VERBOSE (handle
))
247 printf (_("Reading Authenticator from %s...done\n"), filename
);
253 * shishi_authenticator_set_crealm:
254 * @handle: shishi handle as allocated by shishi_init().
255 * @authenticator: authenticator as allocated by shishi_authenticator().
256 * @crealm: input array with realm.
258 * Set realm field in authenticator to specified value.
260 * Return value: Returns SHISHI_OK iff successful.
263 shishi_authenticator_set_crealm (Shishi
* handle
,
264 Shishi_asn1 authenticator
,
269 res
= shishi_asn1_write (handle
, authenticator
, "crealm", crealm
, 0);
270 if (res
!= SHISHI_OK
)
277 * shishi_authenticator_set_cname:
278 * @handle: shishi handle as allocated by shishi_init().
279 * @authenticator: authenticator as allocated by shishi_authenticator().
280 * @name_type: type of principial, see Shishi_name_type, usually
282 * @principal: input array with principal name.
284 * Set principal field in authenticator to specified value.
286 * Return value: Returns SHISHI_OK iff successful.
289 shishi_authenticator_set_cname (Shishi
* handle
,
290 Shishi_asn1 authenticator
,
291 Shishi_name_type name_type
,
296 res
= shishi_principal_name_set (handle
, authenticator
, "cname",
298 if (res
!= SHISHI_OK
)
305 * shishi_authenticator_client_set:
306 * @handle: shishi handle as allocated by shishi_init().
307 * @kdcrep: Authenticator to set client name field in.
308 * @name: zero-terminated string with principal name on RFC 1964 form.
310 * Set the client name field in the Authenticator.
312 * Return value: Returns SHISHI_OK iff successful.
315 shishi_authenticator_client_set (Shishi
* handle
,
316 Shishi_asn1 authenticator
,
321 res
= shishi_principal_set (handle
, authenticator
, "cname", client
);
322 if (res
!= SHISHI_OK
)
329 shishi_authenticator_ctime_get (Shishi
* handle
,
330 Shishi_asn1 authenticator
, char *ctime
)
335 len
= GENERALIZEDTIME_TIME_LEN
+ 1;
336 res
= shishi_asn1_field (handle
, authenticator
, ctime
, &len
, "ctime");
337 if (res
== SHISHI_OK
&& len
== GENERALIZEDTIME_TIME_LEN
)
344 * shishi_authenticator_ctime_set:
345 * @handle: shishi handle as allocated by shishi_init().
346 * @authenticator: Authenticator as allocated by shishi_authenticator().
347 * @ctime: string with generalized time value to store in Authenticator.
349 * Store client time in Authenticator.
351 * Return value: Returns SHISHI_OK iff successful.
354 shishi_authenticator_ctime_set (Shishi
* handle
,
355 Shishi_asn1 authenticator
, char *ctime
)
359 res
= shishi_asn1_write (handle
, authenticator
, "ctime",
360 ctime
, GENERALIZEDTIME_TIME_LEN
);
361 if (res
!= SHISHI_OK
)
368 * shishi_authenticator_cusec_get:
369 * @handle: shishi handle as allocated by shishi_init().
370 * @authenticator: Authenticator as allocated by shishi_authenticator().
371 * @cusec: output integer with client microseconds field.
373 * Extract client microseconds field from Authenticator.
375 * Return value: Returns SHISHI_OK iff successful.
378 shishi_authenticator_cusec_get (Shishi
* handle
,
379 Shishi_asn1 authenticator
, int *cusec
)
383 res
= shishi_asn1_read_integer (handle
, authenticator
, "cusec", cusec
);
384 if (res
!= SHISHI_OK
)
391 * shishi_authenticator_cusec_set:
392 * @handle: shishi handle as allocated by shishi_init().
393 * @authenticator: authenticator as allocated by shishi_authenticator().
394 * @cusec: client microseconds to set in authenticator, 0-999999.
396 * Set the cusec field in the Authenticator.
398 * Return value: Returns SHISHI_OK iff successful.
401 shishi_authenticator_cusec_set (Shishi
* handle
,
402 Shishi_asn1 authenticator
, int cusec
)
406 res
= shishi_asn1_write_integer (handle
, authenticator
, "cusec", cusec
);
407 if (res
!= SHISHI_OK
)
414 shishi_authenticator_cname_get (Shishi
* handle
,
415 Shishi_asn1 authenticator
,
416 char *cname
, int *cnamelen
)
418 return shishi_principal_name_get (handle
, authenticator
,
419 "cname", cname
, cnamelen
);
423 shishi_authenticator_cnamerealm_get (Shishi
* handle
,
424 Shishi_asn1 authenticator
,
425 char *cnamerealm
, int *cnamerealmlen
)
427 return shishi_principal_name_realm_get (handle
, authenticator
,
431 cnamerealm
, cnamerealmlen
);
435 shishi_authenticator_remove_cksum (Shishi
* handle
, Shishi_asn1 authenticator
)
439 /* XXX remove this function */
441 res
= shishi_asn1_write (handle
, authenticator
, "cksum", NULL
, 0);
442 if (res
!= SHISHI_OK
)
449 * shishi_authenticator_cksum:
450 * @handle: shishi handle as allocated by shishi_init().
451 * @authenticator: authenticator as allocated by shishi_authenticator().
452 * @cksumtype: output checksum type.
453 * @cksum: output checksum data from authenticator.
454 * @cksumlen: on input, maximum size of output checksum data buffer,
455 * on output, actual size of output checksum data buffer.
457 * Read checksum value from authenticator.
459 * Return value: Returns SHISHI_OK iff successful.
462 shishi_authenticator_cksum (Shishi
* handle
,
463 Shishi_asn1 authenticator
,
465 char *cksum
, size_t * cksumlen
)
469 res
= shishi_asn1_read_int32 (handle
, authenticator
,
470 "cksum.cksumtype", cksumtype
);
471 if (res
!= SHISHI_OK
)
474 res
= shishi_asn1_field (handle
, authenticator
, cksum
, cksumlen
,
476 if (res
!= SHISHI_OK
)
483 * shishi_authenticator_set_cksum:
484 * @handle: shishi handle as allocated by shishi_init().
485 * @authenticator: authenticator as allocated by shishi_authenticator().
486 * @cksumtype: input checksum type to store in authenticator.
487 * @cksum: input checksum data to store in authenticator.
488 * @cksumlen: size of input checksum data to store in authenticator.
490 * Store checksum value in authenticator. A checksum is usually created
491 * by calling shishi_checksum() on some application specific data using
492 * the key from the ticket that is being used. To save time, you may
493 * want to use shishi_authenticator_add_cksum() instead, which calculates
494 * the checksum and calls this function in one step.
496 * Return value: Returns SHISHI_OK iff successful.
499 shishi_authenticator_set_cksum (Shishi
* handle
,
500 Shishi_asn1 authenticator
,
502 char *cksum
, size_t cksumlen
)
506 res
= shishi_asn1_write_int32 (handle
, authenticator
,
507 "cksum.cksumtype", cksumtype
);
508 if (res
!= SHISHI_OK
)
511 res
= shishi_asn1_write (handle
, authenticator
, "cksum.checksum",
513 if (res
!= SHISHI_OK
)
520 * shishi_authenticator_add_cksum:
521 * @handle: shishi handle as allocated by shishi_init().
522 * @authenticator: authenticator as allocated by shishi_authenticator().
523 * @enckdcreppart: ticket information where the key is taken from.
524 * @data: input array with data to calculate checksum on.
525 * @datalen: size of input array with data to calculate checksum on.
527 * Calculate checksum for data and store it in the authenticator.
529 * Return value: Returns SHISHI_OK iff successful.
532 shishi_authenticator_add_cksum (Shishi
* handle
,
533 Shishi_asn1 authenticator
,
535 int keyusage
, char *data
, int datalen
)
539 if (data
&& datalen
> 0)
543 int cksumtype
= shishi_cipher_defaultcksumtype (shishi_key_type (key
));
545 res
= shishi_checksum (handle
, key
, keyusage
, cksumtype
,
546 data
, datalen
, &cksum
, &cksumlen
);
547 if (res
!= SHISHI_OK
)
550 res
= shishi_authenticator_set_cksum (handle
, authenticator
,
551 cksumtype
, cksum
, cksumlen
);
555 res
= shishi_authenticator_remove_cksum (handle
, authenticator
);
561 * shishi_authenticator_clear_authorizationdata:
562 * @handle: shishi handle as allocated by shishi_init().
563 * @authenticator: Authenticator as allocated by shishi_authenticator().
565 * Remove the authorization-data field from Authenticator.
567 * Return value: Returns SHISHI_OK iff successful.
570 shishi_authenticator_clear_authorizationdata (Shishi
* handle
,
571 Shishi_asn1 authenticator
)
575 res
= shishi_asn1_write (handle
, authenticator
,
576 "authorization-data", NULL
, 0);
577 if (res
!= SHISHI_OK
)
578 return SHISHI_ASN1_ERROR
;
584 * shishi_authenticator_add_authorizationdata:
585 * @handle: shishi handle as allocated by shishi_init().
586 * @authenticator: authenticator as allocated by shishi_authenticator().
587 * @adtype: input authorization data type to add.
588 * @addata: input authorization data to add.
589 * @addatalen: size of input authorization data to add.
591 * Add authorization data to authenticator.
593 * Return value: Returns SHISHI_OK iff successful.
596 shishi_authenticator_add_authorizationdata (Shishi
* handle
,
597 Shishi_asn1 authenticator
,
599 char *addata
, int addatalen
)
605 res
= shishi_asn1_write (handle
, authenticator
,
606 "authorization-data", "NEW", 1);
607 if (res
!= SHISHI_OK
)
610 res
= shishi_asn1_number_of_elements (handle
, authenticator
,
611 "authorization-data", &i
);
612 if (res
!= SHISHI_OK
)
615 asprintf (&format
, "authorization-data.?%d.ad-type", i
);
616 res
= shishi_asn1_write_integer (handle
, authenticator
, format
, adtype
);
617 if (res
!= SHISHI_OK
)
623 sprintf (format
, "authorization-data.?%d.ad-data", i
);
624 res
= shishi_asn1_write (handle
, authenticator
, format
, addata
, addatalen
);
626 if (res
!= SHISHI_OK
)
633 * shishi_authenticator_authorizationdata:
634 * @handle: shishi handle as allocated by shishi_init().
635 * @authenticator: authenticator as allocated by shishi_authenticator().
636 * @adtype: output authorization data type.
637 * @addata: output authorization data.
638 * @addatalen: on input, maximum size of output authorization data,
639 on output, actual size of authorization data.
640 * @nth: element number of authorization-data to extract.
642 * Extract n:th authorization data from authenticator. The first
645 * Return value: Returns SHISHI_OK iff successful.
648 shishi_authenticator_authorizationdata (Shishi
* handle
,
649 Shishi_asn1 authenticator
,
651 char *addata
, int *addatalen
, int nth
)
657 res
= shishi_asn1_number_of_elements (handle
, authenticator
,
658 "authorization-data", &i
);
659 if (res
!= SHISHI_OK
)
660 return SHISHI_ASN1_ERROR
;
663 return SHISHI_OUT_OF_RANGE
;
665 asprintf (&format
, "authorization-data.?%d.ad-type", nth
);
666 res
= shishi_asn1_read_int32 (handle
, authenticator
, format
, adtype
);
668 if (res
!= SHISHI_OK
)
671 asprintf (&format
, "authorization-data.?%d.ad-data", i
);
672 res
= shishi_asn1_field (handle
, authenticator
, addata
, addatalen
, format
);
674 if (res
!= SHISHI_OK
)