Update.
[shishi.git] / examples / client-safe.c
blob7f5f3d38fa0b12b7d16c9349f76d2141354cefe6
1 /* client-safe.c --- Sample Shishi authenticated client with integrity
2 * protected application data exchange.
3 * Copyright (C) 2003, 2004 Simon Josefsson
5 * This file is part of Shishi.
7 * Shishi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Shishi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Shishi; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #include <shishi.h>
29 #define SERVICE "sample"
31 /* XXX remove this */
32 const char *program_name = "client";
34 static int
35 doit (Shishi * handle, Shishi_ap * ap, int verbose)
37 char line[BUFSIZ];
38 int res;
40 printf ("Application exchange start. Press ^D to finish.\n");
42 while (fgets (line, sizeof (line), stdin))
44 Shishi_safe *safe;
46 line[strlen(line)-1] = '\0';
47 printf ("read: %s\n", line);
49 res = shishi_safe (handle, &safe);
50 if (res != SHISHI_OK)
52 printf ("Could not build SAFE: %s\n", shishi_strerror (res));
53 return res;
56 res = shishi_safe_set_user_data (handle, shishi_safe_safe (safe),
57 line, strlen (line));
58 if (res != SHISHI_OK)
60 printf ("Could not set application data in SAFE: %s\n",
61 shishi_strerror (res));
62 return res;
65 res = shishi_safe_build (safe, shishi_ap_key (ap));
66 if (res != SHISHI_OK)
68 printf ("Could not build SAFE: %s\n", shishi_strerror (res));
69 return res;
72 res = shishi_safe_print (handle, stdout, shishi_safe_safe (safe));
73 if (res != SHISHI_OK)
75 printf ("Could not print SAFE: %s\n", shishi_strerror (res));
76 return res;
80 if (ferror (stdin))
82 printf ("error reading stdin\n");
83 return 1;
86 return 0;
89 static Shishi_ap *
90 auth (Shishi * h, int verbose, const char *cname, const char *sname)
92 Shishi_ap *ap;
93 Shishi_tkt *tkt;
94 Shishi_tkts_hint hint;
95 int rc;
97 printf ("Client: %s\n", cname);
98 printf ("Server: %s\n", sname);
100 /* Get a ticket for the server. */
102 memset (&hint, 0, sizeof (hint));
103 hint.client = (char *) cname;
104 hint.server = (char *) sname;
105 tkt = shishi_tkts_get (shishi_tkts_default (h), &hint);
106 if (!tkt)
108 printf ("cannot find ticket for \"%s\"\n", sname);
109 return NULL;
112 if (verbose)
113 shishi_tkt_pretty_print (tkt, stderr);
115 /* Create Authentication context */
117 rc = shishi_ap_tktoptions (h, &ap, tkt, SHISHI_APOPTIONS_MUTUAL_REQUIRED);
118 if (rc != SHISHI_OK)
120 printf ("cannot create authentication context\n");
121 return NULL;
124 /* Build Authentication request */
126 rc = shishi_ap_req_build (ap);
127 if (rc != SHISHI_OK)
129 printf ("cannot build authentication request: %s\n",
130 shishi_strerror (rc));
131 return NULL;
134 if (verbose)
135 shishi_authenticator_print (h, stderr, shishi_ap_authenticator (ap));
137 /* Authentication ourself to server */
139 shishi_apreq_print (h, stdout, shishi_ap_req (ap));
140 /* Note: to get the binary blob to send, use:
142 * char *out; int outlen;
143 * ...
144 * rc = shishi_ap_req_der (ap, &out, &outlen);
145 * ...
146 * write(fd, out, outlen);
149 /* For mutual authentication, wait for server reply. */
151 if (shishi_apreq_mutual_required_p (h, shishi_ap_req (ap)))
153 Shishi_asn1 aprep;
155 printf ("Waiting for server to authenticate itself...\n");
157 rc = shishi_aprep_parse (h, stdin, &aprep);
158 if (rc != SHISHI_OK)
160 printf ("Cannot parse AP-REP from server: %s\n",
161 shishi_strerror (rc));
162 return NULL;
165 rc = shishi_ap_rep_verify_asn1 (ap, aprep);
166 if (rc == SHISHI_OK)
167 printf ("AP-REP verification OK...\n");
168 else
170 if (rc == SHISHI_APREP_VERIFY_FAILED)
171 printf ("AP-REP verification failed...\n");
172 else
173 printf ("AP-REP verification error: %s\n", shishi_strerror (rc));
174 return NULL;
177 /* The server is authenticated. */
178 printf ("Server authenticated.\n");
181 /* We are now authenticated. */
182 printf ("User authenticated.\n");
184 return ap;
188 main (int argc, char *argv[])
190 Shishi *h;
191 Shishi_ap *ap;
192 char *sname;
193 int rc;
195 printf ("sample-client (shishi " SHISHI_VERSION ")\n");
197 if (!shishi_check_version (SHISHI_VERSION))
199 printf ("shishi_check_version() failed:\n"
200 "Header file incompatible with shared library.\n");
201 return 1;
204 rc = shishi_init (&h);
205 if (rc != SHISHI_OK)
207 printf ("error initializing shishi: %s\n", shishi_strerror (rc));
208 return 1;
211 if (argc > 1)
212 sname = argv[1];
213 else
214 sname = shishi_server_for_local_service (h, SERVICE);
216 ap = auth (h, 1, shishi_principal_default (h), sname);
218 if (ap)
219 rc = doit (h, ap, 1);
220 else
221 rc = 1;
223 shishi_done (h);
225 return rc;