Add ticketlife, renewlife.
[shishi.git] / lib / as.c
blobabca0ca7b91924e2990fe39bc897c6533c32724c
1 /* as.c High level client AS functions
2 * Copyright (C) 2002, 2003 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_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 = malloc (sizeof (**as));
49 if (*as == NULL)
50 return SHISHI_MALLOC_ERROR;
51 las = *as;
52 memset (las, 0, sizeof (*las));
54 las->handle = handle;
56 las->asreq = shishi_asreq (handle);
57 if (las->asreq == NULL)
59 shishi_error_printf (handle, "Could not create AS-REQ: %s\n",
60 shishi_strerror_details (handle));
61 return SHISHI_ASN1_ERROR;
64 /* XXX there are reasons for having padata in AS-REQ */
65 res = shishi_kdcreq_clear_padata (las->handle, las->asreq);
66 if (res != SHISHI_OK)
67 return res;
69 las->asrep = shishi_asrep (handle);
70 if (las->asrep == NULL)
72 shishi_error_printf (handle, "Could not create AS-REP: %s\n",
73 shishi_strerror_details (handle));
74 return SHISHI_ASN1_ERROR;
77 las->krberror = shishi_krberror (handle);
78 if (las->krberror == NULL)
80 shishi_error_printf (handle, "Could not create KRB-ERROR: %s\n",
81 shishi_strerror_details (handle));
82 return SHISHI_ASN1_ERROR;
85 res = shishi_tkt (handle, &las->tkt);
86 if (res != SHISHI_OK)
87 return res;
89 res = shishi_tkt_flags_set (las->tkt, SHISHI_TICKETFLAGS_INITIAL);
90 if (res != SHISHI_OK)
91 return res;
93 return SHISHI_OK;
96 /* TODO: add shishi_as_clientserver(h,p,a,client,server) and make the
97 shishi_as_cnamerealmsname function take real cname/sname pointer
98 arrays. */
101 * shishi_as_get_asreq:
102 * @as: structure that holds information about AS exchange
104 * Return value: Returns the generated AS-REQ packet from the AS
105 * exchange, or NULL if not yet set or an error occured.
107 Shishi_asn1
108 shishi_as_req (Shishi_as * as)
110 return as->asreq;
114 * shishi_as_req_build:
115 * @as: structure that holds information about AS exchange
117 * Possibly remove unset fields (e.g., rtime).
119 * Return value: Returns SHISHI_OK iff successful.
122 shishi_as_req_build (Shishi_as * as)
124 int res;
126 res = shishi_kdcreq_build (as->handle, as->asreq);
127 if (res != SHISHI_OK)
128 return res;
130 return SHISHI_OK;
134 * shishi_as_req_set:
135 * @as: structure that holds information about AS exchange
136 * @asreq: asreq to store in AS.
138 * Set the AS-REQ in the AP exchange.
140 void
141 shishi_as_req_set (Shishi_as * as, Shishi_asn1 asreq)
143 if (as->asreq)
144 shishi_asn1_done (as->handle, as->asreq);
145 as->asreq = asreq;
149 * shishi_as_req_der:
150 * @as: structure that holds information about AS exchange
151 * @out: output array with der encoding of AS-REQ.
152 * @outlen: length of output array with der encoding of AS-REQ.
154 * DER encode AS-REQ.
156 * Return value: Returns SHISHI_OK iff successful.
159 shishi_as_req_der (Shishi_as * as, char *out, int *outlen)
161 int rc;
163 rc = shishi_a2d (as->handle, as->asreq, out, outlen);
164 if (rc != SHISHI_OK)
165 return rc;
167 return SHISHI_OK;
171 * shishi_as_req_der_set:
172 * @as: structure that holds information about AS exchange
173 * @der: input array with DER encoded AP-REQ.
174 * @derlen: length of input array with DER encoded AP-REQ.
176 * DER decode AS-REQ and set it AS exchange. If decoding fails, the
177 * AS-REQ in the AS exchange remains.
179 * Return value: Returns SHISHI_OK.
182 shishi_as_req_der_set (Shishi_as * as, char *der, size_t derlen)
184 Shishi_asn1 asreq;
186 asreq = shishi_der2asn1_asreq (as->handle, der, derlen);
188 if (asreq == NULL)
189 return SHISHI_ASN1_ERROR;
191 as->asreq = asreq;
193 return SHISHI_OK;
197 * shishi_as_rep:
198 * @as: structure that holds information about AS exchange
200 * Return value: Returns the received AS-REP packet from the AS
201 * exchange, or NULL if not yet set or an error occured.
203 Shishi_asn1
204 shishi_as_rep (Shishi_as * as)
206 return as->asrep;
210 * shishi_as_rep_process:
211 * @as: structure that holds information about AS exchange
213 * Process new AS-REP and set ticket. The key is used to decrypt the
214 * AP-REP.
216 * Return value: Returns SHISHI_OK iff successful.
219 shishi_as_rep_process (Shishi_as * as, Shishi_key * key, const char *password)
221 Shishi_asn1 ticket, kdcreppart;
222 char user[BUFSIZ];
223 int userlen;
224 int res;
226 if (VERBOSE (as->handle))
227 printf ("Processing AS-REQ and AS-REP...\n");
229 if (VERBOSEASN1 (as->handle))
230 shishi_kdcreq_print (as->handle, stdout, as->asreq);
232 if (VERBOSEASN1 (as->handle))
233 shishi_kdcrep_print (as->handle, stdout, as->asrep);
235 userlen = sizeof (user);
236 res = shishi_asreq_cnamerealm_get (as->handle, as->asreq, user, &userlen);
237 if (res != SHISHI_OK)
239 shishi_error_printf (as->handle, "Could not extract cname and "
240 "realm from AS-REQ: %s\n", shishi_strerror (res),
241 shishi_strerror_details (as->handle));
242 return res;
244 user[userlen] = '\0';
246 if (key == NULL && password == NULL)
248 char password[BUFSIZ];
250 res = shishi_prompt_password (as->handle,
251 stdin, password, BUFSIZ,
252 stdout, "Enter password for `%s': ",
253 user);
254 if (res != SHISHI_OK)
256 shishi_error_printf (as->handle, "Reading password failed: %s\n",
257 shishi_strerror (res));
258 return res;
261 res = shishi_as_process (as->handle, as->asreq, as->asrep,
262 password, &kdcreppart);
264 else if (key == NULL)
265 res = shishi_as_process (as->handle, as->asreq, as->asrep,
266 password, &kdcreppart);
267 else
268 res = shishi_kdc_process (as->handle, as->asreq, as->asrep, key,
269 SHISHI_KEYUSAGE_ENCASREPPART, &kdcreppart);
270 if (res != SHISHI_OK)
271 return res;
273 if (VERBOSE (as->handle))
274 printf ("Got EncKDCRepPart...\n");
276 if (VERBOSEASN1 (as->handle))
277 shishi_enckdcreppart_print (as->handle, stdout, kdcreppart);
279 res = shishi_kdcrep_get_ticket (as->handle, as->asrep, &ticket);
280 if (res != SHISHI_OK)
282 shishi_error_printf (as->handle,
283 "Could not extract ticket from AS-REP: %s",
284 shishi_strerror_details (as->handle));
285 return res;
288 if (VERBOSE (as->handle))
289 printf ("Got Ticket...\n");
291 if (VERBOSEASN1 (as->handle))
292 shishi_ticket_print (as->handle, stdout, ticket);
294 as->tkt = shishi_tkt2 (as->handle, ticket, kdcreppart, as->asrep);
295 if (as->tkt == NULL)
297 shishi_error_printf (as->handle, "Could not create ticket");
298 return SHISHI_MALLOC_ERROR;
301 return SHISHI_OK;
305 * shishi_as_rep_build:
306 * @as: structure that holds information about AS exchange
307 * @key: user's key, used to encrypt the encrypted part of the AS-REP.
309 * Build AS-REP.
311 * Return value: Returns SHISHI_OK iff successful.
314 shishi_as_rep_build (Shishi_as * as, Shishi_key * key)
316 int rc;
318 /* XXX there are reasons for having padata in AS-REP */
319 rc = shishi_kdcrep_clear_padata (as->handle, as->asrep);
320 if (rc != SHISHI_OK)
321 return rc;
323 rc = shishi_enckdcreppart_populate_encticketpart
324 (as->handle, shishi_tkt_enckdcreppart (as->tkt),
325 shishi_tkt_encticketpart (as->tkt));
326 if (rc != SHISHI_OK)
327 return rc;
329 rc = shishi_kdc_copy_nonce (as->handle, as->asreq,
330 shishi_tkt_enckdcreppart (as->tkt));
331 if (rc != SHISHI_OK)
332 return rc;
334 rc = shishi_kdcrep_add_enc_part (as->handle,
335 as->asrep,
336 key,
337 SHISHI_KEYUSAGE_ENCASREPPART,
338 shishi_tkt_enckdcreppart (as->tkt));
339 if (rc != SHISHI_OK)
340 return rc;
342 rc = shishi_kdcrep_set_ticket (as->handle, as->asrep,
343 shishi_tkt_ticket (as->tkt));
344 if (rc != SHISHI_OK)
345 return rc;
347 rc = shishi_kdc_copy_crealm (as->handle, as->asrep,
348 shishi_tkt_encticketpart (as->tkt));
349 if (rc != SHISHI_OK)
350 return rc;
352 rc = shishi_kdc_copy_cname (as->handle, as->asrep,
353 shishi_tkt_encticketpart (as->tkt));
354 if (rc != SHISHI_OK)
355 return rc;
357 return SHISHI_OK;
361 * shishi_as_rep_der:
362 * @as: structure that holds information about AS exchange
363 * @out: output array with der encoding of AS-REP.
364 * @outlen: length of output array with der encoding of AS-REP.
366 * DER encode AS-REP.
368 * Return value: Returns SHISHI_OK iff successful.
371 shishi_as_rep_der (Shishi_as * as, char *out, int *outlen)
373 int rc;
375 rc = shishi_a2d (as->handle, as->asrep, out, outlen);
376 if (rc != SHISHI_OK)
377 return rc;
379 return SHISHI_OK;
383 * shishi_as_rep_set:
384 * @as: structure that holds information about AS exchange
385 * @asrep: asrep to store in AS.
387 * Set the AS-REP in the AP exchange.
389 void
390 shishi_as_rep_set (Shishi_as * as, Shishi_asn1 asrep)
392 if (as->asrep)
393 shishi_asn1_done (as->handle, as->asrep);
394 as->asrep = asrep;
398 * shishi_as_rep_der_set:
399 * @as: structure that holds information about AS exchange
400 * @der: input array with DER encoded AP-REP.
401 * @derlen: length of input array with DER encoded AP-REP.
403 * DER decode AS-REP and set it AS exchange. If decoding fails, the
404 * AS-REP in the AS exchange remains.
406 * Return value: Returns SHISHI_OK.
409 shishi_as_rep_der_set (Shishi_as * as, char *der, size_t derlen)
411 Shishi_asn1 asrep;
413 asrep = shishi_der2asn1_asrep (as->handle, der, derlen);
415 if (asrep == NULL)
416 return SHISHI_ASN1_ERROR;
418 as->asrep = asrep;
420 return SHISHI_OK;
424 * shishi_as_get_krberror:
425 * @as: structure that holds information about AS exchange
427 * Return value: Returns the received KRB-ERROR packet from the AS
428 * exchange, or NULL if not yet set or an error occured.
430 Shishi_asn1
431 shishi_as_krberror (Shishi_as * as)
433 return as->krberror;
437 * shishi_as_krberror_der:
438 * @as: structure that holds information about AS exchange
439 * @out: output array with der encoding of KRB-ERROR.
440 * @outlen: length of output array with der encoding of KRB-ERROR.
442 * DER encode KRB-ERROR.
444 * Return value: Returns SHISHI_OK iff successful.
447 shishi_as_krberror_der (Shishi_as * as, char *out, int *outlen)
449 int rc;
451 rc = shishi_a2d (as->handle, as->krberror, out, outlen);
452 if (rc != SHISHI_OK)
453 return rc;
455 return SHISHI_OK;
459 * shishi_as_krberror_set:
460 * @as: structure that holds information about AS exchange
461 * @krberror: krberror to store in AS.
463 * Set the KRB-ERROR in the AP exchange.
465 void
466 shishi_as_krberror_set (Shishi_as * as, Shishi_asn1 krberror)
468 if (as->krberror)
469 shishi_asn1_done (as->handle, as->krberror);
470 as->krberror = krberror;
474 * shishi_as_get_tkt:
475 * @as: structure that holds information about AS exchange
477 * Return value: Returns the newly aquired tkt from the AS
478 * exchange, or NULL if not yet set or an error occured.
480 Shishi_tkt *
481 shishi_as_tkt (Shishi_as * as)
483 return as->tkt;
487 * shishi_as_tkt_set:
488 * @as: structure that holds information about AS exchange
489 * @tkt: tkt to store in AS.
491 * Set the Tkt in the AP exchange.
493 void
494 shishi_as_tkt_set (Shishi_as * as, Shishi_tkt * tkt)
496 as->tkt = tkt;
500 * shishi_as_sendrecv:
501 * @as: structure that holds information about AS exchange
503 * Send AS-REQ and receive AS-REP or KRB-ERROR. This is the initial
504 * authentication, usually used to acquire a Ticket Granting Ticket.
506 * Return value: Returns SHISHI_OK iff successful.
509 shishi_as_sendrecv (Shishi_as * as)
511 int res;
513 if (VERBOSE (as->handle))
514 printf ("Sending AS-REQ...\n");
516 if (VERBOSEASN1 (as->handle))
517 shishi_kdcreq_print (as->handle, stdout, as->asreq);
519 res = shishi_kdcreq_sendrecv (as->handle, as->asreq, &as->asrep);
520 if (res == SHISHI_GOT_KRBERROR)
522 as->krberror = as->asrep;
523 as->asrep = NULL;
525 if (VERBOSE (as->handle))
526 printf ("Received KRB-ERROR...\n");
527 if (VERBOSEASN1 (as->handle))
528 shishi_krberror_print (as->handle, stdout, as->krberror);
530 if (res != SHISHI_OK)
531 return res;
533 if (VERBOSE (as->handle))
534 printf ("Received AS-REP...\n");
536 if (VERBOSEASN1 (as->handle))
537 shishi_kdcrep_print (as->handle, stdout, as->asrep);
539 return SHISHI_OK;