Add ticketlife, renewlife.
[shishi.git] / lib / ticket.c
blob03aaed5d21881c10b2c5cc7e12be5c2fc3b955e7
1 /* ticket.c low-level ASN.1 Ticket handling
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 int
25 shishi_ticket_realm_get (Shishi * handle,
26 Shishi_asn1 ticket, char *realm, int *realmlen)
28 return shishi_asn1_field (handle, ticket, realm, realmlen, "realm");
31 /**
32 * shishi_ticket_realm_set:
33 * @handle: shishi handle as allocated by shishi_init().
34 * @ticket: input variable with ticket info.
35 * @realm: input array with name of realm.
37 * Set the realm field in the Ticket.
39 * Return value: Returns SHISHI_OK iff successful.
40 **/
41 int
42 shishi_ticket_realm_set (Shishi * handle, Shishi_asn1 ticket,
43 const char *realm)
45 int res;
47 res = shishi_asn1_write (handle, ticket, "realm", realm, 0);
48 if (res != SHISHI_OK)
49 return res;
51 return SHISHI_OK;
54 int
55 shishi_ticket_sname_get (Shishi * handle,
56 Shishi_asn1 ticket, char *server, size_t * serverlen)
58 return shishi_principal_name_get (handle, ticket, "sname",
59 server, serverlen);
62 /**
63 * shishi_ticket_sname_set:
64 * @handle: shishi handle as allocated by shishi_init().
65 * @ticket: Ticket variable to set server name field in.
66 * @name_type: type of principial, see Shishi_name_type, usually
67 * SHISHI_NT_UNKNOWN.
68 * @sname: input array with principal name.
70 * Set the server name field in the Ticket.
72 * Return value: Returns SHISHI_OK iff successful.
73 **/
74 int
75 shishi_ticket_sname_set (Shishi * handle,
76 Shishi_asn1 ticket,
77 Shishi_name_type name_type, char *sname[])
79 int res = SHISHI_OK;
80 char buf[BUFSIZ];
81 int i;
83 sprintf (buf, "%d", name_type);
85 res = shishi_asn1_write (handle, ticket, "sname.name-type", buf, 0);
86 if (res != SHISHI_OK)
87 return res;
89 res = shishi_asn1_write (handle, ticket, "sname.name-string", NULL, 0);
90 if (res != SHISHI_OK)
91 return res;
93 i = 1;
94 while (sname[i - 1])
96 res = shishi_asn1_write (handle, ticket, "sname.name-string", "NEW", 1);
97 if (res != SHISHI_OK)
98 return res;
100 sprintf (buf, "sname.name-string.?%d", i);
101 res = shishi_asn1_write (handle, ticket, buf, sname[i - 1], 0);
102 if (res != SHISHI_OK)
103 return res;
105 i++;
108 return SHISHI_OK;
112 shishi_ticket_set_server (Shishi * handle,
113 Shishi_asn1 ticket, const char *server)
115 char *tmpserver;
116 char **serverbuf;
117 char *tokptr;
118 int res;
119 int i;
121 tmpserver = strdup (server);
122 if (tmpserver == NULL)
123 return SHISHI_MALLOC_ERROR;
125 serverbuf = malloc (sizeof (*serverbuf));
126 for (i = 0;
127 (serverbuf[i] = strtok_r (i == 0 ? tmpserver : NULL, "/", &tokptr));
128 i++)
130 serverbuf = realloc (serverbuf, (i + 2) * sizeof (*serverbuf));
131 if (serverbuf == NULL)
132 return SHISHI_MALLOC_ERROR;
134 res = shishi_ticket_sname_set (handle, ticket,
135 SHISHI_NT_PRINCIPAL, serverbuf);
136 if (res != SHISHI_OK)
138 fprintf (stderr, _("Could not set sname: %s\n"),
139 shishi_strerror_details (handle));
140 return res;
142 free (serverbuf);
143 free (tmpserver);
145 return SHISHI_OK;
149 shishi_ticket_snamerealm_get (Shishi * handle,
150 Shishi_asn1 ticket,
151 char *serverrealm, int *serverrealmlen)
153 return shishi_principal_name_realm_get (handle, ticket, "sname",
154 ticket, "realm",
155 serverrealm, serverrealmlen);
159 shishi_ticket_srealmserver_set (Shishi * handle,
160 Shishi_asn1 ticket, char *realm, char *server)
162 int res;
164 res = shishi_ticket_realm_set (handle, ticket, realm);
165 if (res != SHISHI_OK)
166 return res;
168 res = shishi_ticket_set_server (handle, ticket, server);
169 if (res != SHISHI_OK)
170 return res;
172 return SHISHI_OK;
176 * shishi_ticket_get_enc_part_etype:
177 * @handle: shishi handle as allocated by shishi_init().
178 * @kdcrep: Ticket variable to get value from.
179 * @etype: output variable that holds the value.
181 * Extract Ticket.enc-part.etype.
183 * Return value: Returns SHISHI_OK iff successful.
186 shishi_ticket_get_enc_part_etype (Shishi * handle,
187 Shishi_asn1 ticket, int32_t * etype)
189 int res;
191 res = shishi_asn1_read_int32 (handle, ticket, "enc-part.etype", etype);
193 return res;
197 shishi_ticket_decrypt (Shishi * handle,
198 Shishi_asn1 ticket,
199 Shishi_key * key, Shishi_asn1 * encticketpart)
201 int res;
202 int i;
203 char *buf;
204 size_t buflen;
205 unsigned char cipher[BUFSIZ];
206 size_t cipherlen;
207 int etype;
209 res = shishi_ticket_get_enc_part_etype (handle, ticket, &etype);
210 if (res != SHISHI_OK)
211 return res;
213 if (etype != shishi_key_type (key))
214 return SHISHI_TICKET_BAD_KEYTYPE;
216 cipherlen = BUFSIZ;
217 res = shishi_asn1_field (handle, ticket, cipher, &cipherlen,
218 "enc-part.cipher");
219 if (res != SHISHI_OK)
220 return res;
222 res = shishi_decrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
223 cipher, cipherlen, &buf, &buflen);
225 if (res != SHISHI_OK)
227 shishi_error_printf (handle,
228 "Ticket decrypt failed, wrong password?\n");
229 return SHISHI_TICKET_DECRYPT_FAILED;
232 /* The crypto is so 1980; no length indicator. Trim off pad bytes
233 until we can parse it. */
234 for (i = 0; i < 8; i++)
236 if (VERBOSEASN1 (handle))
237 printf ("Trying with %d pad in enckdcrep...\n", i);
239 *encticketpart = shishi_der2asn1_encticketpart (handle, &buf[0],
240 buflen - i);
241 if (*encticketpart != NULL)
242 break;
245 if (*encticketpart == NULL)
247 shishi_error_printf (handle, "Could not DER decode EncTicketPart. "
248 "Password probably correct (decrypt ok) though\n");
249 return SHISHI_ASN1_ERROR;
252 return SHISHI_OK;
256 * shishi_ticket_set_enc_part:
257 * @handle: shishi handle as allocated by shishi_init().
258 * @ticket: Ticket to add enc-part field to.
259 * @etype: encryption type used to encrypt enc-part.
260 * @kvno: key version number.
261 * @buf: input array with encrypted enc-part.
262 * @buflen: size of input array with encrypted enc-part.
264 * Set the encrypted enc-part field in the Ticket. The encrypted data
265 * is usually created by calling shishi_encrypt() on the DER encoded
266 * enc-part. To save time, you may want to use
267 * shishi_ticket_add_enc_part() instead, which calculates the
268 * encrypted data and calls this function in one step.
270 * Return value: Returns SHISHI_OK iff successful.
273 shishi_ticket_set_enc_part (Shishi * handle,
274 Shishi_asn1 ticket,
275 int etype, int kvno, char *buf, size_t buflen)
277 char *format;
278 int res = SHISHI_OK;
280 res = shishi_asn1_write (handle, ticket, "enc-part.cipher", buf, buflen);
281 if (res != SHISHI_OK)
282 return res;
284 res = shishi_asn1_write_int32 (handle, ticket, "enc-part.etype", etype);
285 if (res != SHISHI_OK)
286 return res;
288 if (kvno == 0)
289 res = shishi_asn1_write (handle, ticket, "enc-part.kvno", NULL, 0);
290 else
291 res = shishi_asn1_write_uint32 (handle, ticket, "enc-part.kvno", kvno);
292 if (res != SHISHI_OK)
293 return res;
295 return SHISHI_OK;
299 * shishi_ticket_add_enc_part:
300 * @handle: shishi handle as allocated by shishi_init().
301 * @ticket: Ticket to add enc-part field to.
302 * @key: key used to encrypt enc-part.
303 * @encticketpart: EncTicketPart to add.
305 * Encrypts DER encoded EncTicketPart using key and stores it in the
306 * Ticket.
308 * Return value: Returns SHISHI_OK iff successful.
311 shishi_ticket_add_enc_part (Shishi * handle,
312 Shishi_asn1 ticket,
313 Shishi_key * key, Shishi_asn1 encticketpart)
315 int res = SHISHI_OK;
316 char *buf;
317 size_t buflen;
318 char *der;
319 size_t derlen;
321 res = shishi_new_a2d (handle, encticketpart, &der, &derlen);
322 if (res != SHISHI_OK)
324 shishi_error_printf (handle, "Could not DER encode encticketpart: %s\n",
325 shishi_strerror (res));
326 return res;
329 res = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
330 der, derlen, &buf, &buflen);
332 free (der);
334 if (res != SHISHI_OK)
336 shishi_error_printf (handle,
337 "Cannot encrypt encrypted part of ticket\n");
338 return res;
341 res = shishi_ticket_set_enc_part (handle, ticket, shishi_key_type (key),
342 shishi_key_version (key), buf, buflen);
344 free (buf);
346 return res;