Fix API.
[shishi.git] / lib / ticket.c
blob2427c30f34ee2f019448693434d1a39fb9798d82
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 /**
25 * shishi_ticket_realm_get:
26 * @handle: shishi handle as allocated by shishi_init().
27 * @ticket: input variable with ticket info.
28 * @realm: output array with newly allocated name of realm in ticket.
29 * @realmlen: size of output array.
31 * Extract realm from ticket.
33 * Return value: Returns SHISHI_OK iff successful.
34 **/
35 int
36 shishi_ticket_realm_get (Shishi * handle,
37 Shishi_asn1 ticket,
38 char **realm, size_t *realmlen)
40 return shishi_asn1_read2 (handle, ticket, "realm", realm, realmlen);
43 /**
44 * shishi_ticket_realm_set:
45 * @handle: shishi handle as allocated by shishi_init().
46 * @ticket: input variable with ticket info.
47 * @realm: input array with name of realm.
49 * Set the realm field in the Ticket.
51 * Return value: Returns SHISHI_OK iff successful.
52 **/
53 int
54 shishi_ticket_realm_set (Shishi * handle, Shishi_asn1 ticket,
55 const char *realm)
57 int res;
59 res = shishi_asn1_write (handle, ticket, "realm", realm, 0);
60 if (res != SHISHI_OK)
61 return res;
63 return SHISHI_OK;
66 int
67 shishi_ticket_sname_get (Shishi * handle,
68 Shishi_asn1 ticket, char *server, size_t * serverlen)
70 return shishi_principal_name_get (handle, ticket, "sname",
71 server, serverlen);
74 /**
75 * shishi_ticket_sname_set:
76 * @handle: shishi handle as allocated by shishi_init().
77 * @ticket: Ticket variable to set server name field in.
78 * @name_type: type of principial, see Shishi_name_type, usually
79 * SHISHI_NT_UNKNOWN.
80 * @sname: input array with principal name.
82 * Set the server name field in the Ticket.
84 * Return value: Returns SHISHI_OK iff successful.
85 **/
86 int
87 shishi_ticket_sname_set (Shishi * handle,
88 Shishi_asn1 ticket,
89 Shishi_name_type name_type, char *sname[])
91 int res = SHISHI_OK;
92 char *buf;
93 int i;
95 asprintf (&buf, "%d", name_type);
96 res = shishi_asn1_write (handle, ticket, "sname.name-type", buf, 0);
97 free (buf);
98 if (res != SHISHI_OK)
99 return res;
101 res = shishi_asn1_write (handle, ticket, "sname.name-string", NULL, 0);
102 if (res != SHISHI_OK)
103 return res;
105 i = 1;
106 while (sname[i - 1])
108 res = shishi_asn1_write (handle, ticket, "sname.name-string", "NEW", 1);
109 if (res != SHISHI_OK)
110 return res;
112 asprintf (&buf, "sname.name-string.?%d", i);
113 res = shishi_asn1_write (handle, ticket, buf, sname[i - 1], 0);
114 free (buf);
115 if (res != SHISHI_OK)
116 return res;
118 i++;
121 return SHISHI_OK;
125 shishi_ticket_set_server (Shishi * handle,
126 Shishi_asn1 ticket, const char *server)
128 char *tmpserver;
129 char **serverbuf;
130 char *tokptr;
131 int res;
132 int i;
134 tmpserver = xstrdup (server);
135 serverbuf = xmalloc (sizeof (*serverbuf));
137 for (i = 0;
138 (serverbuf[i] = strtok_r (i == 0 ? tmpserver : NULL, "/", &tokptr));
139 i++)
141 serverbuf = xrealloc (serverbuf, (i + 2) * sizeof (*serverbuf));
143 res = shishi_ticket_sname_set (handle, ticket,
144 SHISHI_NT_PRINCIPAL, serverbuf);
145 if (res != SHISHI_OK)
147 fprintf (stderr, _("Could not set sname: %s\n"),
148 shishi_error (handle));
149 return res;
151 free (serverbuf);
152 free (tmpserver);
154 return SHISHI_OK;
158 shishi_ticket_snamerealm_get (Shishi * handle,
159 Shishi_asn1 ticket,
160 char *serverrealm, size_t *serverrealmlen)
162 return shishi_principal_name_realm_get (handle, ticket, "sname",
163 ticket, "realm",
164 serverrealm, serverrealmlen);
168 shishi_ticket_srealmserver_set (Shishi * handle,
169 Shishi_asn1 ticket, char *realm, char *server)
171 int res;
173 res = shishi_ticket_realm_set (handle, ticket, realm);
174 if (res != SHISHI_OK)
175 return res;
177 res = shishi_ticket_set_server (handle, ticket, server);
178 if (res != SHISHI_OK)
179 return res;
181 return SHISHI_OK;
185 * shishi_ticket_get_enc_part_etype:
186 * @handle: shishi handle as allocated by shishi_init().
187 * @ticket: Ticket variable to get value from.
188 * @etype: output variable that holds the value.
190 * Extract Ticket.enc-part.etype.
192 * Return value: Returns SHISHI_OK iff successful.
195 shishi_ticket_get_enc_part_etype (Shishi * handle,
196 Shishi_asn1 ticket, int32_t * etype)
198 int res;
200 res = shishi_asn1_read_int32 (handle, ticket, "enc-part.etype", etype);
202 return res;
206 shishi_ticket_decrypt (Shishi * handle,
207 Shishi_asn1 ticket,
208 Shishi_key * key, Shishi_asn1 * encticketpart)
210 int res;
211 int i;
212 char *buf;
213 size_t buflen;
214 char *cipher;
215 size_t cipherlen;
216 int etype;
218 res = shishi_ticket_get_enc_part_etype (handle, ticket, &etype);
219 if (res != SHISHI_OK)
220 return res;
222 if (etype != shishi_key_type (key))
223 return SHISHI_TICKET_BAD_KEYTYPE;
225 res = shishi_asn1_read2 (handle, ticket, "enc-part.cipher",
226 &cipher, &cipherlen);
227 if (res != SHISHI_OK)
228 return res;
230 res = shishi_decrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
231 cipher, cipherlen, &buf, &buflen);
232 free (cipher);
233 if (res != SHISHI_OK)
235 shishi_error_printf (handle,
236 "Ticket decrypt failed, wrong password?\n");
237 return SHISHI_TICKET_DECRYPT_FAILED;
240 /* The crypto is so 1980; no length indicator. Trim off pad bytes
241 until we can parse it. */
242 for (i = 0; i < 8; i++)
244 if (VERBOSEASN1 (handle))
245 printf ("Trying with %d pad in enckdcrep...\n", i);
247 *encticketpart = shishi_der2asn1_encticketpart (handle, &buf[0],
248 buflen - i);
249 if (*encticketpart != NULL)
250 break;
253 if (*encticketpart == NULL)
255 shishi_error_printf (handle, "Could not DER decode EncTicketPart. "
256 "Password probably correct (decrypt ok) though\n");
257 return SHISHI_ASN1_ERROR;
260 return SHISHI_OK;
264 * shishi_ticket_set_enc_part:
265 * @handle: shishi handle as allocated by shishi_init().
266 * @ticket: Ticket to add enc-part field to.
267 * @etype: encryption type used to encrypt enc-part.
268 * @kvno: key version number.
269 * @buf: input array with encrypted enc-part.
270 * @buflen: size of input array with encrypted enc-part.
272 * Set the encrypted enc-part field in the Ticket. The encrypted data
273 * is usually created by calling shishi_encrypt() on the DER encoded
274 * enc-part. To save time, you may want to use
275 * shishi_ticket_add_enc_part() instead, which calculates the
276 * encrypted data and calls this function in one step.
278 * Return value: Returns SHISHI_OK iff successful.
281 shishi_ticket_set_enc_part (Shishi * handle,
282 Shishi_asn1 ticket,
283 int etype, int kvno, char *buf, size_t buflen)
285 int res = SHISHI_OK;
287 res = shishi_asn1_write (handle, ticket, "enc-part.cipher", buf, buflen);
288 if (res != SHISHI_OK)
289 return res;
291 res = shishi_asn1_write_int32 (handle, ticket, "enc-part.etype", etype);
292 if (res != SHISHI_OK)
293 return res;
295 if (kvno == 0)
296 res = shishi_asn1_write (handle, ticket, "enc-part.kvno", NULL, 0);
297 else
298 res = shishi_asn1_write_uint32 (handle, ticket, "enc-part.kvno", kvno);
299 if (res != SHISHI_OK)
300 return res;
302 return SHISHI_OK;
306 * shishi_ticket_add_enc_part:
307 * @handle: shishi handle as allocated by shishi_init().
308 * @ticket: Ticket to add enc-part field to.
309 * @key: key used to encrypt enc-part.
310 * @encticketpart: EncTicketPart to add.
312 * Encrypts DER encoded EncTicketPart using key and stores it in the
313 * Ticket.
315 * Return value: Returns SHISHI_OK iff successful.
318 shishi_ticket_add_enc_part (Shishi * handle,
319 Shishi_asn1 ticket,
320 Shishi_key * key, Shishi_asn1 encticketpart)
322 int res = SHISHI_OK;
323 char *buf;
324 size_t buflen;
325 char *der;
326 size_t derlen;
328 res = shishi_new_a2d (handle, encticketpart, &der, &derlen);
329 if (res != SHISHI_OK)
331 shishi_error_printf (handle, "Could not DER encode encticketpart: %s\n",
332 shishi_strerror (res));
333 return res;
336 res = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
337 der, derlen, &buf, &buflen);
339 free (der);
341 if (res != SHISHI_OK)
343 shishi_error_printf (handle,
344 "Cannot encrypt encrypted part of ticket\n");
345 return res;
348 res = shishi_ticket_set_enc_part (handle, ticket, shishi_key_type (key),
349 shishi_key_version (key), buf, buflen);
351 free (buf);
353 return res;