Change GPLv2+ to GPLv3+.
[shishi.git] / lib / ap.c
blob280f0caca66ea6e97803bc4834d80c9c0ac2b76a
1 /* ap.c --- AP functions
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
23 #include "internal.h"
25 struct Shishi_ap
27 Shishi *handle;
28 Shishi_tkt *tkt;
29 Shishi_key *key;
30 Shishi_asn1 authenticator;
31 Shishi_asn1 apreq;
32 Shishi_asn1 aprep;
33 Shishi_asn1 encapreppart;
34 /* Key usage for encryption entire Authenticator ASN.1 blob, stored
35 in AP-REQ. */
36 int authenticatorkeyusage;
37 /* Key usage for computing checksum of authenticatorcksumdata in the
38 Authenticator, in AP-REQ. */
39 int authenticatorcksumkeyusage;
40 /* Sets the checksum algorithm type in Authenticator, in AP-REQ. If
41 there is data in authenticatorcksumdata to compute a checksum on,
42 this also indicate the algorithm to use for this computation. */
43 int32_t authenticatorcksumtype;
44 /* Auxilliary application data to compute checksum on and store in
45 Authenticator, in AP-REQ. Note that data is not stored in
46 AP-REQ, only a checksum of it. */
47 char *authenticatorcksumdata;
48 size_t authenticatorcksumdatalen;
49 /* Raw checksum data to store in Authenticator, in AP-REQ.
50 Normally, this is the output of the checksum algorithm computed
51 on the data in authenticatorcksumdata, but some applications
52 (e.g., GSS-API) put something weird in the checksum field. */
53 char *authenticatorcksumraw;
54 size_t authenticatorcksumrawlen;
57 /**
58 * shishi_ap:
59 * @handle: shishi handle as allocated by shishi_init().
60 * @ap: pointer to new structure that holds information about AP exchange
62 * Create a new AP exchange with a random subkey of the default
63 * encryption type from configuration. Note that there is no
64 * guarantee that the receiver will understand that key type, you
65 * should probably use shishi_ap_etype() or shishi_ap_nosubkey()
66 * instead. In the future, this function will likely behave as
67 * shishi_ap_nosubkey() and shishi_ap_nosubkey() will be removed.
69 * Return value: Returns SHISHI_OK iff successful.
70 **/
71 int
72 shishi_ap (Shishi * handle, Shishi_ap ** ap)
74 int res;
76 res = shishi_ap_nosubkey (handle, ap);
77 if (res != SHISHI_OK)
79 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
80 shishi_error (handle));
81 return res;
84 res = shishi_authenticator_add_random_subkey (handle, (*ap)->authenticator);
85 if (res != SHISHI_OK)
87 shishi_error_printf (handle, "Could not add random subkey in AP: %s\n",
88 shishi_strerror (res));
89 return res;
92 return SHISHI_OK;
95 /**
96 * shishi_ap_etype:
97 * @handle: shishi handle as allocated by shishi_init().
98 * @ap: pointer to new structure that holds information about AP exchange
99 * @etype: encryption type of newly generated random subkey.
101 * Create a new AP exchange with a random subkey of indicated
102 * encryption type.
104 * Return value: Returns SHISHI_OK iff successful.
107 shishi_ap_etype (Shishi * handle, Shishi_ap ** ap, int etype)
109 int res;
111 res = shishi_ap_nosubkey (handle, ap);
112 if (res != SHISHI_OK)
114 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
115 shishi_error (handle));
116 return res;
119 res = shishi_authenticator_add_random_subkey_etype (handle,
120 (*ap)->authenticator,
121 etype);
122 if (res != SHISHI_OK)
124 shishi_error_printf (handle, "Could not add random subkey in AP: %s\n",
125 shishi_strerror (res));
126 return res;
129 return SHISHI_OK;
133 * shishi_ap_nosubkey:
134 * @handle: shishi handle as allocated by shishi_init().
135 * @ap: pointer to new structure that holds information about AP exchange
137 * Create a new AP exchange without subkey in authenticator.
139 * Return value: Returns SHISHI_OK iff successful.
142 shishi_ap_nosubkey (Shishi * handle, Shishi_ap ** ap)
144 Shishi_ap *lap;
146 *ap = xcalloc (1, sizeof (**ap));
147 lap = *ap;
149 lap->handle = handle;
150 lap->authenticatorcksumtype = SHISHI_NO_CKSUMTYPE;
151 lap->authenticatorcksumkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR_CKSUM;
152 lap->authenticatorkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR;
154 lap->authenticator = shishi_authenticator (handle);
155 if (lap->authenticator == NULL)
157 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
158 shishi_error (handle));
159 return SHISHI_ASN1_ERROR;
162 lap->apreq = shishi_apreq (handle);
163 if (lap->apreq == NULL)
165 shishi_error_printf (handle, "Could not create AP-REQ: %s\n",
166 shishi_error (handle));
167 return SHISHI_ASN1_ERROR;
170 lap->aprep = shishi_aprep (handle);
171 if (lap->aprep == NULL)
173 shishi_error_printf (handle, "Could not create AP-REP: %s\n",
174 shishi_error (handle));
175 return SHISHI_ASN1_ERROR;
178 lap->encapreppart = shishi_encapreppart (handle);
179 if (lap->encapreppart == NULL)
181 shishi_error_printf (handle, "Could not create EncAPRepPart: %s\n",
182 shishi_error (handle));
183 return SHISHI_ASN1_ERROR;
186 return SHISHI_OK;
190 * shishi_ap_done:
191 * @ap: structure that holds information about AP exchange
193 * Deallocate resources associated with AP exchange. This should be
194 * called by the application when it no longer need to utilize the AP
195 * exchange handle.
197 void
198 shishi_ap_done (Shishi_ap * ap)
200 if (ap->authenticatorcksumdata)
201 free (ap->authenticatorcksumdata);
202 if (ap->authenticatorcksumraw)
203 free (ap->authenticatorcksumraw);
204 shishi_asn1_done (ap->handle, ap->authenticator);
205 shishi_asn1_done (ap->handle, ap->apreq);
206 shishi_asn1_done (ap->handle, ap->aprep);
207 shishi_asn1_done (ap->handle, ap->encapreppart);
208 free (ap);
212 * shishi_ap_set_tktoptions:
213 * @ap: structure that holds information about AP exchange
214 * @tkt: ticket to set in AP.
215 * @options: AP-REQ options to set in AP.
217 * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
218 * apoptions (see shishi_apreq_options_set()).
220 * Return value: Returns SHISHI_OK iff successful.
223 shishi_ap_set_tktoptions (Shishi_ap * ap, Shishi_tkt * tkt, int options)
225 int rc;
227 shishi_ap_tkt_set (ap, tkt);
229 rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
230 if (rc != SHISHI_OK)
232 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
233 return rc;
236 return SHISHI_OK;
240 * shishi_ap_set_tktoptionsdata:
241 * @ap: structure that holds information about AP exchange
242 * @tkt: ticket to set in AP.
243 * @options: AP-REQ options to set in AP.
244 * @data: input array with data to checksum in Authenticator.
245 * @len: length of input array with data to checksum in Authenticator.
247 * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
248 * apoptions (see shishi_apreq_options_set()) and set the
249 * Authenticator checksum data.
251 * Return value: Returns SHISHI_OK iff successful.
254 shishi_ap_set_tktoptionsdata (Shishi_ap * ap,
255 Shishi_tkt * tkt,
256 int options, const char *data, size_t len)
258 int rc;
260 shishi_ap_tkt_set (ap, tkt);
262 rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
263 if (rc != SHISHI_OK)
265 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
266 return rc;
269 shishi_ap_authenticator_cksumdata_set (ap, data, len);
271 return SHISHI_OK;
276 * shishi_ap_set_tktoptionsraw:
277 * @ap: structure that holds information about AP exchange
278 * @tkt: ticket to set in AP.
279 * @options: AP-REQ options to set in AP.
280 * @cksumtype: authenticator checksum type to set in AP.
281 * @data: input array with data to store in checksum field in Authenticator.
282 * @len: length of input array with data to store in checksum field in
283 * Authenticator.
285 * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
286 * apoptions (see shishi_apreq_options_set()) and set the raw
287 * Authenticator checksum data.
289 * Return value: Returns SHISHI_OK iff successful.
292 shishi_ap_set_tktoptionsraw (Shishi_ap * ap,
293 Shishi_tkt * tkt,
294 int options,
295 int32_t cksumtype, const char *data, size_t len)
297 int rc;
299 shishi_ap_tkt_set (ap, tkt);
301 rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
302 if (rc != SHISHI_OK)
304 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
305 return rc;
308 shishi_ap_authenticator_cksumraw_set (ap, cksumtype, data, len);
310 return SHISHI_OK;
314 * shishi_ap_set_tktoptionsasn1usage:
315 * @ap: structure that holds information about AP exchange
316 * @tkt: ticket to set in AP.
317 * @options: AP-REQ options to set in AP.
318 * @node: input ASN.1 structure to store as authenticator checksum data.
319 * @field: field in ASN.1 structure to use.
320 * @authenticatorcksumkeyusage: key usage for checksum in authenticator.
321 * @authenticatorkeyusage: key usage for authenticator.
323 * Set ticket, options and authenticator checksum data using
324 * shishi_ap_set_tktoptionsdata(). The authenticator checksum data is
325 * the DER encoding of the ASN.1 field provided.
327 * Return value: Returns SHISHI_OK iff successful.
330 shishi_ap_set_tktoptionsasn1usage (Shishi_ap * ap,
331 Shishi_tkt * tkt,
332 int options,
333 Shishi_asn1 node,
334 const char *field,
335 int authenticatorcksumkeyusage,
336 int authenticatorkeyusage)
338 char *buf;
339 size_t buflen;
340 int res;
342 res = shishi_asn1_to_der_field (ap->handle, node, field, &buf, &buflen);
343 if (res != SHISHI_OK)
344 return res;
346 res = shishi_ap_set_tktoptionsdata (ap, tkt, options, buf, buflen);
347 if (res != SHISHI_OK)
348 return res;
350 ap->authenticatorcksumkeyusage = authenticatorcksumkeyusage;
351 ap->authenticatorkeyusage = authenticatorkeyusage;
353 return SHISHI_OK;
357 * shishi_ap_tktoptions:
358 * @handle: shishi handle as allocated by shishi_init().
359 * @ap: pointer to new structure that holds information about AP exchange
360 * @tkt: ticket to set in newly created AP.
361 * @options: AP-REQ options to set in newly created AP.
363 * Create a new AP exchange using shishi_ap(), and set the ticket and
364 * AP-REQ apoptions using shishi_ap_set_tktoption(). A random session
365 * key is added to the authenticator, using the same keytype as the
366 * ticket.
368 * Return value: Returns SHISHI_OK iff successful.
371 shishi_ap_tktoptions (Shishi * handle,
372 Shishi_ap ** ap, Shishi_tkt * tkt, int options)
374 int rc;
376 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
377 if (rc != SHISHI_OK)
378 return rc;
380 rc = shishi_ap_set_tktoptions (*ap, tkt, options);
381 if (rc != SHISHI_OK)
382 return rc;
384 return SHISHI_OK;
388 * shishi_ap_tktoptionsdata:
389 * @handle: shishi handle as allocated by shishi_init().
390 * @ap: pointer to new structure that holds information about AP exchange
391 * @tkt: ticket to set in newly created AP.
392 * @options: AP-REQ options to set in newly created AP.
393 * @data: input array with data to checksum in Authenticator.
394 * @len: length of input array with data to checksum in Authenticator.
396 * Create a new AP exchange using shishi_ap(), and set the ticket,
397 * AP-REQ apoptions and the Authenticator checksum data using
398 * shishi_ap_set_tktoptionsdata(). A random session key is added to
399 * the authenticator, using the same keytype as the ticket.
401 * Return value: Returns SHISHI_OK iff successful.
404 shishi_ap_tktoptionsdata (Shishi * handle,
405 Shishi_ap ** ap,
406 Shishi_tkt * tkt, int options,
407 const char *data, size_t len)
409 int rc;
411 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
412 if (rc != SHISHI_OK)
413 return rc;
415 rc = shishi_ap_set_tktoptionsdata (*ap, tkt, options, data, len);
416 if (rc != SHISHI_OK)
417 return rc;
419 return SHISHI_OK;
423 * shishi_ap_tktoptionsraw:
424 * @handle: shishi handle as allocated by shishi_init().
425 * @ap: pointer to new structure that holds information about AP exchange
426 * @tkt: ticket to set in newly created AP.
427 * @options: AP-REQ options to set in newly created AP.
428 * @cksumtype: authenticator checksum type to set in AP.
429 * @data: input array with data to store in checksum field in Authenticator.
430 * @len: length of input array with data to store in checksum field in
431 * Authenticator.
433 * Create a new AP exchange using shishi_ap(), and set the ticket,
434 * AP-REQ apoptions and the raw Authenticator checksum data field
435 * using shishi_ap_set_tktoptionsraw(). A random session key is added
436 * to the authenticator, using the same keytype as the ticket.
438 * Return value: Returns SHISHI_OK iff successful.
441 shishi_ap_tktoptionsraw (Shishi * handle,
442 Shishi_ap ** ap,
443 Shishi_tkt * tkt, int options,
444 int32_t cksumtype, const char *data, size_t len)
446 int rc;
448 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
449 if (rc != SHISHI_OK)
450 return rc;
452 rc = shishi_ap_set_tktoptionsraw (*ap, tkt, options, cksumtype, data, len);
453 if (rc != SHISHI_OK)
454 return rc;
456 return SHISHI_OK;
460 * shishi_ap_etype_tktoptionsdata:
461 * @handle: shishi handle as allocated by shishi_init().
462 * @ap: pointer to new structure that holds information about AP exchange
463 * @etype: encryption type of newly generated random subkey.
464 * @tkt: ticket to set in newly created AP.
465 * @options: AP-REQ options to set in newly created AP.
466 * @data: input array with data to checksum in Authenticator.
467 * @len: length of input array with data to checksum in Authenticator.
469 * Create a new AP exchange using shishi_ap(), and set the ticket,
470 * AP-REQ apoptions and the Authenticator checksum data using
471 * shishi_ap_set_tktoptionsdata(). A random session key is added to
472 * the authenticator, using the same keytype as the ticket.
474 * Return value: Returns SHISHI_OK iff successful.
477 shishi_ap_etype_tktoptionsdata (Shishi * handle,
478 Shishi_ap ** ap,
479 int32_t etype,
480 Shishi_tkt * tkt, int options,
481 const char *data, size_t len)
483 int rc;
485 rc = shishi_ap_etype (handle, ap, etype);
486 if (rc != SHISHI_OK)
487 return rc;
489 rc = shishi_ap_set_tktoptionsdata (*ap, tkt, options, data, len);
490 if (rc != SHISHI_OK)
491 return rc;
493 return SHISHI_OK;
497 * shishi_ap_tktoptionsasn1usage:
498 * @handle: shishi handle as allocated by shishi_init().
499 * @ap: pointer to new structure that holds information about AP exchange
500 * @tkt: ticket to set in newly created AP.
501 * @options: AP-REQ options to set in newly created AP.
502 * @node: input ASN.1 structure to store as authenticator checksum data.
503 * @field: field in ASN.1 structure to use.
504 * @authenticatorcksumkeyusage: key usage for checksum in authenticator.
505 * @authenticatorkeyusage: key usage for authenticator.
507 * Create a new AP exchange using shishi_ap(), and set ticket, options
508 * and authenticator checksum data from the DER encoding of the ASN.1
509 * field using shishi_ap_set_tktoptionsasn1usage(). A random session
510 * key is added to the authenticator, using the same keytype as the
511 * ticket.
513 * Return value: Returns SHISHI_OK iff successful.
516 shishi_ap_tktoptionsasn1usage (Shishi * handle,
517 Shishi_ap ** ap,
518 Shishi_tkt * tkt,
519 int options,
520 Shishi_asn1 node,
521 const char *field,
522 int authenticatorcksumkeyusage,
523 int authenticatorkeyusage)
525 int rc;
527 rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
528 if (rc != SHISHI_OK)
529 return rc;
531 rc = shishi_ap_set_tktoptionsasn1usage (*ap, tkt, options,
532 node, field,
533 authenticatorcksumkeyusage,
534 authenticatorkeyusage);
535 if (rc != SHISHI_OK)
536 return rc;
538 return SHISHI_OK;
542 * shishi_ap_tkt:
543 * @ap: structure that holds information about AP exchange
545 * Get Ticket from AP exchange.
547 * Return value: Returns the ticket from the AP exchange, or NULL if
548 * not yet set or an error occured.
550 Shishi_tkt *
551 shishi_ap_tkt (Shishi_ap * ap)
553 return ap->tkt;
557 * shishi_ap_tkt_set:
558 * @ap: structure that holds information about AP exchange
559 * @tkt: ticket to store in AP.
561 * Set the Ticket in the AP exchange.
563 void
564 shishi_ap_tkt_set (Shishi_ap * ap, Shishi_tkt * tkt)
566 ap->tkt = tkt;
570 * shishi_ap_authenticator_cksumdata:
571 * @ap: structure that holds information about AP exchange
572 * @out: output array that holds authenticator checksum data.
573 * @len: on input, maximum length of output array that holds
574 * authenticator checksum data, on output actual length of
575 * output array that holds authenticator checksum data.
577 * Get checksum data from Authenticator.
579 * Return value: Returns SHISHI_OK if successful, or
580 * SHISHI_TOO_SMALL_BUFFER if buffer provided was too small.
583 shishi_ap_authenticator_cksumdata (Shishi_ap * ap, char *out, size_t * len)
585 if (*len < ap->authenticatorcksumdatalen)
586 return SHISHI_TOO_SMALL_BUFFER;
587 if (ap->authenticatorcksumdata)
588 memcpy (out, ap->authenticatorcksumdata, ap->authenticatorcksumdatalen);
589 *len = ap->authenticatorcksumdatalen;
590 return SHISHI_OK;
594 * shishi_ap_authenticator_cksumdata_set:
595 * @ap: structure that holds information about AP exchange
596 * @authenticatorcksumdata: input array with data to compute checksum
597 * on and store in Authenticator in AP-REQ.
598 * @authenticatorcksumdatalen: length of input array with data to
599 * compute checksum on and store in Authenticator in AP-REQ.
601 * Set the Authenticator Checksum Data in the AP exchange. This is
602 * the data that will be checksumed, and the checksum placed in the
603 * checksum field. It is not the actual checksum field. See also
604 * shishi_ap_authenticator_cksumraw_set.
606 void
607 shishi_ap_authenticator_cksumdata_set (Shishi_ap * ap,
608 const char *authenticatorcksumdata,
609 size_t authenticatorcksumdatalen)
611 ap->authenticatorcksumdata = xmemdup (authenticatorcksumdata,
612 authenticatorcksumdatalen);
613 ap->authenticatorcksumdatalen = authenticatorcksumdatalen;
617 * shishi_ap_authenticator_cksumraw_set:
618 * @ap: structure that holds information about AP exchange
619 * @authenticatorcksumtype: authenticator checksum type to set in AP.
620 * @authenticatorcksumraw: input array with authenticator checksum
621 * field value to set in Authenticator in AP-REQ.
622 * @authenticatorcksumrawlen: length of input array with
623 * authenticator checksum field value to set in Authenticator in AP-REQ.
625 * Set the Authenticator Checksum Data in the AP exchange. This is
626 * the actual checksum field, not data to compute checksum on and then
627 * store in the checksum field. See also
628 * shishi_ap_authenticator_cksumdata_set.
630 void
631 shishi_ap_authenticator_cksumraw_set (Shishi_ap * ap,
632 int32_t authenticatorcksumtype,
633 const char *authenticatorcksumraw,
634 size_t authenticatorcksumrawlen)
636 shishi_ap_authenticator_cksumtype_set (ap, authenticatorcksumtype);
637 ap->authenticatorcksumraw = xmemdup (authenticatorcksumraw,
638 authenticatorcksumrawlen);
639 ap->authenticatorcksumrawlen = authenticatorcksumrawlen;
643 * shishi_ap_authenticator_cksumtype:
644 * @ap: structure that holds information about AP exchange
646 * Get the Authenticator Checksum Type in the AP exchange.
648 * Return value: Return the authenticator checksum type.
650 int32_t
651 shishi_ap_authenticator_cksumtype (Shishi_ap * ap)
653 return ap->authenticatorcksumtype;
657 * shishi_ap_authenticator_cksumtype_set:
658 * @ap: structure that holds information about AP exchange
659 * @cksumtype: authenticator checksum type to set in AP.
661 * Set the Authenticator Checksum Type in the AP exchange.
663 void
664 shishi_ap_authenticator_cksumtype_set (Shishi_ap * ap, int32_t cksumtype)
666 ap->authenticatorcksumtype = cksumtype;
670 * shishi_ap_authenticator:
671 * @ap: structure that holds information about AP exchange
673 * Get ASN.1 Authenticator structure from AP exchange.
675 * Return value: Returns the Authenticator from the AP exchange, or
676 * NULL if not yet set or an error occured.
679 Shishi_asn1
680 shishi_ap_authenticator (Shishi_ap * ap)
682 return ap->authenticator;
686 * shishi_ap_authenticator_set:
687 * @ap: structure that holds information about AP exchange
688 * @authenticator: authenticator to store in AP.
690 * Set the Authenticator in the AP exchange.
692 void
693 shishi_ap_authenticator_set (Shishi_ap * ap, Shishi_asn1 authenticator)
695 if (ap->authenticator)
696 shishi_asn1_done (ap->handle, ap->authenticator);
697 ap->authenticator = authenticator;
701 * shishi_ap_req:
702 * @ap: structure that holds information about AP exchange
704 * Get ASN.1 AP-REQ structure from AP exchange.
706 * Return value: Returns the AP-REQ from the AP exchange, or NULL if
707 * not yet set or an error occured.
709 Shishi_asn1
710 shishi_ap_req (Shishi_ap * ap)
712 return ap->apreq;
717 * shishi_ap_req_set:
718 * @ap: structure that holds information about AP exchange
719 * @apreq: apreq to store in AP.
721 * Set the AP-REQ in the AP exchange.
723 void
724 shishi_ap_req_set (Shishi_ap * ap, Shishi_asn1 apreq)
726 if (ap->apreq)
727 shishi_asn1_done (ap->handle, ap->apreq);
728 ap->apreq = apreq;
732 * shishi_ap_req_der:
733 * @ap: structure that holds information about AP exchange
734 * @out: pointer to output array with der encoding of AP-REQ.
735 * @outlen: pointer to length of output array with der encoding of AP-REQ.
737 * Build AP-REQ using shishi_ap_req_build() and DER encode it. @out
738 * is allocated by this function, and it is the responsibility of
739 * caller to deallocate it.
741 * Return value: Returns SHISHI_OK iff successful.
744 shishi_ap_req_der (Shishi_ap * ap, char **out, size_t * outlen)
746 int rc;
748 rc = shishi_ap_req_build (ap);
749 if (rc != SHISHI_OK)
750 return rc;
752 rc = shishi_asn1_to_der (ap->handle, ap->apreq, out, outlen);
753 if (rc != SHISHI_OK)
754 return rc;
756 return SHISHI_OK;
760 * shishi_ap_req_der_set:
761 * @ap: structure that holds information about AP exchange
762 * @der: input array with DER encoded AP-REQ.
763 * @derlen: length of input array with DER encoded AP-REQ.
765 * DER decode AP-REQ and set it AP exchange. If decoding fails, the
766 * AP-REQ in the AP exchange is lost.
768 * Return value: Returns SHISHI_OK.
771 shishi_ap_req_der_set (Shishi_ap * ap, char *der, size_t derlen)
773 ap->apreq = shishi_der2asn1_apreq (ap->handle, der, derlen);
775 if (ap->apreq)
776 return SHISHI_OK;
777 else
778 return SHISHI_ASN1_ERROR;
782 * shishi_ap_req_build:
783 * @ap: structure that holds information about AP exchange
785 * Checksum data in authenticator and add ticket and authenticator to
786 * AP-REQ.
788 * Return value: Returns SHISHI_OK iff successful.
791 shishi_ap_req_build (Shishi_ap * ap)
793 int res;
794 int cksumtype;
796 if (VERBOSE (ap->handle))
797 printf ("Building AP-REQ...\n");
799 if (VERBOSEASN1 (ap->handle))
801 shishi_ticket_print (ap->handle, stdout, shishi_tkt_ticket (ap->tkt));
802 shishi_key_print (ap->handle, stdout, shishi_tkt_key (ap->tkt));
806 res = shishi_apreq_set_ticket (ap->handle, ap->apreq,
807 shishi_tkt_ticket (ap->tkt));
808 if (res != SHISHI_OK)
810 shishi_error_printf (ap->handle, "Could not set ticket in AP-REQ: %s\n",
811 shishi_error (ap->handle));
812 return res;
815 cksumtype = shishi_ap_authenticator_cksumtype (ap);
816 if (ap->authenticatorcksumraw && ap->authenticatorcksumrawlen > 0)
817 res = shishi_authenticator_set_cksum (ap->handle, ap->authenticator,
818 cksumtype,
819 ap->authenticatorcksumraw,
820 ap->authenticatorcksumrawlen);
821 else if (cksumtype == SHISHI_NO_CKSUMTYPE)
822 res = shishi_authenticator_add_cksum (ap->handle, ap->authenticator,
823 shishi_tkt_key (ap->tkt),
824 ap->authenticatorcksumkeyusage,
825 ap->authenticatorcksumdata,
826 ap->authenticatorcksumdatalen);
827 else
828 res = shishi_authenticator_add_cksum_type (ap->handle, ap->authenticator,
829 shishi_tkt_key (ap->tkt),
830 ap->authenticatorcksumkeyusage,
831 cksumtype,
832 ap->authenticatorcksumdata,
833 ap->authenticatorcksumdatalen);
834 if (res != SHISHI_OK)
836 shishi_error_printf (ap->handle,
837 "Could not add checksum to authenticator: %s\n",
838 shishi_error (ap->handle));
839 return res;
842 if (VERBOSE (ap->handle))
843 printf ("Got Authenticator...\n");
845 if (VERBOSEASN1 (ap->handle))
846 shishi_authenticator_print (ap->handle, stdout, ap->authenticator);
848 res = shishi_apreq_add_authenticator (ap->handle, ap->apreq,
849 shishi_tkt_key (ap->tkt),
850 ap->authenticatorkeyusage,
851 ap->authenticator);
852 if (res != SHISHI_OK)
854 shishi_error_printf (ap->handle, "Could not set authenticator: %s\n",
855 shishi_error (ap->handle));
856 return res;
859 if (VERBOSEASN1 (ap->handle))
860 shishi_apreq_print (ap->handle, stdout, ap->apreq);
862 return SHISHI_OK;
866 * shishi_ap_req_decode:
867 * @ap: structure that holds information about AP exchange
869 * Decode ticket in AP-REQ and set the Ticket fields in the AP
870 * exchange.
872 * Return value: Returns SHISHI_OK iff successful.
875 shishi_ap_req_decode (Shishi_ap * ap)
877 Shishi_asn1 ticket;
878 int rc;
880 if (VERBOSEASN1 (ap->handle))
881 shishi_apreq_print (ap->handle, stdout, ap->apreq);
883 rc = shishi_apreq_get_ticket (ap->handle, ap->apreq, &ticket);
884 if (rc != SHISHI_OK)
886 shishi_error_printf (ap->handle,
887 "Could not extract ticket from AP-REQ: %s\n",
888 shishi_strerror (rc));
889 return rc;
892 if (VERBOSEASN1 (ap->handle))
893 shishi_ticket_print (ap->handle, stdout, ticket);
895 rc = shishi_tkt (ap->handle, &ap->tkt);
896 if (rc != SHISHI_OK)
897 return rc;
899 shishi_tkt_ticket_set (ap->tkt, ticket);
901 return SHISHI_OK;
905 * shishi_ap_req_process_keyusage:
906 * @ap: structure that holds information about AP exchange
907 * @key: cryptographic key used to decrypt ticket in AP-REQ.
908 * @keyusage: key usage to use during decryption, for normal
909 * AP-REQ's this is normally SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR,
910 * for AP-REQ's part of TGS-REQ's, this is normally
911 * SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR.
913 * Decrypt ticket in AP-REQ using supplied key and decrypt
914 * Authenticator in AP-REQ using key in decrypted ticket, and on
915 * success set the Ticket and Authenticator fields in the AP exchange.
917 * Return value: Returns SHISHI_OK iff successful.
920 shishi_ap_req_process_keyusage (Shishi_ap * ap,
921 Shishi_key * key, int32_t keyusage)
923 Shishi_asn1 authenticator;
924 Shishi_key *tktkey;
925 int rc;
927 rc = shishi_ap_req_decode (ap);
928 if (rc != SHISHI_OK)
930 shishi_error_printf (ap->handle, "Error decoding ticket: %s\n",
931 shishi_strerror (rc));
932 return rc;
935 rc = shishi_tkt_decrypt (ap->tkt, key);
936 if (rc != SHISHI_OK)
938 shishi_error_printf (ap->handle, "Error decrypting ticket: %s\n",
939 shishi_strerror (rc));
940 return rc;
943 rc = shishi_encticketpart_get_key (ap->handle,
944 shishi_tkt_encticketpart (ap->tkt),
945 &tktkey);
946 if (rc != SHISHI_OK)
948 shishi_error_printf (ap->handle, "Could not get key from ticket: %s\n",
949 shishi_strerror (rc));
950 return rc;
953 if (VERBOSEASN1 (ap->handle))
954 shishi_encticketpart_print (ap->handle, stdout,
955 shishi_tkt_encticketpart (ap->tkt));
957 rc = shishi_apreq_decrypt (ap->handle, ap->apreq, tktkey,
958 keyusage, &authenticator);
959 if (rc != SHISHI_OK)
961 shishi_error_printf (ap->handle, "Error decrypting apreq: %s\n",
962 shishi_strerror (rc));
963 return rc;
966 /* XXX? verify checksum in authenticator. */
968 if (VERBOSEASN1 (ap->handle))
969 shishi_authenticator_print (ap->handle, stdout, authenticator);
971 if (ap->authenticatorcksumdata)
972 free (ap->authenticatorcksumdata);
974 rc = shishi_authenticator_cksum (ap->handle, authenticator,
975 &ap->authenticatorcksumtype,
976 &ap->authenticatorcksumdata,
977 &ap->authenticatorcksumdatalen);
978 if (rc != SHISHI_OK)
980 shishi_error_printf (ap->handle,
981 "Error extracting authenticator checksum: %s\n",
982 shishi_strerror (rc));
983 return rc;
986 ap->authenticator = authenticator;
988 return SHISHI_OK;
992 * shishi_ap_req_process:
993 * @ap: structure that holds information about AP exchange
994 * @key: cryptographic key used to decrypt ticket in AP-REQ.
996 * Decrypt ticket in AP-REQ using supplied key and decrypt
997 * Authenticator in AP-REQ using key in decrypted ticket, and on
998 * success set the Ticket and Authenticator fields in the AP exchange.
1000 * Return value: Returns SHISHI_OK iff successful.
1003 shishi_ap_req_process (Shishi_ap * ap, Shishi_key * key)
1005 return shishi_ap_req_process_keyusage (ap, key,
1006 SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR);
1010 * shishi_ap_req_asn1:
1011 * @ap: structure that holds information about AP exchange
1012 * @apreq: output AP-REQ variable.
1014 * Build AP-REQ using shishi_ap_req_build() and return it.
1016 * Return value: Returns SHISHI_OK iff successful.
1019 shishi_ap_req_asn1 (Shishi_ap * ap, Shishi_asn1 * apreq)
1021 int rc;
1023 rc = shishi_ap_req_build (ap);
1024 if (rc != SHISHI_OK)
1025 return rc;
1027 *apreq = ap->apreq;
1029 return SHISHI_OK;
1033 * shishi_ap_key:
1034 * @ap: structure that holds information about AP exchange
1036 * Extract the application key from AP. If subkeys are used, it is
1037 * taken from the Authenticator, otherwise the session key is used.
1039 * Return value: Return application key from AP.
1041 Shishi_key *
1042 shishi_ap_key (Shishi_ap * ap)
1044 int rc;
1046 /* XXX do real check if subkey is present, don't just assume error
1047 means no subkey */
1049 rc = shishi_authenticator_get_subkey (ap->handle, ap->authenticator,
1050 &ap->key);
1051 if (rc != SHISHI_OK)
1052 ap->key = shishi_tkt_key (ap->tkt);
1054 return ap->key;
1058 * shishi_ap_rep:
1059 * @ap: structure that holds information about AP exchange
1061 * Get ASN.1 AP-REP structure from AP exchange.
1063 * Return value: Returns the AP-REP from the AP exchange, or NULL if
1064 * not yet set or an error occured.
1066 Shishi_asn1
1067 shishi_ap_rep (Shishi_ap * ap)
1069 return ap->aprep;
1073 * shishi_ap_rep_set:
1074 * @ap: structure that holds information about AP exchange
1075 * @aprep: aprep to store in AP.
1077 * Set the AP-REP in the AP exchange.
1079 void
1080 shishi_ap_rep_set (Shishi_ap * ap, Shishi_asn1 aprep)
1082 if (ap->aprep)
1083 shishi_asn1_done (ap->handle, ap->aprep);
1084 ap->aprep = aprep;
1088 * shishi_ap_rep_der:
1089 * @ap: structure that holds information about AP exchange
1090 * @out: output array with newly allocated DER encoding of AP-REP.
1091 * @outlen: length of output array with DER encoding of AP-REP.
1093 * Build AP-REP using shishi_ap_rep_build() and DER encode it. @out
1094 * is allocated by this function, and it is the responsibility of
1095 * caller to deallocate it.
1097 * Return value: Returns SHISHI_OK iff successful.
1100 shishi_ap_rep_der (Shishi_ap * ap, char **out, size_t * outlen)
1102 int rc;
1104 rc = shishi_ap_rep_build (ap);
1105 if (rc != SHISHI_OK)
1106 return rc;
1108 rc = shishi_asn1_to_der (ap->handle, ap->aprep, out, outlen);
1109 if (rc != SHISHI_OK)
1110 return rc;
1112 return SHISHI_OK;
1116 * shishi_ap_rep_der_set:
1117 * @ap: structure that holds information about AP exchange
1118 * @der: input array with DER encoded AP-REP.
1119 * @derlen: length of input array with DER encoded AP-REP.
1121 * DER decode AP-REP and set it AP exchange. If decoding fails, the
1122 * AP-REP in the AP exchange remains.
1124 * Return value: Returns SHISHI_OK.
1127 shishi_ap_rep_der_set (Shishi_ap * ap, char *der, size_t derlen)
1129 Shishi_asn1 aprep;
1131 aprep = shishi_der2asn1_aprep (ap->handle, der, derlen);
1133 if (!aprep)
1134 return SHISHI_ASN1_ERROR;
1136 ap->aprep = aprep;
1138 return SHISHI_OK;
1142 * shishi_ap_rep_build:
1143 * @ap: structure that holds information about AP exchange
1145 * Checksum data in authenticator and add ticket and authenticator to
1146 * AP-REP.
1148 * Return value: Returns SHISHI_OK iff successful.
1151 shishi_ap_rep_build (Shishi_ap * ap)
1153 Shishi_asn1 aprep;
1154 int rc;
1156 if (VERBOSE (ap->handle))
1157 printf ("Building AP-REP...\n");
1159 aprep = shishi_aprep (ap->handle);
1160 rc = shishi_aprep_enc_part_make (ap->handle, aprep, ap->encapreppart,
1161 ap->authenticator,
1162 shishi_tkt_encticketpart (ap->tkt));
1163 if (rc != SHISHI_OK)
1165 shishi_error_printf (ap->handle, "Error creating AP-REP: %s\n",
1166 shishi_strerror (rc));
1167 return rc;
1170 if (VERBOSEASN1 (ap->handle))
1171 shishi_aprep_print (ap->handle, stdout, aprep);
1173 shishi_ap_rep_set (ap, aprep);
1175 return SHISHI_OK;
1179 * shishi_ap_rep_asn1:
1180 * @ap: structure that holds information about AP exchange
1181 * @aprep: output AP-REP variable.
1183 * Build AP-REP using shishi_ap_rep_build() and return it.
1185 * Return value: Returns SHISHI_OK iff successful.
1188 shishi_ap_rep_asn1 (Shishi_ap * ap, Shishi_asn1 * aprep)
1190 int rc;
1192 rc = shishi_ap_rep_build (ap);
1193 if (rc != SHISHI_OK)
1194 return rc;
1196 *aprep = ap->aprep;
1198 return SHISHI_OK;
1202 * shishi_ap_rep_verify:
1203 * @ap: structure that holds information about AP exchange
1205 * Verify AP-REP compared to Authenticator.
1207 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1208 * error.
1211 shishi_ap_rep_verify (Shishi_ap * ap)
1213 int res;
1215 if (VERBOSE (ap->handle))
1216 printf ("Decrypting AP-REP...\n");
1218 if (VERBOSEASN1 (ap->handle))
1219 shishi_aprep_print (ap->handle, stdout, ap->aprep);
1221 res = shishi_aprep_decrypt (ap->handle, ap->aprep,
1222 shishi_tkt_key (ap->tkt),
1223 SHISHI_KEYUSAGE_ENCAPREPPART,
1224 &ap->encapreppart);
1225 if (res != SHISHI_OK)
1226 return res;
1228 if (VERBOSEASN1 (ap->handle))
1229 shishi_encapreppart_print (ap->handle, stdout, ap->encapreppart);
1231 res = shishi_aprep_verify (ap->handle, ap->authenticator, ap->encapreppart);
1232 if (res != SHISHI_OK)
1233 return res;
1235 if (VERBOSE (ap->handle))
1236 printf ("Verified AP-REP successfully...\n");
1238 return SHISHI_OK;
1242 * shishi_ap_rep_verify_der:
1243 * @ap: structure that holds information about AP exchange
1244 * @der: input array with DER encoded AP-REP.
1245 * @derlen: length of input array with DER encoded AP-REP.
1247 * DER decode AP-REP and set it in AP exchange using
1248 * shishi_ap_rep_der_set() and verify it using shishi_ap_rep_verify().
1250 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1251 * error.
1254 shishi_ap_rep_verify_der (Shishi_ap * ap, char *der, size_t derlen)
1256 int res;
1258 res = shishi_ap_rep_der_set (ap, der, derlen);
1259 if (res != SHISHI_OK)
1260 return res;
1262 res = shishi_ap_rep_verify (ap);
1263 if (res != SHISHI_OK)
1264 return res;
1266 return SHISHI_OK;
1270 * shishi_ap_rep_verify_asn1:
1271 * @ap: structure that holds information about AP exchange
1272 * @aprep: input AP-REP.
1274 * Set the AP-REP in the AP exchange using shishi_ap_rep_set() and
1275 * verify it using shishi_ap_rep_verify().
1277 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1278 * error.
1281 shishi_ap_rep_verify_asn1 (Shishi_ap * ap, Shishi_asn1 aprep)
1283 int res;
1285 shishi_ap_rep_set (ap, aprep);
1287 res = shishi_ap_rep_verify (ap);
1288 if (res != SHISHI_OK)
1289 return res;
1291 return SHISHI_OK;
1295 * shishi_ap_encapreppart:
1296 * @ap: structure that holds information about AP exchange
1298 * Get ASN.1 EncAPRepPart structure from AP exchange.
1300 * Return value: Returns the EncAPREPPart from the AP exchange, or
1301 * NULL if not yet set or an error occured.
1303 Shishi_asn1
1304 shishi_ap_encapreppart (Shishi_ap * ap)
1306 return ap->encapreppart;
1310 * shishi_ap_encapreppart_set:
1311 * @ap: structure that holds information about AP exchange
1312 * @encapreppart: EncAPRepPart to store in AP.
1314 * Set the EncAPRepPart in the AP exchange.
1316 void
1317 shishi_ap_encapreppart_set (Shishi_ap * ap, Shishi_asn1 encapreppart)
1319 if (ap->encapreppart)
1320 shishi_asn1_done (ap->handle, ap->encapreppart);
1321 ap->encapreppart = encapreppart;
1324 #define APOPTION_RESERVED "reserved"
1325 #define APOPTION_USE_SESSION_KEY "use-session-key"
1326 #define APOPTION_MUTUAL_REQUIRED "mutual-required"
1327 #define APOPTION_UNKNOWN "unknown"
1330 * shishi_ap_option2string:
1331 * @option: enumerated AP-Option type, see Shishi_apoptions.
1333 * Convert AP-Option type to AP-Option name string. Note that @option
1334 * must be just one of the AP-Option types, it cannot be an binary
1335 * ORed indicating several AP-Options.
1337 * Return value: Returns static string with name of AP-Option that
1338 * must not be deallocated, or "unknown" if AP-Option was not understood.
1340 const char *
1341 shishi_ap_option2string (Shishi_apoptions option)
1343 const char *str;
1345 switch (option)
1347 case SHISHI_APOPTIONS_RESERVED:
1348 str = APOPTION_RESERVED;
1349 break;
1351 case SHISHI_APOPTIONS_USE_SESSION_KEY:
1352 str = APOPTION_USE_SESSION_KEY;
1353 break;
1355 case SHISHI_APOPTIONS_MUTUAL_REQUIRED:
1356 str = APOPTION_MUTUAL_REQUIRED;
1357 break;
1359 default:
1360 str = APOPTION_UNKNOWN;
1361 break;
1364 return str;
1368 * shishi_ap_string2option:
1369 * @str: zero terminated character array with name of AP-Option,
1370 * e.g. "use-session-key".
1372 * Convert AP-Option name to AP-Option type.
1374 * Return value: Returns enumerated type member corresponding to AP-Option,
1375 * or 0 if string was not understood.
1377 Shishi_apoptions
1378 shishi_ap_string2option (const char *str)
1380 int option;
1382 if (strcasecmp (str, APOPTION_RESERVED) == 0)
1383 option = SHISHI_APOPTIONS_RESERVED;
1384 else if (strcasecmp (str, APOPTION_USE_SESSION_KEY) == 0)
1385 option = SHISHI_APOPTIONS_USE_SESSION_KEY;
1386 else if (strcasecmp (str, APOPTION_MUTUAL_REQUIRED) == 0)
1387 option = SHISHI_APOPTIONS_MUTUAL_REQUIRED;
1388 else
1389 option = strtol (str, (char **) NULL, 0);
1391 return option;