No need for getline.h.
[shishi.git] / lib / diskio.c
blob4e85930f7494cb4c3a9a7bd2e0124bd619eb8d4f
1 /* diskio.c --- Read and write data structures from disk.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
23 /* XXX oh, please, rewrite this file. */
25 #include <libtasn1.h>
26 #define _SHISHI_HAS_LIBTASN1_H 1
27 #include "internal.h"
28 #include "diskio.h"
30 #define HEADERBEG "-----BEGIN SHISHI %s-----"
31 #define HEADEREND "-----END SHISHI %s-----"
34 * Note to self: if you change any *print* function, remember to change
35 * the corresponding *parse* function too.
39 static char *
40 armor_data (const char *data, size_t len,
41 const char *armortype,
42 const char *armorheaders)
44 /* Must be a multiple of 4. */
45 #define WRAP_COL 64
46 char *armorbegin, *armorend;
47 char *b64data, *out;
48 size_t wrapb64len = BASE64_LENGTH (len) + BASE64_LENGTH (len) / WRAP_COL + 1;
49 size_t i;
51 b64data = xmalloc (wrapb64len + 1);
53 for (i = 0; i <= BASE64_LENGTH (len) / WRAP_COL; i++)
55 size_t readpos = i * WRAP_COL * 3 /4;
56 size_t nread = WRAP_COL * 3 /4;
57 size_t storepos = i * WRAP_COL + i;
58 size_t nstore = WRAP_COL;
60 if (readpos >= len)
61 break;
63 if (readpos + nread >= len)
65 nread = len - readpos;
66 nstore = BASE64_LENGTH (nread);
69 base64_encode (data + readpos, nread, b64data + storepos, nstore);
70 b64data[storepos + nstore] = '\n';
71 b64data[storepos + nstore + 1] = '\0';
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
81 armorbegin = xasprintf (HEADERBEG, armortype);
82 armorend = xasprintf (HEADEREND, armortype);
84 out = xasprintf ("%s\n%s%s%s%s\n",
85 armorbegin,
86 armorheaders ? armorheaders : "",
87 armorheaders ? "\n" : "",
88 b64data,
89 armorend);
91 free (b64data);
92 free (armorend);
93 free (armorbegin);
95 return out;
98 static char *
99 armor_asn1 (Shishi * handle,
100 Shishi_asn1 asn1,
101 const char *armortype,
102 const char *armorheaders)
104 char *der;
105 size_t derlen;
106 char *out;
107 int rc;
109 rc = shishi_asn1_to_der (handle, asn1, &der, &derlen);
110 if (rc != SHISHI_OK)
111 return NULL;
113 out = armor_data (der, derlen, armortype, armorheaders);
115 free (der);
117 return out;
121 _shishi_print_armored_data (Shishi * handle,
122 FILE * fh,
123 Shishi_asn1 asn1,
124 const char *asn1type, char *headers)
126 char *data = armor_asn1 (handle, asn1, asn1type, headers);
128 asn1_print_structure (fh, asn1, "", ASN1_PRINT_NAME_TYPE_VALUE);
130 fprintf (fh, "%s\n", data);
132 return SHISHI_OK;
136 _shishi_save_data (Shishi * handle, FILE * fh, Shishi_asn1 asn1,
137 const char *asn1type)
139 char *der;
140 size_t derlen;
141 size_t i;
142 int res;
144 res = shishi_asn1_to_der_field (handle, asn1, asn1type, &der, &derlen);
145 if (res != SHISHI_OK)
146 return res;
148 i = fwrite (der, sizeof (der[0]), derlen, fh);
149 if (i != derlen)
150 return SHISHI_IO_ERROR;
152 return SHISHI_OK;
156 shishi_padata_print (Shishi * handle, FILE * fh, Shishi_asn1 padata)
158 return _shishi_print_armored_data (handle, fh, padata, "PA-DATA", NULL);
162 shishi_methoddata_print (Shishi * handle, FILE * fh, Shishi_asn1 methoddata)
164 return _shishi_print_armored_data (handle, fh, methoddata,
165 "METHOD-DATA", NULL);
169 shishi_etype_info_print (Shishi * handle, FILE * fh, Shishi_asn1 etypeinfo)
171 return _shishi_print_armored_data (handle, fh, etypeinfo,
172 "ETYPE-INFO", NULL);
176 shishi_etype_info2_print (Shishi * handle, FILE * fh, Shishi_asn1 etypeinfo2)
178 return _shishi_print_armored_data (handle, fh, etypeinfo2,
179 "ETYPE-INFO2", NULL);
183 shishi_enckdcreppart_print (Shishi * handle,
184 FILE * fh, Shishi_asn1 enckdcreppart)
186 return _shishi_print_armored_data (handle, fh, enckdcreppart,
187 "EncKDCRepPart", NULL);
191 shishi_enckdcreppart_save (Shishi * handle,
192 FILE * fh, Shishi_asn1 enckdcreppart)
194 return _shishi_save_data (handle, fh, enckdcreppart, "EncKDCRepPart");
198 shishi_ticket_save (Shishi * handle, FILE * fh, Shishi_asn1 ticket)
200 return _shishi_save_data (handle, fh, ticket, "Ticket");
204 shishi_ticket_print (Shishi * handle, FILE * fh, Shishi_asn1 ticket)
206 return _shishi_print_armored_data (handle, fh, ticket, "Ticket", NULL);
210 shishi_encticketpart_print (Shishi * handle, FILE * fh,
211 Shishi_asn1 encticketpart)
213 return _shishi_print_armored_data (handle, fh, encticketpart,
214 "EncTicketPart", NULL);
217 static int
218 _shishi_read_armored_data (Shishi * handle,
219 FILE * fh, char *buffer, size_t len,
220 const char *tag)
222 char *line = NULL;
223 size_t linelen = 0;
224 char *armorbegin, *armorend;
225 int phase = 0;
226 int res = SHISHI_OK;
228 armorbegin = xasprintf (HEADERBEG, tag);
229 armorend = xasprintf (HEADEREND, tag);
231 while (getline (&line, &linelen, fh) > 0)
233 if (line[strlen (line) - 1] == '\r')
234 line[strlen (line) - 1] = '\0';
235 if (line[strlen (line) - 1] == '\n')
236 line[strlen (line) - 1] = '\0';
238 if (phase == 1)
240 if (strcmp (line, armorend) == 0)
242 phase = 2;
243 break;
246 else
248 if (strcmp (line, armorbegin) == 0)
249 phase = 1;
250 continue;
253 if (len <= strlen (line))
255 res = SHISHI_TOO_SMALL_BUFFER;
256 goto done;
259 memcpy (buffer, line, strlen (line));
260 buffer += strlen (line);
261 len -= strlen (line);
264 if (len == 0)
265 res = SHISHI_TOO_SMALL_BUFFER;
266 else
267 *buffer = '\0';
269 if (phase != 2)
270 res = SHISHI_IO_ERROR;
272 done:
274 free (armorbegin);
275 free (armorend);
276 if (line)
277 free (line);
279 return res;
282 static int
283 _shishi_ticket_input (Shishi * handle,
284 FILE * fh, Shishi_asn1 * ticket, int type)
286 char der[BUFSIZ];
287 size_t derlen;
288 char b64der[BUFSIZ];
289 size_t b64len = 0;
290 int res;
292 if (type == 0)
294 b64len = sizeof (b64der);
295 res = _shishi_read_armored_data (handle, fh, b64der, b64len, "Ticket");
296 if (res != SHISHI_OK)
298 shishi_error_printf (handle, "armor data read fail\n");
299 return res;
302 derlen = sizeof (der);
303 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
304 return SHISHI_BASE64_ERROR;
306 else
308 derlen =
309 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
310 if (derlen <= 0 || !feof (fh) || ferror (fh))
312 shishi_error_printf (handle,
313 "Error reading from file (got %d bytes)...",
314 derlen);
315 return !SHISHI_OK;
319 *ticket = shishi_der2asn1_ticket (handle, der, derlen);
320 if (*ticket == NULL)
321 return SHISHI_ASN1_ERROR;
323 return SHISHI_OK;
327 shishi_ticket_parse (Shishi * handle, FILE * fh, Shishi_asn1 * ticket)
329 return _shishi_ticket_input (handle, fh, ticket, 0);
333 shishi_ticket_read (Shishi * handle, FILE * fh, Shishi_asn1 * ticket)
335 return _shishi_ticket_input (handle, fh, ticket, 1);
338 static int
339 _shishi_enckdcreppart_input (Shishi * handle,
340 FILE * fh, Shishi_asn1 * enckdcreppart, int type)
342 char der[BUFSIZ];
343 size_t derlen;
344 char b64der[BUFSIZ];
345 size_t b64len = 0;
346 int res;
348 if (type == 0)
350 b64len = sizeof (b64der);
351 res = _shishi_read_armored_data (handle, fh,
352 b64der, b64len, "EncKDCRepPart");
353 if (res != SHISHI_OK)
355 shishi_error_printf (handle, "armor data read fail\n");
356 return res;
359 derlen = sizeof (der);
360 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
361 return SHISHI_BASE64_ERROR;
363 else
365 derlen =
366 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
367 if (derlen <= 0 || !feof (fh) || ferror (fh))
369 shishi_error_printf (handle,
370 "Error reading from file (got %d bytes)...",
371 derlen);
372 return !SHISHI_OK;
376 *enckdcreppart = shishi_der2asn1_encasreppart (handle, der, derlen);
377 if (*enckdcreppart == NULL)
379 shishi_error_printf (handle, "Could not DER decode Encasreppart: %s",
380 shishi_error (handle));
382 *enckdcreppart = shishi_der2asn1_enctgsreppart (handle, der, derlen);
383 if (*enckdcreppart == NULL)
385 shishi_error_printf (handle,
386 "Could not DER decode Enctgsreppart: %s",
387 shishi_error (handle));
389 *enckdcreppart =
390 shishi_der2asn1_enckdcreppart (handle, der, derlen);
391 if (*enckdcreppart == NULL)
393 shishi_error_printf (handle,
394 "Could not DER decode Enckdcreppart: %s",
395 shishi_error (handle));
396 return !SHISHI_OK;
401 return SHISHI_OK;
405 shishi_enckdcreppart_parse (Shishi * handle,
406 FILE * fh, Shishi_asn1 * enckdcreppart)
408 return _shishi_enckdcreppart_input (handle, fh, enckdcreppart, 0);
412 shishi_enckdcreppart_read (Shishi * handle,
413 FILE * fh, Shishi_asn1 * enckdcreppart)
415 return _shishi_enckdcreppart_input (handle, fh, enckdcreppart, 1);
419 _shishi_kdcreq_input (Shishi * handle, FILE * fh, Shishi_asn1 * asreq,
420 int type)
422 char der[BUFSIZ];
423 size_t derlen;
424 char b64der[BUFSIZ];
425 size_t b64len = 0;
426 int res;
428 if (type == 0)
430 b64len = sizeof (b64der);
431 res = _shishi_read_armored_data (handle, fh, b64der, b64len, "KDC-REQ");
432 if (res != SHISHI_OK)
434 shishi_error_printf (handle, "armor data read fail\n");
435 return res;
438 derlen = sizeof (der);
439 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
440 return SHISHI_BASE64_ERROR;
442 else
444 derlen =
445 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
446 if (derlen <= 0 || !feof (fh) || ferror (fh))
448 shishi_error_printf (handle,
449 "Error reading from file (got %d bytes)...",
450 derlen);
451 return !SHISHI_OK;
455 *asreq = shishi_der2asn1_asreq (handle, der, derlen);
456 if (*asreq == NULL)
458 printf ("bad asreq magic\n");
459 shishi_error_printf (handle, "Could not DER decode AS-REQ\n");
461 *asreq = shishi_der2asn1_tgsreq (handle, der, derlen);
462 if (*asreq == NULL)
464 printf ("bad tgsreq magic\n");
465 shishi_error_printf (handle, "Could not DER decode TGS-REQ\n");
467 *asreq = shishi_der2asn1_kdcreq (handle, der, derlen);
468 if (*asreq == NULL)
470 printf ("bad kdcreq magic\n");
471 shishi_error_printf (handle, "Could not DER decode KDC-REQ\n");
473 return !SHISHI_OK;
478 return SHISHI_OK;
482 _shishi_kdcrep_input (Shishi * handle, FILE * fh, Shishi_asn1 * asrep,
483 int type)
485 char der[BUFSIZ];
486 size_t derlen;
487 char b64der[BUFSIZ];
488 size_t b64len = 0;
489 int res;
491 if (type == 0)
493 b64len = sizeof (b64der);
494 res = _shishi_read_armored_data (handle, fh, b64der, b64len, "KDC-REP");
495 if (res != SHISHI_OK)
497 shishi_error_printf (handle, "armor data read fail\n");
498 return res;
501 derlen = sizeof (der);
502 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
503 return SHISHI_BASE64_ERROR;
505 else
507 derlen =
508 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
509 if (derlen <= 0 || !feof (fh) || ferror (fh))
511 shishi_error_printf (handle,
512 "Error reading from file (got %d bytes)...",
513 derlen);
514 return !SHISHI_OK;
518 *asrep = shishi_der2asn1_asrep (handle, der, derlen);
519 if (*asrep == NULL)
521 *asrep = shishi_der2asn1_tgsrep (handle, der, derlen);
522 if (*asrep == NULL)
524 printf ("Could not DER decode KDC-REP: %s\n",
525 shishi_error (handle));
526 printf ("Parsing AS/TGS-REP as KDC-REP (bug work around)\n");
528 *asrep = shishi_der2asn1_kdcrep (handle, der, derlen);
529 if (*asrep == NULL)
531 fprintf (stderr, "Could not DER decode KDC-REP: %s\n",
532 shishi_error (handle));
533 return !SHISHI_OK;
536 fprintf (stderr, "Bug workaround code successful...\n");
540 return SHISHI_OK;
544 _shishi_apreq_input (Shishi * handle, FILE * fh, Shishi_asn1 * apreq,
545 int type)
547 char der[BUFSIZ];
548 size_t derlen;
549 char b64der[BUFSIZ];
550 size_t b64len = 0;
551 int res;
553 if (type == 0)
555 b64len = sizeof (b64der);
556 res = _shishi_read_armored_data (handle, fh, b64der, b64len, "AP-REQ");
557 if (res != SHISHI_OK)
559 shishi_error_printf (handle, "armor data read fail\n");
560 return res;
563 derlen = sizeof (der);
564 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
565 return SHISHI_BASE64_ERROR;
567 else
569 derlen =
570 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
571 if (derlen <= 0 || !feof (fh) || ferror (fh))
573 shishi_error_printf (handle,
574 "Error reading from file (got %d bytes)...",
575 derlen);
576 return !SHISHI_OK;
580 *apreq = shishi_der2asn1_apreq (handle, der, derlen);
581 if (*apreq == NULL)
583 printf ("bad magic %s\n", shishi_error (handle));
584 shishi_error_printf (handle, "Could not DER decode AP-REQ\n");
586 return !SHISHI_OK;
589 return SHISHI_OK;
593 _shishi_aprep_input (Shishi * handle, FILE * fh, Shishi_asn1 * aprep,
594 int type)
596 char der[BUFSIZ];
597 size_t derlen;
598 char b64der[BUFSIZ];
599 size_t b64len = 0;
600 int res;
602 if (type == 0)
604 b64len = sizeof (b64der);
605 res = _shishi_read_armored_data (handle, fh, b64der, b64len, "AP-REP");
606 if (res != SHISHI_OK)
608 shishi_error_printf (handle, "armor data read fail\n");
609 return res;
612 derlen = sizeof (der);
613 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
614 return SHISHI_BASE64_ERROR;
616 else
618 derlen =
619 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
620 if (derlen <= 0 || !feof (fh) || ferror (fh))
622 shishi_error_printf (handle,
623 "Error reading from file (got %d bytes)...",
624 derlen);
625 return !SHISHI_OK;
629 *aprep = shishi_der2asn1_aprep (handle, der, derlen);
630 if (*aprep == NULL)
632 printf ("bad magic %s\n", shishi_error (handle));
633 shishi_error_printf (handle, "Could not DER decode AP-REP\n");
635 return !SHISHI_OK;
638 return SHISHI_OK;
642 _shishi_encapreppart_input (Shishi * handle, FILE * fh,
643 Shishi_asn1 * encapreppart, int type)
645 char der[BUFSIZ];
646 size_t derlen;
647 char b64der[BUFSIZ];
648 size_t b64len = 0;
649 int res;
651 if (type == 0)
653 b64len = sizeof (b64der);
654 res =
655 _shishi_read_armored_data (handle, fh, b64der, b64len,
656 "EncAPRepPart");
657 if (res != SHISHI_OK)
659 shishi_error_printf (handle, "armor data read fail\n");
660 return res;
663 derlen = sizeof (der);
664 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
665 return SHISHI_BASE64_ERROR;
667 else
669 derlen =
670 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
671 if (derlen <= 0 || !feof (fh) || ferror (fh))
673 shishi_error_printf (handle,
674 "Error reading from file (got %d bytes)...",
675 derlen);
676 return !SHISHI_OK;
680 *encapreppart = shishi_der2asn1_encapreppart (handle, der, derlen);
681 if (*encapreppart == NULL)
683 printf ("bad magic %s\n", shishi_error (handle));
684 shishi_error_printf (handle, "Could not DER decode EncAPRepPart\n");
686 return !SHISHI_OK;
689 return SHISHI_OK;
693 _shishi_authenticator_input (Shishi * handle,
694 FILE * fh, Shishi_asn1 * authenticator, int type)
696 char der[BUFSIZ];
697 size_t derlen;
698 char b64der[BUFSIZ];
699 size_t b64len = 0;
700 int res;
702 if (type == 0)
704 b64len = sizeof (b64der);
705 res = _shishi_read_armored_data (handle, fh, b64der, b64len,
706 "Authenticator");
707 if (res != SHISHI_OK)
709 shishi_error_printf (handle, "armor data read fail\n");
710 return res;
713 derlen = sizeof (der);
714 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
715 return SHISHI_BASE64_ERROR;
717 else
719 derlen =
720 fread (der, sizeof (der[0]), sizeof (der) / sizeof (der[0]), fh);
721 if (derlen <= 0 || !feof (fh) || ferror (fh))
723 shishi_error_printf (handle,
724 "Error reading from file (got %d bytes)...",
725 derlen);
726 return !SHISHI_OK;
730 *authenticator = shishi_der2asn1_authenticator (handle, der, derlen);
731 if (*authenticator == NULL)
733 printf ("bad magic %s\n", shishi_error (handle));
734 shishi_error_printf (handle, "Could not DER decode AP-REQ\n");
736 return !SHISHI_OK;
739 return SHISHI_OK;
743 _shishi_krberror_input (Shishi * handle,
744 FILE * fh, Shishi_asn1 * krberror, int type)
746 char der[BUFSIZ];
747 size_t derlen;
748 char b64der[BUFSIZ];
749 size_t b64len = 0;
750 int res;
752 if (type == 0)
754 b64len = sizeof (b64der);
755 res = _shishi_read_armored_data (handle, fh, b64der, b64len,
756 "KRB-ERROR");
757 if (res != SHISHI_OK)
759 shishi_error_printf (handle, "armor data read fail\n");
760 return res;
763 derlen = sizeof (der);
764 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
765 return SHISHI_BASE64_ERROR;
767 else
769 derlen = fread (der, sizeof (der[0]),
770 sizeof (der) / sizeof (der[0]), fh);
771 if (derlen <= 0 || !feof (fh) || ferror (fh))
773 shishi_error_printf (handle,
774 "Error reading from file (got %d bytes)...",
775 derlen);
776 return !SHISHI_OK;
780 *krberror = shishi_der2asn1_krberror (handle, der, derlen);
781 if (*krberror == NULL)
783 printf ("bad magic %s\n", shishi_error (handle));
784 shishi_error_printf (handle, "Could not DER decode AP-REQ\n");
786 return !SHISHI_OK;
789 return SHISHI_OK;
793 _shishi_safe_input (Shishi * handle, FILE * fh, Shishi_asn1 * safe, int type)
795 char der[BUFSIZ];
796 size_t derlen;
797 char b64der[BUFSIZ];
798 size_t b64len = 0;
799 int res;
801 if (type == 0)
803 b64len = sizeof (b64der);
804 res = _shishi_read_armored_data (handle, fh, b64der, b64len,
805 "KRB-SAFE");
806 if (res != SHISHI_OK)
808 shishi_error_printf (handle, "armor data read fail\n");
809 return res;
812 derlen = sizeof (der);
813 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
814 return SHISHI_BASE64_ERROR;
816 else
818 derlen = fread (der, sizeof (der[0]),
819 sizeof (der) / sizeof (der[0]), fh);
820 if (derlen <= 0 || !feof (fh) || ferror (fh))
822 shishi_error_printf (handle,
823 "Error reading from file (got %d bytes)...",
824 derlen);
825 return !SHISHI_OK;
829 *safe = shishi_der2asn1_krbsafe (handle, der, derlen);
830 if (*safe == NULL)
832 printf ("bad magic %s\n", shishi_error (handle));
833 shishi_error_printf (handle, "Could not DER decode KRB-SAFE\n");
835 return !SHISHI_OK;
838 return SHISHI_OK;
842 _shishi_priv_input (Shishi * handle, FILE * fh, Shishi_asn1 * priv, int type)
844 char der[BUFSIZ];
845 size_t derlen;
846 char b64der[BUFSIZ];
847 size_t b64len = 0;
848 int res;
850 if (type == 0)
852 b64len = sizeof (b64der);
853 res = _shishi_read_armored_data (handle, fh, b64der, b64len,
854 "KRB-PRIV");
855 if (res != SHISHI_OK)
857 shishi_error_printf (handle, "armor data read fail\n");
858 return res;
861 derlen = sizeof (der);
862 if (!base64_decode (b64der, strlen (b64der), der, &derlen))
863 return SHISHI_BASE64_ERROR;
865 else
867 derlen = fread (der, sizeof (der[0]),
868 sizeof (der) / sizeof (der[0]), fh);
869 if (derlen <= 0 || !feof (fh) || ferror (fh))
871 shishi_error_printf (handle,
872 "Error reading from file (got %d bytes)...",
873 derlen);
874 return !SHISHI_OK;
878 *priv = shishi_der2asn1_priv (handle, der, derlen);
879 if (*priv == NULL)
881 printf ("bad magic %s\n", shishi_error (handle));
882 shishi_error_printf (handle, "Could not DER decode KRB-PRIV\n");
884 return !SHISHI_OK;
887 return SHISHI_OK;
891 shishi_key_parse (Shishi * handle, FILE * fh, Shishi_key ** key)
893 int lno = 0;
894 char line[BUFSIZ];
895 char *b64buffer;
896 char armorbegin[BUFSIZ];
897 char armorend[BUFSIZ];
898 int in_key = 0, in_body = 0;
899 int res;
900 size_t len;
901 Shishi_key *lkey = NULL;
903 sprintf (armorbegin, HEADERBEG, "KEY");
904 sprintf (armorend, HEADEREND, "KEY");
906 len = 0;
907 while (fgets (line, sizeof (line), fh))
909 lno++;
910 line[sizeof (line) - 1] = '\0';
911 if (!*line || line[strlen (line) - 1] != '\n')
913 fprintf (stderr, "input line %u too long or missing LF\n", lno);
914 continue;
916 line[strlen (line) - 1] = '\0';
917 if (VERBOSENOISE (handle))
918 printf ("line %d read %d bytes: %s\n", lno, strlen (line), line);
920 if (!in_key)
922 in_key = strncmp (line, armorbegin, strlen (armorbegin)) == 0;
923 if (in_key)
925 res = shishi_key (handle, &lkey);
926 if (res != SHISHI_OK)
927 return res;
930 continue;
933 if (strcmp (line, armorend) == 0)
934 break;
936 if (in_body)
938 int ok = base64_decode_alloc (line, strlen (line), &b64buffer, NULL);
939 if (!ok)
940 return SHISHI_BASE64_ERROR;
941 shishi_key_value_set (lkey, b64buffer);
943 else
945 if (strcmp (line, "") == 0 || strcmp (line, " ") == 0)
946 in_body = 1;
948 if (strncmp (line, "Keytype: ", strlen ("Keytype: ")) == 0)
950 int type;
951 if (sscanf (line, "Keytype: %d (", &type) == 1)
952 shishi_key_type_set (lkey, type);
954 else if (strncmp (line, "Key-Version-Number: ",
955 strlen ("Key-Version-Number: ")) == 0)
957 int type;
958 if (sscanf (line, "Key-Version-Number: %d", &type) == 1)
959 shishi_key_version_set (lkey, type);
961 else if (strncmp (line, "Realm: ", strlen ("Realm: ")) == 0)
963 shishi_key_realm_set (lkey, line + strlen ("Realm: "));
965 else if (strncmp (line, "Principal: ", strlen ("Principal: ")) == 0)
967 shishi_key_principal_set (lkey, line + strlen ("Principal: "));
972 if (!lkey)
973 return SHISHI_OK;
975 *key = lkey;
977 return SHISHI_OK;
981 * shishi_key_print:
982 * @handle: shishi handle as allocated by shishi_init().
983 * @fh: file handle opened for writing.
984 * @key: key to print.
986 * Print an ASCII representation of a key structure to file
987 * descriptor. Example output:
989 * -----BEGIN SHISHI KEY-----
990 * Keytype: 18 (aes256-cts-hmac-sha1-96)
991 * Principal: host/latte.josefsson.org
992 * Realm: JOSEFSSON.ORG
993 * Key-Version-Number: 1
995 * P1QdeW/oSiag/bTyVEBAY2msiGSTmgLXlopuCKoppDs=
996 * -----END SHISHI KEY-----
998 * Return value: Returns SHISHI_OK iff successful.
1001 shishi_key_print (Shishi * handle, FILE * fh, const Shishi_key * key)
1003 char *b64key;
1004 size_t i;
1006 base64_encode_alloc (shishi_key_value (key), shishi_key_length (key),
1007 &b64key);
1009 if (!b64key)
1010 return SHISHI_MALLOC_ERROR;
1012 fprintf (fh, HEADERBEG "\n", "KEY");
1014 fprintf (fh, "Keytype: %d (%s)\n", shishi_key_type (key),
1015 shishi_cipher_name (shishi_key_type (key)));
1016 if (shishi_key_principal (key))
1017 fprintf (fh, "Principal: %s\n", shishi_key_principal (key));
1018 if (shishi_key_realm (key))
1019 fprintf (fh, "Realm: %s\n", shishi_key_realm (key));
1020 if (shishi_key_version (key) != UINT32_MAX)
1021 fprintf (fh, "Key-Version-Number: %d\n", shishi_key_version (key));
1022 fprintf (fh, "\n");
1024 for (i = 0; i < strlen (b64key); i++)
1026 fprintf (fh, "%c", b64key[i]);
1027 if ((i + 1) % 64 == 0)
1028 fprintf (fh, "\n");
1030 if ((i + 1) % 64 != 0)
1031 fprintf (fh, "\n");
1033 free (b64key);
1035 #if 0
1036 if (VERBOSENOISE (handle))
1038 for (i = 0; i < shishi_key_length (key); i++)
1039 fprintf (stdout, "%02x", shishi_key_value (key)[i] & 0xFF);
1040 fprintf (stdout, "\n");
1042 #endif
1044 fprintf (fh, HEADEREND "\n", "KEY");
1046 return SHISHI_OK;
1050 * shishi_key_to_file:
1051 * @handle: shishi handle as allocated by shishi_init().
1052 * @filename: filename to append key to.
1053 * @key: key to print.
1055 * Print an ASCII representation of a key structure to a file. The
1056 * file is appended to if it exists. See shishi_key_print() for
1057 * format of output.
1059 * Return value: Returns SHISHI_OK iff successful.
1062 shishi_key_to_file (Shishi * handle, const char *filename, Shishi_key * key)
1064 FILE *fh;
1065 int res;
1067 if (VERBOSE (handle))
1068 printf (_("Writing KEY to %s...\n"), filename);
1070 fh = fopen (filename, "a");
1071 if (fh == NULL)
1072 return SHISHI_FOPEN_ERROR;
1074 res = shishi_key_print (handle, fh, key);
1075 if (res != SHISHI_OK)
1076 return res;
1078 res = fclose (fh);
1079 if (res != 0)
1080 return SHISHI_IO_ERROR;
1082 if (VERBOSE (handle))
1083 printf (_("Writing KEY to %s...done\n"), filename);
1085 return SHISHI_OK;