- move towards verification
[oweals/gnunet.git] / src / credential / gnunet-credential.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012-2013 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @file gnunet-credential.c
22  * @brief command line tool to access command line Credential service
23  * @author Adnan Husain
24  */
25 #include "platform.h"
26 #include <gnunet_util_lib.h>
27 #include <gnunet_identity_service.h>
28 #include <gnunet_credential_service.h>
29
30 /**
31  * Configuration we are using.
32  */
33 static const struct GNUNET_CONFIGURATION_Handle *cfg;
34
35 /**
36  * Handle to Credential service.
37  */
38 static struct GNUNET_CREDENTIAL_Handle *credential;
39
40 /**
41  * Desired timeout for the lookup (default is no timeout).
42  */
43 static struct GNUNET_TIME_Relative timeout;
44
45 /**
46  * Credential to lookup. (-u option)
47  */
48 static char *lookup_credential;
49
50 /**
51  * Handle to verify request
52  */
53 static struct GNUNET_CREDENTIAL_VerifyRequest *verify_request;
54
55 /**
56  * Lookup an ego with the identity service.
57  */
58 static struct GNUNET_IDENTITY_EgoLookup *el;
59
60 /**
61  * Handle for identity service.
62  */
63 static struct GNUNET_IDENTITY_Handle *identity;
64
65 /**
66  * Active operation on identity service.
67  */
68 static struct GNUNET_IDENTITY_Operation *id_op;
69
70 /**
71  * Task scheduled to handle timeout.
72  */
73 static struct GNUNET_SCHEDULER_Task *tt;
74
75 /**
76  * Subject pubkey string
77  */
78 static char *subject_key;
79
80 /**
81  * Subject pubkey string
82  */
83 static char *issuer_key;
84
85 /*
86  * Credential flags
87  */
88 static int credential_flags;
89
90
91
92 /**
93  * Identity of the zone to use for the lookup (-z option)
94  */
95 static char *zone_ego_name;
96
97
98 /**
99  * Task run on shutdown.  Cleans up everything.
100  *
101  * @param cls unused
102  */
103 static void
104 do_shutdown (void *cls)
105 {
106   if (NULL != el)
107   {
108     GNUNET_IDENTITY_ego_lookup_cancel (el);
109     el = NULL;
110   }
111   if (NULL != id_op)
112   {
113     GNUNET_IDENTITY_cancel (id_op);
114     id_op = NULL;
115   }
116   if (NULL != verify_request)
117   {
118     GNUNET_CREDENTIAL_verify_cancel (verify_request);
119     verify_request = NULL;
120   }
121   if (NULL != identity)
122   {
123     GNUNET_IDENTITY_disconnect (identity);
124     identity = NULL;
125   }
126   if (NULL != credential)
127   {
128     GNUNET_CREDENTIAL_disconnect (credential);
129     credential = NULL;
130   }
131   if (NULL != tt)
132   {
133     GNUNET_SCHEDULER_cancel (tt);
134     tt = NULL;
135   }
136 }
137
138
139 /**
140  * Task run on timeout. Triggers shutdown.
141  *
142  * @param cls unused
143  */
144 static void
145 do_timeout (void *cls)
146 {
147   tt = NULL;
148   GNUNET_SCHEDULER_shutdown ();
149 }
150
151
152 /**
153  * Function called with the result of a Credential lookup.
154  *
155  * @param cls the 'const char *' name that was resolved
156  * @param cd_count number of records returned
157  * @param cd array of @a cd_count records with the results
158  */
159 static void
160 handle_verify_result (void *cls,
161                                 struct GNUNET_IDENTITY_Ego *issuer,
162                 uint16_t issuer_len,
163                                 const struct GNUNET_CREDENTIAL_RecordData *data)
164 {
165   
166
167   verify_request = NULL;
168   if (0 == issuer_len)
169     printf ("No results.\n");
170   else
171         printf ("%u\n",
172           issuer_len);
173
174   
175   GNUNET_SCHEDULER_shutdown ();
176 }
177
178
179
180
181 /**
182  * Perform the actual resolution, with the subject pkey and
183  * the issuer public key
184  *
185  * @param pkey public key to use for the zone, can be NULL
186  * @param shorten_key private key used for shortening, can be NULL
187  */
188 static void
189 lookup_credentials (struct GNUNET_IDENTITY_Ego *ego)
190 {
191   
192   struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey;
193   struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey;
194
195   if (NULL != subject_key && NULL != issuer_key && NULL != lookup_credential)
196   {
197     if (GNUNET_OK !=
198         GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key,
199                                                     strlen (subject_key),
200                                                     &subject_pkey))
201     {
202       fprintf (stderr,
203                _("Subject public key `%s' is not well-formed\n"),
204                subject_key);
205       GNUNET_SCHEDULER_shutdown ();
206       return;
207     }
208
209     if (GNUNET_OK !=
210         GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
211                                                     strlen (issuer_key),
212                                                     &issuer_pkey))
213     {
214       fprintf (stderr,
215                _("Authority public key `%s' is not well-formed\n"),
216                issuer_key);
217       GNUNET_SCHEDULER_shutdown ();
218       return;
219     }
220     
221   verify_request = GNUNET_CREDENTIAL_verify(credential,
222                     "",
223                     lookup_credential,
224                     &subject_pkey,
225                     &issuer_pkey,
226                     credential_flags,
227                     &handle_verify_result,
228                     NULL);
229    return;
230   }
231   else
232   {
233     fprintf (stderr,
234        _("Please specify name to lookup, subject key and issuer key!\n"));
235     GNUNET_SCHEDULER_shutdown ();
236     return;
237   }
238 }
239
240
241 /**
242  * Method called to with the ego we are to use for the lookup,
243  * when the ego is the one for the default master zone.
244  *
245  * @param cls closure (NULL, unused)
246  * @param ego ego handle, NULL if not found
247  * @param ctx context for application to store data for this ego
248  *                 (during the lifetime of this process, initially NULL)
249  * @param name name assigned by the user for this ego,
250  *                   NULL if the user just deleted the ego and it
251  *                   must thus no longer be used
252  */
253 static void
254 identity_master_cb (void *cls,
255                     struct GNUNET_IDENTITY_Ego *ego,
256                     void **ctx,
257                     const char *name)
258 {
259   
260   id_op = NULL;
261   if (NULL == ego)
262   {
263     fprintf (stderr,
264              _("Ego for `gns-master' not found, cannot perform lookup.  Did you run gnunet-gns-import.sh?\n"));
265     GNUNET_SCHEDULER_shutdown ();
266     return;
267   }
268
269   lookup_credentials(ego);
270
271   
272 }
273
274
275 /**
276  * Main function that will be run.
277  *
278  * @param cls closure
279  * @param args remaining command-line arguments
280  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
281  * @param c configuration
282  */
283 static void
284 run (void *cls,
285      char *const *args,
286      const char *cfgfile,
287      const struct GNUNET_CONFIGURATION_Handle *c)
288 {
289   
290   cfg = c;
291   credential = GNUNET_CREDENTIAL_connect (cfg);
292   identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
293
294  
295
296   
297   if (NULL == credential)
298   {
299     fprintf (stderr,
300              _("Failed to connect to CREDENTIAL\n"));
301     return;
302   }
303   if (NULL == identity)
304   {
305     fprintf (stderr,
306              _("Failed to connect to IDENTITY\n"));
307     return;
308   }
309   tt = GNUNET_SCHEDULER_add_delayed (timeout,
310                                      &do_timeout, NULL);
311   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
312   
313
314   
315         GNUNET_break (NULL == id_op);
316         id_op = GNUNET_IDENTITY_get (identity,
317                          "gns-master",//# TODO: Create credential-master
318                          &identity_master_cb,
319                          cls);
320         GNUNET_assert (NULL != id_op);
321
322
323  
324
325 }
326
327
328 /**
329  * The main function for gnunet-gns.
330  *
331  * @param argc number of arguments from the command line
332  * @param argv command line arguments
333  * @return 0 ok, 1 on error
334  */
335 int
336 main (int argc, char *const *argv)
337 {
338   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
339     {'u', "lookup", "CREDENTIAL",
340       gettext_noop ("Lookup a record for the given credential"), 1,
341       &GNUNET_GETOPT_set_string, &lookup_credential},
342    /** { 'T', "timeout", "DELAY",
343       gettext_noop ("Specify timeout for the lookup"), 1,
344       &GNUNET_GETOPT_set_relative_time, &timeout },
345     {'t', "type", "TYPE",
346       gettext_noop ("Specify the type of the record to lookup"), 1,
347     &GNUNET_GETOPT_set_string, &lookup_type},**/
348     {'z', "zone", "NAME",
349     gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1,
350     &GNUNET_GETOPT_set_string, &zone_ego_name},
351     {'s', "subject", "PKEY",
352       gettext_noop ("Specify the public key of the subject to lookup the credential for"), 1,
353       &GNUNET_GETOPT_set_string, &subject_key},
354     {'i', "issuer", "PKEY",
355       gettext_noop ("Specify the public key of the authority to verify the credential against"), 1,
356       &GNUNET_GETOPT_set_string, &issuer_key},
357     GNUNET_GETOPT_OPTION_END
358   };
359   int ret;
360
361   timeout = GNUNET_TIME_UNIT_FOREVER_REL;
362   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
363     return 2;
364
365   GNUNET_log_setup ("gnunet-credential", "WARNING", NULL);
366   ret =
367       (GNUNET_OK ==
368        GNUNET_PROGRAM_run (argc, argv, "gnunet-credential",
369                            _("GNUnet credential resolver tool"),
370                            options,
371                            &run, NULL)) ? 0 : 1;
372   GNUNET_free ((void*) argv);
373   return ret;
374 }
375
376 /* end of gnunet-credential.c */