Bump versions.
[shishi.git] / lib / as.c
bloba7e25a48d9a33e91c1bb998c5637d3f73d632cb4
1 /* as.c --- High level client AS 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_as
26 Shishi *handle;
27 Shishi_asn1 asreq;
28 Shishi_asn1 asrep;
29 Shishi_asn1 krberror;
30 Shishi_tkt *tkt;
33 /**
34 * shishi_as:
35 * @handle: shishi handle as allocated by shishi_init().
36 * @as: holds pointer to newly allocate Shishi_as structure.
38 * Allocate a new AS exchange variable.
40 * Return value: Returns SHISHI_OK iff successful.
41 **/
42 int
43 shishi_as (Shishi * handle, Shishi_as ** as)
45 Shishi_as *las;
46 int res;
48 *as = xmalloc (sizeof (**as));
49 las = *as;
50 memset (las, 0, sizeof (*las));
52 las->handle = handle;
54 las->asreq = shishi_asreq (handle);
55 if (las->asreq == NULL)
57 shishi_error_printf (handle, "Could not create AS-REQ: %s\n",
58 shishi_error (handle));
59 return SHISHI_ASN1_ERROR;
62 las->asrep = shishi_asrep (handle);
63 if (las->asrep == NULL)
65 shishi_error_printf (handle, "Could not create AS-REP: %s\n",
66 shishi_error (handle));
67 return SHISHI_ASN1_ERROR;
70 las->krberror = shishi_krberror (handle);
71 if (las->krberror == NULL)
73 shishi_error_printf (handle, "Could not create KRB-ERROR: %s\n",
74 shishi_error (handle));
75 return SHISHI_ASN1_ERROR;
78 res = shishi_tkt (handle, &las->tkt);
79 if (res != SHISHI_OK)
80 return res;
82 res = shishi_tkt_flags_set (las->tkt, SHISHI_TICKETFLAGS_INITIAL);
83 if (res != SHISHI_OK)
84 return res;
86 return SHISHI_OK;
89 /**
90 * shishi_as_done:
91 * @as: structure that holds information about AS exchange
93 * Deallocate resources associated with AS exchange. This should be
94 * called by the application when it no longer need to utilize the AS
95 * exchange handle.
96 **/
97 void
98 shishi_as_done (Shishi_as * as)
100 shishi_asn1_done (as->handle, as->asreq);
101 shishi_asn1_done (as->handle, as->asrep);
102 shishi_asn1_done (as->handle, as->krberror);
103 shishi_tkt_done (as->tkt);
104 free (as);
107 /* TODO: add shishi_as_clientserver(h,p,a,client,server) and make the
108 shishi_as_cnamerealmsname function take real cname/sname pointer
109 arrays. */
112 * shishi_as_req:
113 * @as: structure that holds information about AS exchange
115 * Get ASN.1 AS-REQ structure from AS exchange.
117 * Return value: Returns the generated AS-REQ packet from the AS
118 * exchange, or NULL if not yet set or an error occured.
120 Shishi_asn1
121 shishi_as_req (Shishi_as * as)
123 return as->asreq;
127 * shishi_as_req_build:
128 * @as: structure that holds information about AS exchange
130 * Possibly remove unset fields (e.g., rtime).
132 * Return value: Returns SHISHI_OK iff successful.
135 shishi_as_req_build (Shishi_as * as)
137 int res;
139 res = shishi_kdcreq_build (as->handle, as->asreq);
140 if (res != SHISHI_OK)
141 return res;
143 return SHISHI_OK;
147 * shishi_as_req_set:
148 * @as: structure that holds information about AS exchange
149 * @asreq: asreq to store in AS.
151 * Set the AS-REQ in the AS exchange.
153 void
154 shishi_as_req_set (Shishi_as * as, Shishi_asn1 asreq)
156 if (as->asreq)
157 shishi_asn1_done (as->handle, as->asreq);
158 as->asreq = asreq;
162 * shishi_as_req_der:
163 * @as: structure that holds information about AS exchange
164 * @out: output array with newly allocated DER encoding of AS-REQ.
165 * @outlen: length of output array with DER encoding of AS-REQ.
167 * DER encode AS-REQ. @out is allocated by this function, and it is
168 * the responsibility of caller to deallocate it.
170 * Return value: Returns SHISHI_OK iff successful.
173 shishi_as_req_der (Shishi_as * as, char **out, size_t * outlen)
175 int rc;
177 rc = shishi_asn1_to_der (as->handle, as->asreq, out, outlen);
178 if (rc != SHISHI_OK)
179 return rc;
181 return SHISHI_OK;
185 * shishi_as_req_der_set:
186 * @as: structure that holds information about AS exchange
187 * @der: input array with DER encoded AP-REQ.
188 * @derlen: length of input array with DER encoded AP-REQ.
190 * DER decode AS-REQ and set it AS exchange. If decoding fails, the
191 * AS-REQ in the AS exchange remains.
193 * Return value: Returns SHISHI_OK.
196 shishi_as_req_der_set (Shishi_as * as, char *der, size_t derlen)
198 Shishi_asn1 asreq;
200 asreq = shishi_der2asn1_asreq (as->handle, der, derlen);
202 if (asreq == NULL)
203 return SHISHI_ASN1_ERROR;
205 as->asreq = asreq;
207 return SHISHI_OK;
211 * shishi_as_rep:
212 * @as: structure that holds information about AS exchange
214 * Get ASN.1 AS-REP structure from AS exchange.
216 * Return value: Returns the received AS-REP packet from the AS
217 * exchange, or NULL if not yet set or an error occured.
219 Shishi_asn1
220 shishi_as_rep (Shishi_as * as)
222 return as->asrep;
226 * shishi_as_rep_process:
227 * @as: structure that holds information about AS exchange
228 * @key: user's key, used to encrypt the encrypted part of the AS-REP.
229 * @password: user's password, used if key is NULL.
231 * Process new AS-REP and set ticket. The key is used to decrypt the
232 * AP-REP. If both key and password is NULL, the user is queried for
233 * it.
235 * Return value: Returns SHISHI_OK iff successful.
238 shishi_as_rep_process (Shishi_as * as, Shishi_key * key, const char *password)
240 Shishi_asn1 ticket, kdcreppart;
241 int res;
243 if (VERBOSE (as->handle))
244 printf ("Processing AS-REQ and AS-REP...\n");
246 if (VERBOSEASN1 (as->handle))
247 shishi_kdcreq_print (as->handle, stdout, as->asreq);
249 if (VERBOSEASN1 (as->handle))
250 shishi_kdcrep_print (as->handle, stdout, as->asrep);
252 if (key == NULL && password == NULL)
254 char *passwd;
255 char *user;
256 size_t userlen;
258 res = shishi_asreq_clientrealm (as->handle, as->asreq, &user, &userlen);
259 if (res != SHISHI_OK)
261 shishi_error_printf (as->handle, "Could not extract cname and "
262 "realm from AS-REQ: %s\n",
263 shishi_strerror (res),
264 shishi_error (as->handle));
265 return res;
268 res = shishi_prompt_password (as->handle, &passwd,
269 "Enter password for `%s': ", user);
270 free (user);
271 if (res != SHISHI_OK)
273 shishi_error_printf (as->handle, "Reading password failed: %s\n",
274 shishi_strerror (res));
275 return res;
278 res = shishi_as_process (as->handle, as->asreq, as->asrep,
279 passwd, &kdcreppart);
280 free (passwd);
282 else if (key == NULL)
283 res = shishi_as_process (as->handle, as->asreq, as->asrep,
284 password, &kdcreppart);
285 else
286 res = shishi_kdc_process (as->handle, as->asreq, as->asrep, key,
287 SHISHI_KEYUSAGE_ENCASREPPART, &kdcreppart);
288 if (res != SHISHI_OK)
289 return res;
291 if (VERBOSE (as->handle))
292 printf ("Got EncKDCRepPart...\n");
294 if (VERBOSEASN1 (as->handle))
295 shishi_enckdcreppart_print (as->handle, stdout, kdcreppart);
297 res = shishi_kdcrep_get_ticket (as->handle, as->asrep, &ticket);
298 if (res != SHISHI_OK)
300 shishi_error_printf (as->handle,
301 "Could not extract ticket from AS-REP: %s",
302 shishi_error (as->handle));
303 return res;
306 if (VERBOSE (as->handle))
307 printf ("Got Ticket...\n");
309 if (VERBOSEASN1 (as->handle))
310 shishi_ticket_print (as->handle, stdout, ticket);
312 /* XXX */
313 as->tkt = shishi_tkt2 (as->handle, ticket, kdcreppart, as->asrep);
315 return SHISHI_OK;
319 * shishi_as_rep_build:
320 * @as: structure that holds information about AS exchange
321 * @key: user's key, used to encrypt the encrypted part of the AS-REP.
323 * Build AS-REP.
325 * Return value: Returns SHISHI_OK iff successful.
328 shishi_as_rep_build (Shishi_as * as, Shishi_key * key)
330 int rc;
332 /* XXX there are reasons for having padata in AS-REP */
333 rc = shishi_kdcrep_clear_padata (as->handle, as->asrep);
334 if (rc != SHISHI_OK)
335 return rc;
337 rc = shishi_enckdcreppart_populate_encticketpart
338 (as->handle, shishi_tkt_enckdcreppart (as->tkt),
339 shishi_tkt_encticketpart (as->tkt));
340 if (rc != SHISHI_OK)
341 return rc;
343 rc = shishi_kdc_copy_nonce (as->handle, as->asreq,
344 shishi_tkt_enckdcreppart (as->tkt));
345 if (rc != SHISHI_OK)
346 return rc;
348 rc = shishi_kdcrep_add_enc_part (as->handle,
349 as->asrep,
350 key,
351 SHISHI_KEYUSAGE_ENCASREPPART,
352 shishi_tkt_enckdcreppart (as->tkt));
353 if (rc != SHISHI_OK)
354 return rc;
356 rc = shishi_kdcrep_set_ticket (as->handle, as->asrep,
357 shishi_tkt_ticket (as->tkt));
358 if (rc != SHISHI_OK)
359 return rc;
361 rc = shishi_kdc_copy_crealm (as->handle, as->asrep,
362 shishi_tkt_encticketpart (as->tkt));
363 if (rc != SHISHI_OK)
364 return rc;
366 rc = shishi_kdc_copy_cname (as->handle, as->asrep,
367 shishi_tkt_encticketpart (as->tkt));
368 if (rc != SHISHI_OK)
369 return rc;
371 return SHISHI_OK;
375 * shishi_as_rep_der:
376 * @as: structure that holds information about AS exchange
377 * @out: output array with newly allocated DER encoding of AS-REP.
378 * @outlen: length of output array with DER encoding of AS-REP.
380 * DER encode AS-REP. @out is allocated by this function, and it is
381 * the responsibility of caller to deallocate it.
383 * Return value: Returns SHISHI_OK iff successful.
386 shishi_as_rep_der (Shishi_as * as, char **out, size_t * outlen)
388 int rc;
390 rc = shishi_asn1_to_der (as->handle, as->asrep, out, outlen);
391 if (rc != SHISHI_OK)
392 return rc;
394 return SHISHI_OK;
398 * shishi_as_rep_set:
399 * @as: structure that holds information about AS exchange
400 * @asrep: asrep to store in AS.
402 * Set the AS-REP in the AS exchange.
404 void
405 shishi_as_rep_set (Shishi_as * as, Shishi_asn1 asrep)
407 if (as->asrep)
408 shishi_asn1_done (as->handle, as->asrep);
409 as->asrep = asrep;
413 * shishi_as_rep_der_set:
414 * @as: structure that holds information about AS exchange
415 * @der: input array with DER encoded AP-REP.
416 * @derlen: length of input array with DER encoded AP-REP.
418 * DER decode AS-REP and set it AS exchange. If decoding fails, the
419 * AS-REP in the AS exchange remains.
421 * Return value: Returns SHISHI_OK.
424 shishi_as_rep_der_set (Shishi_as * as, char *der, size_t derlen)
426 Shishi_asn1 asrep;
428 asrep = shishi_der2asn1_asrep (as->handle, der, derlen);
430 if (asrep == NULL)
431 return SHISHI_ASN1_ERROR;
433 as->asrep = asrep;
435 return SHISHI_OK;
439 * shishi_as_krberror:
440 * @as: structure that holds information about AS exchange
442 * Get ASN.1 KRB-ERROR structure from AS exchange.
444 * Return value: Returns the received KRB-ERROR packet from the AS
445 * exchange, or NULL if not yet set or an error occured.
447 Shishi_asn1
448 shishi_as_krberror (Shishi_as * as)
450 return as->krberror;
454 * shishi_as_krberror_der:
455 * @as: structure that holds information about AS exchange
456 * @out: output array with newly allocated DER encoding of KRB-ERROR.
457 * @outlen: length of output array with DER encoding of KRB-ERROR.
459 * DER encode KRB-ERROR. @out is allocated by this function, and it is
460 * the responsibility of caller to deallocate it.
462 * Return value: Returns SHISHI_OK iff successful.
465 shishi_as_krberror_der (Shishi_as * as, char **out, size_t * outlen)
467 int rc;
469 rc = shishi_krberror_der (as->handle, as->krberror, out, outlen);
470 if (rc != SHISHI_OK)
471 return rc;
473 return SHISHI_OK;
477 * shishi_as_krberror_set:
478 * @as: structure that holds information about AS exchange
479 * @krberror: krberror to store in AS.
481 * Set the KRB-ERROR in the AS exchange.
483 void
484 shishi_as_krberror_set (Shishi_as * as, Shishi_asn1 krberror)
486 if (as->krberror)
487 shishi_asn1_done (as->handle, as->krberror);
488 as->krberror = krberror;
492 * shishi_as_tkt:
493 * @as: structure that holds information about AS exchange
495 * Get Ticket in AS exchange.
497 * Return value: Returns the newly aquired tkt from the AS
498 * exchange, or NULL if not yet set or an error occured.
500 Shishi_tkt *
501 shishi_as_tkt (Shishi_as * as)
503 return as->tkt;
507 * shishi_as_tkt_set:
508 * @as: structure that holds information about AS exchange
509 * @tkt: tkt to store in AS.
511 * Set the Tkt in the AS exchange.
513 void
514 shishi_as_tkt_set (Shishi_as * as, Shishi_tkt * tkt)
516 as->tkt = tkt;
520 * shishi_as_sendrecv_hint:
521 * @as: structure that holds information about AS exchange
522 * @hint: additional parameters that modify connection behaviour, or %NULL.
524 * Send AS-REQ and receive AS-REP or KRB-ERROR. This is the initial
525 * authentication, usually used to acquire a Ticket Granting Ticket.
526 * The @hint structure can be used to set, e.g., parameters for TLS
527 * authentication.
529 * Return value: Returns SHISHI_OK iff successful.
532 shishi_as_sendrecv_hint (Shishi_as * as, Shishi_tkts_hint * hint)
534 int res;
536 if (VERBOSE (as->handle))
537 printf ("Sending AS-REQ...\n");
539 if (VERBOSEASN1 (as->handle))
540 shishi_kdcreq_print (as->handle, stdout, as->asreq);
542 res = shishi_kdcreq_sendrecv_hint (as->handle, as->asreq, &as->asrep, hint);
543 if (res == SHISHI_GOT_KRBERROR)
545 as->krberror = as->asrep;
546 as->asrep = NULL;
548 if (VERBOSE (as->handle))
549 printf ("Received KRB-ERROR...\n");
550 if (VERBOSEASN1 (as->handle))
551 shishi_krberror_print (as->handle, stdout, as->krberror);
552 if (VERBOSEASN1(as->handle))
553 shishi_krberror_pretty_print (as->handle, stdout, as->krberror);
555 if (res != SHISHI_OK)
556 return res;
558 if (VERBOSE (as->handle))
559 printf ("Received AS-REP...\n");
561 if (VERBOSEASN1 (as->handle))
562 shishi_kdcrep_print (as->handle, stdout, as->asrep);
564 return SHISHI_OK;
568 * shishi_as_sendrecv:
569 * @as: structure that holds information about AS exchange
571 * Send AS-REQ and receive AS-REP or KRB-ERROR. This is the initial
572 * authentication, usually used to acquire a Ticket Granting Ticket.
574 * Return value: Returns SHISHI_OK iff successful.
577 shishi_as_sendrecv (Shishi_as * as)
579 return shishi_as_sendrecv_hint (as, NULL);