Fix standalone libtasn1.
[shishi.git] / lib / ticket.c
blob6fb61c87e94a9707c4bce04b9a42b21128404868
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, char **realm, size_t * realmlen)
39 return shishi_asn1_read2 (handle, ticket, "realm", realm, realmlen);
42 /**
43 * shishi_ticket_realm_set:
44 * @handle: shishi handle as allocated by shishi_init().
45 * @ticket: input variable with ticket info.
46 * @realm: input array with name of realm.
48 * Set the realm field in the Ticket.
50 * Return value: Returns SHISHI_OK iff successful.
51 **/
52 int
53 shishi_ticket_realm_set (Shishi * handle, Shishi_asn1 ticket,
54 const char *realm)
56 int res;
58 res = shishi_asn1_write (handle, ticket, "realm", realm, 0);
59 if (res != SHISHI_OK)
60 return res;
62 return SHISHI_OK;
65 int
66 shishi_ticket_sname_get (Shishi * handle,
67 Shishi_asn1 ticket, char *server, size_t * serverlen)
69 return shishi_principal_name_get (handle, ticket, "sname",
70 server, serverlen);
73 /**
74 * shishi_ticket_sname_set:
75 * @handle: shishi handle as allocated by shishi_init().
76 * @ticket: Ticket variable to set server name field in.
77 * @name_type: type of principial, see Shishi_name_type, usually
78 * SHISHI_NT_UNKNOWN.
79 * @sname: input array with principal name.
81 * Set the server name field in the Ticket.
83 * Return value: Returns SHISHI_OK iff successful.
84 **/
85 int
86 shishi_ticket_sname_set (Shishi * handle,
87 Shishi_asn1 ticket,
88 Shishi_name_type name_type, char *sname[])
90 int res = SHISHI_OK;
91 char *buf;
92 int i;
94 asprintf (&buf, "%d", name_type);
95 res = shishi_asn1_write (handle, ticket, "sname.name-type", buf, 0);
96 free (buf);
97 if (res != SHISHI_OK)
98 return res;
100 res = shishi_asn1_write (handle, ticket, "sname.name-string", NULL, 0);
101 if (res != SHISHI_OK)
102 return res;
104 i = 1;
105 while (sname[i - 1])
107 res = shishi_asn1_write (handle, ticket, "sname.name-string", "NEW", 1);
108 if (res != SHISHI_OK)
109 return res;
111 asprintf (&buf, "sname.name-string.?%d", i);
112 res = shishi_asn1_write (handle, ticket, buf, sname[i - 1], 0);
113 free (buf);
114 if (res != SHISHI_OK)
115 return res;
117 i++;
120 return SHISHI_OK;
124 shishi_ticket_set_server (Shishi * handle,
125 Shishi_asn1 ticket, const char *server)
127 char *tmpserver;
128 char **serverbuf;
129 char *tokptr;
130 int res;
131 int i;
133 tmpserver = xstrdup (server);
134 serverbuf = xmalloc (sizeof (*serverbuf));
136 for (i = 0;
137 (serverbuf[i] = strtok_r (i == 0 ? tmpserver : NULL, "/", &tokptr));
138 i++)
140 serverbuf = xrealloc (serverbuf, (i + 2) * sizeof (*serverbuf));
142 res = shishi_ticket_sname_set (handle, ticket,
143 SHISHI_NT_PRINCIPAL, serverbuf);
144 if (res != SHISHI_OK)
146 fprintf (stderr, _("Could not set sname: %s\n"), shishi_error (handle));
147 return res;
149 free (serverbuf);
150 free (tmpserver);
152 return SHISHI_OK;
156 shishi_ticket_snamerealm_get (Shishi * handle,
157 Shishi_asn1 ticket,
158 char *serverrealm, size_t * serverrealmlen)
160 return shishi_principal_name_realm_get (handle, ticket, "sname",
161 ticket, "realm",
162 serverrealm, serverrealmlen);
166 shishi_ticket_srealmserver_set (Shishi * handle,
167 Shishi_asn1 ticket, char *realm, char *server)
169 int res;
171 res = shishi_ticket_realm_set (handle, ticket, realm);
172 if (res != SHISHI_OK)
173 return res;
175 res = shishi_ticket_set_server (handle, ticket, server);
176 if (res != SHISHI_OK)
177 return res;
179 return SHISHI_OK;
183 * shishi_ticket_get_enc_part_etype:
184 * @handle: shishi handle as allocated by shishi_init().
185 * @ticket: Ticket variable to get value from.
186 * @etype: output variable that holds the value.
188 * Extract Ticket.enc-part.etype.
190 * Return value: Returns SHISHI_OK iff successful.
193 shishi_ticket_get_enc_part_etype (Shishi * handle,
194 Shishi_asn1 ticket, int32_t * etype)
196 int res;
198 res = shishi_asn1_read_int32 (handle, ticket, "enc-part.etype", etype);
200 return res;
204 shishi_ticket_decrypt (Shishi * handle,
205 Shishi_asn1 ticket,
206 Shishi_key * key, Shishi_asn1 * encticketpart)
208 int res;
209 int i;
210 char *buf;
211 size_t buflen;
212 char *cipher;
213 size_t cipherlen;
214 int etype;
216 res = shishi_ticket_get_enc_part_etype (handle, ticket, &etype);
217 if (res != SHISHI_OK)
218 return res;
220 if (etype != shishi_key_type (key))
221 return SHISHI_TICKET_BAD_KEYTYPE;
223 res = shishi_asn1_read2 (handle, ticket, "enc-part.cipher",
224 &cipher, &cipherlen);
225 if (res != SHISHI_OK)
226 return res;
228 res = shishi_decrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
229 cipher, cipherlen, &buf, &buflen);
230 free (cipher);
231 if (res != SHISHI_OK)
233 shishi_error_printf (handle,
234 "Ticket decrypt failed, wrong password?\n");
235 return SHISHI_TICKET_DECRYPT_FAILED;
238 /* The crypto is so 1980; no length indicator. Trim off pad bytes
239 until we can parse it. */
240 for (i = 0; i < 8; i++)
242 if (VERBOSEASN1 (handle))
243 printf ("Trying with %d pad in enckdcrep...\n", i);
245 *encticketpart = shishi_der2asn1_encticketpart (handle, &buf[0],
246 buflen - i);
247 if (*encticketpart != NULL)
248 break;
251 if (*encticketpart == NULL)
253 shishi_error_printf (handle, "Could not DER decode EncTicketPart. "
254 "Password probably correct (decrypt ok) though\n");
255 return SHISHI_ASN1_ERROR;
258 return SHISHI_OK;
262 * shishi_ticket_set_enc_part:
263 * @handle: shishi handle as allocated by shishi_init().
264 * @ticket: Ticket to add enc-part field to.
265 * @etype: encryption type used to encrypt enc-part.
266 * @kvno: key version number.
267 * @buf: input array with encrypted enc-part.
268 * @buflen: size of input array with encrypted enc-part.
270 * Set the encrypted enc-part field in the Ticket. The encrypted data
271 * is usually created by calling shishi_encrypt() on the DER encoded
272 * enc-part. To save time, you may want to use
273 * shishi_ticket_add_enc_part() instead, which calculates the
274 * encrypted data and calls this function in one step.
276 * Return value: Returns SHISHI_OK iff successful.
279 shishi_ticket_set_enc_part (Shishi * handle,
280 Shishi_asn1 ticket,
281 int etype, int kvno, char *buf, size_t buflen)
283 int res = SHISHI_OK;
285 res = shishi_asn1_write (handle, ticket, "enc-part.cipher", buf, buflen);
286 if (res != SHISHI_OK)
287 return res;
289 res = shishi_asn1_write_int32 (handle, ticket, "enc-part.etype", etype);
290 if (res != SHISHI_OK)
291 return res;
293 if (kvno == 0)
294 res = shishi_asn1_write (handle, ticket, "enc-part.kvno", NULL, 0);
295 else
296 res = shishi_asn1_write_uint32 (handle, ticket, "enc-part.kvno", kvno);
297 if (res != SHISHI_OK)
298 return res;
300 return SHISHI_OK;
304 * shishi_ticket_add_enc_part:
305 * @handle: shishi handle as allocated by shishi_init().
306 * @ticket: Ticket to add enc-part field to.
307 * @key: key used to encrypt enc-part.
308 * @encticketpart: EncTicketPart to add.
310 * Encrypts DER encoded EncTicketPart using key and stores it in the
311 * Ticket.
313 * Return value: Returns SHISHI_OK iff successful.
316 shishi_ticket_add_enc_part (Shishi * handle,
317 Shishi_asn1 ticket,
318 Shishi_key * key, Shishi_asn1 encticketpart)
320 int res = SHISHI_OK;
321 char *buf;
322 size_t buflen;
323 char *der;
324 size_t derlen;
326 res = shishi_new_a2d (handle, encticketpart, &der, &derlen);
327 if (res != SHISHI_OK)
329 shishi_error_printf (handle, "Could not DER encode encticketpart: %s\n",
330 shishi_strerror (res));
331 return res;
334 res = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
335 der, derlen, &buf, &buflen);
337 free (der);
339 if (res != SHISHI_OK)
341 shishi_error_printf (handle,
342 "Cannot encrypt encrypted part of ticket\n");
343 return res;
346 res = shishi_ticket_set_enc_part (handle, ticket, shishi_key_type (key),
347 shishi_key_version (key), buf, buflen);
349 free (buf);
351 return res;