1 /* priv.c --- Application data privacy protection.
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 struct Shishi_priv
29 {
30 Shishi *handle;
31 Shishi_key *key;
32 Shishi_asn1 priv;
33 Shishi_asn1 encprivpart;
34 unsigned long seqnumber;
35 };
36
37 /**
38 * shishi_priv:
39 * @handle: shishi handle as allocated by shishi_init().
40 * @priv: pointer to new structure that holds information about PRIV exchange
41 *
42 * Create a new PRIV exchange.
43 *
44 * Return value: Returns SHISHI_OK iff successful.
45 **/
46 int
shishi_priv(Shishi * handle,Shishi_priv ** priv)47 shishi_priv (Shishi * handle, Shishi_priv ** priv)
48 {
49 Shishi_priv *lpriv;
50 struct timeval tv;
51 char *usec;
52 int rc;
53
54 *priv = xcalloc (1, sizeof (**priv));
55 lpriv = *priv;
56
57 lpriv->handle = handle;
58 rc = shishi_key (handle, &lpriv->key);
59 if (rc != SHISHI_OK)
60 return rc;
61
62 lpriv->priv = shishi_asn1_priv (handle);
63 if (lpriv->priv == NULL)
64 return SHISHI_ASN1_ERROR;
65
66 rc = shishi_asn1_write (handle, lpriv->priv, "pvno", "5", 0);
67 if (rc != SHISHI_OK)
68 return rc;
69
70 rc = shishi_asn1_write (handle, lpriv->priv, "msg-type", "21", 0);
71 if (rc != SHISHI_OK)
72 return rc;
73
74 rc = shishi_asn1_write (handle, lpriv->priv, "enc-part.kvno", "0", 0);
75 if (rc != SHISHI_OK)
76 return rc;
77
78 lpriv->encprivpart = shishi_asn1_encprivpart (handle);
79 if (lpriv->priv == NULL)
80 return SHISHI_ASN1_ERROR;
81
82 rc = shishi_asn1_write (handle, lpriv->encprivpart, "timestamp",
83 shishi_generalize_time (handle, time (NULL)), 0);
84 if (rc != SHISHI_OK)
85 return rc;
86
87 rc = gettimeofday (&tv, NULL);
88 if (rc != 0)
89 return SHISHI_GETTIMEOFDAY_ERROR;
90 usec = xasprintf ("%ld", tv.tv_usec % 1000000);
91 rc = shishi_asn1_write (handle, lpriv->encprivpart, "usec", usec, 0);
92 free (usec);
93 if (rc != SHISHI_OK)
94 return rc;
95
96 rc = shishi_asn1_write (handle, lpriv->encprivpart, "seq-number", NULL, 0);
97 if (rc != SHISHI_OK)
98 return rc;
99
100 rc = shishi_asn1_write (handle, lpriv->encprivpart, "s-address.addr-type",
101 /* directional */
102 "3", 0);
103 if (rc != SHISHI_OK)
104 return rc;
105
106 rc = shishi_asn1_write (handle, lpriv->encprivpart, "s-address.address",
107 /* sender */
108 "\x00\x00\x00\x00", 4);
109 if (rc != SHISHI_OK)
110 return rc;
111
112 rc = shishi_asn1_write (handle, lpriv->encprivpart, "r-address", NULL, 0);
113 if (rc != SHISHI_OK)
114 return rc;
115
116 return SHISHI_OK;
117 }
118
119 /**
120 * shishi_priv_done:
121 * @priv: structure that holds information about PRIV exchange
122 *
123 * Deallocate resources associated with PRIV exchange. This should be
124 * called by the application when it no longer need to utilize the
125 * PRIV exchange handle.
126 **/
127 void
shishi_priv_done(Shishi_priv * priv)128 shishi_priv_done (Shishi_priv * priv)
129 {
130 shishi_asn1_done (priv->handle, priv->priv);
131 shishi_asn1_done (priv->handle, priv->encprivpart);
132 shishi_key_done (priv->key);
133 free (priv);
134 }
135
136 /**
137 * shishi_priv_key:
138 * @priv: structure that holds information about PRIV exchange
139 *
140 * Get key from PRIV exchange.
141 *
142 * Return value: Returns the key used in the PRIV exchange, or NULL if
143 * not yet set or an error occured.
144 **/
145 Shishi_key *
shishi_priv_key(Shishi_priv * priv)146 shishi_priv_key (Shishi_priv * priv)
147 {
148 return priv->key;
149 }
150
151 /**
152 * shishi_priv_key_set:
153 * @priv: structure that holds information about PRIV exchange
154 * @key: key to store in PRIV.
155 *
156 * Set the Key in the PRIV exchange.
157 **/
158 void
shishi_priv_key_set(Shishi_priv * priv,Shishi_key * key)159 shishi_priv_key_set (Shishi_priv * priv, Shishi_key * key)
160 {
161 shishi_key_copy (priv->key, key);
162 }
163
164 /**
165 * shishi_priv_priv:
166 * @priv: structure that holds information about PRIV exchange
167 *
168 * Get ASN.1 PRIV structure in PRIV exchange.
169 *
170 * Return value: Returns the ASN.1 priv in the PRIV exchange, or NULL if
171 * not yet set or an error occured.
172 **/
173 Shishi_asn1
shishi_priv_priv(Shishi_priv * priv)174 shishi_priv_priv (Shishi_priv * priv)
175 {
176 return priv->priv;
177 }
178
179 /**
180 * shishi_priv_priv_set:
181 * @priv: structure that holds information about PRIV exchange
182 * @asn1priv: KRB-PRIV to store in PRIV exchange.
183 *
184 * Set the KRB-PRIV in the PRIV exchange.
185 **/
186 void
shishi_priv_priv_set(Shishi_priv * priv,Shishi_asn1 asn1priv)187 shishi_priv_priv_set (Shishi_priv * priv, Shishi_asn1 asn1priv)
188 {
189 if (priv->priv)
190 shishi_asn1_done (priv->handle, priv->priv);
191 priv->priv = asn1priv;
192 }
193
194 /**
195 * shishi_priv_priv_der:
196 * @priv: priv as allocated by shishi_priv().
197 * @out: output array with newly allocated DER encoding of PRIV.
198 * @outlen: length of output array with DER encoding of PRIV.
199 *
200 * DER encode PRIV structure. Typically shishi_priv_build() is used
201 * to build the PRIV structure first. @out is allocated by this
202 * function, and it is the responsibility of caller to deallocate it.
203 *
204 * Return value: Returns SHISHI_OK iff successful.
205 **/
206 int
shishi_priv_priv_der(Shishi_priv * priv,char ** out,size_t * outlen)207 shishi_priv_priv_der (Shishi_priv * priv, char **out, size_t * outlen)
208 {
209 int rc;
210
211 rc = shishi_asn1_to_der (priv->handle, priv->priv, out, outlen);
212 if (rc != SHISHI_OK)
213 return rc;
214
215 return SHISHI_OK;
216 }
217
218 /**
219 * shishi_priv_priv_der_set:
220 * @priv: priv as allocated by shishi_priv().
221 * @der: input array with DER encoded KRB-PRIV.
222 * @derlen: length of input array with DER encoded KRB-PRIV.
223 *
224 * DER decode KRB-PRIV and set it PRIV exchange. If decoding fails, the
225 * KRB-PRIV in the PRIV exchange remains.
226 *
227 * Return value: Returns SHISHI_OK.
228 **/
229 int
shishi_priv_priv_der_set(Shishi_priv * priv,char * der,size_t derlen)230 shishi_priv_priv_der_set (Shishi_priv * priv, char *der, size_t derlen)
231 {
232 Shishi_asn1 asn1priv;
233
234 asn1priv = shishi_der2asn1_priv (priv->handle, der, derlen);
235
236 if (asn1priv == NULL)
237 return SHISHI_ASN1_ERROR;
238
239 shishi_priv_priv_set (priv, asn1priv);
240
241 return SHISHI_OK;
242 }
243
244 /**
245 * shishi_priv_encprivpart:
246 * @priv: structure that holds information about PRIV exchange
247 *
248 * Get ASN.1 EncPrivPart structure from PRIV exchange.
249 *
250 * Return value: Returns the ASN.1 encprivpart in the PRIV exchange, or NULL if
251 * not yet set or an error occured.
252 **/
253 Shishi_asn1
shishi_priv_encprivpart(Shishi_priv * priv)254 shishi_priv_encprivpart (Shishi_priv * priv)
255 {
256 return priv->encprivpart;
257 }
258
259 /**
260 * shishi_priv_encprivpart_set:
261 * @priv: structure that holds information about PRIV exchange
262 * @asn1encprivpart: ENCPRIVPART to store in PRIV exchange.
263 *
264 * Set the ENCPRIVPART in the PRIV exchange.
265 **/
266 void
shishi_priv_encprivpart_set(Shishi_priv * priv,Shishi_asn1 asn1encprivpart)267 shishi_priv_encprivpart_set (Shishi_priv * priv, Shishi_asn1 asn1encprivpart)
268 {
269 if (priv->encprivpart)
270 shishi_asn1_done (priv->handle, priv->encprivpart);
271 priv->encprivpart = asn1encprivpart;
272 }
273
274 /**
275 * shishi_priv_encprivpart_der:
276 * @priv: priv as allocated by shishi_priv().
277 * @out: output array with newly allocated DER encoding of ENCPRIVPART.
278 * @outlen: length of output array with DER encoding of ENCPRIVPART.
279 *
280 * DER encode ENCPRIVPART structure. @out is allocated by this
281 * function, and it is the responsibility of caller to deallocate it.
282 *
283 * Return value: Returns SHISHI_OK iff successful.
284 **/
285 int
shishi_priv_encprivpart_der(Shishi_priv * priv,char ** out,size_t * outlen)286 shishi_priv_encprivpart_der (Shishi_priv * priv, char **out, size_t * outlen)
287 {
288 int rc;
289
290 rc = shishi_asn1_to_der (priv->handle, priv->encprivpart, out, outlen);
291 if (rc != SHISHI_OK)
292 return rc;
293
294 return SHISHI_OK;
295 }
296
297 /**
298 * shishi_priv_encprivpart_der_set:
299 * @priv: priv as allocated by shishi_priv().
300 * @der: input array with DER encoded ENCPRIVPART.
301 * @derlen: length of input array with DER encoded ENCPRIVPART.
302 *
303 * DER decode ENCPRIVPART and set it PRIV exchange. If decoding
304 * fails, the ENCPRIVPART in the PRIV exchange remains.
305 *
306 * Return value: Returns SHISHI_OK.
307 **/
308 int
shishi_priv_encprivpart_der_set(Shishi_priv * priv,char * der,size_t derlen)309 shishi_priv_encprivpart_der_set (Shishi_priv * priv, char *der, size_t derlen)
310 {
311 Shishi_asn1 asn1encprivpart;
312
313 asn1encprivpart = shishi_der2asn1_encprivpart (priv->handle, der, derlen);
314
315 if (asn1encprivpart == NULL)
316 return SHISHI_ASN1_ERROR;
317
318 shishi_priv_encprivpart_set (priv, asn1encprivpart);
319
320 return SHISHI_OK;
321 }
322
323 /**
324 * shishi_priv_print:
325 * @handle: shishi handle as allocated by shishi_init().
326 * @fh: file handle open for writing.
327 * @priv: PRIV to print.
328 *
329 * Print ASCII armored DER encoding of PRIV to file.
330 *
331 * Return value: Returns SHISHI_OK iff successful.
332 **/
333 int
shishi_priv_print(Shishi * handle,FILE * fh,Shishi_asn1 priv)334 shishi_priv_print (Shishi * handle, FILE * fh, Shishi_asn1 priv)
335 {
336 return _shishi_print_armored_data (handle, fh, priv, "KRB-PRIV", NULL);
337 }
338
339 /**
340 * shishi_priv_save:
341 * @handle: shishi handle as allocated by shishi_init().
342 * @fh: file handle open for writing.
343 * @priv: PRIV to save.
344 *
345 * Save DER encoding of PRIV to file.
346 *
347 * Return value: Returns SHISHI_OK iff successful.
348 **/
349 int
shishi_priv_save(Shishi * handle,FILE * fh,Shishi_asn1 priv)350 shishi_priv_save (Shishi * handle, FILE * fh, Shishi_asn1 priv)
351 {
352 return _shishi_save_data (handle, fh, priv, "PRIV");
353 }
354
355 /**
356 * shishi_priv_to_file:
357 * @handle: shishi handle as allocated by shishi_init().
358 * @priv: PRIV to save.
359 * @filetype: input variable specifying type of file to be written,
360 * see Shishi_filetype.
361 * @filename: input variable with filename to write to.
362 *
363 * Write PRIV to file in specified TYPE. The file will be
364 * truncated if it exists.
365 *
366 * Return value: Returns SHISHI_OK iff successful.
367 **/
368 int
shishi_priv_to_file(Shishi * handle,Shishi_asn1 priv,int filetype,const char * filename)369 shishi_priv_to_file (Shishi * handle, Shishi_asn1 priv,
370 int filetype, const char *filename)
371 {
372 FILE *fh;
373 int res;
374
375 if (VERBOSE (handle))
376 printf (_("Writing PRIV to %s...\n"), filename);
377
378 fh = fopen (filename, "w");
379 if (fh == NULL)
380 return SHISHI_FOPEN_ERROR;
381
382 if (VERBOSE (handle))
383 printf (_("Writing PRIV in %s format...\n"),
384 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
385
386 if (filetype == SHISHI_FILETYPE_TEXT)
387 res = shishi_priv_print (handle, fh, priv);
388 else
389 res = shishi_priv_save (handle, fh, priv);
390 if (res != SHISHI_OK)
391 return res;
392
393 res = fclose (fh);
394 if (res != 0)
395 return SHISHI_IO_ERROR;
396
397 if (VERBOSE (handle))
398 printf (_("Writing PRIV to %s...done\n"), filename);
399
400 return SHISHI_OK;
401 }
402
403 /**
404 * shishi_priv_parse:
405 * @handle: shishi handle as allocated by shishi_init().
406 * @fh: file handle open for reading.
407 * @priv: output variable with newly allocated PRIV.
408 *
409 * Read ASCII armored DER encoded PRIV from file and populate given
410 * variable.
411 *
412 * Return value: Returns SHISHI_OK iff successful.
413 **/
414 int
shishi_priv_parse(Shishi * handle,FILE * fh,Shishi_asn1 * priv)415 shishi_priv_parse (Shishi * handle, FILE * fh, Shishi_asn1 * priv)
416 {
417 return _shishi_priv_input (handle, fh, priv, 0);
418 }
419
420 /**
421 * shishi_priv_read:
422 * @handle: shishi handle as allocated by shishi_init().
423 * @fh: file handle open for reading.
424 * @priv: output variable with newly allocated PRIV.
425 *
426 * Read DER encoded PRIV from file and populate given variable.
427 *
428 * Return value: Returns SHISHI_OK iff successful.
429 **/
430 int
shishi_priv_read(Shishi * handle,FILE * fh,Shishi_asn1 * priv)431 shishi_priv_read (Shishi * handle, FILE * fh, Shishi_asn1 * priv)
432 {
433 return _shishi_priv_input (handle, fh, priv, 1);
434 }
435
436 /**
437 * shishi_priv_from_file:
438 * @handle: shishi handle as allocated by shishi_init().
439 * @priv: output variable with newly allocated PRIV.
440 * @filetype: input variable specifying type of file to be read,
441 * see Shishi_filetype.
442 * @filename: input variable with filename to read from.
443 *
444 * Read PRIV from file in specified TYPE.
445 *
446 * Return value: Returns SHISHI_OK iff successful.
447 **/
448 int
shishi_priv_from_file(Shishi * handle,Shishi_asn1 * priv,int filetype,const char * filename)449 shishi_priv_from_file (Shishi * handle, Shishi_asn1 * priv,
450 int filetype, const char *filename)
451 {
452 int res;
453 FILE *fh;
454
455 if (VERBOSE (handle))
456 printf (_("Reading PRIV from %s...\n"), filename);
457
458 fh = fopen (filename, "r");
459 if (fh == NULL)
460 return SHISHI_FOPEN_ERROR;
461
462 if (VERBOSE (handle))
463 printf (_("Reading PRIV in %s format...\n"),
464 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
465
466 if (filetype == SHISHI_FILETYPE_TEXT)
467 res = shishi_priv_parse (handle, fh, priv);
468 else
469 res = shishi_priv_read (handle, fh, priv);
470 if (res != SHISHI_OK)
471 return res;
472
473 res = fclose (fh);
474 if (res != 0)
475 return SHISHI_IO_ERROR;
476
477 if (VERBOSE (handle))
478 printf (_("Reading PRIV from %s...done\n"), filename);
479
480 return SHISHI_OK;
481 }
482
483 /**
484 * shishi_priv_enc_part_etype:
485 * @handle: shishi handle as allocated by shishi_init().
486 * @priv: PRIV variable to get value from.
487 * @etype: output variable that holds the value.
488 *
489 * Extract PRIV.enc-part.etype.
490 *
491 * Return value: Returns SHISHI_OK iff successful.
492 **/
493 int
shishi_priv_enc_part_etype(Shishi * handle,Shishi_asn1 priv,int32_t * etype)494 shishi_priv_enc_part_etype (Shishi * handle,
495 Shishi_asn1 priv, int32_t * etype)
496 {
497 return shishi_asn1_read_int32 (handle, priv, "enc-part.etype", etype);
498 }
499
500 /**
501 * shishi_priv_set_enc_part:
502 * @handle: shishi handle as allocated by shishi_init().
503 * @priv: priv as allocated by shishi_priv().
504 * @etype: input encryption type to store in PRIV.
505 * @encpart: input encrypted data to store in PRIV.
506 * @encpartlen: size of input encrypted data to store in PRIV.
507 *
508 * Store encrypted data in PRIV. The encrypted data is usually
509 * created by calling shishi_encrypt() on some application specific
510 * data using the key from the ticket that is being used. To save
511 * time, you may want to use shishi_priv_build() instead, which
512 * encryptes the data and calls this function in one step.
513 *
514 * Return value: Returns SHISHI_OK iff successful.
515 **/
516 int
shishi_priv_set_enc_part(Shishi * handle,Shishi_asn1 priv,int32_t etype,const char * encpart,size_t encpartlen)517 shishi_priv_set_enc_part (Shishi * handle,
518 Shishi_asn1 priv,
519 int32_t etype,
520 const char *encpart, size_t encpartlen)
521 {
522 int res;
523
524 res = shishi_asn1_write_integer (handle, priv, "enc-part.etype", etype);
525 if (res != SHISHI_OK)
526 return res;
527
528 res = shishi_asn1_write (handle, priv, "enc-part.cipher",
529 encpart, encpartlen);
530 if (res != SHISHI_OK)
531 return res;
532
533 return SHISHI_OK;
534 }
535
536 /**
537 * shishi_encprivpart_user_data:
538 * @handle: shishi handle as allocated by shishi_init().
539 * @encprivpart: encprivpart as allocated by shishi_priv().
540 * @userdata: output array with newly allocated user data from KRB-PRIV.
541 * @userdatalen: output size of output user data buffer.
542 *
543 * Read user data value from KRB-PRIV. @userdata is allocated by this
544 * function, and it is the responsibility of caller to deallocate it.
545 *
546 * Return value: Returns SHISHI_OK iff successful.
547 **/
548 int
shishi_encprivpart_user_data(Shishi * handle,Shishi_asn1 encprivpart,char ** userdata,size_t * userdatalen)549 shishi_encprivpart_user_data (Shishi * handle,
550 Shishi_asn1 encprivpart,
551 char **userdata, size_t * userdatalen)
552 {
553 int res;
554
555 res = shishi_asn1_read (handle, encprivpart, "user-data",
556 userdata, userdatalen);
557 if (res != SHISHI_OK)
558 return res;
559
560 return SHISHI_OK;
561 }
562
563 /**
564 * shishi_encprivpart_set_user_data:
565 * @handle: shishi handle as allocated by shishi_init().
566 * @encprivpart: encprivpart as allocated by shishi_priv().
567 * @userdata: input user application to store in PRIV.
568 * @userdatalen: size of input user application to store in PRIV.
569 *
570 * Set the application data in PRIV.
571 *
572 * Return value: Returns SHISHI_OK iff successful.
573 **/
574 int
shishi_encprivpart_set_user_data(Shishi * handle,Shishi_asn1 encprivpart,const char * userdata,size_t userdatalen)575 shishi_encprivpart_set_user_data (Shishi * handle,
576 Shishi_asn1 encprivpart,
577 const char *userdata, size_t userdatalen)
578 {
579 int res;
580
581 res = shishi_asn1_write (handle, encprivpart, "user-data",
582 userdata, userdatalen);
583 if (res != SHISHI_OK)
584 return res;
585
586 return SHISHI_OK;
587 }
588
589 /**
590 * shishi_priv_build:
591 * @priv: priv as allocated by shishi_priv().
592 * @key: key for session, used to encrypt data.
593 *
594 * Build checksum and set it in KRB-PRIV. Note that this follows RFC
595 * 1510bis and is incompatible with RFC 1510, although presumably few
596 * implementations use the RFC1510 algorithm.
597 *
598 * Return value: Returns SHISHI_OK iff successful.
599 **/
600 int
shishi_priv_build(Shishi_priv * priv,Shishi_key * key)601 shishi_priv_build (Shishi_priv * priv, Shishi_key * key)
602 {
603 int res;
604 char *buf;
605 size_t buflen;
606 char *der;
607 size_t derlen;
608
609 res = shishi_asn1_to_der (priv->handle, priv->encprivpart, &der, &derlen);
610 if (res != SHISHI_OK)
611 {
612 shishi_error_printf (priv->handle,
613 "Could not DER encode EncPrivPart: %s\n",
614 shishi_strerror (res));
615 return res;
616 }
617
618 res = shishi_encrypt (priv->handle, key, SHISHI_KEYUSAGE_KRB_PRIV,
619 der, derlen, &buf, &buflen);
620
621 free (der);
622
623 if (res != SHISHI_OK)
624 {
625 shishi_error_printf (priv->handle, "Cannot encrypt EncPrivPart.\n");
626 return res;
627 }
628
629 res = shishi_priv_set_enc_part (priv->handle, priv->priv,
630 shishi_key_type (key), buf, buflen);
631 if (res != SHISHI_OK)
632 return res;
633
634 return SHISHI_OK;
635 }
636
637 /**
638 * shishi_priv_process:
639 * @priv: priv as allocated by shishi_priv().
640 * @key: key to use to decrypt EncPrivPart.
641 *
642 * Decrypt encrypted data in KRB-PRIV and set the EncPrivPart in the
643 * PRIV exchange.
644 *
645 * Return value: Returns SHISHI_OK iff successful,
646 * SHISHI_PRIV_BAD_KEYTYPE if an incompatible key type is used, or
647 * SHISHI_CRYPTO_ERROR if the actual decryption failed.
648 **/
649 int
shishi_priv_process(Shishi_priv * priv,Shishi_key * key)650 shishi_priv_process (Shishi_priv * priv, Shishi_key * key)
651 {
652 int res;
653 int i;
654 char *buf;
655 size_t buflen;
656 char *cipher;
657 size_t cipherlen;
658 int32_t etype;
659
660 res = shishi_priv_enc_part_etype (priv->handle, priv->priv, &etype);
661 if (res != SHISHI_OK)
662 return res;
663
664 if (etype != shishi_key_type (key))
665 return SHISHI_PRIV_BAD_KEYTYPE;
666
667 res = shishi_asn1_read (priv->handle, priv->priv, "enc-part.cipher",
668 &cipher, &cipherlen);
669 if (res != SHISHI_OK)
670 return res;
671
672 res = shishi_decrypt (priv->handle, key, SHISHI_KEYUSAGE_KRB_PRIV,
673 cipher, cipherlen, &buf, &buflen);
674 free (cipher);
675 if (res != SHISHI_OK)
676 {
677 shishi_error_printf (priv->handle,
678 "PRIV decryption failed, bad key?\n");
679 return res;
680 }
681
682 /* The crypto is so 1980; no length indicator. Trim off pad bytes
683 until we can parse it. */
684 for (i = 0; i < 8; i++)
685 {
686 if (VERBOSEASN1 (priv->handle))
687 printf ("Trying with %d pad in enckdcrep...\n", i);
688
689 priv->encprivpart = shishi_der2asn1_encprivpart (priv->handle, &buf[0],
690 buflen - i);
691 if (priv->encprivpart != NULL)
692 break;
693 }
694
695 free (buf);
696
697 if (priv->encprivpart == NULL)
698 {
699 shishi_error_printf (priv->handle, "Could not DER decode EncPrivPart. "
700 "Key probably correct (decrypt ok) though\n");
701 return SHISHI_ASN1_ERROR;
702 }
703
704 return SHISHI_OK;
705 }
706