Update gnulib files.
[shishi.git] / lib / as.c
blobc2fb529a035d5efe7e6c0a0621510a7ed7beefe7
1 /* as.c --- High level client AS 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_as
27 Shishi *handle;
28 Shishi_asn1 asreq;
29 Shishi_asn1 asrep;
30 Shishi_asn1 krberror;
31 Shishi_tkt *tkt;
34 /**
35 * shishi_as:
36 * @handle: shishi handle as allocated by shishi_init().
37 * @as: holds pointer to newly allocate Shishi_as structure.
39 * Allocate a new AS exchange variable.
41 * Return value: Returns SHISHI_OK iff successful.
42 **/
43 int
44 shishi_as (Shishi * handle, Shishi_as ** as)
46 Shishi_as *las;
47 int res;
49 *as = xmalloc (sizeof (**as));
50 las = *as;
51 memset (las, 0, sizeof (*las));
53 las->handle = handle;
55 las->asreq = shishi_asreq (handle);
56 if (las->asreq == NULL)
58 shishi_error_printf (handle, "Could not create AS-REQ: %s\n",
59 shishi_error (handle));
60 return SHISHI_ASN1_ERROR;
63 las->asrep = shishi_asrep (handle);
64 if (las->asrep == NULL)
66 shishi_error_printf (handle, "Could not create AS-REP: %s\n",
67 shishi_error (handle));
68 return SHISHI_ASN1_ERROR;
71 las->krberror = shishi_krberror (handle);
72 if (las->krberror == NULL)
74 shishi_error_printf (handle, "Could not create KRB-ERROR: %s\n",
75 shishi_error (handle));
76 return SHISHI_ASN1_ERROR;
79 res = shishi_tkt (handle, &las->tkt);
80 if (res != SHISHI_OK)
81 return res;
83 res = shishi_tkt_flags_set (las->tkt, SHISHI_TICKETFLAGS_INITIAL);
84 if (res != SHISHI_OK)
85 return res;
87 return SHISHI_OK;
90 /**
91 * shishi_as_done:
92 * @as: structure that holds information about AS exchange
94 * Deallocate resources associated with AS exchange. This should be
95 * called by the application when it no longer need to utilize the AS
96 * exchange handle.
97 **/
98 void
99 shishi_as_done (Shishi_as * as)
101 shishi_asn1_done (as->handle, as->asreq);
102 shishi_asn1_done (as->handle, as->asrep);
103 shishi_asn1_done (as->handle, as->krberror);
104 shishi_tkt_done (as->tkt);
105 free (as);
108 /* TODO: add shishi_as_clientserver(h,p,a,client,server) and make the
109 shishi_as_cnamerealmsname function take real cname/sname pointer
110 arrays. */
113 * shishi_as_req:
114 * @as: structure that holds information about AS exchange
116 * Get ASN.1 AS-REQ structure from AS exchange.
118 * Return value: Returns the generated AS-REQ packet from the AS
119 * exchange, or NULL if not yet set or an error occured.
121 Shishi_asn1
122 shishi_as_req (Shishi_as * as)
124 return as->asreq;
128 * shishi_as_req_build:
129 * @as: structure that holds information about AS exchange
131 * Possibly remove unset fields (e.g., rtime).
133 * Return value: Returns SHISHI_OK iff successful.
136 shishi_as_req_build (Shishi_as * as)
138 int res;
140 res = shishi_kdcreq_build (as->handle, as->asreq);
141 if (res != SHISHI_OK)
142 return res;
144 return SHISHI_OK;
148 * shishi_as_req_set:
149 * @as: structure that holds information about AS exchange
150 * @asreq: asreq to store in AS.
152 * Set the AS-REQ in the AS exchange.
154 void
155 shishi_as_req_set (Shishi_as * as, Shishi_asn1 asreq)
157 if (as->asreq)
158 shishi_asn1_done (as->handle, as->asreq);
159 as->asreq = asreq;
163 * shishi_as_req_der:
164 * @as: structure that holds information about AS exchange
165 * @out: output array with newly allocated DER encoding of AS-REQ.
166 * @outlen: length of output array with DER encoding of AS-REQ.
168 * DER encode AS-REQ. @out is allocated by this function, and it is
169 * the responsibility of caller to deallocate it.
171 * Return value: Returns SHISHI_OK iff successful.
174 shishi_as_req_der (Shishi_as * as, char **out, size_t * outlen)
176 int rc;
178 rc = shishi_asn1_to_der (as->handle, as->asreq, out, outlen);
179 if (rc != SHISHI_OK)
180 return rc;
182 return SHISHI_OK;
186 * shishi_as_req_der_set:
187 * @as: structure that holds information about AS exchange
188 * @der: input array with DER encoded AP-REQ.
189 * @derlen: length of input array with DER encoded AP-REQ.
191 * DER decode AS-REQ and set it AS exchange. If decoding fails, the
192 * AS-REQ in the AS exchange remains.
194 * Return value: Returns SHISHI_OK.
197 shishi_as_req_der_set (Shishi_as * as, char *der, size_t derlen)
199 Shishi_asn1 asreq;
201 asreq = shishi_der2asn1_asreq (as->handle, der, derlen);
203 if (asreq == NULL)
204 return SHISHI_ASN1_ERROR;
206 as->asreq = asreq;
208 return SHISHI_OK;
212 * shishi_as_rep:
213 * @as: structure that holds information about AS exchange
215 * Get ASN.1 AS-REP structure from AS exchange.
217 * Return value: Returns the received AS-REP packet from the AS
218 * exchange, or NULL if not yet set or an error occured.
220 Shishi_asn1
221 shishi_as_rep (Shishi_as * as)
223 return as->asrep;
227 * shishi_as_rep_process:
228 * @as: structure that holds information about AS exchange
229 * @key: user's key, used to encrypt the encrypted part of the AS-REP.
230 * @password: user's password, used if key is NULL.
232 * Process new AS-REP and set ticket. The key is used to decrypt the
233 * AP-REP. If both key and password is NULL, the user is queried for
234 * it.
236 * Return value: Returns SHISHI_OK iff successful.
239 shishi_as_rep_process (Shishi_as * as, Shishi_key * key, const char *password)
241 Shishi_asn1 ticket, kdcreppart;
242 int res;
244 if (VERBOSE (as->handle))
245 printf ("Processing AS-REQ and AS-REP...\n");
247 if (VERBOSEASN1 (as->handle))
248 shishi_kdcreq_print (as->handle, stdout, as->asreq);
250 if (VERBOSEASN1 (as->handle))
251 shishi_kdcrep_print (as->handle, stdout, as->asrep);
253 if (key == NULL && password == NULL)
255 char *passwd;
256 char *user;
257 size_t userlen;
259 res = shishi_asreq_clientrealm (as->handle, as->asreq, &user, &userlen);
260 if (res != SHISHI_OK)
262 shishi_error_printf (as->handle, "Could not extract cname and "
263 "realm from AS-REQ: %s\n",
264 shishi_strerror (res),
265 shishi_error (as->handle));
266 return res;
269 res = shishi_prompt_password (as->handle, &passwd,
270 "Enter password for `%s': ", user);
271 free (user);
272 if (res != SHISHI_OK)
274 shishi_error_printf (as->handle, "Reading password failed: %s\n",
275 shishi_strerror (res));
276 return res;
279 res = shishi_as_process (as->handle, as->asreq, as->asrep,
280 passwd, &kdcreppart);
281 free (passwd);
283 else if (key == NULL)
284 res = shishi_as_process (as->handle, as->asreq, as->asrep,
285 password, &kdcreppart);
286 else
287 res = shishi_kdc_process (as->handle, as->asreq, as->asrep, key,
288 SHISHI_KEYUSAGE_ENCASREPPART, &kdcreppart);
289 if (res != SHISHI_OK)
290 return res;
292 if (VERBOSE (as->handle))
293 printf ("Got EncKDCRepPart...\n");
295 if (VERBOSEASN1 (as->handle))
296 shishi_enckdcreppart_print (as->handle, stdout, kdcreppart);
298 res = shishi_kdcrep_get_ticket (as->handle, as->asrep, &ticket);
299 if (res != SHISHI_OK)
301 shishi_error_printf (as->handle,
302 "Could not extract ticket from AS-REP: %s",
303 shishi_error (as->handle));
304 return res;
307 if (VERBOSE (as->handle))
308 printf ("Got Ticket...\n");
310 if (VERBOSEASN1 (as->handle))
311 shishi_ticket_print (as->handle, stdout, ticket);
313 /* XXX */
314 as->tkt = shishi_tkt2 (as->handle, ticket, kdcreppart, as->asrep);
316 return SHISHI_OK;
320 * shishi_as_rep_build:
321 * @as: structure that holds information about AS exchange
322 * @key: user's key, used to encrypt the encrypted part of the AS-REP.
324 * Build AS-REP.
326 * Return value: Returns SHISHI_OK iff successful.
329 shishi_as_rep_build (Shishi_as * as, Shishi_key * key)
331 int rc;
333 /* XXX there are reasons for having padata in AS-REP */
334 rc = shishi_kdcrep_clear_padata (as->handle, as->asrep);
335 if (rc != SHISHI_OK)
336 return rc;
338 rc = shishi_enckdcreppart_populate_encticketpart
339 (as->handle, shishi_tkt_enckdcreppart (as->tkt),
340 shishi_tkt_encticketpart (as->tkt));
341 if (rc != SHISHI_OK)
342 return rc;
344 rc = shishi_kdc_copy_nonce (as->handle, as->asreq,
345 shishi_tkt_enckdcreppart (as->tkt));
346 if (rc != SHISHI_OK)
347 return rc;
349 rc = shishi_kdcrep_add_enc_part (as->handle,
350 as->asrep,
351 key,
352 SHISHI_KEYUSAGE_ENCASREPPART,
353 shishi_tkt_enckdcreppart (as->tkt));
354 if (rc != SHISHI_OK)
355 return rc;
357 rc = shishi_kdcrep_set_ticket (as->handle, as->asrep,
358 shishi_tkt_ticket (as->tkt));
359 if (rc != SHISHI_OK)
360 return rc;
362 rc = shishi_kdc_copy_crealm (as->handle, as->asrep,
363 shishi_tkt_encticketpart (as->tkt));
364 if (rc != SHISHI_OK)
365 return rc;
367 rc = shishi_kdc_copy_cname (as->handle, as->asrep,
368 shishi_tkt_encticketpart (as->tkt));
369 if (rc != SHISHI_OK)
370 return rc;
372 return SHISHI_OK;
376 * shishi_as_rep_der:
377 * @as: structure that holds information about AS exchange
378 * @out: output array with newly allocated DER encoding of AS-REP.
379 * @outlen: length of output array with DER encoding of AS-REP.
381 * DER encode AS-REP. @out is allocated by this function, and it is
382 * the responsibility of caller to deallocate it.
384 * Return value: Returns SHISHI_OK iff successful.
387 shishi_as_rep_der (Shishi_as * as, char **out, size_t * outlen)
389 int rc;
391 rc = shishi_asn1_to_der (as->handle, as->asrep, out, outlen);
392 if (rc != SHISHI_OK)
393 return rc;
395 return SHISHI_OK;
399 * shishi_as_rep_set:
400 * @as: structure that holds information about AS exchange
401 * @asrep: asrep to store in AS.
403 * Set the AS-REP in the AS exchange.
405 void
406 shishi_as_rep_set (Shishi_as * as, Shishi_asn1 asrep)
408 if (as->asrep)
409 shishi_asn1_done (as->handle, as->asrep);
410 as->asrep = asrep;
414 * shishi_as_rep_der_set:
415 * @as: structure that holds information about AS exchange
416 * @der: input array with DER encoded AP-REP.
417 * @derlen: length of input array with DER encoded AP-REP.
419 * DER decode AS-REP and set it AS exchange. If decoding fails, the
420 * AS-REP in the AS exchange remains.
422 * Return value: Returns SHISHI_OK.
425 shishi_as_rep_der_set (Shishi_as * as, char *der, size_t derlen)
427 Shishi_asn1 asrep;
429 asrep = shishi_der2asn1_asrep (as->handle, der, derlen);
431 if (asrep == NULL)
432 return SHISHI_ASN1_ERROR;
434 as->asrep = asrep;
436 return SHISHI_OK;
440 * shishi_as_krberror:
441 * @as: structure that holds information about AS exchange
443 * Get ASN.1 KRB-ERROR structure from AS exchange.
445 * Return value: Returns the received KRB-ERROR packet from the AS
446 * exchange, or NULL if not yet set or an error occured.
448 Shishi_asn1
449 shishi_as_krberror (Shishi_as * as)
451 return as->krberror;
455 * shishi_as_krberror_der:
456 * @as: structure that holds information about AS exchange
457 * @out: output array with newly allocated DER encoding of KRB-ERROR.
458 * @outlen: length of output array with DER encoding of KRB-ERROR.
460 * DER encode KRB-ERROR. @out is allocated by this function, and it is
461 * the responsibility of caller to deallocate it.
463 * Return value: Returns SHISHI_OK iff successful.
466 shishi_as_krberror_der (Shishi_as * as, char **out, size_t * outlen)
468 int rc;
470 rc = shishi_krberror_der (as->handle, as->krberror, out, outlen);
471 if (rc != SHISHI_OK)
472 return rc;
474 return SHISHI_OK;
478 * shishi_as_krberror_set:
479 * @as: structure that holds information about AS exchange
480 * @krberror: krberror to store in AS.
482 * Set the KRB-ERROR in the AS exchange.
484 void
485 shishi_as_krberror_set (Shishi_as * as, Shishi_asn1 krberror)
487 if (as->krberror)
488 shishi_asn1_done (as->handle, as->krberror);
489 as->krberror = krberror;
493 * shishi_as_tkt:
494 * @as: structure that holds information about AS exchange
496 * Get Ticket in AS exchange.
498 * Return value: Returns the newly aquired tkt from the AS
499 * exchange, or NULL if not yet set or an error occured.
501 Shishi_tkt *
502 shishi_as_tkt (Shishi_as * as)
504 return as->tkt;
508 * shishi_as_tkt_set:
509 * @as: structure that holds information about AS exchange
510 * @tkt: tkt to store in AS.
512 * Set the Tkt in the AS exchange.
514 void
515 shishi_as_tkt_set (Shishi_as * as, Shishi_tkt * tkt)
517 as->tkt = tkt;
521 * shishi_as_sendrecv_hint:
522 * @as: structure that holds information about AS exchange
523 * @hint: additional parameters that modify connection behaviour, or %NULL.
525 * Send AS-REQ and receive AS-REP or KRB-ERROR. This is the initial
526 * authentication, usually used to acquire a Ticket Granting Ticket.
527 * The @hint structure can be used to set, e.g., parameters for TLS
528 * authentication.
530 * Return value: Returns SHISHI_OK iff successful.
533 shishi_as_sendrecv_hint (Shishi_as * as, Shishi_tkts_hint * hint)
535 int res;
537 if (VERBOSE (as->handle))
538 printf ("Sending AS-REQ...\n");
540 if (VERBOSEASN1 (as->handle))
541 shishi_kdcreq_print (as->handle, stdout, as->asreq);
543 res = shishi_kdcreq_sendrecv_hint (as->handle, as->asreq, &as->asrep, hint);
544 if (res == SHISHI_GOT_KRBERROR)
546 as->krberror = as->asrep;
547 as->asrep = NULL;
549 if (VERBOSE (as->handle))
550 printf ("Received KRB-ERROR...\n");
551 if (VERBOSEASN1 (as->handle))
552 shishi_krberror_print (as->handle, stdout, as->krberror);
553 if (VERBOSEASN1(as->handle))
554 shishi_krberror_pretty_print (as->handle, stdout, as->krberror);
556 if (res != SHISHI_OK)
557 return res;
559 if (VERBOSE (as->handle))
560 printf ("Received AS-REP...\n");
562 if (VERBOSEASN1 (as->handle))
563 shishi_kdcrep_print (as->handle, stdout, as->asrep);
565 return SHISHI_OK;
569 * shishi_as_sendrecv:
570 * @as: structure that holds information about AS exchange
572 * Send AS-REQ and receive AS-REP or KRB-ERROR. This is the initial
573 * authentication, usually used to acquire a Ticket Granting Ticket.
575 * Return value: Returns SHISHI_OK iff successful.
578 shishi_as_sendrecv (Shishi_as * as)
580 return shishi_as_sendrecv_hint (as, NULL);