Add.
[shishi.git] / lib / ap.c
blobe6ab55ebd195295ebbce679edea1826314ace811
1 /* ap.c --- AP functions
2 * Copyright (C) 2002, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "internal.h"
24 struct Shishi_ap
26 Shishi *handle;
27 Shishi_tkt *tkt;
28 Shishi_key *key;
29 Shishi_asn1 authenticator;
30 Shishi_asn1 apreq;
31 Shishi_asn1 aprep;
32 Shishi_asn1 encapreppart;
33 /* Key usage for encryption entire Authenticator ASN.1 blob, stored
34 in AP-REQ. */
35 int authenticatorkeyusage;
36 /* Key usage for computing checksum of authenticatorcksumdata in the
37 Authenticator, in AP-REQ. */
38 int authenticatorcksumkeyusage;
39 /* Sets the checksum algorithm type in Authenticator, in AP-REQ. If
40 there is data in authenticatorcksumdata to compute a checksum on,
41 this also indicate the algorithm to use for this computation. */
42 int32_t authenticatorcksumtype;
43 /* Auxilliary application data to compute checksum on and store in
44 Authenticator, in AP-REQ. Note that data is not stored in
45 AP-REQ, only a checksum of it. */
46 char *authenticatorcksumdata;
47 size_t authenticatorcksumdatalen;
48 /* Raw checksum data to store in Authenticator, in AP-REQ.
49 Normally, this is the output of the checksum algorithm computed
50 on the data in authenticatorcksumdata, but some applications
51 (e.g., GSS-API) put something weird in the checksum field. */
52 char *authenticatorcksumraw;
53 size_t authenticatorcksumrawlen;
56 /**
57 * shishi_ap:
58 * @handle: shishi handle as allocated by shishi_init().
59 * @ap: pointer to new structure that holds information about AP exchange
61 * Create a new AP exchange with a random subkey of the default
62 * encryption type from configuration. Note that there is no
63 * guarantee that the receiver will understand that key type, you
64 * should probably use shishi_ap_etype() or shishi_ap_nosubkey()
65 * instead. In the future, this function will likely behave as
66 * shishi_ap_nosubkey() and shishi_ap_nosubkey() will be removed.
68 * Return value: Returns SHISHI_OK iff successful.
69 **/
70 int
71 shishi_ap (Shishi * handle, Shishi_ap ** ap)
73 int res;
75 res = shishi_ap_nosubkey (handle, ap);
76 if (res != SHISHI_OK)
78 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
79 shishi_error (handle));
80 return res;
83 res = shishi_authenticator_add_random_subkey (handle, (*ap)->authenticator);
84 if (res != SHISHI_OK)
86 shishi_error_printf (handle, "Could not add random subkey in AP: %s\n",
87 shishi_strerror (res));
88 return res;
91 return SHISHI_OK;
94 /**
95 * shishi_ap_etype:
96 * @handle: shishi handle as allocated by shishi_init().
97 * @ap: pointer to new structure that holds information about AP exchange
98 * @etype: encryption type of newly generated random subkey.
100 * Create a new AP exchange with a random subkey of indicated
101 * encryption type.
103 * Return value: Returns SHISHI_OK iff successful.
106 shishi_ap_etype (Shishi * handle, Shishi_ap ** ap, int etype)
108 int res;
110 res = shishi_ap_nosubkey (handle, ap);
111 if (res != SHISHI_OK)
113 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
114 shishi_error (handle));
115 return res;
118 res = shishi_authenticator_add_random_subkey_etype (handle,
119 (*ap)->authenticator,
120 etype);
121 if (res != SHISHI_OK)
123 shishi_error_printf (handle, "Could not add random subkey in AP: %s\n",
124 shishi_strerror (res));
125 return res;
128 return SHISHI_OK;
132 * shishi_ap_nosubkey:
133 * @handle: shishi handle as allocated by shishi_init().
134 * @ap: pointer to new structure that holds information about AP exchange
136 * Create a new AP exchange without subkey in authenticator.
138 * Return value: Returns SHISHI_OK iff successful.
141 shishi_ap_nosubkey (Shishi * handle, Shishi_ap ** ap)
143 Shishi_ap *lap;
145 *ap = xcalloc (1, sizeof (**ap));
146 lap = *ap;
148 lap->handle = handle;
149 lap->authenticatorcksumtype = SHISHI_NO_CKSUMTYPE;
150 lap->authenticatorcksumkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR_CKSUM;
151 lap->authenticatorkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR;
153 lap->authenticator = shishi_authenticator (handle);
154 if (lap->authenticator == NULL)
156 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
157 shishi_error (handle));
158 return SHISHI_ASN1_ERROR;
161 lap->apreq = shishi_apreq (handle);
162 if (lap->apreq == NULL)
164 shishi_error_printf (handle, "Could not create AP-REQ: %s\n",
165 shishi_error (handle));
166 return SHISHI_ASN1_ERROR;
169 lap->aprep = shishi_aprep (handle);
170 if (lap->aprep == NULL)
172 shishi_error_printf (handle, "Could not create AP-REP: %s\n",
173 shishi_error (handle));
174 return SHISHI_ASN1_ERROR;
177 lap->encapreppart = shishi_encapreppart (handle);
178 if (lap->encapreppart == NULL)
180 shishi_error_printf (handle, "Could not create EncAPRepPart: %s\n",
181 shishi_error (handle));
182 return SHISHI_ASN1_ERROR;
185 return SHISHI_OK;
189 * shishi_ap_done:
190 * @ap: structure that holds information about AP exchange
192 * Deallocate resources associated with AP exchange. This should be
193 * called by the application when it no longer need to utilize the AP
194 * exchange handle.
196 void
197 shishi_ap_done (Shishi_ap * ap)
199 if (ap->authenticatorcksumdata)
200 free (ap->authenticatorcksumdata);
201 if (ap->authenticatorcksumraw)
202 free (ap->authenticatorcksumraw);
203 shishi_asn1_done (ap->handle, ap->authenticator);
204 shishi_asn1_done (ap->handle, ap->apreq);
205 shishi_asn1_done (ap->handle, ap->aprep);
206 shishi_asn1_done (ap->handle, ap->encapreppart);
207 free (ap);
211 * shishi_ap_set_tktoptions:
212 * @ap: structure that holds information about AP exchange
213 * @tkt: ticket to set in AP.
214 * @options: AP-REQ options to set in AP.
216 * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
217 * apoptions (see shishi_apreq_options_set()).
219 * Return value: Returns SHISHI_OK iff successful.
222 shishi_ap_set_tktoptions (Shishi_ap * ap, Shishi_tkt * tkt, int options)
224 int rc;
226 shishi_ap_tkt_set (ap, tkt);
228 rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
229 if (rc != SHISHI_OK)
231 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
232 return rc;
235 return SHISHI_OK;
239 * shishi_ap_set_tktoptionsdata:
240 * @ap: structure that holds information about AP exchange
241 * @tkt: ticket to set in AP.
242 * @options: AP-REQ options to set in AP.
243 * @data: input array with data to checksum in Authenticator.
244 * @len: length of input array with data to checksum in Authenticator.
246 * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
247 * apoptions (see shishi_apreq_options_set()) and set the
248 * Authenticator checksum data.
250 * Return value: Returns SHISHI_OK iff successful.
253 shishi_ap_set_tktoptionsdata (Shishi_ap * ap,
254 Shishi_tkt * tkt,
255 int options, const char *data, size_t len)
257 int rc;
259 shishi_ap_tkt_set (ap, tkt);
261 rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
262 if (rc != SHISHI_OK)
264 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
265 return rc;
268 shishi_ap_authenticator_cksumdata_set (ap, data, len);
270 return SHISHI_OK;
275 * shishi_ap_set_tktoptionsraw:
276 * @ap: structure that holds information about AP exchange
277 * @tkt: ticket to set in AP.
278 * @options: AP-REQ options to set in AP.
279 * @cksumtype: authenticator checksum type to set in AP.
280 * @data: input array with data to store in checksum field in Authenticator.
281 * @len: length of input array with data to store in checksum field in
282 * Authenticator.
284 * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
285 * apoptions (see shishi_apreq_options_set()) and set the raw
286 * Authenticator checksum data.
288 * Return value: Returns SHISHI_OK iff successful.
291 shishi_ap_set_tktoptionsraw (Shishi_ap * ap,
292 Shishi_tkt * tkt,
293 int options,
294 int32_t cksumtype, const char *data, size_t len)
296 int rc;
298 shishi_ap_tkt_set (ap, tkt);
300 rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
301 if (rc != SHISHI_OK)
303 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
304 return rc;
307 shishi_ap_authenticator_cksumraw_set (ap, cksumtype, data, len);
309 return SHISHI_OK;
313 * shishi_ap_set_tktoptionsasn1usage:
314 * @ap: structure that holds information about AP exchange
315 * @tkt: ticket to set in AP.
316 * @options: AP-REQ options to set in AP.
317 * @node: input ASN.1 structure to store as authenticator checksum data.
318 * @field: field in ASN.1 structure to use.
319 * @authenticatorcksumkeyusage: key usage for checksum in authenticator.
320 * @authenticatorkeyusage: key usage for authenticator.
322 * Set ticket, options and authenticator checksum data using
323 * shishi_ap_set_tktoptionsdata(). The authenticator checksum data is
324 * the DER encoding of the ASN.1 field provided.
326 * Return value: Returns SHISHI_OK iff successful.
329 shishi_ap_set_tktoptionsasn1usage (Shishi_ap * ap,
330 Shishi_tkt * tkt,
331 int options,
332 Shishi_asn1 node,
333 const char *field,
334 int authenticatorcksumkeyusage,
335 int authenticatorkeyusage)
337 char *buf;
338 size_t buflen;
339 int res;
341 res = shishi_asn1_to_der_field (ap->handle, node, field, &buf, &buflen);
342 if (res != SHISHI_OK)
343 return res;
345 res = shishi_ap_set_tktoptionsdata (ap, tkt, options, buf, buflen);
346 if (res != SHISHI_OK)
347 return res;
349 ap->authenticatorcksumkeyusage = authenticatorcksumkeyusage;
350 ap->authenticatorkeyusage = authenticatorkeyusage;
352 return SHISHI_OK;
356 * shishi_ap_tktoptions:
357 * @handle: shishi handle as allocated by shishi_init().
358 * @ap: pointer to new structure that holds information about AP exchange
359 * @tkt: ticket to set in newly created AP.
360 * @options: AP-REQ options to set in newly created AP.
362 * Create a new AP exchange using shishi_ap(), and set the ticket and
363 * AP-REQ apoptions using shishi_ap_set_tktoption(). A random session
364 * key is added to the authenticator, using the same keytype as the
365 * ticket.
367 * Return value: Returns SHISHI_OK iff successful.
370 shishi_ap_tktoptions (Shishi * handle,
371 Shishi_ap ** ap, Shishi_tkt * tkt, int options)
373 int rc;
375 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
376 if (rc != SHISHI_OK)
377 return rc;
379 rc = shishi_ap_set_tktoptions (*ap, tkt, options);
380 if (rc != SHISHI_OK)
381 return rc;
383 return SHISHI_OK;
387 * shishi_ap_tktoptionsdata:
388 * @handle: shishi handle as allocated by shishi_init().
389 * @ap: pointer to new structure that holds information about AP exchange
390 * @tkt: ticket to set in newly created AP.
391 * @options: AP-REQ options to set in newly created AP.
392 * @data: input array with data to checksum in Authenticator.
393 * @len: length of input array with data to checksum in Authenticator.
395 * Create a new AP exchange using shishi_ap(), and set the ticket,
396 * AP-REQ apoptions and the Authenticator checksum data using
397 * shishi_ap_set_tktoptionsdata(). A random session key is added to
398 * the authenticator, using the same keytype as the ticket.
400 * Return value: Returns SHISHI_OK iff successful.
403 shishi_ap_tktoptionsdata (Shishi * handle,
404 Shishi_ap ** ap,
405 Shishi_tkt * tkt, int options,
406 const char *data, size_t len)
408 int rc;
410 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
411 if (rc != SHISHI_OK)
412 return rc;
414 rc = shishi_ap_set_tktoptionsdata (*ap, tkt, options, data, len);
415 if (rc != SHISHI_OK)
416 return rc;
418 return SHISHI_OK;
422 * shishi_ap_tktoptionsraw:
423 * @handle: shishi handle as allocated by shishi_init().
424 * @ap: pointer to new structure that holds information about AP exchange
425 * @tkt: ticket to set in newly created AP.
426 * @options: AP-REQ options to set in newly created AP.
427 * @cksumtype: authenticator checksum type to set in AP.
428 * @data: input array with data to store in checksum field in Authenticator.
429 * @len: length of input array with data to store in checksum field in
430 * Authenticator.
432 * Create a new AP exchange using shishi_ap(), and set the ticket,
433 * AP-REQ apoptions and the raw Authenticator checksum data field
434 * using shishi_ap_set_tktoptionsraw(). A random session key is added
435 * to the authenticator, using the same keytype as the ticket.
437 * Return value: Returns SHISHI_OK iff successful.
440 shishi_ap_tktoptionsraw (Shishi * handle,
441 Shishi_ap ** ap,
442 Shishi_tkt * tkt, int options,
443 int32_t cksumtype, const char *data, size_t len)
445 int rc;
447 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
448 if (rc != SHISHI_OK)
449 return rc;
451 rc = shishi_ap_set_tktoptionsraw (*ap, tkt, options, cksumtype, data, len);
452 if (rc != SHISHI_OK)
453 return rc;
455 return SHISHI_OK;
459 * shishi_ap_etype_tktoptionsdata:
460 * @handle: shishi handle as allocated by shishi_init().
461 * @ap: pointer to new structure that holds information about AP exchange
462 * @etype: encryption type of newly generated random subkey.
463 * @tkt: ticket to set in newly created AP.
464 * @options: AP-REQ options to set in newly created AP.
465 * @data: input array with data to checksum in Authenticator.
466 * @len: length of input array with data to checksum in Authenticator.
468 * Create a new AP exchange using shishi_ap(), and set the ticket,
469 * AP-REQ apoptions and the Authenticator checksum data using
470 * shishi_ap_set_tktoptionsdata(). A random session key is added to
471 * the authenticator, using the same keytype as the ticket.
473 * Return value: Returns SHISHI_OK iff successful.
476 shishi_ap_etype_tktoptionsdata (Shishi * handle,
477 Shishi_ap ** ap,
478 int32_t etype,
479 Shishi_tkt * tkt, int options,
480 const char *data, size_t len)
482 int rc;
484 rc = shishi_ap_etype (handle, ap, etype);
485 if (rc != SHISHI_OK)
486 return rc;
488 rc = shishi_ap_set_tktoptionsdata (*ap, tkt, options, data, len);
489 if (rc != SHISHI_OK)
490 return rc;
492 return SHISHI_OK;
496 * shishi_ap_tktoptionsasn1usage:
497 * @handle: shishi handle as allocated by shishi_init().
498 * @ap: pointer to new structure that holds information about AP exchange
499 * @tkt: ticket to set in newly created AP.
500 * @options: AP-REQ options to set in newly created AP.
501 * @node: input ASN.1 structure to store as authenticator checksum data.
502 * @field: field in ASN.1 structure to use.
503 * @authenticatorcksumkeyusage: key usage for checksum in authenticator.
504 * @authenticatorkeyusage: key usage for authenticator.
506 * Create a new AP exchange using shishi_ap(), and set ticket, options
507 * and authenticator checksum data from the DER encoding of the ASN.1
508 * field using shishi_ap_set_tktoptionsasn1usage(). A random session
509 * key is added to the authenticator, using the same keytype as the
510 * ticket.
512 * Return value: Returns SHISHI_OK iff successful.
515 shishi_ap_tktoptionsasn1usage (Shishi * handle,
516 Shishi_ap ** ap,
517 Shishi_tkt * tkt,
518 int options,
519 Shishi_asn1 node,
520 const char *field,
521 int authenticatorcksumkeyusage,
522 int authenticatorkeyusage)
524 int rc;
526 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
527 if (rc != SHISHI_OK)
528 return rc;
530 rc = shishi_ap_set_tktoptionsasn1usage (*ap, tkt, options,
531 node, field,
532 authenticatorcksumkeyusage,
533 authenticatorkeyusage);
534 if (rc != SHISHI_OK)
535 return rc;
537 return SHISHI_OK;
541 * shishi_ap_tkt:
542 * @ap: structure that holds information about AP exchange
544 * Get Ticket from AP exchange.
546 * Return value: Returns the ticket from the AP exchange, or NULL if
547 * not yet set or an error occured.
549 Shishi_tkt *
550 shishi_ap_tkt (Shishi_ap * ap)
552 return ap->tkt;
556 * shishi_ap_tkt_set:
557 * @ap: structure that holds information about AP exchange
558 * @tkt: ticket to store in AP.
560 * Set the Ticket in the AP exchange.
562 void
563 shishi_ap_tkt_set (Shishi_ap * ap, Shishi_tkt * tkt)
565 ap->tkt = tkt;
569 * shishi_ap_authenticator_cksumdata:
570 * @ap: structure that holds information about AP exchange
571 * @out: output array that holds authenticator checksum data.
572 * @len: on input, maximum length of output array that holds
573 * authenticator checksum data, on output actual length of
574 * output array that holds authenticator checksum data.
576 * Get checksum data from Authenticator.
578 * Return value: Returns SHISHI_OK if successful, or
579 * SHISHI_TOO_SMALL_BUFFER if buffer provided was too small.
582 shishi_ap_authenticator_cksumdata (Shishi_ap * ap, char *out, size_t * len)
584 if (*len < ap->authenticatorcksumdatalen)
585 return SHISHI_TOO_SMALL_BUFFER;
586 if (ap->authenticatorcksumdata)
587 memcpy (out, ap->authenticatorcksumdata, ap->authenticatorcksumdatalen);
588 *len = ap->authenticatorcksumdatalen;
589 return SHISHI_OK;
593 * shishi_ap_authenticator_cksumdata_set:
594 * @ap: structure that holds information about AP exchange
595 * @authenticatorcksumdata: input array with data to compute checksum
596 * on and store in Authenticator in AP-REQ.
597 * @authenticatorcksumdatalen: length of input array with data to
598 * compute checksum on and store in Authenticator in AP-REQ.
600 * Set the Authenticator Checksum Data in the AP exchange. This is
601 * the data that will be checksumed, and the checksum placed in the
602 * checksum field. It is not the actual checksum field. See also
603 * shishi_ap_authenticator_cksumraw_set.
605 void
606 shishi_ap_authenticator_cksumdata_set (Shishi_ap * ap,
607 const char *authenticatorcksumdata,
608 size_t authenticatorcksumdatalen)
610 ap->authenticatorcksumdata = xmemdup (authenticatorcksumdata,
611 authenticatorcksumdatalen);
612 ap->authenticatorcksumdatalen = authenticatorcksumdatalen;
616 * shishi_ap_authenticator_cksumraw_set:
617 * @ap: structure that holds information about AP exchange
618 * @authenticatorcksumtype: authenticator checksum type to set in AP.
619 * @authenticatorcksumraw: input array with authenticator checksum
620 * field value to set in Authenticator in AP-REQ.
621 * @authenticatorcksumrawlen: length of input array with
622 * authenticator checksum field value to set in Authenticator in AP-REQ.
624 * Set the Authenticator Checksum Data in the AP exchange. This is
625 * the actual checksum field, not data to compute checksum on and then
626 * store in the checksum field. See also
627 * shishi_ap_authenticator_cksumdata_set.
629 void
630 shishi_ap_authenticator_cksumraw_set (Shishi_ap * ap,
631 int32_t authenticatorcksumtype,
632 const char *authenticatorcksumraw,
633 size_t authenticatorcksumrawlen)
635 shishi_ap_authenticator_cksumtype_set (ap, authenticatorcksumtype);
636 ap->authenticatorcksumraw = xmemdup (authenticatorcksumraw,
637 authenticatorcksumrawlen);
638 ap->authenticatorcksumrawlen = authenticatorcksumrawlen;
642 * shishi_ap_authenticator_cksumtype:
643 * @ap: structure that holds information about AP exchange
645 * Get the Authenticator Checksum Type in the AP exchange.
647 * Return value: Return the authenticator checksum type.
649 int32_t
650 shishi_ap_authenticator_cksumtype (Shishi_ap * ap)
652 return ap->authenticatorcksumtype;
656 * shishi_ap_authenticator_cksumtype_set:
657 * @ap: structure that holds information about AP exchange
658 * @cksumtype: authenticator checksum type to set in AP.
660 * Set the Authenticator Checksum Type in the AP exchange.
662 void
663 shishi_ap_authenticator_cksumtype_set (Shishi_ap * ap, int32_t cksumtype)
665 ap->authenticatorcksumtype = cksumtype;
669 * shishi_ap_authenticator:
670 * @ap: structure that holds information about AP exchange
672 * Get ASN.1 Authenticator structure from AP exchange.
674 * Return value: Returns the Authenticator from the AP exchange, or
675 * NULL if not yet set or an error occured.
678 Shishi_asn1
679 shishi_ap_authenticator (Shishi_ap * ap)
681 return ap->authenticator;
685 * shishi_ap_authenticator_set:
686 * @ap: structure that holds information about AP exchange
687 * @authenticator: authenticator to store in AP.
689 * Set the Authenticator in the AP exchange.
691 void
692 shishi_ap_authenticator_set (Shishi_ap * ap, Shishi_asn1 authenticator)
694 if (ap->authenticator)
695 shishi_asn1_done (ap->handle, ap->authenticator);
696 ap->authenticator = authenticator;
700 * shishi_ap_req:
701 * @ap: structure that holds information about AP exchange
703 * Get ASN.1 AP-REQ structure from AP exchange.
705 * Return value: Returns the AP-REQ from the AP exchange, or NULL if
706 * not yet set or an error occured.
708 Shishi_asn1
709 shishi_ap_req (Shishi_ap * ap)
711 return ap->apreq;
716 * shishi_ap_req_set:
717 * @ap: structure that holds information about AP exchange
718 * @apreq: apreq to store in AP.
720 * Set the AP-REQ in the AP exchange.
722 void
723 shishi_ap_req_set (Shishi_ap * ap, Shishi_asn1 apreq)
725 if (ap->apreq)
726 shishi_asn1_done (ap->handle, ap->apreq);
727 ap->apreq = apreq;
731 * shishi_ap_req_der:
732 * @ap: structure that holds information about AP exchange
733 * @out: pointer to output array with der encoding of AP-REQ.
734 * @outlen: pointer to length of output array with der encoding of AP-REQ.
736 * Build AP-REQ using shishi_ap_req_build() and DER encode it. @out
737 * is allocated by this function, and it is the responsibility of
738 * caller to deallocate it.
740 * Return value: Returns SHISHI_OK iff successful.
743 shishi_ap_req_der (Shishi_ap * ap, char **out, size_t * outlen)
745 int rc;
747 rc = shishi_ap_req_build (ap);
748 if (rc != SHISHI_OK)
749 return rc;
751 rc = shishi_asn1_to_der (ap->handle, ap->apreq, out, outlen);
752 if (rc != SHISHI_OK)
753 return rc;
755 return SHISHI_OK;
759 * shishi_ap_req_der_set:
760 * @ap: structure that holds information about AP exchange
761 * @der: input array with DER encoded AP-REQ.
762 * @derlen: length of input array with DER encoded AP-REQ.
764 * DER decode AP-REQ and set it AP exchange. If decoding fails, the
765 * AP-REQ in the AP exchange is lost.
767 * Return value: Returns SHISHI_OK.
770 shishi_ap_req_der_set (Shishi_ap * ap, char *der, size_t derlen)
772 ap->apreq = shishi_der2asn1_apreq (ap->handle, der, derlen);
774 if (ap->apreq)
775 return SHISHI_OK;
776 else
777 return SHISHI_ASN1_ERROR;
781 * shishi_ap_req_build:
782 * @ap: structure that holds information about AP exchange
784 * Checksum data in authenticator and add ticket and authenticator to
785 * AP-REQ.
787 * Return value: Returns SHISHI_OK iff successful.
790 shishi_ap_req_build (Shishi_ap * ap)
792 int res;
793 int cksumtype;
795 if (VERBOSE (ap->handle))
796 printf ("Building AP-REQ...\n");
798 if (VERBOSEASN1 (ap->handle))
800 shishi_ticket_print (ap->handle, stdout, shishi_tkt_ticket (ap->tkt));
801 shishi_key_print (ap->handle, stdout, shishi_tkt_key (ap->tkt));
805 res = shishi_apreq_set_ticket (ap->handle, ap->apreq,
806 shishi_tkt_ticket (ap->tkt));
807 if (res != SHISHI_OK)
809 shishi_error_printf (ap->handle, "Could not set ticket in AP-REQ: %s\n",
810 shishi_error (ap->handle));
811 return res;
814 cksumtype = shishi_ap_authenticator_cksumtype (ap);
815 if (ap->authenticatorcksumraw && ap->authenticatorcksumrawlen > 0)
816 res = shishi_authenticator_set_cksum (ap->handle, ap->authenticator,
817 cksumtype,
818 ap->authenticatorcksumraw,
819 ap->authenticatorcksumrawlen);
820 else if (cksumtype == SHISHI_NO_CKSUMTYPE)
821 res = shishi_authenticator_add_cksum (ap->handle, ap->authenticator,
822 shishi_tkt_key (ap->tkt),
823 ap->authenticatorcksumkeyusage,
824 ap->authenticatorcksumdata,
825 ap->authenticatorcksumdatalen);
826 else
827 res = shishi_authenticator_add_cksum_type (ap->handle, ap->authenticator,
828 shishi_tkt_key (ap->tkt),
829 ap->authenticatorcksumkeyusage,
830 cksumtype,
831 ap->authenticatorcksumdata,
832 ap->authenticatorcksumdatalen);
833 if (res != SHISHI_OK)
835 shishi_error_printf (ap->handle,
836 "Could not add checksum to authenticator: %s\n",
837 shishi_error (ap->handle));
838 return res;
841 if (VERBOSE (ap->handle))
842 printf ("Got Authenticator...\n");
844 if (VERBOSEASN1 (ap->handle))
845 shishi_authenticator_print (ap->handle, stdout, ap->authenticator);
847 res = shishi_apreq_add_authenticator (ap->handle, ap->apreq,
848 shishi_tkt_key (ap->tkt),
849 ap->authenticatorkeyusage,
850 ap->authenticator);
851 if (res != SHISHI_OK)
853 shishi_error_printf (ap->handle, "Could not set authenticator: %s\n",
854 shishi_error (ap->handle));
855 return res;
858 if (VERBOSEASN1 (ap->handle))
859 shishi_apreq_print (ap->handle, stdout, ap->apreq);
861 return SHISHI_OK;
865 * shishi_ap_req_decode:
866 * @ap: structure that holds information about AP exchange
868 * Decode ticket in AP-REQ and set the Ticket fields in the AP
869 * exchange.
871 * Return value: Returns SHISHI_OK iff successful.
874 shishi_ap_req_decode (Shishi_ap * ap)
876 Shishi_asn1 ticket;
877 int rc;
879 if (VERBOSEASN1 (ap->handle))
880 shishi_apreq_print (ap->handle, stdout, ap->apreq);
882 rc = shishi_apreq_get_ticket (ap->handle, ap->apreq, &ticket);
883 if (rc != SHISHI_OK)
885 shishi_error_printf (ap->handle,
886 "Could not extract ticket from AP-REQ: %s\n",
887 shishi_strerror (rc));
888 return rc;
891 if (VERBOSEASN1 (ap->handle))
892 shishi_ticket_print (ap->handle, stdout, ticket);
894 rc = shishi_tkt (ap->handle, &ap->tkt);
895 if (rc != SHISHI_OK)
896 return rc;
898 shishi_tkt_ticket_set (ap->tkt, ticket);
900 return SHISHI_OK;
904 * shishi_ap_req_process_keyusage:
905 * @ap: structure that holds information about AP exchange
906 * @key: cryptographic key used to decrypt ticket in AP-REQ.
907 * @keyusage: key usage to use during decryption, for normal
908 * AP-REQ's this is normally SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR,
909 * for AP-REQ's part of TGS-REQ's, this is normally
910 * SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR.
912 * Decrypt ticket in AP-REQ using supplied key and decrypt
913 * Authenticator in AP-REQ using key in decrypted ticket, and on
914 * success set the Ticket and Authenticator fields in the AP exchange.
916 * Return value: Returns SHISHI_OK iff successful.
919 shishi_ap_req_process_keyusage (Shishi_ap * ap,
920 Shishi_key * key, int32_t keyusage)
922 Shishi_asn1 authenticator;
923 Shishi_key *tktkey;
924 int rc;
926 rc = shishi_ap_req_decode (ap);
927 if (rc != SHISHI_OK)
929 shishi_error_printf (ap->handle, "Error decoding ticket: %s\n",
930 shishi_strerror (rc));
931 return rc;
934 rc = shishi_tkt_decrypt (ap->tkt, key);
935 if (rc != SHISHI_OK)
937 shishi_error_printf (ap->handle, "Error decrypting ticket: %s\n",
938 shishi_strerror (rc));
939 return rc;
942 rc = shishi_encticketpart_get_key (ap->handle,
943 shishi_tkt_encticketpart (ap->tkt),
944 &tktkey);
945 if (rc != SHISHI_OK)
947 shishi_error_printf (ap->handle, "Could not get key from ticket: %s\n",
948 shishi_strerror (rc));
949 return rc;
952 if (VERBOSEASN1 (ap->handle))
953 shishi_encticketpart_print (ap->handle, stdout,
954 shishi_tkt_encticketpart (ap->tkt));
956 rc = shishi_apreq_decrypt (ap->handle, ap->apreq, tktkey,
957 keyusage, &authenticator);
958 if (rc != SHISHI_OK)
960 shishi_error_printf (ap->handle, "Error decrypting apreq: %s\n",
961 shishi_strerror (rc));
962 return rc;
965 /* XXX? verify checksum in authenticator. */
967 if (VERBOSEASN1 (ap->handle))
968 shishi_authenticator_print (ap->handle, stdout, authenticator);
970 if (ap->authenticatorcksumdata)
971 free (ap->authenticatorcksumdata);
973 rc = shishi_authenticator_cksum (ap->handle, authenticator,
974 &ap->authenticatorcksumtype,
975 &ap->authenticatorcksumdata,
976 &ap->authenticatorcksumdatalen);
977 if (rc != SHISHI_OK)
979 shishi_error_printf (ap->handle,
980 "Error extracting authenticator checksum: %s\n",
981 shishi_strerror (rc));
982 return rc;
985 ap->authenticator = authenticator;
987 return SHISHI_OK;
991 * shishi_ap_req_process:
992 * @ap: structure that holds information about AP exchange
993 * @key: cryptographic key used to decrypt ticket in AP-REQ.
995 * Decrypt ticket in AP-REQ using supplied key and decrypt
996 * Authenticator in AP-REQ using key in decrypted ticket, and on
997 * success set the Ticket and Authenticator fields in the AP exchange.
999 * Return value: Returns SHISHI_OK iff successful.
1002 shishi_ap_req_process (Shishi_ap * ap, Shishi_key * key)
1004 return shishi_ap_req_process_keyusage (ap, key,
1005 SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR);
1009 * shishi_ap_req_asn1:
1010 * @ap: structure that holds information about AP exchange
1011 * @apreq: output AP-REQ variable.
1013 * Build AP-REQ using shishi_ap_req_build() and return it.
1015 * Return value: Returns SHISHI_OK iff successful.
1018 shishi_ap_req_asn1 (Shishi_ap * ap, Shishi_asn1 * apreq)
1020 int rc;
1022 rc = shishi_ap_req_build (ap);
1023 if (rc != SHISHI_OK)
1024 return rc;
1026 *apreq = ap->apreq;
1028 return SHISHI_OK;
1032 * shishi_ap_key:
1033 * @ap: structure that holds information about AP exchange
1035 * Extract the application key from AP. If subkeys are used, it is
1036 * taken from the Authenticator, otherwise the session key is used.
1038 * Return value: Return application key from AP.
1040 Shishi_key *
1041 shishi_ap_key (Shishi_ap * ap)
1043 int rc;
1045 /* XXX do real check if subkey is present, don't just assume error
1046 means no subkey */
1048 rc = shishi_authenticator_get_subkey (ap->handle, ap->authenticator,
1049 &ap->key);
1050 if (rc != SHISHI_OK)
1051 ap->key = shishi_tkt_key (ap->tkt);
1053 return ap->key;
1057 * shishi_ap_rep:
1058 * @ap: structure that holds information about AP exchange
1060 * Get ASN.1 AP-REP structure from AP exchange.
1062 * Return value: Returns the AP-REP from the AP exchange, or NULL if
1063 * not yet set or an error occured.
1065 Shishi_asn1
1066 shishi_ap_rep (Shishi_ap * ap)
1068 return ap->aprep;
1072 * shishi_ap_rep_set:
1073 * @ap: structure that holds information about AP exchange
1074 * @aprep: aprep to store in AP.
1076 * Set the AP-REP in the AP exchange.
1078 void
1079 shishi_ap_rep_set (Shishi_ap * ap, Shishi_asn1 aprep)
1081 if (ap->aprep)
1082 shishi_asn1_done (ap->handle, ap->aprep);
1083 ap->aprep = aprep;
1087 * shishi_ap_rep_der:
1088 * @ap: structure that holds information about AP exchange
1089 * @out: output array with newly allocated DER encoding of AP-REP.
1090 * @outlen: length of output array with DER encoding of AP-REP.
1092 * Build AP-REP using shishi_ap_rep_build() and DER encode it. @out
1093 * is allocated by this function, and it is the responsibility of
1094 * caller to deallocate it.
1096 * Return value: Returns SHISHI_OK iff successful.
1099 shishi_ap_rep_der (Shishi_ap * ap, char **out, size_t * outlen)
1101 int rc;
1103 rc = shishi_ap_rep_build (ap);
1104 if (rc != SHISHI_OK)
1105 return rc;
1107 rc = shishi_asn1_to_der (ap->handle, ap->aprep, out, outlen);
1108 if (rc != SHISHI_OK)
1109 return rc;
1111 return SHISHI_OK;
1115 * shishi_ap_rep_der_set:
1116 * @ap: structure that holds information about AP exchange
1117 * @der: input array with DER encoded AP-REP.
1118 * @derlen: length of input array with DER encoded AP-REP.
1120 * DER decode AP-REP and set it AP exchange. If decoding fails, the
1121 * AP-REP in the AP exchange remains.
1123 * Return value: Returns SHISHI_OK.
1126 shishi_ap_rep_der_set (Shishi_ap * ap, char *der, size_t derlen)
1128 Shishi_asn1 aprep;
1130 aprep = shishi_der2asn1_aprep (ap->handle, der, derlen);
1132 if (!aprep)
1133 return SHISHI_ASN1_ERROR;
1135 ap->aprep = aprep;
1137 return SHISHI_OK;
1141 * shishi_ap_rep_build:
1142 * @ap: structure that holds information about AP exchange
1144 * Checksum data in authenticator and add ticket and authenticator to
1145 * AP-REP.
1147 * Return value: Returns SHISHI_OK iff successful.
1150 shishi_ap_rep_build (Shishi_ap * ap)
1152 Shishi_asn1 aprep;
1153 int rc;
1155 if (VERBOSE (ap->handle))
1156 printf ("Building AP-REP...\n");
1158 aprep = shishi_aprep (ap->handle);
1159 rc = shishi_aprep_enc_part_make (ap->handle, aprep, ap->encapreppart,
1160 ap->authenticator,
1161 shishi_tkt_encticketpart (ap->tkt));
1162 if (rc != SHISHI_OK)
1164 shishi_error_printf (ap->handle, "Error creating AP-REP: %s\n",
1165 shishi_strerror (rc));
1166 return rc;
1169 if (VERBOSEASN1 (ap->handle))
1170 shishi_aprep_print (ap->handle, stdout, aprep);
1172 shishi_ap_rep_set (ap, aprep);
1174 return SHISHI_OK;
1178 * shishi_ap_rep_asn1:
1179 * @ap: structure that holds information about AP exchange
1180 * @aprep: output AP-REP variable.
1182 * Build AP-REP using shishi_ap_rep_build() and return it.
1184 * Return value: Returns SHISHI_OK iff successful.
1187 shishi_ap_rep_asn1 (Shishi_ap * ap, Shishi_asn1 * aprep)
1189 int rc;
1191 rc = shishi_ap_rep_build (ap);
1192 if (rc != SHISHI_OK)
1193 return rc;
1195 *aprep = ap->aprep;
1197 return SHISHI_OK;
1201 * shishi_ap_rep_verify:
1202 * @ap: structure that holds information about AP exchange
1204 * Verify AP-REP compared to Authenticator.
1206 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1207 * error.
1210 shishi_ap_rep_verify (Shishi_ap * ap)
1212 int res;
1214 if (VERBOSE (ap->handle))
1215 printf ("Decrypting AP-REP...\n");
1217 if (VERBOSEASN1 (ap->handle))
1218 shishi_aprep_print (ap->handle, stdout, ap->aprep);
1220 res = shishi_aprep_decrypt (ap->handle, ap->aprep,
1221 shishi_tkt_key (ap->tkt),
1222 SHISHI_KEYUSAGE_ENCAPREPPART,
1223 &ap->encapreppart);
1224 if (res != SHISHI_OK)
1225 return res;
1227 if (VERBOSEASN1 (ap->handle))
1228 shishi_encapreppart_print (ap->handle, stdout, ap->encapreppart);
1230 res = shishi_aprep_verify (ap->handle, ap->authenticator, ap->encapreppart);
1231 if (res != SHISHI_OK)
1232 return res;
1234 if (VERBOSE (ap->handle))
1235 printf ("Verified AP-REP successfully...\n");
1237 return SHISHI_OK;
1241 * shishi_ap_rep_verify_der:
1242 * @ap: structure that holds information about AP exchange
1243 * @der: input array with DER encoded AP-REP.
1244 * @derlen: length of input array with DER encoded AP-REP.
1246 * DER decode AP-REP and set it in AP exchange using
1247 * shishi_ap_rep_der_set() and verify it using shishi_ap_rep_verify().
1249 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1250 * error.
1253 shishi_ap_rep_verify_der (Shishi_ap * ap, char *der, size_t derlen)
1255 int res;
1257 res = shishi_ap_rep_der_set (ap, der, derlen);
1258 if (res != SHISHI_OK)
1259 return res;
1261 res = shishi_ap_rep_verify (ap);
1262 if (res != SHISHI_OK)
1263 return res;
1265 return SHISHI_OK;
1269 * shishi_ap_rep_verify_asn1:
1270 * @ap: structure that holds information about AP exchange
1271 * @aprep: input AP-REP.
1273 * Set the AP-REP in the AP exchange using shishi_ap_rep_set() and
1274 * verify it using shishi_ap_rep_verify().
1276 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1277 * error.
1280 shishi_ap_rep_verify_asn1 (Shishi_ap * ap, Shishi_asn1 aprep)
1282 int res;
1284 shishi_ap_rep_set (ap, aprep);
1286 res = shishi_ap_rep_verify (ap);
1287 if (res != SHISHI_OK)
1288 return res;
1290 return SHISHI_OK;
1294 * shishi_ap_encapreppart:
1295 * @ap: structure that holds information about AP exchange
1297 * Get ASN.1 EncAPRepPart structure from AP exchange.
1299 * Return value: Returns the EncAPREPPart from the AP exchange, or
1300 * NULL if not yet set or an error occured.
1302 Shishi_asn1
1303 shishi_ap_encapreppart (Shishi_ap * ap)
1305 return ap->encapreppart;
1309 * shishi_ap_encapreppart_set:
1310 * @ap: structure that holds information about AP exchange
1311 * @encapreppart: EncAPRepPart to store in AP.
1313 * Set the EncAPRepPart in the AP exchange.
1315 void
1316 shishi_ap_encapreppart_set (Shishi_ap * ap, Shishi_asn1 encapreppart)
1318 if (ap->encapreppart)
1319 shishi_asn1_done (ap->handle, ap->encapreppart);
1320 ap->encapreppart = encapreppart;
1323 #define APOPTION_RESERVED "reserved"
1324 #define APOPTION_USE_SESSION_KEY "use-session-key"
1325 #define APOPTION_MUTUAL_REQUIRED "mutual-required"
1326 #define APOPTION_UNKNOWN "unknown"
1329 * shishi_ap_option2string:
1330 * @option: enumerated AP-Option type, see Shishi_apoptions.
1332 * Convert AP-Option type to AP-Option name string. Note that @option
1333 * must be just one of the AP-Option types, it cannot be an binary
1334 * ORed indicating several AP-Options.
1336 * Return value: Returns static string with name of AP-Option that
1337 * must not be deallocated, or "unknown" if AP-Option was not understood.
1339 const char *
1340 shishi_ap_option2string (Shishi_apoptions option)
1342 const char *str;
1344 switch (option)
1346 case SHISHI_APOPTIONS_RESERVED:
1347 str = APOPTION_RESERVED;
1348 break;
1350 case SHISHI_APOPTIONS_USE_SESSION_KEY:
1351 str = APOPTION_USE_SESSION_KEY;
1352 break;
1354 case SHISHI_APOPTIONS_MUTUAL_REQUIRED:
1355 str = APOPTION_MUTUAL_REQUIRED;
1356 break;
1358 default:
1359 str = APOPTION_UNKNOWN;
1360 break;
1363 return str;
1367 * shishi_ap_string2option:
1368 * @str: zero terminated character array with name of AP-Option,
1369 * e.g. "use-session-key".
1371 * Convert AP-Option name to AP-Option type.
1373 * Return value: Returns enumerated type member corresponding to AP-Option,
1374 * or 0 if string was not understood.
1376 Shishi_apoptions
1377 shishi_ap_string2option (const char *str)
1379 int option;
1381 if (strcasecmp (str, APOPTION_RESERVED) == 0)
1382 option = SHISHI_APOPTIONS_RESERVED;
1383 else if (strcasecmp (str, APOPTION_USE_SESSION_KEY) == 0)
1384 option = SHISHI_APOPTIONS_USE_SESSION_KEY;
1385 else if (strcasecmp (str, APOPTION_MUTUAL_REQUIRED) == 0)
1386 option = SHISHI_APOPTIONS_MUTUAL_REQUIRED;
1387 else
1388 option = strtol (str, (char **) NULL, 0);
1390 return option;