Use GPL instead of LGPL.
[shishi.git] / lib / ap.c
blobf8d0bc848937868c91cfc55be5ecc2886d623a27
1 /* ap.c AP functions
2 * Copyright (C) 2002 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
22 #include "internal.h"
24 struct Shishi_ap
26 Shishi *handle;
27 Shishi_ticket *ticket;
28 ASN1_TYPE authenticator;
29 ASN1_TYPE apreq;
30 ASN1_TYPE aprep;
31 ASN1_TYPE encapreppart;
32 int authenticatorcksumkeyusage;
33 int authenticatorkeyusage;
34 char *authenticatorcksumdata;
35 int authenticatorcksumdatalen;
38 /**
39 * shishi_ap:
40 * @handle: shishi handle as allocated by shishi_init().
41 * @ap: pointer to new structure that holds information about AP exchange
43 * Create a new AP exchange.
45 * Return value: Returns SHISHI_OK iff successful.
46 **/
47 int
48 shishi_ap (Shishi * handle, Shishi_ap ** ap)
50 Shishi_ap *lap;
52 *ap = malloc (sizeof (**ap));
53 if (*ap == NULL)
54 return SHISHI_MALLOC_ERROR;
55 lap = *ap;
56 memset(lap, 0, sizeof(*lap));
58 lap->handle = handle;
59 lap->authenticatorcksumkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR_CKSUM;
60 lap->authenticatorkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR;
62 lap->authenticator = shishi_authenticator (handle);
63 if (lap->authenticator == NULL)
65 shishi_error_printf (handle, "Could not create Authenticator: %s\n",
66 shishi_strerror_details (handle));
67 return SHISHI_ASN1_ERROR;
70 lap->apreq = shishi_apreq (handle);
71 if (lap->apreq == NULL)
73 shishi_error_printf (handle, "Could not create AP-REQ: %s\n",
74 shishi_strerror_details (handle));
75 return SHISHI_ASN1_ERROR;
78 lap->aprep = shishi_aprep (handle);
79 if (lap->aprep == NULL)
81 shishi_error_printf (handle, "Could not create AP-REP: %s\n",
82 shishi_strerror_details (handle));
83 return SHISHI_ASN1_ERROR;
86 lap->encapreppart = shishi_encapreppart (handle);
87 if (lap->encapreppart == NULL)
89 shishi_error_printf (handle, "Could not create EncAPRepPart: %s\n",
90 shishi_strerror_details (handle));
91 return SHISHI_ASN1_ERROR;
94 return SHISHI_OK;
97 /**
98 * shishi_ap_tktoptions:
99 * @handle: shishi handle as allocated by shishi_init().
100 * @ap: pointer to new structure that holds information about AP exchange
101 * @ticket: ticket to set in newly created AP.
102 * @options: AP-REQ options to set in newly created AP.
104 * Create a new AP exchange, and set the ticket (see
105 * shishi_ap_ticket_set()) and set the AP-REQ apoptions (see
106 * shishi_apreq_options_set()).
108 * Return value: Returns SHISHI_OK iff successful.
111 shishi_ap_tktoptions (Shishi * handle,
112 Shishi_ap ** ap,
113 Shishi_ticket *ticket,
114 int options)
116 int rc;
118 rc = shishi_ap(handle, ap);
119 if (rc != SHISHI_OK)
120 return rc;
122 shishi_ap_ticket_set (*ap, ticket);
124 rc = shishi_apreq_options_set (handle, shishi_ap_req(*ap), options);
125 if (rc != SHISHI_OK)
127 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
128 return rc;
131 return SHISHI_OK;
135 * shishi_ap_tktoptionsdata:
136 * @handle: shishi handle as allocated by shishi_init().
137 * @ap: pointer to new structure that holds information about AP exchange
138 * @ticket: ticket to set in newly created AP.
139 * @options: AP-REQ options to set in newly created AP.
140 * @data: input array with data to checksum in Authenticator.
141 * @len: length of input array with data to checksum in Authenticator.
143 * Create a new AP exchange, and set the ticket (see
144 * shishi_ap_ticket_set()) and set the AP-REQ apoptions (see
145 * shishi_apreq_options_set()) and set the Authenticator checksum
146 * data.
148 * Return value: Returns SHISHI_OK iff successful.
151 shishi_ap_tktoptionsdata (Shishi * handle,
152 Shishi_ap ** ap,
153 Shishi_ticket *ticket,
154 int options,
155 char *data,
156 int len)
158 int rc;
160 rc = shishi_ap(handle, ap);
161 if (rc != SHISHI_OK)
162 return rc;
164 shishi_ap_ticket_set (*ap, ticket);
166 rc = shishi_apreq_options_set (handle, shishi_ap_req(*ap), options);
167 if (rc != SHISHI_OK)
169 printf ("Could not set AP-Options: %s", shishi_strerror (rc));
170 return rc;
173 shishi_ap_authenticator_cksumdata_set (*ap, data, len);
175 return SHISHI_OK;
179 * shishi_ap_tktoptionsasn1:
180 * @handle: shishi handle as allocated by shishi_init().
181 * @ap: pointer to new structure that holds information about AP exchange
182 * @ticket: ticket to set in newly created AP.
183 * @options: AP-REQ options to set in newly created AP.
184 * @node: input ASN.1 structure to store as authenticator checksum data.
186 * DER decode ASN.1 structure and allocate new AP exchange and set
187 * ticket, options and authenticator checksum data using
188 * shishi_ap_tktoptionsdata().
190 * Return value: Returns SHISHI_OK iff successful.
193 shishi_ap_tktoptionsasn1usage (Shishi * handle,
194 Shishi_ap ** ap,
195 Shishi_ticket *ticket,
196 int options,
197 ASN1_TYPE node,
198 char *field,
199 int authenticatorcksumkeyusage,
200 int authenticatorkeyusage)
202 char *buf;
203 int buflen;
204 int res;
206 buf = malloc(BUFSIZ);
207 buflen = BUFSIZ;
209 res = _shishi_a2d_field (handle, node, field, buf, &buflen);
210 if (res != SHISHI_OK)
211 return res;
213 /* XXX what is this? */
214 memmove (buf, buf + 2, buflen - 2);
215 buflen -= 2;
217 res = shishi_ap_tktoptionsdata(handle, ap, ticket, options, buf, buflen);
218 if (res != SHISHI_OK)
219 return res;
221 (*ap)->authenticatorcksumkeyusage = authenticatorcksumkeyusage;
222 (*ap)->authenticatorkeyusage = authenticatorkeyusage;
224 return SHISHI_OK;
228 * shishi_ap_ticket:
229 * @ap: structure that holds information about AP exchange
231 * Return value: Returns the ticket from the AP exchange, or NULL if
232 * not yet set or an error occured.
234 Shishi_ticket *
235 shishi_ap_ticket (Shishi_ap * ap)
237 return ap->ticket;
241 * shishi_ap_ticket_set:
242 * @ap: structure that holds information about AP exchange
243 * @ticket: ticket to store in AP.
245 * Set the Ticket in the AP exchange.
247 void
248 shishi_ap_ticket_set (Shishi_ap * ap, Shishi_ticket * ticket)
250 ap->ticket = ticket;
254 * shishi_ap_authenticatorcksumdata:
255 * @ap: structure that holds information about AP exchange
256 * @out: output array that holds authenticator checksum data.
257 * @len: on input, maximum length of output array that holds
258 * authenticator checksum data, on output actual length of
259 * output array that holds authenticator checksum data.
261 * Return value: Returns SHISHI_OK if successful, or
262 * SHISHI_TOO_SMALL_BUFFER if buffer provided was too small.
265 shishi_ap_authenticator_cksumdata (Shishi_ap * ap, char *out, int *len)
267 if (*len < ap->authenticatorcksumdatalen)
268 return SHISHI_TOO_SMALL_BUFFER;
269 if(ap->authenticatorcksumdata)
270 memcpy(out, ap->authenticatorcksumdata, ap->authenticatorcksumdatalen);
271 *len = ap->authenticatorcksumdatalen;
272 return SHISHI_OK;
276 * shishi_ap_authenticator_cksumdata_set:
277 * @ap: structure that holds information about AP exchange
278 * @authenticatorcksumdata: input array with authenticator checksum
279 * data to use in AP.
280 * @authenticatorcksumdata: length of input array with authenticator
281 * checksum data to use in AP.
283 * Set the Authenticator Checksum Data in the AP exchange.
285 void
286 shishi_ap_authenticator_cksumdata_set (Shishi_ap * ap,
287 char *authenticatorcksumdata,
288 int authenticatorcksumdatalen)
290 ap->authenticatorcksumdata = authenticatorcksumdata;
291 ap->authenticatorcksumdatalen = authenticatorcksumdatalen;
295 * shishi_ap_authenticator:
296 * @ap: structure that holds information about AP exchange
298 * Return value: Returns the Authenticator from the AP exchange, or
299 * NULL if not yet set or an error occured.
301 ASN1_TYPE
302 shishi_ap_authenticator (Shishi_ap * ap)
304 return ap->authenticator;
308 * shishi_ap_authenticator_set:
309 * @ap: structure that holds information about AP exchange
310 * @authenticator: authenticator to store in AP.
312 * Set the Authenticator in the AP exchange.
314 void
315 shishi_ap_authenticator_set (Shishi_ap * ap, ASN1_TYPE authenticator)
317 if (ap->authenticator)
318 _shishi_asn1_done(ap->handle, ap->authenticator);
319 ap->authenticator = authenticator;
323 * shishi_ap_req:
324 * @ap: structure that holds information about AP exchange
326 * Return value: Returns the AP-REQ from the AP exchange, or NULL if
327 * not yet set or an error occured.
329 ASN1_TYPE
330 shishi_ap_req (Shishi_ap * ap)
332 return ap->apreq;
336 * shishi_ap_req_build:
337 * @ap: structure that holds information about AP exchange
339 * Checksum data in authenticator and add ticket and authenticator to
340 * AP-REQ.
342 * Return value: Returns SHISHI_OK iff successful.
345 shishi_ap_req_build (Shishi_ap * ap)
347 int res;
349 res = shishi_apreq_set_ticket (ap->handle, ap->apreq,
350 shishi_ticket_ticket(ap->ticket));
351 if (res != SHISHI_OK)
353 shishi_error_printf (ap->handle, "Could not set ticket in AP-REQ: %s\n",
354 shishi_strerror_details (ap->handle));
355 return res;
358 res = shishi_authenticator_add_cksum (ap->handle, ap->authenticator,
359 shishi_ticket_key(ap->ticket),
360 ap->authenticatorcksumkeyusage,
361 ap->authenticatorcksumdata,
362 ap->authenticatorcksumdatalen);
363 if (res != SHISHI_OK)
365 shishi_error_printf (ap->handle,
366 "Could not add checksum to authenticator: %s\n",
367 shishi_strerror_details (ap->handle));
368 return res;
371 res = shishi_apreq_add_authenticator (ap->handle, ap->apreq,
372 shishi_ticket_key(ap->ticket),
373 ap->authenticatorkeyusage,
374 ap->authenticator);
375 if (res != SHISHI_OK)
377 shishi_error_printf (ap->handle, "Could not set authenticator: %s\n",
378 shishi_strerror_details (ap->handle));
379 return res;
382 return SHISHI_OK;
386 * shishi_ap_req_der:
387 * @ap: structure that holds information about AP exchange
388 * @out: output array with der encoding of AP-REQ.
389 * @outlen: length of output array with der encoding of AP-REQ.
391 * Build AP-REQ using shishi_ap_req_buidl() and DER encode it.
393 * Return value: Returns SHISHI_OK iff successful.
396 shishi_ap_req_der (Shishi_ap * ap, char *out, int *outlen)
398 int rc;
400 rc = shishi_ap_req_build(ap);
401 if (rc != SHISHI_OK)
402 return rc;
404 rc = _shishi_a2d (ap->handle, ap->apreq, out, outlen);
405 if (rc != SHISHI_OK)
406 return rc;
408 return SHISHI_OK;
412 * shishi_ap_req_asn1:
413 * @ap: structure that holds information about AP exchange
414 * @apreq: output AP-REQ variable.
416 * Build AP-REQ using shishi_ap_req_build() and return it.
418 * Return value: Returns SHISHI_OK iff successful.
421 shishi_ap_req_asn1 (Shishi_ap * ap, ASN1_TYPE * apreq)
423 int rc;
425 rc = shishi_ap_req_build(ap);
426 if (rc != SHISHI_OK)
427 return rc;
429 *apreq = ap->apreq;
431 return SHISHI_OK;
435 * shishi_ap_req_set:
436 * @ap: structure that holds information about AP exchange
437 * @apreq: apreq to store in AP.
439 * Set the AP-REQ in the AP exchange.
441 void
442 shishi_ap_req_set (Shishi_ap * ap, ASN1_TYPE apreq)
444 if (ap->apreq)
445 _shishi_asn1_done(ap->handle, ap->apreq);
446 ap->apreq = apreq;
450 * shishi_ap_rep:
451 * @ap: structure that holds information about AP exchange
453 * Return value: Returns the AP-REP from the AP exchange, or NULL if
454 * not yet set or an error occured.
456 ASN1_TYPE
457 shishi_ap_rep (Shishi_ap * ap)
459 return ap->aprep;
463 * shishi_ap_rep_der_set:
464 * @ap: structure that holds information about AP exchange
465 * @der: input array with DER encoded AP-REP.
466 * @derlen: length of input array with DER encoded AP-REP.
468 * DER decode AP-REP and set it AP exchange. If decoding fails, the
469 * AP-REP in the AP exchange is reset.
471 * Return value: Returns SHISHI_OK.
474 shishi_ap_rep_der_set (Shishi_ap * ap, char *der, int derlen)
476 ap->aprep = shishi_d2a_aprep (ap->handle, der, derlen);
478 return SHISHI_OK;
482 * shishi_ap_rep_verify:
483 * @ap: structure that holds information about AP exchange
485 * Verify AP-REP compared to Authenticator.
487 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
488 * error.
491 shishi_ap_rep_verify (Shishi_ap * ap)
493 int etype;
494 int res;
496 res = shishi_aprep_decrypt (ap->handle, ap->aprep,
497 shishi_ticket_key(ap->ticket),
498 SHISHI_KEYUSAGE_ENCAPREPPART, &ap->encapreppart);
499 if (res != SHISHI_OK)
500 return res;
502 res = shishi_aprep_verify (ap->handle, ap->authenticator, ap->encapreppart);
503 if (res != SHISHI_OK)
504 return res;
506 return SHISHI_OK;
510 * shishi_ap_rep_verify_der:
511 * @ap: structure that holds information about AP exchange
512 * @der: input array with DER encoded AP-REP.
513 * @derlen: length of input array with DER encoded AP-REP.
515 * DER decode AP-REP and set it in AP exchange using
516 * shishi_ap_rep_der_set() and verify it using shishi_ap_rep_verify().
518 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
519 * error.
522 shishi_ap_rep_verify_der (Shishi_ap * ap, char *der, int derlen)
524 int res;
526 res = shishi_ap_rep_der_set (ap, der, derlen);
527 if (res != SHISHI_OK)
528 return res;
530 res = shishi_ap_rep_verify (ap);
531 if (res != SHISHI_OK)
532 return res;
534 return SHISHI_OK;
538 * shishi_ap_rep_verify_asn1:
539 * @ap: structure that holds information about AP exchange
540 * @aprep: input AP-REP.
542 * Set the AP-REP in the AP exchange using shishi_ap_rep_set() and
543 * verify it using shishi_ap_rep_verify().
545 * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
546 * error.
549 shishi_ap_rep_verify_asn1 (Shishi_ap * ap, ASN1_TYPE aprep)
551 int res;
553 shishi_ap_rep_set (ap, aprep);
555 res = shishi_ap_rep_verify (ap);
556 if (res != SHISHI_OK)
557 return res;
559 return SHISHI_OK;
563 * shishi_ap_rep_set:
564 * @ap: structure that holds information about AP exchange
565 * @aprep: aprep to store in AP.
567 * Set the AP-REP in the AP exchange.
569 void
570 shishi_ap_rep_set (Shishi_ap * ap, ASN1_TYPE aprep)
572 if (ap->aprep)
573 _shishi_asn1_done(ap->handle, ap->aprep);
574 ap->aprep = aprep;
578 * shishi_ap_rep:
579 * @ap: structure that holds information about AP exchange
581 * Return value: Returns the EncAPREPPart from the AP exchange, or
582 * NULL if not yet set or an error occured.
584 ASN1_TYPE
585 shishi_ap_encapreppart (Shishi_ap * ap)
587 return ap->encapreppart;
591 * shishi_ap_encapreppart_set:
592 * @ap: structure that holds information about AP exchange
593 * @encapreppart: EncAPRepPart to store in AP.
595 * Set the EncAPRepPart in the AP exchange.
597 void
598 shishi_ap_encapreppart_set (Shishi_ap * ap, ASN1_TYPE encapreppart)
600 if (ap->encapreppart)
601 _shishi_asn1_done(ap->handle, ap->encapreppart);
602 ap->encapreppart = encapreppart;
605 #define APOPTION_RESERVED "reserved"
606 #define APOPTION_USE_SESSION_KEY "use-session-key"
607 #define APOPTION_MUTUAL_REQUIRED "mutual-required"
608 #define APOPTION_UNKNOWN "unknown"
610 const char *
611 shishi_ap_option2string (int option)
613 char *str;
615 switch (option)
617 case SHISHI_APOPTIONS_RESERVED:
618 str = APOPTION_RESERVED;
619 break;
621 case SHISHI_APOPTIONS_USE_SESSION_KEY:
622 str = APOPTION_USE_SESSION_KEY;
623 break;
625 case SHISHI_APOPTIONS_MUTUAL_REQUIRED:
626 str = APOPTION_MUTUAL_REQUIRED;
627 break;
629 default:
630 str = APOPTION_UNKNOWN;
631 break;
634 return str;
638 shishi_ap_string2option (const char *str)
640 int option;
642 if (strcasecmp (str, APOPTION_RESERVED) == 0)
643 option = SHISHI_APOPTIONS_RESERVED;
644 else if (strcasecmp (str, APOPTION_USE_SESSION_KEY) == 0)
645 option = SHISHI_APOPTIONS_USE_SESSION_KEY;
646 else if (strcasecmp (str, APOPTION_MUTUAL_REQUIRED) == 0)
647 option = SHISHI_APOPTIONS_MUTUAL_REQUIRED;
648 else
649 option = strtol (str, (char **) NULL, 0);
651 return option;