Use new libtasn1 API.
[shishi.git] / lib / ticket.c
blob3cec66a403a431b5b0f9dbb847094a00320e7218
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, int *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",
90 NULL, 0);
91 if (res != SHISHI_OK)
92 return res;
94 i = 1;
95 while (sname[i - 1])
97 res = shishi_asn1_write (handle, ticket, "sname.name-string",
98 "NEW", 1);
99 if (res != SHISHI_OK)
100 return res;
102 sprintf (buf, "sname.name-string.?%d", i);
103 res = shishi_asn1_write (handle, ticket, buf, sname[i - 1], 0);
104 if (res != SHISHI_OK)
105 return res;
107 i++;
110 return SHISHI_OK;
114 shishi_ticket_set_server (Shishi * handle,
115 Shishi_asn1 ticket, const char *server)
117 char *tmpserver;
118 char **serverbuf;
119 char *tokptr;
120 int res;
121 int i;
123 tmpserver = strdup (server);
124 if (tmpserver == NULL)
125 return SHISHI_MALLOC_ERROR;
127 serverbuf = malloc (sizeof (*serverbuf));
128 for (i = 0;
129 (serverbuf[i] = strtok_r (i == 0 ? tmpserver : NULL, "/", &tokptr));
130 i++)
132 serverbuf = realloc (serverbuf, (i + 2) * sizeof (*serverbuf));
133 if (serverbuf == NULL)
134 return SHISHI_MALLOC_ERROR;
136 res = shishi_ticket_sname_set (handle, ticket,
137 SHISHI_NT_PRINCIPAL, serverbuf);
138 if (res != SHISHI_OK)
140 fprintf (stderr, _("Could not set sname: %s\n"),
141 shishi_strerror_details (handle));
142 return res;
144 free (serverbuf);
145 free (tmpserver);
147 return SHISHI_OK;
151 shishi_ticket_snamerealm_get (Shishi * handle,
152 Shishi_asn1 ticket,
153 char *serverrealm, int *serverrealmlen)
155 return shishi_principal_name_realm_get (handle, ticket, "sname",
156 ticket, "realm",
157 serverrealm, serverrealmlen);
161 shishi_ticket_srealmserver_set (Shishi * handle,
162 Shishi_asn1 ticket, char *realm, char *server)
164 int res;
166 res = shishi_ticket_realm_set (handle, ticket, realm);
167 if (res != SHISHI_OK)
168 return res;
170 res = shishi_ticket_set_server (handle, ticket, server);
171 if (res != SHISHI_OK)
172 return res;
174 return SHISHI_OK;
178 * shishi_ticket_get_enc_part_etype:
179 * @handle: shishi handle as allocated by shishi_init().
180 * @kdcrep: Ticket variable to get value from.
181 * @etype: output variable that holds the value.
183 * Extract Ticket.enc-part.etype.
185 * Return value: Returns SHISHI_OK iff successful.
188 shishi_ticket_get_enc_part_etype (Shishi * handle,
189 Shishi_asn1 ticket, int *etype)
191 int buflen;
192 int res;
194 *etype = 0;
195 buflen = sizeof (*etype);
196 res = shishi_asn1_field (handle, ticket,
197 (char *) etype, &buflen, "enc-part.etype");
199 return res;
203 shishi_ticket_decrypt (Shishi * handle,
204 Shishi_asn1 ticket,
205 Shishi_key * key, Shishi_asn1 * encticketpart)
207 int res;
208 int i;
209 int buflen = BUFSIZ;
210 unsigned char buf[BUFSIZ];
211 unsigned char cipher[BUFSIZ];
212 int cipherlen;
213 int etype;
215 res = shishi_ticket_get_enc_part_etype (handle, ticket, &etype);
216 if (res != SHISHI_OK)
217 return res;
219 if (etype != shishi_key_type (key))
220 return SHISHI_TICKET_BAD_KEYTYPE;
222 cipherlen = BUFSIZ;
223 res = shishi_asn1_field (handle, ticket, cipher, &cipherlen,
224 "enc-part.cipher");
225 if (res != SHISHI_OK)
226 return res;
228 res = shishi_decrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
229 cipher, cipherlen, buf, &buflen);
231 if (res != SHISHI_OK)
233 if (VERBOSE (handle))
234 printf ("des_decrypt failed: %s\n", shishi_strerror_details (handle));
235 shishi_error_printf (handle,
236 "des_decrypt fail, most likely 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, int buflen)
285 char *format;
286 int res = SHISHI_OK;
288 res = shishi_asn1_write (handle, ticket, "enc-part.cipher",
289 buf, buflen);
290 if (res != SHISHI_OK)
291 return res;
293 shishi_asprintf (&format, "%d", etype);
294 res = shishi_asn1_write (handle, ticket, "enc-part.etype",
295 format, 0);
296 free (format);
297 if (res != SHISHI_OK)
298 return res;
300 if (kvno == 0)
301 res = shishi_asn1_write (handle, ticket, "enc-part.kvno", NULL, 0);
302 else
304 shishi_asprintf (&format, "%d", etype);
305 res = shishi_asn1_write (handle, ticket, "enc-part.kvno",
306 format, 0);
307 free (format);
309 if (res != SHISHI_OK)
310 return res;
312 return SHISHI_OK;
316 * shishi_ticket_add_enc_part:
317 * @handle: shishi handle as allocated by shishi_init().
318 * @ticket: Ticket to add enc-part field to.
319 * @key: key used to encrypt enc-part.
320 * @encticketpart: EncTicketPart to add.
322 * Encrypts DER encoded EncTicketPart using key and stores it in the
323 * Ticket.
325 * Return value: Returns SHISHI_OK iff successful.
328 shishi_ticket_add_enc_part (Shishi * handle,
329 Shishi_asn1 ticket,
330 Shishi_key * key, Shishi_asn1 encticketpart)
332 int res = SHISHI_OK;
333 char buf[BUFSIZ];
334 int buflen;
335 char der[BUFSIZ];
336 size_t derlen;
338 res = shishi_a2d (handle, encticketpart, der, &derlen);
339 if (res != SHISHI_OK)
341 shishi_error_printf (handle, "Could not DER encode encticketpart: %s\n",
342 shishi_strerror (res));
343 return !SHISHI_OK;
346 buflen = BUFSIZ;
347 res = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
348 der, derlen, buf, &buflen);
349 if (res != SHISHI_OK)
351 shishi_error_printf (handle, "des_encrypt fail\n");
352 return res;
355 res = shishi_ticket_set_enc_part (handle, ticket, shishi_key_type (key),
356 shishi_key_version (key), buf, buflen);
358 return res;