Branch data Line data Source code
1 : : /* priv.c --- Application data privacy protection.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2010 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
47 : 1 : shishi_priv (Shishi * handle, Shishi_priv ** priv)
48 : : {
49 : : Shishi_priv *lpriv;
50 : : struct timeval tv;
51 : : char *usec;
52 : : int rc;
53 : :
54 : 1 : *priv = xcalloc (1, sizeof (**priv));
55 : 1 : lpriv = *priv;
56 : :
57 : 1 : lpriv->handle = handle;
58 : 1 : rc = shishi_key (handle, &lpriv->key);
59 [ - + ]: 1 : if (rc != SHISHI_OK)
60 : 0 : return rc;
61 : :
62 : 1 : lpriv->priv = shishi_asn1_priv (handle);
63 [ - + ]: 1 : if (lpriv->priv == NULL)
64 : 0 : return SHISHI_ASN1_ERROR;
65 : :
66 : 1 : rc = shishi_asn1_write (handle, lpriv->priv, "pvno", "5", 0);
67 [ - + ]: 1 : if (rc != SHISHI_OK)
68 : 0 : return rc;
69 : :
70 : 1 : rc = shishi_asn1_write (handle, lpriv->priv, "msg-type", "21", 0);
71 [ - + ]: 1 : if (rc != SHISHI_OK)
72 : 0 : return rc;
73 : :
74 : 1 : rc = shishi_asn1_write (handle, lpriv->priv, "enc-part.kvno", "0", 0);
75 [ - + ]: 1 : if (rc != SHISHI_OK)
76 : 0 : return rc;
77 : :
78 : 1 : lpriv->encprivpart = shishi_asn1_encprivpart (handle);
79 [ - + ]: 1 : if (lpriv->priv == NULL)
80 : 0 : return SHISHI_ASN1_ERROR;
81 : :
82 : 1 : rc = shishi_asn1_write (handle, lpriv->encprivpart, "timestamp",
83 : : shishi_generalize_time (handle, time (NULL)), 0);
84 [ - + ]: 1 : if (rc != SHISHI_OK)
85 : 0 : return rc;
86 : :
87 : 1 : rc = gettimeofday (&tv, NULL);
88 [ - + ]: 1 : if (rc != 0)
89 : 0 : return SHISHI_GETTIMEOFDAY_ERROR;
90 : 1 : usec = xasprintf ("%ld", tv.tv_usec % 1000000);
91 : 1 : rc = shishi_asn1_write (handle, lpriv->encprivpart, "usec", usec, 0);
92 : 1 : free (usec);
93 [ - + ]: 1 : if (rc != SHISHI_OK)
94 : 0 : return rc;
95 : :
96 : 1 : rc = shishi_asn1_write (handle, lpriv->encprivpart, "seq-number", NULL, 0);
97 [ - + ]: 1 : if (rc != SHISHI_OK)
98 : 0 : return rc;
99 : :
100 : 1 : rc = shishi_asn1_write (handle, lpriv->encprivpart, "s-address.addr-type",
101 : : /* directional */
102 : : "3", 0);
103 [ - + ]: 1 : if (rc != SHISHI_OK)
104 : 0 : return rc;
105 : :
106 : 1 : rc = shishi_asn1_write (handle, lpriv->encprivpart, "s-address.address",
107 : : /* sender */
108 : : "\x00\x00\x00\x00", 4);
109 [ - + ]: 1 : if (rc != SHISHI_OK)
110 : 0 : return rc;
111 : :
112 : 1 : rc = shishi_asn1_write (handle, lpriv->encprivpart, "r-address", NULL, 0);
113 [ - + ]: 1 : if (rc != SHISHI_OK)
114 : 0 : return rc;
115 : :
116 : 1 : 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
128 : 1 : shishi_priv_done (Shishi_priv * priv)
129 : : {
130 : 1 : shishi_asn1_done (priv->handle, priv->priv);
131 : 1 : shishi_asn1_done (priv->handle, priv->encprivpart);
132 : 1 : shishi_key_done (priv->key);
133 : 1 : free (priv);
134 : 1 : }
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 *
146 : 1 : shishi_priv_key (Shishi_priv * priv)
147 : : {
148 : 1 : 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
159 : 0 : shishi_priv_key_set (Shishi_priv * priv, Shishi_key * key)
160 : : {
161 : 0 : shishi_key_copy (priv->key, key);
162 : 0 : }
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
174 : 1 : shishi_priv_priv (Shishi_priv * priv)
175 : : {
176 : 1 : 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
187 : 0 : shishi_priv_priv_set (Shishi_priv * priv, Shishi_asn1 asn1priv)
188 : : {
189 [ # # ]: 0 : if (priv->priv)
190 : 0 : shishi_asn1_done (priv->handle, priv->priv);
191 : 0 : priv->priv = asn1priv;
192 : 0 : }
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
207 : 1 : shishi_priv_priv_der (Shishi_priv * priv, char **out, size_t * outlen)
208 : : {
209 : : int rc;
210 : :
211 : 1 : rc = shishi_asn1_to_der (priv->handle, priv->priv, out, outlen);
212 [ - + ]: 1 : if (rc != SHISHI_OK)
213 : 0 : return rc;
214 : :
215 : 1 : 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
230 : 0 : shishi_priv_priv_der_set (Shishi_priv * priv, char *der, size_t derlen)
231 : : {
232 : : Shishi_asn1 asn1priv;
233 : :
234 : 0 : asn1priv = shishi_der2asn1_priv (priv->handle, der, derlen);
235 : :
236 [ # # ]: 0 : if (asn1priv == NULL)
237 : 0 : return SHISHI_ASN1_ERROR;
238 : :
239 : 0 : shishi_priv_priv_set (priv, asn1priv);
240 : :
241 : 0 : 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
254 : 1 : shishi_priv_encprivpart (Shishi_priv * priv)
255 : : {
256 : 1 : 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
267 : 0 : shishi_priv_encprivpart_set (Shishi_priv * priv, Shishi_asn1 asn1encprivpart)
268 : : {
269 [ # # ]: 0 : if (priv->encprivpart)
270 : 0 : shishi_asn1_done (priv->handle, priv->encprivpart);
271 : 0 : priv->encprivpart = asn1encprivpart;
272 : 0 : }
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
286 : 0 : shishi_priv_encprivpart_der (Shishi_priv * priv, char **out, size_t * outlen)
287 : : {
288 : : int rc;
289 : :
290 : 0 : rc = shishi_asn1_to_der (priv->handle, priv->encprivpart, out, outlen);
291 [ # # ]: 0 : if (rc != SHISHI_OK)
292 : 0 : return rc;
293 : :
294 : 0 : 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
309 : 0 : shishi_priv_encprivpart_der_set (Shishi_priv * priv, char *der, size_t derlen)
310 : : {
311 : : Shishi_asn1 asn1encprivpart;
312 : :
313 : 0 : asn1encprivpart = shishi_der2asn1_encprivpart (priv->handle, der, derlen);
314 : :
315 [ # # ]: 0 : if (asn1encprivpart == NULL)
316 : 0 : return SHISHI_ASN1_ERROR;
317 : :
318 : 0 : shishi_priv_encprivpart_set (priv, asn1encprivpart);
319 : :
320 : 0 : 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
334 : 1 : shishi_priv_print (Shishi * handle, FILE * fh, Shishi_asn1 priv)
335 : : {
336 : 1 : 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
350 : 0 : shishi_priv_save (Shishi * handle, FILE * fh, Shishi_asn1 priv)
351 : : {
352 : 0 : 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
369 : 1 : shishi_priv_to_file (Shishi * handle, Shishi_asn1 priv,
370 : : int filetype, const char *filename)
371 : : {
372 : : FILE *fh;
373 : : int res;
374 : :
375 [ - + ]: 1 : if (VERBOSE (handle))
376 : 0 : printf (_("Writing PRIV to %s...\n"), filename);
377 : :
378 : 1 : fh = fopen (filename, "w");
379 [ - + ]: 1 : if (fh == NULL)
380 : 0 : return SHISHI_FOPEN_ERROR;
381 : :
382 [ - + ]: 1 : if (VERBOSE (handle))
383 [ # # ]: 0 : printf (_("Writing PRIV in %s format...\n"),
384 : : filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
385 : :
386 [ + - ]: 1 : if (filetype == SHISHI_FILETYPE_TEXT)
387 : 1 : res = shishi_priv_print (handle, fh, priv);
388 : : else
389 : 0 : res = shishi_priv_save (handle, fh, priv);
390 [ - + ]: 1 : if (res != SHISHI_OK)
391 : 0 : return res;
392 : :
393 : 1 : res = fclose (fh);
394 [ - + ]: 1 : if (res != 0)
395 : 0 : return SHISHI_IO_ERROR;
396 : :
397 [ - + ]: 1 : if (VERBOSE (handle))
398 : 0 : printf (_("Writing PRIV to %s...done\n"), filename);
399 : :
400 : 1 : 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
415 : 1 : shishi_priv_parse (Shishi * handle, FILE * fh, Shishi_asn1 * priv)
416 : : {
417 : 1 : 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
431 : 0 : shishi_priv_read (Shishi * handle, FILE * fh, Shishi_asn1 * priv)
432 : : {
433 : 0 : 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
449 : 1 : shishi_priv_from_file (Shishi * handle, Shishi_asn1 * priv,
450 : : int filetype, const char *filename)
451 : : {
452 : : int res;
453 : : FILE *fh;
454 : :
455 [ - + ]: 1 : if (VERBOSE (handle))
456 : 0 : printf (_("Reading PRIV from %s...\n"), filename);
457 : :
458 : 1 : fh = fopen (filename, "r");
459 [ - + ]: 1 : if (fh == NULL)
460 : 0 : return SHISHI_FOPEN_ERROR;
461 : :
462 [ - + ]: 1 : if (VERBOSE (handle))
463 [ # # ]: 0 : printf (_("Reading PRIV in %s format...\n"),
464 : : filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
465 : :
466 [ + - ]: 1 : if (filetype == SHISHI_FILETYPE_TEXT)
467 : 1 : res = shishi_priv_parse (handle, fh, priv);
468 : : else
469 : 0 : res = shishi_priv_read (handle, fh, priv);
470 [ - + ]: 1 : if (res != SHISHI_OK)
471 : 0 : return res;
472 : :
473 : 1 : res = fclose (fh);
474 [ - + ]: 1 : if (res != 0)
475 : 0 : return SHISHI_IO_ERROR;
476 : :
477 [ - + ]: 1 : if (VERBOSE (handle))
478 : 0 : printf (_("Reading PRIV from %s...done\n"), filename);
479 : :
480 : 1 : 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
494 : 2 : shishi_priv_enc_part_etype (Shishi * handle,
495 : : Shishi_asn1 priv, int32_t * etype)
496 : : {
497 : 2 : 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
517 : 1 : 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 : 1 : res = shishi_asn1_write_integer (handle, priv, "enc-part.etype", etype);
525 [ - + ]: 1 : if (res != SHISHI_OK)
526 : 0 : return res;
527 : :
528 : 1 : res = shishi_asn1_write (handle, priv, "enc-part.cipher",
529 : : encpart, encpartlen);
530 [ - + ]: 1 : if (res != SHISHI_OK)
531 : 0 : return res;
532 : :
533 : 1 : 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
549 : 1 : shishi_encprivpart_user_data (Shishi * handle,
550 : : Shishi_asn1 encprivpart,
551 : : char **userdata, size_t * userdatalen)
552 : : {
553 : : int res;
554 : :
555 : 1 : res = shishi_asn1_read (handle, encprivpart, "user-data",
556 : : userdata, userdatalen);
557 [ - + ]: 1 : if (res != SHISHI_OK)
558 : 0 : return res;
559 : :
560 : 1 : 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
575 : 1 : shishi_encprivpart_set_user_data (Shishi * handle,
576 : : Shishi_asn1 encprivpart,
577 : : const char *userdata, size_t userdatalen)
578 : : {
579 : : int res;
580 : :
581 : 1 : res = shishi_asn1_write (handle, encprivpart, "user-data",
582 : : userdata, userdatalen);
583 [ - + ]: 1 : if (res != SHISHI_OK)
584 : 0 : return res;
585 : :
586 : 1 : 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
601 : 0 : 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 : 0 : res = shishi_asn1_to_der (priv->handle, priv->encprivpart, &der, &derlen);
610 [ # # ]: 0 : if (res != SHISHI_OK)
611 : : {
612 : 0 : shishi_error_printf (priv->handle,
613 : : "Could not DER encode EncPrivPart: %s\n",
614 : : shishi_strerror (res));
615 : 0 : return res;
616 : : }
617 : :
618 : 0 : res = shishi_encrypt (priv->handle, key, SHISHI_KEYUSAGE_KRB_PRIV,
619 : : der, derlen, &buf, &buflen);
620 : :
621 : 0 : free (der);
622 : :
623 [ # # ]: 0 : if (res != SHISHI_OK)
624 : : {
625 : 0 : shishi_error_printf (priv->handle, "Cannot encrypt EncPrivPart.\n");
626 : 0 : return res;
627 : : }
628 : :
629 : 0 : res = shishi_priv_set_enc_part (priv->handle, priv->priv,
630 : : shishi_key_type (key), buf, buflen);
631 [ # # ]: 0 : if (res != SHISHI_OK)
632 : 0 : return res;
633 : :
634 : 0 : 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
650 : 1 : 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 : 1 : res = shishi_priv_enc_part_etype (priv->handle, priv->priv, &etype);
661 [ - + ]: 1 : if (res != SHISHI_OK)
662 : 0 : return res;
663 : :
664 [ + - ]: 1 : if (etype != shishi_key_type (key))
665 : 1 : return SHISHI_PRIV_BAD_KEYTYPE;
666 : :
667 : 0 : res = shishi_asn1_read (priv->handle, priv->priv, "enc-part.cipher",
668 : : &cipher, &cipherlen);
669 [ # # ]: 0 : if (res != SHISHI_OK)
670 : 0 : return res;
671 : :
672 : 0 : res = shishi_decrypt (priv->handle, key, SHISHI_KEYUSAGE_KRB_PRIV,
673 : : cipher, cipherlen, &buf, &buflen);
674 : 0 : free (cipher);
675 [ # # ]: 0 : if (res != SHISHI_OK)
676 : : {
677 : 0 : shishi_error_printf (priv->handle,
678 : : "PRIV decryption failed, bad key?\n");
679 : 0 : return res;
680 : : }
681 : :
682 : : /* The crypto is so 1980; no length indicator. Trim off pad bytes
683 : : until we can parse it. */
684 [ # # ]: 0 : for (i = 0; i < 8; i++)
685 : : {
686 [ # # ]: 0 : if (VERBOSEASN1 (priv->handle))
687 : 0 : printf ("Trying with %d pad in enckdcrep...\n", i);
688 : :
689 : 0 : priv->encprivpart = shishi_der2asn1_encprivpart (priv->handle, &buf[0],
690 : : buflen - i);
691 [ # # ]: 0 : if (priv->encprivpart != NULL)
692 : 0 : break;
693 : : }
694 : :
695 : 0 : free (buf);
696 : :
697 [ # # ]: 0 : if (priv->encprivpart == NULL)
698 : : {
699 : 0 : shishi_error_printf (priv->handle, "Could not DER decode EncPrivPart. "
700 : : "Key probably correct (decrypt ok) though\n");
701 : 0 : return SHISHI_ASN1_ERROR;
702 : : }
703 : :
704 : 1 : return SHISHI_OK;
705 : : }
|