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
;
44 node
= shishi_asn1_authenticator (handle
);
48 res
= shishi_asn1_write (handle
, node
, "authenticator-vno", "5", 0);
52 res
= shishi_authenticator_set_crealm (handle
, node
,
53 shishi_realm_default (handle
));
57 res
= shishi_authenticator_client_set (handle
, node
,
58 shishi_principal_default (handle
));
62 gettimeofday (&tv
, &tz
);
63 res
= shishi_authenticator_cusec_set (handle
, node
, tv
.tv_usec
% 1000000);
67 res
= shishi_asn1_write (handle
, node
, "ctime",
68 shishi_generalize_time (handle
, time (NULL
)), 0);
72 res
= shishi_asn1_write (handle
, node
, "subkey", NULL
, 0);
76 res
= shishi_asn1_write (handle
, node
, "seq-number", NULL
, 0);
83 shishi_asn1_done (handle
, node
);
88 * shishi_authenticator_print:
89 * @handle: shishi handle as allocated by shishi_init().
90 * @fh: file handle open for writing.
91 * @authenticator: authenticator as allocated by shishi_authenticator().
93 * Print ASCII armored DER encoding of authenticator to file.
95 * Return value: Returns SHISHI_OK iff successful.
98 shishi_authenticator_print (Shishi
* handle
,
99 FILE * fh
, Shishi_asn1 authenticator
)
101 return _shishi_print_armored_data (handle
, fh
, authenticator
,
102 "Authenticator", NULL
);
106 * shishi_authenticator_save:
107 * @handle: shishi handle as allocated by shishi_init().
108 * @fh: file handle open for writing.
109 * @authenticator: authenticator as allocated by shishi_authenticator().
111 * Save DER encoding of authenticator to file.
113 * Return value: Returns SHISHI_OK iff successful.
116 shishi_authenticator_save (Shishi
* handle
,
117 FILE * fh
, Shishi_asn1 authenticator
)
119 return _shishi_save_data (handle
, fh
, authenticator
, "Authenticator");
123 * shishi_authenticator_to_file:
124 * @handle: shishi handle as allocated by shishi_init().
125 * @authenticator: Authenticator to save.
126 * @filetype: input variable specifying type of file to be written,
127 * see Shishi_filetype.
128 * @filename: input variable with filename to write to.
130 * Write Authenticator to file in specified TYPE. The file will be
131 * truncated if it exists.
133 * Return value: Returns SHISHI_OK iff successful.
136 shishi_authenticator_to_file (Shishi
* handle
, Shishi_asn1 authenticator
,
137 int filetype
, char *filename
)
142 if (VERBOSE (handle
))
143 printf (_("Writing Authenticator to %s...\n"), filename
);
145 fh
= fopen (filename
, "w");
147 return SHISHI_FOPEN_ERROR
;
149 if (VERBOSE (handle
))
150 printf (_("Writing Authenticator in %s format...\n"),
151 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
153 if (filetype
== SHISHI_FILETYPE_TEXT
)
154 res
= shishi_authenticator_print (handle
, fh
, authenticator
);
156 res
= shishi_authenticator_save (handle
, fh
, authenticator
);
157 if (res
!= SHISHI_OK
)
162 return SHISHI_FCLOSE_ERROR
;
164 if (VERBOSE (handle
))
165 printf (_("Writing Authenticator to %s...done\n"), filename
);
171 * shishi_authenticator_parse:
172 * @handle: shishi handle as allocated by shishi_init().
173 * @fh: file handle open for reading.
174 * @authenticator: output variable with newly allocated authenticator.
176 * Read ASCII armored DER encoded authenticator from file and populate
177 * given authenticator variable.
179 * Return value: Returns SHISHI_OK iff successful.
182 shishi_authenticator_parse (Shishi
* handle
,
183 FILE * fh
, Shishi_asn1
* authenticator
)
185 return _shishi_authenticator_input (handle
, fh
, authenticator
, 0);
189 * shishi_authenticator_read:
190 * @handle: shishi handle as allocated by shishi_init().
191 * @fh: file handle open for reading.
192 * @authenticator: output variable with newly allocated authenticator.
194 * Read DER encoded authenticator from file and populate given
195 * authenticator variable.
197 * Return value: Returns SHISHI_OK iff successful.
200 shishi_authenticator_read (Shishi
* handle
,
201 FILE * fh
, Shishi_asn1
* authenticator
)
203 return _shishi_authenticator_input (handle
, fh
, authenticator
, 1);
207 * shishi_authenticator_from_file:
208 * @handle: shishi handle as allocated by shishi_init().
209 * @authenticator: output variable with newly allocated Authenticator.
210 * @filetype: input variable specifying type of file to be read,
211 * see Shishi_filetype.
212 * @filename: input variable with filename to read from.
214 * Read Authenticator from file in specified TYPE.
216 * Return value: Returns SHISHI_OK iff successful.
219 shishi_authenticator_from_file (Shishi
* handle
, Shishi_asn1
* authenticator
,
220 int filetype
, char *filename
)
225 if (VERBOSE (handle
))
226 printf (_("Reading Authenticator from %s...\n"), filename
);
228 fh
= fopen (filename
, "r");
230 return SHISHI_FOPEN_ERROR
;
232 if (VERBOSE (handle
))
233 printf (_("Reading Authenticator in %s format...\n"),
234 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
236 if (filetype
== SHISHI_FILETYPE_TEXT
)
237 res
= shishi_authenticator_parse (handle
, fh
, authenticator
);
239 res
= shishi_authenticator_read (handle
, fh
, authenticator
);
240 if (res
!= SHISHI_OK
)
245 return SHISHI_FCLOSE_ERROR
;
247 if (VERBOSE (handle
))
248 printf (_("Reading Authenticator from %s...done\n"), filename
);
254 * shishi_authenticator_set_crealm:
255 * @handle: shishi handle as allocated by shishi_init().
256 * @authenticator: authenticator as allocated by shishi_authenticator().
257 * @crealm: input array with realm.
259 * Set realm field in authenticator to specified value.
261 * Return value: Returns SHISHI_OK iff successful.
264 shishi_authenticator_set_crealm (Shishi
* handle
,
265 Shishi_asn1 authenticator
,
270 res
= shishi_asn1_write (handle
, authenticator
, "crealm",
272 if (res
!= SHISHI_OK
)
279 * shishi_authenticator_set_cname:
280 * @handle: shishi handle as allocated by shishi_init().
281 * @authenticator: authenticator as allocated by shishi_authenticator().
282 * @name_type: type of principial, see Shishi_name_type, usually
284 * @principal: input array with principal name.
286 * Set principal field in authenticator to specified value.
288 * Return value: Returns SHISHI_OK iff successful.
291 shishi_authenticator_set_cname (Shishi
* handle
,
292 Shishi_asn1 authenticator
,
293 Shishi_name_type name_type
,
298 res
= shishi_principal_name_set (handle
, authenticator
, "cname",
300 if (res
!= SHISHI_OK
)
307 * shishi_authenticator_client_set:
308 * @handle: shishi handle as allocated by shishi_init().
309 * @kdcrep: Authenticator to set client name field in.
310 * @name: zero-terminated string with principal name on RFC 1964 form.
312 * Set the client name field in the Authenticator.
314 * Return value: Returns SHISHI_OK iff successful.
317 shishi_authenticator_client_set (Shishi
* handle
,
318 Shishi_asn1 authenticator
,
323 res
= shishi_principal_set (handle
, authenticator
, "cname", client
);
324 if (res
!= SHISHI_OK
)
331 shishi_authenticator_ctime_get (Shishi
* handle
,
332 Shishi_asn1 authenticator
, char *ctime
)
337 len
= GENERALIZEDTIME_TIME_LEN
+ 1;
338 res
= shishi_asn1_field (handle
, authenticator
,
339 ctime
, &len
, "ctime");
340 if (res
== SHISHI_OK
&& len
== GENERALIZEDTIME_TIME_LEN
)
347 * shishi_authenticator_ctime_set:
348 * @handle: shishi handle as allocated by shishi_init().
349 * @authenticator: Authenticator as allocated by shishi_authenticator().
350 * @ctime: string with generalized time value to store in Authenticator.
352 * Store client time in Authenticator.
354 * Return value: Returns SHISHI_OK iff successful.
357 shishi_authenticator_ctime_set (Shishi
* handle
,
358 Shishi_asn1 authenticator
,
363 res
= shishi_asn1_write (handle
, authenticator
, "ctime",
364 ctime
, GENERALIZEDTIME_TIME_LEN
);
365 if (res
!= SHISHI_OK
)
372 * shishi_authenticator_cusec_get:
373 * @handle: shishi handle as allocated by shishi_init().
374 * @authenticator: Authenticator as allocated by shishi_authenticator().
375 * @cusec: output integer with client microseconds field.
377 * Extract client microseconds field from Authenticator.
379 * Return value: Returns SHISHI_OK iff successful.
382 shishi_authenticator_cusec_get (Shishi
* handle
,
383 Shishi_asn1 authenticator
,
388 res
= shishi_asn1_read_integer (handle
, authenticator
, "cusec", cusec
);
389 if (res
!= SHISHI_OK
)
396 * shishi_authenticator_cusec_set:
397 * @handle: shishi handle as allocated by shishi_init().
398 * @authenticator: authenticator as allocated by shishi_authenticator().
399 * @cusec: client microseconds to set in authenticator, 0-999999.
401 * Set the cusec field in the Authenticator.
403 * Return value: Returns SHISHI_OK iff successful.
406 shishi_authenticator_cusec_set (Shishi
* handle
,
407 Shishi_asn1 authenticator
,
412 res
= shishi_asn1_write_integer (handle
, authenticator
, "cusec", cusec
);
413 if (res
!= SHISHI_OK
)
420 shishi_authenticator_cname_get (Shishi
* handle
,
421 Shishi_asn1 authenticator
,
422 char *cname
, int *cnamelen
)
424 return shishi_principal_name_get (handle
, authenticator
,
425 "cname", cname
, cnamelen
);
429 shishi_authenticator_cnamerealm_get (Shishi
* handle
,
430 Shishi_asn1 authenticator
,
431 char *cnamerealm
, int *cnamerealmlen
)
433 return shishi_principal_name_realm_get (handle
, authenticator
,
437 cnamerealm
, cnamerealmlen
);
441 shishi_authenticator_remove_cksum (Shishi
* handle
, Shishi_asn1 authenticator
)
445 /* XXX remove this function */
447 res
= shishi_asn1_write (handle
, authenticator
, "cksum",
449 if (res
!= SHISHI_OK
)
456 * shishi_authenticator_cksum:
457 * @handle: shishi handle as allocated by shishi_init().
458 * @authenticator: authenticator as allocated by shishi_authenticator().
459 * @cksumtype: output checksum type.
460 * @cksum: output checksum data from authenticator.
461 * @cksumlen: on input, maximum size of output checksum data buffer,
462 * on output, actual size of output checksum data buffer.
464 * Read checksum value from authenticator.
466 * Return value: Returns SHISHI_OK iff successful.
469 shishi_authenticator_cksum (Shishi
* handle
,
470 Shishi_asn1 authenticator
,
471 int *cksumtype
, char *cksum
, size_t * cksumlen
)
475 res
= shishi_asn1_integer_field (handle
, authenticator
, cksumtype
,
477 if (res
!= SHISHI_OK
)
480 res
= shishi_asn1_field (handle
, authenticator
, cksum
, cksumlen
,
482 if (res
!= SHISHI_OK
)
489 * shishi_authenticator_set_cksum:
490 * @handle: shishi handle as allocated by shishi_init().
491 * @authenticator: authenticator as allocated by shishi_authenticator().
492 * @cksumtype: input checksum type to store in authenticator.
493 * @cksum: input checksum data to store in authenticator.
494 * @cksumlen: size of input checksum data to store in authenticator.
496 * Store checksum value in authenticator. A checksum is usually created
497 * by calling shishi_checksum() on some application specific data using
498 * the key from the ticket that is being used. To save time, you may
499 * want to use shishi_authenticator_add_cksum() instead, which calculates
500 * the checksum and calls this function in one step.
502 * Return value: Returns SHISHI_OK iff successful.
505 shishi_authenticator_set_cksum (Shishi
* handle
,
506 Shishi_asn1 authenticator
,
507 int cksumtype
, char *cksum
, int cksumlen
)
511 res
= shishi_asn1_write_integer (handle
, authenticator
,
512 "cksum.cksumtype", cksumtype
);
513 if (res
!= SHISHI_OK
)
514 return SHISHI_ASN1_ERROR
;
516 res
= shishi_asn1_write (handle
, authenticator
, "cksum.checksum",
518 if (res
!= SHISHI_OK
)
519 return SHISHI_ASN1_ERROR
;
525 * shishi_authenticator_add_cksum:
526 * @handle: shishi handle as allocated by shishi_init().
527 * @authenticator: authenticator as allocated by shishi_authenticator().
528 * @enckdcreppart: ticket information where the key is taken from.
529 * @data: input array with data to calculate checksum on.
530 * @datalen: size of input array with data to calculate checksum on.
532 * Calculate checksum for data and store it in the authenticator.
534 * Return value: Returns SHISHI_OK iff successful.
537 shishi_authenticator_add_cksum (Shishi
* handle
,
538 Shishi_asn1 authenticator
,
540 int keyusage
, char *data
, int datalen
)
544 if (data
&& datalen
> 0)
548 int cksumtype
= shishi_cipher_defaultcksumtype (shishi_key_type (key
));
550 cksumlen
= sizeof (cksum
);
551 res
= shishi_checksum (handle
, key
, keyusage
, cksumtype
,
552 data
, datalen
, cksum
, &cksumlen
);
553 if (res
!= SHISHI_OK
)
556 res
= shishi_authenticator_set_cksum (handle
, authenticator
,
557 cksumtype
, cksum
, cksumlen
);
560 res
= shishi_authenticator_remove_cksum (handle
, authenticator
);
566 * shishi_authenticator_clear_authorizationdata:
567 * @handle: shishi handle as allocated by shishi_init().
568 * @authenticator: Authenticator as allocated by shishi_authenticator().
570 * Remove the authorization-data field from Authenticator.
572 * Return value: Returns SHISHI_OK iff successful.
575 shishi_authenticator_clear_authorizationdata (Shishi
* handle
,
576 Shishi_asn1 authenticator
)
580 res
= shishi_asn1_write (handle
, authenticator
,
581 "authorization-data", NULL
, 0);
582 if (res
!= SHISHI_OK
)
583 return SHISHI_ASN1_ERROR
;
589 * shishi_authenticator_add_authorizationdata:
590 * @handle: shishi handle as allocated by shishi_init().
591 * @authenticator: authenticator as allocated by shishi_authenticator().
592 * @adtype: input authorization data type to add.
593 * @addata: input authorization data to add.
594 * @addatalen: size of input authorization data to add.
596 * Add authorization data to authenticator.
598 * Return value: Returns SHISHI_OK iff successful.
601 shishi_authenticator_add_authorizationdata (Shishi
* handle
,
602 Shishi_asn1 authenticator
,
604 char *addata
, int addatalen
)
611 res
= shishi_asn1_write (handle
, authenticator
,
612 "authorization-data", "NEW", 1);
613 if (res
!= SHISHI_OK
)
616 res
= shishi_asn1_number_of_elements (handle
, authenticator
,
617 "authorization-data",
619 if (res
!= SHISHI_OK
)
622 sprintf (buf
, "%d", adtype
);
623 sprintf (format
, "authorization-data.?%d.ad-type", i
);
624 res
= shishi_asn1_write (handle
, authenticator
, format
, buf
, 0);
625 if (res
!= SHISHI_OK
)
628 sprintf (format
, "authorization-data.?%d.ad-data", i
);
629 res
= shishi_asn1_write (handle
, authenticator
, format
, addata
, addatalen
);
630 if (res
!= SHISHI_OK
)
637 * shishi_authenticator_authorizationdata:
638 * @handle: shishi handle as allocated by shishi_init().
639 * @authenticator: authenticator as allocated by shishi_authenticator().
640 * @adtype: output authorization data type.
641 * @addata: output authorization data.
642 * @addatalen: on input, maximum size of output authorization data,
643 on output, actual size of authorization data.
644 * @nth: element number of authorization-data to extract.
646 * Extract n:th authorization data from authenticator. The first
649 * Return value: Returns SHISHI_OK iff successful.
652 shishi_authenticator_authorizationdata (Shishi
* handle
,
653 Shishi_asn1 authenticator
,
655 char *addata
, int *addatalen
, int nth
)
661 res
= shishi_asn1_number_of_elements (handle
, authenticator
,
662 "authorization-data",
664 if (res
!= SHISHI_OK
)
665 return SHISHI_ASN1_ERROR
;
668 return SHISHI_OUT_OF_RANGE
;
670 shishi_asprintf (&format
, "authorization-data.?%d.ad-type",
672 res
= shishi_asn1_integer_field (handle
, authenticator
, adtype
, format
);
674 if (res
!= SHISHI_OK
)
677 shishi_asprintf (&format
, "authorization-data.?%d.ad-data",
679 res
= shishi_asn1_field (handle
, authenticator
, addata
, addatalen
, format
);
681 if (res
!= SHISHI_OK
)