1 /* ticket.c --- Low-level ASN.1 Ticket handling.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but
12 * 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, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
25 #define SHISHI_TICKET_DEFAULT_TKTVNO "5"
26 #define SHISHI_TICKET_DEFAULT_TKTVNO_LEN 0
30 * @handle: shishi handle as allocated by shishi_init().
32 * This function creates a new ASN.1 Ticket, populated with some
35 * Return value: Returns the ticket or NULL on failure.
38 shishi_ticket (Shishi
* handle
)
40 Shishi_asn1 node
= NULL
;
43 node
= shishi_asn1_ticket (handle
);
47 rc
= shishi_asn1_write (handle
, node
, "tkt-vno",
48 SHISHI_TICKET_DEFAULT_TKTVNO
,
49 SHISHI_TICKET_DEFAULT_TKTVNO_LEN
);
56 shishi_asn1_done (handle
, node
);
61 * shishi_ticket_realm_get:
62 * @handle: shishi handle as allocated by shishi_init().
63 * @ticket: input variable with ticket info.
64 * @realm: output array with newly allocated name of realm in ticket.
65 * @realmlen: size of output array.
67 * Extract realm from ticket.
69 * Return value: Returns SHISHI_OK iff successful.
72 shishi_ticket_realm_get (Shishi
* handle
,
73 Shishi_asn1 ticket
, char **realm
, size_t * realmlen
)
75 return shishi_asn1_read (handle
, ticket
, "realm", realm
, realmlen
);
79 * shishi_ticket_realm_set:
80 * @handle: shishi handle as allocated by shishi_init().
81 * @ticket: input variable with ticket info.
82 * @realm: input array with name of realm.
84 * Set the realm field in the Ticket.
86 * Return value: Returns SHISHI_OK iff successful.
89 shishi_ticket_realm_set (Shishi
* handle
, Shishi_asn1 ticket
,
94 res
= shishi_asn1_write (handle
, ticket
, "realm", realm
, 0);
102 * shishi_ticket_server:
103 * @handle: Shishi library handle create by shishi_init().
104 * @ticket: ASN.1 Ticket variable to get server name from.
105 * @server: pointer to newly allocated zero terminated string containing
106 * principal name. May be %NULL (to only populate @serverlen).
107 * @serverlen: pointer to length of @server on output, excluding terminating
108 * zero. May be %NULL (to only populate @server).
110 * Represent server principal name in Ticket as zero-terminated
111 * string. The string is allocate by this function, and it is the
112 * responsibility of the caller to deallocate it. Note that the
113 * output length @serverlen does not include the terminating zero.
115 * Return value: Returns SHISHI_OK iff successful.
118 shishi_ticket_server (Shishi
* handle
, Shishi_asn1 ticket
,
119 char **server
, size_t * serverlen
)
121 return shishi_principal_name (handle
, ticket
, "sname", server
, serverlen
);
125 * shishi_ticket_sname_set:
126 * @handle: shishi handle as allocated by shishi_init().
127 * @ticket: Ticket variable to set server name field in.
128 * @name_type: type of principial, see Shishi_name_type, usually
130 * @sname: input array with principal name.
132 * Set the server name field in the Ticket.
134 * Return value: Returns SHISHI_OK iff successful.
137 shishi_ticket_sname_set (Shishi
* handle
,
139 Shishi_name_type name_type
, char *sname
[])
145 asprintf (&buf
, "%d", name_type
);
146 res
= shishi_asn1_write (handle
, ticket
, "sname.name-type", buf
, 0);
148 if (res
!= SHISHI_OK
)
151 res
= shishi_asn1_write (handle
, ticket
, "sname.name-string", NULL
, 0);
152 if (res
!= SHISHI_OK
)
158 res
= shishi_asn1_write (handle
, ticket
, "sname.name-string", "NEW", 1);
159 if (res
!= SHISHI_OK
)
162 asprintf (&buf
, "sname.name-string.?%d", i
);
163 res
= shishi_asn1_write (handle
, ticket
, buf
, sname
[i
- 1], 0);
165 if (res
!= SHISHI_OK
)
175 shishi_ticket_set_server (Shishi
* handle
,
176 Shishi_asn1 ticket
, const char *server
)
184 tmpserver
= xstrdup (server
);
185 serverbuf
= xmalloc (sizeof (*serverbuf
));
188 (serverbuf
[i
] = strtok_r (i
== 0 ? tmpserver
: NULL
, "/", &tokptr
));
191 serverbuf
= xrealloc (serverbuf
, (i
+ 2) * sizeof (*serverbuf
));
193 res
= shishi_ticket_sname_set (handle
, ticket
,
194 SHISHI_NT_PRINCIPAL
, serverbuf
);
195 if (res
!= SHISHI_OK
)
197 fprintf (stderr
, _("Could not set sname: %s\n"), shishi_error (handle
));
207 shishi_ticket_srealmserver_set (Shishi
* handle
,
209 const char *realm
, const char *server
)
213 res
= shishi_ticket_realm_set (handle
, ticket
, realm
);
214 if (res
!= SHISHI_OK
)
217 res
= shishi_ticket_set_server (handle
, ticket
, server
);
218 if (res
!= SHISHI_OK
)
225 * shishi_ticket_get_enc_part_etype:
226 * @handle: shishi handle as allocated by shishi_init().
227 * @ticket: Ticket variable to get value from.
228 * @etype: output variable that holds the value.
230 * Extract Ticket.enc-part.etype.
232 * Return value: Returns SHISHI_OK iff successful.
235 shishi_ticket_get_enc_part_etype (Shishi
* handle
,
236 Shishi_asn1 ticket
, int32_t * etype
)
240 res
= shishi_asn1_read_int32 (handle
, ticket
, "enc-part.etype", etype
);
246 shishi_ticket_decrypt (Shishi
* handle
,
248 Shishi_key
* key
, Shishi_asn1
* encticketpart
)
258 res
= shishi_ticket_get_enc_part_etype (handle
, ticket
, &etype
);
259 if (res
!= SHISHI_OK
)
262 if (etype
!= shishi_key_type (key
))
263 return SHISHI_TICKET_BAD_KEYTYPE
;
265 res
= shishi_asn1_read (handle
, ticket
, "enc-part.cipher",
266 &cipher
, &cipherlen
);
267 if (res
!= SHISHI_OK
)
270 res
= shishi_decrypt (handle
, key
, SHISHI_KEYUSAGE_ENCTICKETPART
,
271 cipher
, cipherlen
, &buf
, &buflen
);
273 if (res
!= SHISHI_OK
)
275 shishi_error_printf (handle
,
276 "Ticket decrypt failed, wrong password?\n");
277 return SHISHI_TICKET_DECRYPT_FAILED
;
280 /* The crypto is so 1980; no length indicator. Trim off pad bytes
281 until we can parse it. */
282 for (i
= 0; i
< 8; i
++)
284 if (VERBOSEASN1 (handle
))
285 printf ("Trying with %d pad in enckdcrep...\n", i
);
287 *encticketpart
= shishi_der2asn1_encticketpart (handle
, &buf
[0],
289 if (*encticketpart
!= NULL
)
293 if (*encticketpart
== NULL
)
295 shishi_error_printf (handle
, "Could not DER decode EncTicketPart. "
296 "Password probably correct (decrypt ok) though\n");
297 return SHISHI_ASN1_ERROR
;
304 * shishi_ticket_set_enc_part:
305 * @handle: shishi handle as allocated by shishi_init().
306 * @ticket: Ticket to add enc-part field to.
307 * @etype: encryption type used to encrypt enc-part.
308 * @kvno: key version number.
309 * @buf: input array with encrypted enc-part.
310 * @buflen: size of input array with encrypted enc-part.
312 * Set the encrypted enc-part field in the Ticket. The encrypted data
313 * is usually created by calling shishi_encrypt() on the DER encoded
314 * enc-part. To save time, you may want to use
315 * shishi_ticket_add_enc_part() instead, which calculates the
316 * encrypted data and calls this function in one step.
318 * Return value: Returns SHISHI_OK iff successful.
321 shishi_ticket_set_enc_part (Shishi
* handle
,
323 int32_t etype
, uint32_t kvno
,
324 const char *buf
, size_t buflen
)
328 res
= shishi_asn1_write (handle
, ticket
, "enc-part.cipher", buf
, buflen
);
329 if (res
!= SHISHI_OK
)
332 res
= shishi_asn1_write_int32 (handle
, ticket
, "enc-part.etype", etype
);
333 if (res
!= SHISHI_OK
)
336 if (kvno
== UINT32_MAX
)
337 res
= shishi_asn1_write (handle
, ticket
, "enc-part.kvno", NULL
, 0);
339 res
= shishi_asn1_write_uint32 (handle
, ticket
, "enc-part.kvno", kvno
);
340 if (res
!= SHISHI_OK
)
347 * shishi_ticket_add_enc_part:
348 * @handle: shishi handle as allocated by shishi_init().
349 * @ticket: Ticket to add enc-part field to.
350 * @key: key used to encrypt enc-part.
351 * @encticketpart: EncTicketPart to add.
353 * Encrypts DER encoded EncTicketPart using key and stores it in the
356 * Return value: Returns SHISHI_OK iff successful.
359 shishi_ticket_add_enc_part (Shishi
* handle
,
361 Shishi_key
* key
, Shishi_asn1 encticketpart
)
369 res
= shishi_asn1_to_der (handle
, encticketpart
, &der
, &derlen
);
370 if (res
!= SHISHI_OK
)
372 shishi_error_printf (handle
, "Could not DER encode encticketpart: %s\n",
373 shishi_strerror (res
));
377 res
= shishi_encrypt (handle
, key
, SHISHI_KEYUSAGE_ENCTICKETPART
,
378 der
, derlen
, &buf
, &buflen
);
382 if (res
!= SHISHI_OK
)
384 shishi_error_printf (handle
,
385 "Cannot encrypt encrypted part of ticket\n");
389 res
= shishi_ticket_set_enc_part (handle
, ticket
, shishi_key_type (key
),
390 shishi_key_version (key
), buf
, buflen
);