Branch data Line data Source code
1 : : /* diskio.c --- Read and write data structures from disk.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 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 : : /* XXX oh, please, rewrite this file. */
24 : :
25 : : #include "internal.h"
26 : : #include "diskio.h"
27 : :
28 : : #define HEADERBEG "-----BEGIN SHISHI %s-----"
29 : : #define HEADEREND "-----END SHISHI %s-----"
30 : :
31 : : #define BUFSIZE 5000
32 : :
33 : : /*
34 : : * Note to self: if you change any *print* function, remember to change
35 : : * the corresponding *parse* function too.
36 : : *
37 : : */
38 : :
39 : : static char *
40 : 15 : armor_data (const char *data, size_t len,
41 : : const char *armortype, const char *armorheaders)
42 : : {
43 : : /* Must be a multiple of 4. */
44 : : #define WRAP_COL 64
45 : : char *armorbegin, *armorend;
46 : : char *b64data, *out;
47 : : size_t wrapb64len =
48 : 15 : BASE64_LENGTH (len) + BASE64_LENGTH (len) / WRAP_COL + 1;
49 : : size_t i;
50 : :
51 : 15 : b64data = xmalloc (wrapb64len + 1);
52 : :
53 [ + + ]: 101 : for (i = 0; i <= BASE64_LENGTH (len) / WRAP_COL; i++)
54 : : {
55 : 87 : size_t readpos = i * WRAP_COL * 3 / 4;
56 : 87 : size_t nread = WRAP_COL * 3 / 4;
57 : 87 : size_t storepos = i * WRAP_COL + i;
58 : 87 : size_t nstore = WRAP_COL;
59 : :
60 [ + + ]: 87 : if (readpos >= len)
61 : 1 : break;
62 : :
63 [ + + ]: 86 : if (readpos + nread >= len)
64 : : {
65 : 15 : nread = len - readpos;
66 : 15 : nstore = BASE64_LENGTH (nread);
67 : : }
68 : :
69 : 86 : base64_encode (data + readpos, nread, b64data + storepos, nstore);
70 : 86 : b64data[storepos + nstore] = '\n';
71 : 86 : b64data[storepos + nstore + 1] = '\0';
72 : :
73 : : #if 0
74 : : printf ("alloc %d len %d curlen %d "
75 : : "readpos %d nread %d storepos %d nstore %d\n",
76 : : wrapb64len + 1, len, strlen (b64data),
77 : : readpos, nread, storepos, nstore);
78 : : #endif
79 : : }
80 : :
81 : 15 : armorbegin = xasprintf (HEADERBEG, armortype);
82 : 15 : armorend = xasprintf (HEADEREND, armortype);
83 : :
84 [ - + ][ - + ]: 15 : out = xasprintf ("%s\n%s%s%s%s\n",
85 : : armorbegin,
86 : : armorheaders ? armorheaders : "",
87 : : armorheaders ? "\n" : "", b64data, armorend);
88 : :
89 : 15 : free (b64data);
90 : 15 : free (armorend);
91 : 15 : free (armorbegin);
92 : :
93 : 15 : return out;
94 : : }
95 : :
96 : : static char *
97 : 15 : armor_asn1 (Shishi * handle,
98 : : Shishi_asn1 asn1, const char *armortype, const char *armorheaders)
99 : : {
100 : : char *der;
101 : : size_t derlen;
102 : : char *out;
103 : : int rc;
104 : :
105 : 15 : rc = shishi_asn1_to_der (handle, asn1, &der, &derlen);
106 [ - + ]: 15 : if (rc != SHISHI_OK)
107 : 0 : return NULL;
108 : :
109 : 15 : out = armor_data (der, derlen, armortype, armorheaders);
110 : :
111 : 15 : free (der);
112 : :
113 : 15 : return out;
114 : : }
115 : :
116 : : int
117 : 15 : _shishi_print_armored_data (Shishi * handle,
118 : : FILE * fh,
119 : : Shishi_asn1 asn1,
120 : : const char *asn1type, char *headers)
121 : : {
122 : 15 : char *data = armor_asn1 (handle, asn1, asn1type, headers);
123 : :
124 : 15 : shishi_asn1_print (handle, asn1, fh);
125 : :
126 : 15 : fprintf (fh, "%s\n", data);
127 : :
128 : 15 : return SHISHI_OK;
129 : : }
130 : :
131 : : int
132 : 0 : _shishi_save_data (Shishi * handle, FILE * fh, Shishi_asn1 asn1,
133 : : const char *asn1type)
134 : : {
135 : : char *der;
136 : : size_t derlen;
137 : : size_t i;
138 : : int res;
139 : :
140 : 0 : res = shishi_asn1_to_der_field (handle, asn1, asn1type, &der, &derlen);
141 [ # # ]: 0 : if (res != SHISHI_OK)
142 : 0 : return res;
143 : :
144 : 0 : i = fwrite (der, sizeof (der[0]), derlen, fh);
145 [ # # ]: 0 : if (i != derlen)
146 : 0 : return SHISHI_IO_ERROR;
147 : :
148 : 0 : return SHISHI_OK;
149 : : }
150 : :
151 : : int
152 : 0 : shishi_padata_print (Shishi * handle, FILE * fh, Shishi_asn1 padata)
153 : : {
154 : 0 : return _shishi_print_armored_data (handle, fh, padata, "PA-DATA", NULL);
155 : : }
156 : :
157 : : int
158 : 0 : shishi_methoddata_print (Shishi * handle, FILE * fh, Shishi_asn1 methoddata)
159 : : {
160 : 0 : return _shishi_print_armored_data (handle, fh, methoddata,
161 : : "METHOD-DATA", NULL);
162 : : }
163 : :
164 : : int
165 : 0 : shishi_etype_info_print (Shishi * handle, FILE * fh, Shishi_asn1 etypeinfo)
166 : : {
167 : 0 : return _shishi_print_armored_data (handle, fh, etypeinfo,
168 : : "ETYPE-INFO", NULL);
169 : : }
170 : :
171 : : int
172 : 0 : shishi_etype_info2_print (Shishi * handle, FILE * fh, Shishi_asn1 etypeinfo2)
173 : : {
174 : 0 : return _shishi_print_armored_data (handle, fh, etypeinfo2,
175 : : "ETYPE-INFO2", NULL);
176 : : }
177 : :
178 : : int
179 : 4 : shishi_enckdcreppart_print (Shishi * handle,
180 : : FILE * fh, Shishi_asn1 enckdcreppart)
181 : : {
182 : 4 : return _shishi_print_armored_data (handle, fh, enckdcreppart,
183 : : "EncKDCRepPart", NULL);
184 : : }
185 : :
186 : : int
187 : 0 : shishi_enckdcreppart_save (Shishi * handle,
188 : : FILE * fh, Shishi_asn1 enckdcreppart)
189 : : {
190 : 0 : return _shishi_save_data (handle, fh, enckdcreppart, "EncKDCRepPart");
191 : : }
192 : :
193 : : int
194 : 0 : shishi_ticket_save (Shishi * handle, FILE * fh, Shishi_asn1 ticket)
195 : : {
196 : 0 : return _shishi_save_data (handle, fh, ticket, "Ticket");
197 : : }
198 : :
199 : : int
200 : 4 : shishi_ticket_print (Shishi * handle, FILE * fh, Shishi_asn1 ticket)
201 : : {
202 : 4 : return _shishi_print_armored_data (handle, fh, ticket, "Ticket", NULL);
203 : : }
204 : :
205 : : int
206 : 0 : shishi_encticketpart_print (Shishi * handle, FILE * fh,
207 : : Shishi_asn1 encticketpart)
208 : : {
209 : 0 : return _shishi_print_armored_data (handle, fh, encticketpart,
210 : : "EncTicketPart", NULL);
211 : : }
212 : :
213 : : static int
214 : 10 : _shishi_read_armored_data (Shishi * handle,
215 : : FILE * fh, char *buffer, size_t len,
216 : : const char *tag)
217 : : {
218 : 10 : char *line = NULL;
219 : 10 : size_t linelen = 0;
220 : : char *armorbegin, *armorend;
221 : 10 : int phase = 0;
222 : 10 : int res = SHISHI_OK;
223 : :
224 : 10 : armorbegin = xasprintf (HEADERBEG, tag);
225 : 10 : armorend = xasprintf (HEADEREND, tag);
226 : :
227 [ + + ]: 239 : while (getline (&line, &linelen, fh) > 0)
228 : : {
229 [ + + ][ + + ]: 476 : while (*line && strchr ("\n\r\t ", line[strlen (line) - 1]))
230 : 238 : line[strlen (line) - 1] = '\0';
231 : :
232 [ + + ]: 238 : if (phase == 1)
233 : : {
234 [ + + ]: 60 : if (strcmp (line, armorend) == 0)
235 : : {
236 : 9 : phase = 2;
237 : 9 : break;
238 : : }
239 : : }
240 : : else
241 : : {
242 [ + + ]: 178 : if (strcmp (line, armorbegin) == 0)
243 : 9 : phase = 1;
244 : 178 : continue;
245 : : }
246 : :
247 [ - + ]: 51 : if (len <= strlen (line))
248 : : {
249 : 0 : res = SHISHI_TOO_SMALL_BUFFER;
250 : 0 : goto done;
251 : : }
252 : :
253 : 51 : memcpy (buffer, line, strlen (line));
254 : 51 : buffer += strlen (line);
255 : 51 : len -= strlen (line);
256 : : }
257 : :
258 [ - + ]: 10 : if (len == 0)
259 : 0 : res = SHISHI_TOO_SMALL_BUFFER;
260 : : else
261 : 10 : *buffer = '\0';
262 : :
263 [ + + ]: 10 : if (phase != 2)
264 : 1 : res = SHISHI_IO_ERROR;
265 : :
266 : : done:
267 : :
268 : 10 : free (armorbegin);
269 : 10 : free (armorend);
270 : 10 : free (line);
271 : :
272 : 10 : return res;
273 : : }
274 : :
275 : : static int
276 : 2 : _shishi_ticket_input (Shishi * handle,
277 : : FILE * fh, Shishi_asn1 * ticket, int type)
278 : : {
279 : : char der[BUFSIZE];
280 : : size_t derlen;
281 : : char b64der[BUFSIZE];
282 : 2 : size_t b64len = 0;
283 : : int res;
284 : :
285 [ + - ]: 2 : if (type == 0)
286 : : {
287 : 2 : b64len = sizeof (b64der);
288 : 2 : res = _shishi_read_armored_data (handle, fh, b64der, b64len, "Ticket");
289 [ - + ]: 2 : if (res != SHISHI_OK)
290 : : {
291 : 0 : shishi_error_printf (handle, "armor data read fail\n");
292 : 0 : return res;
293 : : }
294 : :
295 : 2 : derlen = sizeof (der);
296 [ - + ]: 2 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
297 : 2 : return SHISHI_BASE64_ERROR;
298 : : }
299 : : else
300 : : {
301 : 0 : derlen =
302 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
303 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
304 : : {
305 : 0 : shishi_error_printf (handle,
306 : : "Error reading from file (got %d bytes)...",
307 : : derlen);
308 : 0 : return !SHISHI_OK;
309 : : }
310 : : }
311 : :
312 : 2 : *ticket = shishi_der2asn1_ticket (handle, der, derlen);
313 [ - + ]: 2 : if (*ticket == NULL)
314 : 0 : return SHISHI_ASN1_ERROR;
315 : :
316 : 2 : return SHISHI_OK;
317 : : }
318 : :
319 : : int
320 : 2 : shishi_ticket_parse (Shishi * handle, FILE * fh, Shishi_asn1 * ticket)
321 : : {
322 : 2 : return _shishi_ticket_input (handle, fh, ticket, 0);
323 : : }
324 : :
325 : : int
326 : 0 : shishi_ticket_read (Shishi * handle, FILE * fh, Shishi_asn1 * ticket)
327 : : {
328 : 0 : return _shishi_ticket_input (handle, fh, ticket, 1);
329 : : }
330 : :
331 : : static int
332 : 2 : _shishi_enckdcreppart_input (Shishi * handle,
333 : : FILE * fh, Shishi_asn1 * enckdcreppart, int type)
334 : : {
335 : : char der[BUFSIZE];
336 : : size_t derlen;
337 : : char b64der[BUFSIZE];
338 : 2 : size_t b64len = 0;
339 : : int res;
340 : :
341 [ + - ]: 2 : if (type == 0)
342 : : {
343 : 2 : b64len = sizeof (b64der);
344 : 2 : res = _shishi_read_armored_data (handle, fh,
345 : : b64der, b64len, "EncKDCRepPart");
346 [ - + ]: 2 : if (res != SHISHI_OK)
347 : : {
348 : 0 : shishi_error_printf (handle, "armor data read fail\n");
349 : 0 : return res;
350 : : }
351 : :
352 : 2 : derlen = sizeof (der);
353 [ - + ]: 2 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
354 : 2 : return SHISHI_BASE64_ERROR;
355 : : }
356 : : else
357 : : {
358 : 0 : derlen =
359 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
360 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
361 : : {
362 : 0 : shishi_error_printf (handle,
363 : : "Error reading from file (got %d bytes)...",
364 : : derlen);
365 : 0 : return !SHISHI_OK;
366 : : }
367 : : }
368 : :
369 : 2 : *enckdcreppart = shishi_der2asn1_encasreppart (handle, der, derlen);
370 [ + + ]: 2 : if (*enckdcreppart == NULL)
371 : : {
372 : 1 : shishi_error_printf (handle, "Could not DER decode Encasreppart: %s",
373 : : shishi_error (handle));
374 : :
375 : 1 : *enckdcreppart = shishi_der2asn1_enctgsreppart (handle, der, derlen);
376 [ - + ]: 1 : if (*enckdcreppart == NULL)
377 : : {
378 : 0 : shishi_error_printf (handle,
379 : : "Could not DER decode Enctgsreppart: %s",
380 : : shishi_error (handle));
381 : :
382 : 0 : *enckdcreppart =
383 : 0 : shishi_der2asn1_enckdcreppart (handle, der, derlen);
384 [ # # ]: 0 : if (*enckdcreppart == NULL)
385 : : {
386 : 0 : shishi_error_printf (handle,
387 : : "Could not DER decode Enckdcreppart: %s",
388 : : shishi_error (handle));
389 : 0 : return !SHISHI_OK;
390 : : }
391 : : }
392 : : }
393 : :
394 : 2 : return SHISHI_OK;
395 : : }
396 : :
397 : : int
398 : 2 : shishi_enckdcreppart_parse (Shishi * handle,
399 : : FILE * fh, Shishi_asn1 * enckdcreppart)
400 : : {
401 : 2 : return _shishi_enckdcreppart_input (handle, fh, enckdcreppart, 0);
402 : : }
403 : :
404 : : int
405 : 0 : shishi_enckdcreppart_read (Shishi * handle,
406 : : FILE * fh, Shishi_asn1 * enckdcreppart)
407 : : {
408 : 0 : return _shishi_enckdcreppart_input (handle, fh, enckdcreppart, 1);
409 : : }
410 : :
411 : : int
412 : 0 : _shishi_kdcreq_input (Shishi * handle, FILE * fh, Shishi_asn1 * asreq,
413 : : int type)
414 : : {
415 : : char der[BUFSIZE];
416 : : size_t derlen;
417 : : char b64der[BUFSIZE];
418 : 0 : size_t b64len = 0;
419 : : int res;
420 : :
421 [ # # ]: 0 : if (type == 0)
422 : : {
423 : 0 : b64len = sizeof (b64der);
424 : 0 : res = _shishi_read_armored_data (handle, fh, b64der, b64len, "KDC-REQ");
425 [ # # ]: 0 : if (res != SHISHI_OK)
426 : : {
427 : 0 : shishi_error_printf (handle, "armor data read fail\n");
428 : 0 : return res;
429 : : }
430 : :
431 : 0 : derlen = sizeof (der);
432 [ # # ]: 0 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
433 : 0 : return SHISHI_BASE64_ERROR;
434 : : }
435 : : else
436 : : {
437 : 0 : derlen =
438 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
439 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
440 : : {
441 : 0 : shishi_error_printf (handle,
442 : : "Error reading from file (got %d bytes)...",
443 : : derlen);
444 : 0 : return !SHISHI_OK;
445 : : }
446 : : }
447 : :
448 : 0 : *asreq = shishi_der2asn1_asreq (handle, der, derlen);
449 [ # # ]: 0 : if (*asreq == NULL)
450 : : {
451 : 0 : printf ("bad asreq magic\n");
452 : 0 : shishi_error_printf (handle, "Could not DER decode AS-REQ\n");
453 : :
454 : 0 : *asreq = shishi_der2asn1_tgsreq (handle, der, derlen);
455 [ # # ]: 0 : if (*asreq == NULL)
456 : : {
457 : 0 : printf ("bad tgsreq magic\n");
458 : 0 : shishi_error_printf (handle, "Could not DER decode TGS-REQ\n");
459 : :
460 : 0 : *asreq = shishi_der2asn1_kdcreq (handle, der, derlen);
461 [ # # ]: 0 : if (*asreq == NULL)
462 : : {
463 : 0 : printf ("bad kdcreq magic\n");
464 : 0 : shishi_error_printf (handle, "Could not DER decode KDC-REQ\n");
465 : :
466 : 0 : return !SHISHI_OK;
467 : : }
468 : : }
469 : : }
470 : :
471 : 0 : return SHISHI_OK;
472 : : }
473 : :
474 : : int
475 : 3 : _shishi_kdcrep_input (Shishi * handle, FILE * fh, Shishi_asn1 * asrep,
476 : : int type)
477 : : {
478 : : char der[BUFSIZE];
479 : : size_t derlen;
480 : : char b64der[BUFSIZE];
481 : 3 : size_t b64len = 0;
482 : : int res;
483 : :
484 [ + - ]: 3 : if (type == 0)
485 : : {
486 : 3 : b64len = sizeof (b64der);
487 : 3 : res = _shishi_read_armored_data (handle, fh, b64der, b64len, "KDC-REP");
488 [ + + ]: 3 : if (res != SHISHI_OK)
489 : : {
490 : 1 : shishi_error_printf (handle, "armor data read fail\n");
491 : 1 : return res;
492 : : }
493 : :
494 : 2 : derlen = sizeof (der);
495 [ - + ]: 2 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
496 : 2 : return SHISHI_BASE64_ERROR;
497 : : }
498 : : else
499 : : {
500 : 0 : derlen =
501 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
502 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
503 : : {
504 : 0 : shishi_error_printf (handle,
505 : : "Error reading from file (got %d bytes)...",
506 : : derlen);
507 : 0 : return !SHISHI_OK;
508 : : }
509 : : }
510 : :
511 : 2 : *asrep = shishi_der2asn1_asrep (handle, der, derlen);
512 [ + + ]: 2 : if (*asrep == NULL)
513 : : {
514 : 1 : *asrep = shishi_der2asn1_tgsrep (handle, der, derlen);
515 [ - + ]: 1 : if (*asrep == NULL)
516 : : {
517 : 0 : printf ("Could not DER decode KDC-REP: %s\n",
518 : : shishi_error (handle));
519 : 0 : printf ("Parsing AS/TGS-REP as KDC-REP (bug work around)\n");
520 : :
521 : 0 : *asrep = shishi_der2asn1_kdcrep (handle, der, derlen);
522 [ # # ]: 0 : if (*asrep == NULL)
523 : : {
524 : 0 : fprintf (stderr, "Could not DER decode KDC-REP: %s\n",
525 : : shishi_error (handle));
526 : 0 : return !SHISHI_OK;
527 : : }
528 : :
529 : 0 : fprintf (stderr, "Bug workaround code successful...\n");
530 : : }
531 : : }
532 : :
533 : 3 : return SHISHI_OK;
534 : : }
535 : :
536 : : int
537 : 0 : _shishi_apreq_input (Shishi * handle, FILE * fh, Shishi_asn1 * apreq,
538 : : int type)
539 : : {
540 : : char der[BUFSIZE];
541 : : size_t derlen;
542 : : char b64der[BUFSIZE];
543 : 0 : size_t b64len = 0;
544 : : int res;
545 : :
546 [ # # ]: 0 : if (type == 0)
547 : : {
548 : 0 : b64len = sizeof (b64der);
549 : 0 : res = _shishi_read_armored_data (handle, fh, b64der, b64len, "AP-REQ");
550 [ # # ]: 0 : if (res != SHISHI_OK)
551 : : {
552 : 0 : shishi_error_printf (handle, "armor data read fail\n");
553 : 0 : return res;
554 : : }
555 : :
556 : 0 : derlen = sizeof (der);
557 [ # # ]: 0 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
558 : 0 : return SHISHI_BASE64_ERROR;
559 : : }
560 : : else
561 : : {
562 : 0 : derlen =
563 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
564 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
565 : : {
566 : 0 : shishi_error_printf (handle,
567 : : "Error reading from file (got %d bytes)...",
568 : : derlen);
569 : 0 : return !SHISHI_OK;
570 : : }
571 : : }
572 : :
573 : 0 : *apreq = shishi_der2asn1_apreq (handle, der, derlen);
574 [ # # ]: 0 : if (*apreq == NULL)
575 : : {
576 : 0 : printf ("bad magic %s\n", shishi_error (handle));
577 : 0 : shishi_error_printf (handle, "Could not DER decode AP-REQ\n");
578 : :
579 : 0 : return !SHISHI_OK;
580 : : }
581 : :
582 : 0 : return SHISHI_OK;
583 : : }
584 : :
585 : : int
586 : 0 : _shishi_aprep_input (Shishi * handle, FILE * fh, Shishi_asn1 * aprep,
587 : : int type)
588 : : {
589 : : char der[BUFSIZE];
590 : : size_t derlen;
591 : : char b64der[BUFSIZE];
592 : 0 : size_t b64len = 0;
593 : : int res;
594 : :
595 [ # # ]: 0 : if (type == 0)
596 : : {
597 : 0 : b64len = sizeof (b64der);
598 : 0 : res = _shishi_read_armored_data (handle, fh, b64der, b64len, "AP-REP");
599 [ # # ]: 0 : if (res != SHISHI_OK)
600 : : {
601 : 0 : shishi_error_printf (handle, "armor data read fail\n");
602 : 0 : return res;
603 : : }
604 : :
605 : 0 : derlen = sizeof (der);
606 [ # # ]: 0 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
607 : 0 : return SHISHI_BASE64_ERROR;
608 : : }
609 : : else
610 : : {
611 : 0 : derlen =
612 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
613 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
614 : : {
615 : 0 : shishi_error_printf (handle,
616 : : "Error reading from file (got %d bytes)...",
617 : : derlen);
618 : 0 : return !SHISHI_OK;
619 : : }
620 : : }
621 : :
622 : 0 : *aprep = shishi_der2asn1_aprep (handle, der, derlen);
623 [ # # ]: 0 : if (*aprep == NULL)
624 : : {
625 : 0 : printf ("bad magic %s\n", shishi_error (handle));
626 : 0 : shishi_error_printf (handle, "Could not DER decode AP-REP\n");
627 : :
628 : 0 : return !SHISHI_OK;
629 : : }
630 : :
631 : 0 : return SHISHI_OK;
632 : : }
633 : :
634 : : int
635 : 0 : _shishi_encapreppart_input (Shishi * handle, FILE * fh,
636 : : Shishi_asn1 * encapreppart, int type)
637 : : {
638 : : char der[BUFSIZE];
639 : : size_t derlen;
640 : : char b64der[BUFSIZE];
641 : 0 : size_t b64len = 0;
642 : : int res;
643 : :
644 [ # # ]: 0 : if (type == 0)
645 : : {
646 : 0 : b64len = sizeof (b64der);
647 : 0 : res =
648 : 0 : _shishi_read_armored_data (handle, fh, b64der, b64len,
649 : : "EncAPRepPart");
650 [ # # ]: 0 : if (res != SHISHI_OK)
651 : : {
652 : 0 : shishi_error_printf (handle, "armor data read fail\n");
653 : 0 : return res;
654 : : }
655 : :
656 : 0 : derlen = sizeof (der);
657 [ # # ]: 0 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
658 : 0 : return SHISHI_BASE64_ERROR;
659 : : }
660 : : else
661 : : {
662 : 0 : derlen =
663 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
664 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
665 : : {
666 : 0 : shishi_error_printf (handle,
667 : : "Error reading from file (got %d bytes)...",
668 : : derlen);
669 : 0 : return !SHISHI_OK;
670 : : }
671 : : }
672 : :
673 : 0 : *encapreppart = shishi_der2asn1_encapreppart (handle, der, derlen);
674 [ # # ]: 0 : if (*encapreppart == NULL)
675 : : {
676 : 0 : printf ("bad magic %s\n", shishi_error (handle));
677 : 0 : shishi_error_printf (handle, "Could not DER decode EncAPRepPart\n");
678 : :
679 : 0 : return !SHISHI_OK;
680 : : }
681 : :
682 : 0 : return SHISHI_OK;
683 : : }
684 : :
685 : : int
686 : 1 : _shishi_authenticator_input (Shishi * handle,
687 : : FILE * fh, Shishi_asn1 * authenticator, int type)
688 : : {
689 : : char der[BUFSIZE];
690 : : size_t derlen;
691 : : char b64der[BUFSIZE];
692 : 1 : size_t b64len = 0;
693 : : int res;
694 : :
695 [ + - ]: 1 : if (type == 0)
696 : : {
697 : 1 : b64len = sizeof (b64der);
698 : 1 : res = _shishi_read_armored_data (handle, fh, b64der, b64len,
699 : : "Authenticator");
700 [ - + ]: 1 : if (res != SHISHI_OK)
701 : : {
702 : 0 : shishi_error_printf (handle, "armor data read fail\n");
703 : 0 : return res;
704 : : }
705 : :
706 : 1 : derlen = sizeof (der);
707 [ - + ]: 1 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
708 : 1 : return SHISHI_BASE64_ERROR;
709 : : }
710 : : else
711 : : {
712 : 0 : derlen =
713 : 0 : fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
714 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
715 : : {
716 : 0 : shishi_error_printf (handle,
717 : : "Error reading from file (got %d bytes)...",
718 : : derlen);
719 : 0 : return !SHISHI_OK;
720 : : }
721 : : }
722 : :
723 : 1 : *authenticator = shishi_der2asn1_authenticator (handle, der, derlen);
724 [ - + ]: 1 : if (*authenticator == NULL)
725 : : {
726 : 0 : printf ("bad magic %s\n", shishi_error (handle));
727 : 0 : shishi_error_printf (handle, "Could not DER decode AP-REQ\n");
728 : :
729 : 0 : return !SHISHI_OK;
730 : : }
731 : :
732 : 1 : return SHISHI_OK;
733 : : }
734 : :
735 : : int
736 : 0 : _shishi_krberror_input (Shishi * handle,
737 : : FILE * fh, Shishi_asn1 * krberror, int type)
738 : : {
739 : : char der[BUFSIZE];
740 : : size_t derlen;
741 : : char b64der[BUFSIZE];
742 : 0 : size_t b64len = 0;
743 : : int res;
744 : :
745 [ # # ]: 0 : if (type == 0)
746 : : {
747 : 0 : b64len = sizeof (b64der);
748 : 0 : res = _shishi_read_armored_data (handle, fh, b64der, b64len,
749 : : "KRB-ERROR");
750 [ # # ]: 0 : if (res != SHISHI_OK)
751 : : {
752 : 0 : shishi_error_printf (handle, "armor data read fail\n");
753 : 0 : return res;
754 : : }
755 : :
756 : 0 : derlen = sizeof (der);
757 [ # # ]: 0 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
758 : 0 : return SHISHI_BASE64_ERROR;
759 : : }
760 : : else
761 : : {
762 : 0 : derlen = fread (der, sizeof (der[0]),
763 : : sizeof (der) / sizeof (der[0]), fh);
764 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
765 : : {
766 : 0 : shishi_error_printf (handle,
767 : : "Error reading from file (got %d bytes)...",
768 : : derlen);
769 : 0 : return !SHISHI_OK;
770 : : }
771 : : }
772 : :
773 : 0 : *krberror = shishi_der2asn1_krberror (handle, der, derlen);
774 [ # # ]: 0 : if (*krberror == NULL)
775 : : {
776 : 0 : printf ("bad magic %s\n", shishi_error (handle));
777 : 0 : shishi_error_printf (handle, "Could not DER decode AP-REQ\n");
778 : :
779 : 0 : return !SHISHI_OK;
780 : : }
781 : :
782 : 0 : return SHISHI_OK;
783 : : }
784 : :
785 : : int
786 : 1 : _shishi_safe_input (Shishi * handle, FILE * fh, Shishi_asn1 * safe, int type)
787 : : {
788 : : char der[BUFSIZE];
789 : : size_t derlen;
790 : : char b64der[BUFSIZE];
791 : 1 : size_t b64len = 0;
792 : : int res;
793 : :
794 [ + - ]: 1 : if (type == 0)
795 : : {
796 : 1 : b64len = sizeof (b64der);
797 : 1 : res = _shishi_read_armored_data (handle, fh, b64der, b64len,
798 : : "KRB-SAFE");
799 [ - + ]: 1 : if (res != SHISHI_OK)
800 : : {
801 : 0 : shishi_error_printf (handle, "armor data read fail\n");
802 : 0 : return res;
803 : : }
804 : :
805 : 1 : derlen = sizeof (der);
806 [ - + ]: 1 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
807 : 1 : return SHISHI_BASE64_ERROR;
808 : : }
809 : : else
810 : : {
811 : 0 : derlen = fread (der, sizeof (der[0]),
812 : : sizeof (der) / sizeof (der[0]), fh);
813 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
814 : : {
815 : 0 : shishi_error_printf (handle,
816 : : "Error reading from file (got %d bytes)...",
817 : : derlen);
818 : 0 : return !SHISHI_OK;
819 : : }
820 : : }
821 : :
822 : 1 : *safe = shishi_der2asn1_krbsafe (handle, der, derlen);
823 [ - + ]: 1 : if (*safe == NULL)
824 : : {
825 : 0 : printf ("bad magic %s\n", shishi_error (handle));
826 : 0 : shishi_error_printf (handle, "Could not DER decode KRB-SAFE\n");
827 : :
828 : 0 : return !SHISHI_OK;
829 : : }
830 : :
831 : 1 : return SHISHI_OK;
832 : : }
833 : :
834 : : int
835 : 1 : _shishi_priv_input (Shishi * handle, FILE * fh, Shishi_asn1 * priv, int type)
836 : : {
837 : : char der[BUFSIZE];
838 : : size_t derlen;
839 : : char b64der[BUFSIZE];
840 : 1 : size_t b64len = 0;
841 : : int res;
842 : :
843 [ + - ]: 1 : if (type == 0)
844 : : {
845 : 1 : b64len = sizeof (b64der);
846 : 1 : res = _shishi_read_armored_data (handle, fh, b64der, b64len,
847 : : "KRB-PRIV");
848 [ - + ]: 1 : if (res != SHISHI_OK)
849 : : {
850 : 0 : shishi_error_printf (handle, "armor data read fail\n");
851 : 0 : return res;
852 : : }
853 : :
854 : 1 : derlen = sizeof (der);
855 [ - + ]: 1 : if (!base64_decode (b64der, strlen (b64der), der, &derlen))
856 : 1 : return SHISHI_BASE64_ERROR;
857 : : }
858 : : else
859 : : {
860 : 0 : derlen = fread (der, sizeof (der[0]),
861 : : sizeof (der) / sizeof (der[0]), fh);
862 [ # # # # ]: 0 : if (derlen <= 0 || !feof (fh) || ferror (fh))
[ # # ]
863 : : {
864 : 0 : shishi_error_printf (handle,
865 : : "Error reading from file (got %d bytes)...",
866 : : derlen);
867 : 0 : return !SHISHI_OK;
868 : : }
869 : : }
870 : :
871 : 1 : *priv = shishi_der2asn1_priv (handle, der, derlen);
872 [ - + ]: 1 : if (*priv == NULL)
873 : : {
874 : 0 : printf ("bad magic %s\n", shishi_error (handle));
875 : 0 : shishi_error_printf (handle, "Could not DER decode KRB-PRIV\n");
876 : :
877 : 0 : return !SHISHI_OK;
878 : : }
879 : :
880 : 1 : return SHISHI_OK;
881 : : }
882 : :
883 : : int
884 : 0 : shishi_key_parse (Shishi * handle, FILE * fh, Shishi_key ** key)
885 : : {
886 : 0 : int lno = 0;
887 : : char line[BUFSIZE];
888 : : char *b64buffer;
889 : : char armorbegin[BUFSIZE];
890 : : char armorend[BUFSIZE];
891 : 0 : int in_key = 0, in_body = 0;
892 : : int res;
893 : : size_t len;
894 : 0 : Shishi_key *lkey = NULL;
895 : :
896 : 0 : sprintf (armorbegin, HEADERBEG, "KEY");
897 : 0 : sprintf (armorend, HEADEREND, "KEY");
898 : :
899 : 0 : len = 0;
900 [ # # ]: 0 : while (fgets (line, sizeof (line), fh))
901 : : {
902 : 0 : lno++;
903 : 0 : line[sizeof (line) - 1] = '\0';
904 [ # # ][ # # ]: 0 : if (!*line || line[strlen (line) - 1] != '\n')
905 : : {
906 : 0 : fprintf (stderr, "input line %u too long or missing LF\n", lno);
907 : 0 : continue;
908 : : }
909 : 0 : line[strlen (line) - 1] = '\0';
910 [ # # ]: 0 : if (VERBOSENOISE (handle))
911 : 0 : printf ("line %d read %d bytes: %s\n", lno, strlen (line), line);
912 : :
913 [ # # ]: 0 : if (!in_key)
914 : : {
915 : 0 : in_key = strncmp (line, armorbegin, strlen (armorbegin)) == 0;
916 [ # # ]: 0 : if (in_key)
917 : : {
918 : 0 : res = shishi_key (handle, &lkey);
919 [ # # ]: 0 : if (res != SHISHI_OK)
920 : 0 : return res;
921 : :
922 : : }
923 : 0 : continue;
924 : : }
925 : :
926 [ # # ]: 0 : if (strcmp (line, armorend) == 0)
927 : 0 : break;
928 : :
929 [ # # ]: 0 : if (in_body)
930 : : {
931 : : int ok =
932 : 0 : base64_decode_alloc (line, strlen (line), &b64buffer, NULL);
933 [ # # ]: 0 : if (!ok)
934 : 0 : return SHISHI_BASE64_ERROR;
935 : 0 : shishi_key_value_set (lkey, b64buffer);
936 : : }
937 : : else
938 : : {
939 [ # # ][ # # ]: 0 : if (strcmp (line, "") == 0 || strcmp (line, " ") == 0)
940 : 0 : in_body = 1;
941 : :
942 [ # # ]: 0 : if (strncmp (line, "Keytype: ", strlen ("Keytype: ")) == 0)
943 : : {
944 : : int type;
945 [ # # ]: 0 : if (sscanf (line, "Keytype: %d (", &type) == 1)
946 : 0 : shishi_key_type_set (lkey, type);
947 : : }
948 [ # # ]: 0 : else if (strncmp (line, "Key-Version-Number: ",
949 : : strlen ("Key-Version-Number: ")) == 0)
950 : : {
951 : : int type;
952 [ # # ]: 0 : if (sscanf (line, "Key-Version-Number: %d", &type) == 1)
953 : 0 : shishi_key_version_set (lkey, type);
954 : : }
955 [ # # ]: 0 : else if (strncmp (line, "Realm: ", strlen ("Realm: ")) == 0)
956 : : {
957 : 0 : shishi_key_realm_set (lkey, line + strlen ("Realm: "));
958 : : }
959 [ # # ]: 0 : else if (strncmp (line, "Principal: ", strlen ("Principal: ")) == 0)
960 : : {
961 : 0 : shishi_key_principal_set (lkey, line + strlen ("Principal: "));
962 : : }
963 : : }
964 : : }
965 : :
966 [ # # ]: 0 : if (!lkey)
967 : 0 : return SHISHI_OK;
968 : :
969 : 0 : *key = lkey;
970 : :
971 : 0 : return SHISHI_OK;
972 : : }
973 : :
974 : : /**
975 : : * shishi_key_print:
976 : : * @handle: shishi handle as allocated by shishi_init().
977 : : * @fh: file handle opened for writing.
978 : : * @key: key to print.
979 : : *
980 : : * Print an ASCII representation of a key structure to file
981 : : * descriptor. Example output:
982 : : *
983 : : * -----BEGIN SHISHI KEY-----
984 : : * Keytype: 18 (aes256-cts-hmac-sha1-96)
985 : : * Principal: host/latte.josefsson.org
986 : : * Realm: JOSEFSSON.ORG
987 : : * Key-Version-Number: 1
988 : : *
989 : : * P1QdeW/oSiag/bTyVEBAY2msiGSTmgLXlopuCKoppDs=
990 : : * -----END SHISHI KEY-----
991 : : *
992 : : * Return value: Returns SHISHI_OK iff successful.
993 : : **/
994 : : int
995 : 0 : shishi_key_print (Shishi * handle, FILE * fh, const Shishi_key * key)
996 : : {
997 : : char *b64key;
998 : : size_t i;
999 : :
1000 : 0 : base64_encode_alloc (shishi_key_value (key), shishi_key_length (key),
1001 : : &b64key);
1002 : :
1003 [ # # ]: 0 : if (!b64key)
1004 : 0 : return SHISHI_MALLOC_ERROR;
1005 : :
1006 : 0 : fprintf (fh, HEADERBEG "\n", "KEY");
1007 : :
1008 : 0 : fprintf (fh, "Keytype: %d (%s)\n", shishi_key_type (key),
1009 : : shishi_cipher_name (shishi_key_type (key)));
1010 [ # # ]: 0 : if (shishi_key_principal (key))
1011 : 0 : fprintf (fh, "Principal: %s\n", shishi_key_principal (key));
1012 [ # # ]: 0 : if (shishi_key_realm (key))
1013 : 0 : fprintf (fh, "Realm: %s\n", shishi_key_realm (key));
1014 [ # # ]: 0 : if (shishi_key_version (key) != UINT32_MAX)
1015 : 0 : fprintf (fh, "Key-Version-Number: %d\n", shishi_key_version (key));
1016 : 0 : fprintf (fh, "\n");
1017 : :
1018 [ # # ]: 0 : for (i = 0; i < strlen (b64key); i++)
1019 : : {
1020 : 0 : fprintf (fh, "%c", b64key[i]);
1021 [ # # ]: 0 : if ((i + 1) % 64 == 0)
1022 : 0 : fprintf (fh, "\n");
1023 : : }
1024 [ # # ]: 0 : if ((i + 1) % 64 != 0)
1025 : 0 : fprintf (fh, "\n");
1026 : :
1027 : 0 : free (b64key);
1028 : :
1029 : : #if 0
1030 : : if (VERBOSENOISE (handle))
1031 : : {
1032 : : for (i = 0; i < shishi_key_length (key); i++)
1033 : : fprintf (stdout, "%02x", shishi_key_value (key)[i] & 0xFF);
1034 : : fprintf (stdout, "\n");
1035 : : }
1036 : : #endif
1037 : :
1038 : 0 : fprintf (fh, HEADEREND "\n", "KEY");
1039 : :
1040 : 0 : return SHISHI_OK;
1041 : : }
1042 : :
1043 : : /**
1044 : : * shishi_key_to_file:
1045 : : * @handle: shishi handle as allocated by shishi_init().
1046 : : * @filename: filename to append key to.
1047 : : * @key: key to print.
1048 : : *
1049 : : * Print an ASCII representation of a key structure to a file. The
1050 : : * file is appended to if it exists. See shishi_key_print() for
1051 : : * format of output.
1052 : : *
1053 : : * Return value: Returns SHISHI_OK iff successful.
1054 : : **/
1055 : : int
1056 : 0 : shishi_key_to_file (Shishi * handle, const char *filename, Shishi_key * key)
1057 : : {
1058 : : FILE *fh;
1059 : : int res;
1060 : :
1061 [ # # ]: 0 : if (VERBOSE (handle))
1062 : 0 : printf (_("Writing KEY to %s...\n"), filename);
1063 : :
1064 : 0 : fh = fopen (filename, "a");
1065 [ # # ]: 0 : if (fh == NULL)
1066 : 0 : return SHISHI_FOPEN_ERROR;
1067 : :
1068 : 0 : res = shishi_key_print (handle, fh, key);
1069 [ # # ]: 0 : if (res != SHISHI_OK)
1070 : 0 : return res;
1071 : :
1072 : 0 : res = fclose (fh);
1073 [ # # ]: 0 : if (res != 0)
1074 : 0 : return SHISHI_IO_ERROR;
1075 : :
1076 [ # # ]: 0 : if (VERBOSE (handle))
1077 : 0 : printf (_("Writing KEY to %s...done\n"), filename);
1078 : :
1079 : 0 : return SHISHI_OK;
1080 : : }
|