1 /* kdcrep.c --- Key distribution (AS/TGS) Reply functions.
2 * Copyright (C) 2002-2013 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
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.
10 *
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.
15 *
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
20 *
21 */
22
23 #include "internal.h"
24
25 /* Get _shishi_print_armored_data, etc. */
26 #include "diskio.h"
27
28 #define SHISHI_KDCREP_DEFAULT_PVNO "5"
29 #define SHISHI_KDCREP_DEFAULT_PVNO_LEN 0
30 #define SHISHI_AS_REP_DEFAULT_MSG_TYPE "11"
31 #define SHISHI_AS_REP_DEFAULT_MSG_TYPE_LEN 0
32 #define SHISHI_TGS_REP_DEFAULT_MSG_TYPE "13"
33 #define SHISHI_TGS_REP_DEFAULT_MSG_TYPE_LEN 0
34
35 static Shishi_asn1
_shishi_kdcrep(Shishi * handle,int as)36 _shishi_kdcrep (Shishi * handle, int as)
37 {
38 int res;
39 Shishi_asn1 node;
40
41 if (as)
42 node = shishi_asn1_asrep (handle);
43 else
44 node = shishi_asn1_tgsrep (handle);
45 if (!node)
46 return NULL;
47
48 res = shishi_asn1_write (handle, node, "pvno",
49 SHISHI_KDCREP_DEFAULT_PVNO,
50 SHISHI_KDCREP_DEFAULT_PVNO_LEN);
51 if (res != SHISHI_OK)
52 goto error;
53
54 if (as)
55 res = shishi_asn1_write (handle, node, "msg-type",
56 SHISHI_AS_REP_DEFAULT_MSG_TYPE,
57 SHISHI_AS_REP_DEFAULT_MSG_TYPE_LEN);
58 else
59 res = shishi_asn1_write (handle, node, "msg-type",
60 SHISHI_TGS_REP_DEFAULT_MSG_TYPE,
61 SHISHI_TGS_REP_DEFAULT_MSG_TYPE_LEN);
62 if (res != SHISHI_OK)
63 goto error;
64
65 return node;
66
67 error:
68 shishi_asn1_done (handle, node);
69 return NULL;
70 }
71
72 /**
73 * shishi_asrep:
74 * @handle: shishi handle as allocated by shishi_init().
75 *
76 * This function creates a new AS-REP, populated with some default
77 * values.
78 *
79 * Return value: Returns the AS-REP or NULL on failure.
80 **/
81 Shishi_asn1
shishi_asrep(Shishi * handle)82 shishi_asrep (Shishi * handle)
83 {
84 return _shishi_kdcrep (handle, 1);
85 }
86
87 /**
88 * shishi_tgsrep:
89 * @handle: shishi handle as allocated by shishi_init().
90 *
91 * This function creates a new TGS-REP, populated with some default
92 * values.
93 *
94 * Return value: Returns the TGS-REP or NULL on failure.
95 **/
96 Shishi_asn1
shishi_tgsrep(Shishi * handle)97 shishi_tgsrep (Shishi * handle)
98 {
99 return _shishi_kdcrep (handle, 0);
100 }
101
102
103 /**
104 * shishi_kdcrep_print:
105 * @handle: shishi handle as allocated by shishi_init().
106 * @fh: file handle open for writing.
107 * @kdcrep: KDC-REP to print.
108 *
109 * Print ASCII armored DER encoding of KDC-REP to file.
110 *
111 * Return value: Returns SHISHI_OK iff successful.
112 **/
113 int
shishi_kdcrep_print(Shishi * handle,FILE * fh,Shishi_asn1 kdcrep)114 shishi_kdcrep_print (Shishi * handle, FILE * fh, Shishi_asn1 kdcrep)
115 {
116 return _shishi_print_armored_data (handle, fh, kdcrep, "KDC-REP", NULL);
117 }
118
119 /**
120 * shishi_kdcrep_save:
121 * @handle: shishi handle as allocated by shishi_init().
122 * @fh: file handle open for writing.
123 * @kdcrep: KDC-REP to save.
124 *
125 * Print DER encoding of KDC-REP to file.
126 *
127 * Return value: Returns SHISHI_OK iff successful.
128 **/
129 int
shishi_kdcrep_save(Shishi * handle,FILE * fh,Shishi_asn1 kdcrep)130 shishi_kdcrep_save (Shishi * handle, FILE * fh, Shishi_asn1 kdcrep)
131 {
132 return _shishi_save_data (handle, fh, kdcrep, "KDC-REP");
133 }
134
135 /**
136 * shishi_kdcrep_to_file:
137 * @handle: shishi handle as allocated by shishi_init().
138 * @kdcrep: KDC-REP to save.
139 * @filetype: input variable specifying type of file to be written,
140 * see Shishi_filetype.
141 * @filename: input variable with filename to write to.
142 *
143 * Write KDC-REP to file in specified TYPE. The file will be truncated
144 * if it exists.
145 *
146 * Return value: Returns SHISHI_OK iff successful.
147 **/
148 int
shishi_kdcrep_to_file(Shishi * handle,Shishi_asn1 kdcrep,int filetype,const char * filename)149 shishi_kdcrep_to_file (Shishi * handle, Shishi_asn1 kdcrep,
150 int filetype, const char *filename)
151 {
152 FILE *fh;
153 int res;
154
155 if (VERBOSE (handle))
156 printf (_("Writing KDC-REP to %s...\n"), filename);
157
158 fh = fopen (filename, "w");
159 if (fh == NULL)
160 return SHISHI_FOPEN_ERROR;
161
162 if (VERBOSE (handle))
163 printf (_("Writing KDC-REP in %s format...\n"),
164 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
165
166 if (filetype == SHISHI_FILETYPE_TEXT)
167 res = shishi_kdcrep_print (handle, fh, kdcrep);
168 else
169 res = shishi_kdcrep_save (handle, fh, kdcrep);
170 if (res != SHISHI_OK)
171 return res;
172
173 res = fclose (fh);
174 if (res != 0)
175 return SHISHI_IO_ERROR;
176
177 if (VERBOSE (handle))
178 printf (_("Writing KDC-REP to %s...done\n"), filename);
179
180 return SHISHI_OK;
181 }
182
183 /**
184 * shishi_kdcrep_parse:
185 * @handle: shishi handle as allocated by shishi_init().
186 * @fh: file handle open for reading.
187 * @kdcrep: output variable with newly allocated KDC-REP.
188 *
189 * Read ASCII armored DER encoded KDC-REP from file and populate given
190 * variable.
191 *
192 * Return value: Returns SHISHI_OK iff successful.
193 **/
194 int
shishi_kdcrep_parse(Shishi * handle,FILE * fh,Shishi_asn1 * kdcrep)195 shishi_kdcrep_parse (Shishi * handle, FILE * fh, Shishi_asn1 * kdcrep)
196 {
197 return _shishi_kdcrep_input (handle, fh, kdcrep, 0);
198 }
199
200 /**
201 * shishi_kdcrep_read:
202 * @handle: shishi handle as allocated by shishi_init().
203 * @fh: file handle open for reading.
204 * @kdcrep: output variable with newly allocated KDC-REP.
205 *
206 * Read DER encoded KDC-REP from file and populate given variable.
207 *
208 * Return value: Returns SHISHI_OK iff successful.
209 **/
210 int
shishi_kdcrep_read(Shishi * handle,FILE * fh,Shishi_asn1 * kdcrep)211 shishi_kdcrep_read (Shishi * handle, FILE * fh, Shishi_asn1 * kdcrep)
212 {
213 return _shishi_kdcrep_input (handle, fh, kdcrep, 1);
214 }
215
216 /**
217 * shishi_kdcrep_from_file:
218 * @handle: shishi handle as allocated by shishi_init().
219 * @kdcrep: output variable with newly allocated KDC-REP.
220 * @filetype: input variable specifying type of file to be read,
221 * see Shishi_filetype.
222 * @filename: input variable with filename to read from.
223 *
224 * Read KDC-REP from file in specified TYPE.
225 *
226 * Return value: Returns SHISHI_OK iff successful.
227 **/
228 int
shishi_kdcrep_from_file(Shishi * handle,Shishi_asn1 * kdcrep,int filetype,const char * filename)229 shishi_kdcrep_from_file (Shishi * handle, Shishi_asn1 * kdcrep,
230 int filetype, const char *filename)
231 {
232 int res;
233 FILE *fh;
234
235 if (VERBOSE (handle))
236 printf (_("Reading KDC-REP from %s...\n"), filename);
237
238 fh = fopen (filename, "r");
239 if (fh == NULL)
240 return SHISHI_FOPEN_ERROR;
241
242 if (VERBOSE (handle))
243 printf (_("Reading KDC-REP in %s format...\n"),
244 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
245
246 if (filetype == SHISHI_FILETYPE_TEXT)
247 res = shishi_kdcrep_parse (handle, fh, kdcrep);
248 else
249 res = shishi_kdcrep_read (handle, fh, kdcrep);
250 if (res != SHISHI_OK)
251 return res;
252
253 res = fclose (fh);
254 if (res != 0)
255 return SHISHI_IO_ERROR;
256
257 if (VERBOSE (handle))
258 printf (_("Reading KDC-REP from %s...done\n"), filename);
259
260 return SHISHI_OK;
261 }
262
263 /**
264 * shishi_kdcrep_crealm_set:
265 * @handle: shishi handle as allocated by shishi_init().
266 * @kdcrep: Kdcrep variable to set realm field in.
267 * @crealm: input array with name of realm.
268 *
269 * Set the client realm field in the KDC-REP.
270 *
271 * Return value: Returns SHISHI_OK iff successful.
272 **/
273 int
shishi_kdcrep_crealm_set(Shishi * handle,Shishi_asn1 kdcrep,const char * crealm)274 shishi_kdcrep_crealm_set (Shishi * handle,
275 Shishi_asn1 kdcrep, const char *crealm)
276 {
277 int res;
278
279 res = shishi_asn1_write (handle, kdcrep, "crealm", crealm, 0);
280 if (res != SHISHI_OK)
281 return res;
282
283 return SHISHI_OK;
284 }
285
286 /**
287 * shishi_kdcrep_cname_set:
288 * @handle: shishi handle as allocated by shishi_init().
289 * @kdcrep: Kdcrep variable to set server name field in.
290 * @name_type: type of principial, see Shishi_name_type, usually
291 * SHISHI_NT_UNKNOWN.
292 * @cname: input array with principal name.
293 *
294 * Set the client name field in the KDC-REP.
295 *
296 * Return value: Returns SHISHI_OK iff successful.
297 **/
298 int
shishi_kdcrep_cname_set(Shishi * handle,Shishi_asn1 kdcrep,Shishi_name_type name_type,const char * cname[])299 shishi_kdcrep_cname_set (Shishi * handle,
300 Shishi_asn1 kdcrep,
301 Shishi_name_type name_type, const char *cname[])
302 {
303 int res;
304
305 res = shishi_principal_name_set (handle, kdcrep, "cname", name_type, cname);
306 if (res != SHISHI_OK)
307 return res;
308
309 return SHISHI_OK;
310 }
311
312 /**
313 * shishi_kdcrep_client_set:
314 * @handle: shishi handle as allocated by shishi_init().
315 * @kdcrep: Kdcrep variable to set server name field in.
316 * @client: zero-terminated string with principal name on RFC 1964 form.
317 *
318 * Set the client name field in the KDC-REP.
319 *
320 * Return value: Returns SHISHI_OK iff successful.
321 **/
322 int
shishi_kdcrep_client_set(Shishi * handle,Shishi_asn1 kdcrep,const char * client)323 shishi_kdcrep_client_set (Shishi * handle,
324 Shishi_asn1 kdcrep, const char *client)
325 {
326 int res;
327
328 res = shishi_principal_set (handle, kdcrep, "cname", client);
329 if (res != SHISHI_OK)
330 return res;
331
332 return SHISHI_OK;
333 }
334
335 int
shishi_kdcrep_crealmserver_set(Shishi * handle,Shishi_asn1 kdcrep,const char * crealm,const char * client)336 shishi_kdcrep_crealmserver_set (Shishi * handle,
337 Shishi_asn1 kdcrep,
338 const char *crealm, const char *client)
339 {
340 int res;
341
342 res = shishi_kdcrep_crealm_set (handle, kdcrep, crealm);
343 if (res != SHISHI_OK)
344 return res;
345
346 res = shishi_kdcrep_client_set (handle, kdcrep, client);
347 if (res != SHISHI_OK)
348 return res;
349
350 return SHISHI_OK;
351 }
352
353 /**
354 * shishi_kdcrep_get_enc_part_etype:
355 * @handle: shishi handle as allocated by shishi_init().
356 * @kdcrep: KDC-REP variable to get value from.
357 * @etype: output variable that holds the value.
358 *
359 * Extract KDC-REP.enc-part.etype.
360 *
361 * Return value: Returns SHISHI_OK iff successful.
362 **/
363 int
shishi_kdcrep_get_enc_part_etype(Shishi * handle,Shishi_asn1 kdcrep,int32_t * etype)364 shishi_kdcrep_get_enc_part_etype (Shishi * handle,
365 Shishi_asn1 kdcrep, int32_t * etype)
366 {
367 return shishi_asn1_read_int32 (handle, kdcrep, "enc-part.etype", etype);
368 }
369
370 /**
371 * shishi_kdcrep_get_ticket:
372 * @handle: shishi handle as allocated by shishi_init().
373 * @kdcrep: KDC-REP variable to get ticket from.
374 * @ticket: output variable to hold extracted ticket.
375 *
376 * Extract ticket from KDC-REP.
377 *
378 * Return value: Returns SHISHI_OK iff successful.
379 **/
380 int
shishi_kdcrep_get_ticket(Shishi * handle,Shishi_asn1 kdcrep,Shishi_asn1 * ticket)381 shishi_kdcrep_get_ticket (Shishi * handle,
382 Shishi_asn1 kdcrep, Shishi_asn1 * ticket)
383 {
384 char *buf;
385 char *format;
386 size_t buflen;
387 int res;
388 size_t i, n;
389
390 /* there's GOT to be an easier way to do this */
391
392 *ticket = shishi_ticket (handle);
393 if (!*ticket)
394 return SHISHI_ASN1_ERROR;
395
396 res = shishi_asn1_read (handle, kdcrep, "ticket.tkt-vno", &buf, &buflen);
397 if (res != SHISHI_OK)
398 goto error;
399
400 res = shishi_asn1_write (handle, *ticket, "tkt-vno", buf, buflen);
401 free (buf);
402 if (res != SHISHI_OK)
403 goto error;
404
405 res = shishi_asn1_read (handle, kdcrep, "ticket.realm", &buf, &buflen);
406 if (res != SHISHI_OK)
407 goto error;
408
409 res = shishi_asn1_write (handle, *ticket, "realm", buf, buflen);
410 free (buf);
411 if (res != SHISHI_OK)
412 goto error;
413
414 res = shishi_asn1_read (handle, kdcrep, "ticket.sname.name-type",
415 &buf, &buflen);
416 if (res != SHISHI_OK)
417 goto error;
418
419 res = shishi_asn1_write (handle, *ticket, "sname.name-type", buf, buflen);
420 free (buf);
421 if (res != SHISHI_OK)
422 goto error;
423
424 res = shishi_asn1_number_of_elements (handle, kdcrep,
425 "ticket.sname.name-string", &n);
426 if (res != SHISHI_OK)
427 goto error;
428
429 for (i = 1; i <= n; i++)
430 {
431 res = shishi_asn1_write (handle, *ticket, "sname.name-string",
432 "NEW", 1);
433 if (res != SHISHI_OK)
434 goto error;
435
436 format = xasprintf ("ticket.sname.name-string.?%d", i);
437 res = shishi_asn1_read (handle, kdcrep, format, &buf, &buflen);
438 free (format);
439 if (res != SHISHI_OK)
440 goto error;
441
442 format = xasprintf ("sname.name-string.?%d", i);
443 res = shishi_asn1_write (handle, *ticket, format, buf, buflen);
444 free (format);
445 free (buf);
446 if (res != SHISHI_OK)
447 goto error;
448 }
449
450 res = shishi_asn1_read (handle, kdcrep, "ticket.enc-part.etype",
451 &buf, &buflen);
452 if (res != SHISHI_OK)
453 goto error;
454
455 res = shishi_asn1_write (handle, *ticket, "enc-part.etype", buf, buflen);
456 free (buf);
457 if (res != SHISHI_OK)
458 goto error;
459
460 res = shishi_asn1_read (handle, kdcrep, "ticket.enc-part.kvno",
461 &buf, &buflen);
462 if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT)
463 goto error;
464
465 if (res == SHISHI_ASN1_NO_ELEMENT)
466 res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", NULL, 0);
467 else
468 {
469 res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", buf, buflen);
470 free (buf);
471 }
472 if (res != SHISHI_OK)
473 goto error;
474
475 res = shishi_asn1_read (handle, kdcrep, "ticket.enc-part.cipher",
476 &buf, &buflen);
477 if (res != SHISHI_OK)
478 goto error;
479
480 res = shishi_asn1_write (handle, *ticket, "enc-part.cipher", buf, buflen);
481 free (buf);
482 if (res != SHISHI_OK)
483 goto error;
484
485 return SHISHI_OK;
486
487 error:
488 shishi_asn1_done (handle, *ticket);
489 return res;
490 }
491
492 /**
493 * shishi_kdcrep_set_ticket:
494 * @handle: shishi handle as allocated by shishi_init().
495 * @kdcrep: KDC-REP to add ticket field to.
496 * @ticket: input ticket to copy into KDC-REP ticket field.
497 *
498 * Copy ticket into KDC-REP.
499 *
500 * Return value: Returns SHISHI_OK iff successful.
501 **/
502 int
shishi_kdcrep_set_ticket(Shishi * handle,Shishi_asn1 kdcrep,Shishi_asn1 ticket)503 shishi_kdcrep_set_ticket (Shishi * handle, Shishi_asn1 kdcrep,
504 Shishi_asn1 ticket)
505 {
506 int res = SHISHI_OK;
507 char *format;
508 char *buf;
509 size_t buflen;
510 size_t i, n;
511
512 res = shishi_asn1_read (handle, ticket, "tkt-vno", &buf, &buflen);
513 if (res != SHISHI_OK)
514 return res;
515
516 res = shishi_asn1_write (handle, kdcrep, "ticket.tkt-vno", buf, buflen);
517 free (buf);
518 if (res != SHISHI_OK)
519 return res;
520
521 res = shishi_asn1_read (handle, ticket, "realm", &buf, &buflen);
522 if (res != SHISHI_OK)
523 return res;
524
525 res = shishi_asn1_write (handle, kdcrep, "ticket.realm", buf, buflen);
526 free (buf);
527 if (res != SHISHI_OK)
528 return res;
529
530 res = shishi_asn1_read (handle, ticket, "sname.name-type", &buf, &buflen);
531 if (res != SHISHI_OK)
532 return res;
533
534 res = shishi_asn1_write (handle, kdcrep, "ticket.sname.name-type",
535 buf, buflen);
536 free (buf);
537 if (res != SHISHI_OK)
538 return res;
539
540 res = shishi_asn1_number_of_elements (handle, ticket,
541 "sname.name-string", &n);
542 if (res != SHISHI_OK)
543 return res;
544
545 for (i = 1; i <= n; i++)
546 {
547 res = shishi_asn1_write (handle, kdcrep,
548 "ticket.sname.name-string", "NEW", 1);
549 if (res != SHISHI_OK)
550 return res;
551
552 format = xasprintf ("sname.name-string.?%d", i);
553 res = shishi_asn1_read (handle, ticket, format, &buf, &buflen);
554 free (format);
555 if (res != SHISHI_OK)
556 return res;
557
558 format = xasprintf ("ticket.sname.name-string.?%d", i);
559 res = shishi_asn1_write (handle, kdcrep, format, buf, buflen);
560 free (format);
561 free (buf);
562 if (res != SHISHI_OK)
563 return res;
564 }
565
566 res = shishi_asn1_read (handle, ticket, "enc-part.etype", &buf, &buflen);
567 if (res != SHISHI_OK)
568 return res;
569
570 res = shishi_asn1_write (handle, kdcrep, "ticket.enc-part.etype",
571 buf, buflen);
572 free (buf);
573 if (res != SHISHI_OK)
574 return res;
575
576 res = shishi_asn1_read (handle, ticket, "enc-part.kvno", &buf, &buflen);
577 if (res != SHISHI_OK)
578 res = shishi_asn1_write (handle, kdcrep, "ticket.enc-part.kvno", NULL, 0);
579 else
580 {
581 res = shishi_asn1_write (handle, kdcrep, "ticket.enc-part.kvno",
582 buf, buflen);
583 free (buf);
584 }
585 if (res != SHISHI_OK)
586 return res;
587
588 res = shishi_asn1_read (handle, ticket, "enc-part.cipher", &buf, &buflen);
589 if (res != SHISHI_OK)
590 return res;
591
592 res = shishi_asn1_write (handle, kdcrep, "ticket.enc-part.cipher",
593 buf, buflen);
594 free (buf);
595 if (res != SHISHI_OK)
596 return res;
597
598 return SHISHI_OK;
599 }
600
601 /**
602 * shishi_kdcrep_set_enc_part:
603 * @handle: shishi handle as allocated by shishi_init().
604 * @kdcrep: KDC-REP to add enc-part field to.
605 * @etype: encryption type used to encrypt enc-part.
606 * @kvno: key version number.
607 * @buf: input array with encrypted enc-part.
608 * @buflen: size of input array with encrypted enc-part.
609 *
610 * Set the encrypted enc-part field in the KDC-REP. The encrypted
611 * data is usually created by calling shishi_encrypt() on the DER
612 * encoded enc-part. To save time, you may want to use
613 * shishi_kdcrep_add_enc_part() instead, which calculates the
614 * encrypted data and calls this function in one step.
615 *
616 * Return value: Returns SHISHI_OK iff successful.
617 **/
618 int
shishi_kdcrep_set_enc_part(Shishi * handle,Shishi_asn1 kdcrep,int32_t etype,uint32_t kvno,const char * buf,size_t buflen)619 shishi_kdcrep_set_enc_part (Shishi * handle,
620 Shishi_asn1 kdcrep,
621 int32_t etype, uint32_t kvno,
622 const char *buf, size_t buflen)
623 {
624 int res = SHISHI_OK;
625
626 res = shishi_asn1_write (handle, kdcrep, "enc-part.cipher", buf, buflen);
627 if (res != SHISHI_OK)
628 return res;
629
630 res = shishi_asn1_write_int32 (handle, kdcrep, "enc-part.etype", etype);
631 if (res != SHISHI_OK)
632 return res;
633
634 if (kvno == UINT32_MAX)
635 res = shishi_asn1_write (handle, kdcrep, "enc-part.kvno", NULL, 0);
636 else
637 res = shishi_asn1_write_uint32 (handle, kdcrep, "enc-part.kvno", kvno);
638 if (res != SHISHI_OK)
639 return res;
640
641 return SHISHI_OK;
642 }
643
644 /**
645 * shishi_kdcrep_add_enc_part:
646 * @handle: shishi handle as allocated by shishi_init().
647 * @kdcrep: KDC-REP to add enc-part field to.
648 * @key: key used to encrypt enc-part.
649 * @keyusage: key usage to use, normally SHISHI_KEYUSAGE_ENCASREPPART,
650 * SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY or
651 * SHISHI_KEYUSAGE_ENCTGSREPPART_AUTHENTICATOR_KEY.
652 * @enckdcreppart: EncKDCRepPart to add.
653 *
654 * Encrypts DER encoded EncKDCRepPart using key and stores it in the
655 * KDC-REP.
656 *
657 * Return value: Returns SHISHI_OK iff successful.
658 **/
659 int
shishi_kdcrep_add_enc_part(Shishi * handle,Shishi_asn1 kdcrep,Shishi_key * key,int keyusage,Shishi_asn1 enckdcreppart)660 shishi_kdcrep_add_enc_part (Shishi * handle,
661 Shishi_asn1 kdcrep,
662 Shishi_key * key,
663 int keyusage, Shishi_asn1 enckdcreppart)
664 {
665 int res = SHISHI_OK;
666 char *buf;
667 size_t buflen;
668 char *der;
669 size_t derlen;
670
671 res = shishi_asn1_to_der (handle, enckdcreppart, &der, &derlen);
672 if (res != SHISHI_OK)
673 {
674 shishi_error_printf (handle, "Could not DER encode enckdcreppart: %s\n",
675 shishi_strerror (res));
676 return SHISHI_ASN1_ERROR;
677 }
678
679 res = shishi_encrypt (handle, key, keyusage, der, derlen, &buf, &buflen);
680
681 free (der);
682
683 if (res != SHISHI_OK)
684 {
685 shishi_error_printf (handle, "Cannot encrypt EncKDCRepPart\n");
686 return res;
687 }
688
689 res = shishi_kdcrep_set_enc_part (handle, kdcrep, shishi_key_type (key),
690 shishi_key_version (key), buf, buflen);
691
692 free (buf);
693
694 return res;
695 }
696
697 int
shishi_kdcrep_decrypt(Shishi * handle,Shishi_asn1 kdcrep,Shishi_key * key,int keyusage,Shishi_asn1 * enckdcreppart)698 shishi_kdcrep_decrypt (Shishi * handle,
699 Shishi_asn1 kdcrep,
700 Shishi_key * key,
701 int keyusage, Shishi_asn1 * enckdcreppart)
702 {
703 int res;
704 int i;
705 char *buf;
706 size_t buflen;
707 char *cipher;
708 size_t cipherlen;
709 int etype;
710
711 res = shishi_kdcrep_get_enc_part_etype (handle, kdcrep, &etype);
712 if (res != SHISHI_OK)
713 return res;
714
715 if (etype != shishi_key_type (key))
716 return SHISHI_KDCREP_BAD_KEYTYPE;
717
718 res = shishi_asn1_read (handle, kdcrep, "enc-part.cipher",
719 &cipher, &cipherlen);
720 if (res != SHISHI_OK)
721 return res;
722
723 res = shishi_decrypt (handle, key, keyusage,
724 cipher, cipherlen, &buf, &buflen);
725 free (cipher);
726 if (res != SHISHI_OK)
727 {
728 shishi_error_printf (handle,
729 "KDCRep decryption failed, wrong password?");
730 return res;
731 }
732
733 /* The crypto is so 1980; no length indicator. Trim off pad bytes
734 until we can parse it. */
735 for (i = 0; i < 8; i++)
736 {
737 if (VERBOSEASN1 (handle))
738 printf ("Trying with %d pad in enckdcrep...\n", i);
739
740 *enckdcreppart = shishi_der2asn1_encasreppart (handle, &buf[0],
741 buflen - i);
742 if (*enckdcreppart != NULL)
743 break;
744
745 *enckdcreppart = shishi_der2asn1_enctgsreppart (handle, &buf[0],
746 buflen - i);
747 if (*enckdcreppart != NULL)
748 break;
749
750 *enckdcreppart = shishi_der2asn1_enckdcreppart (handle, &buf[0],
751 buflen - i);
752 if (*enckdcreppart != NULL)
753 break;
754 }
755
756 free (buf);
757
758 if (*enckdcreppart == NULL)
759 {
760 shishi_error_printf (handle, "Could not DER decode EncKDCRepPart. "
761 "Password probably correct (decrypt ok) though\n");
762 return SHISHI_ASN1_ERROR;
763 }
764
765 return SHISHI_OK;
766 }
767
768 /**
769 * shishi_kdcrep_clear_padata:
770 * @handle: shishi handle as allocated by shishi_init().
771 * @kdcrep: KDC-REP to remove PA-DATA from.
772 *
773 * Remove the padata field from KDC-REP.
774 *
775 * Return value: Returns SHISHI_OK iff successful.
776 **/
777 int
shishi_kdcrep_clear_padata(Shishi * handle,Shishi_asn1 kdcrep)778 shishi_kdcrep_clear_padata (Shishi * handle, Shishi_asn1 kdcrep)
779 {
780 int res;
781
782 res = shishi_asn1_write (handle, kdcrep, "padata", NULL, 0);
783 if (res != SHISHI_OK)
784 return res;
785
786 return SHISHI_OK;
787 }
788