Merge branch 'credentials' of git+ssh://gnunet.org/gnunet into credentials
[oweals/gnunet.git] / src / identity-provider / gnunet-identity-token.c
1 /*
2    This file is part of GNUnet.
3    Copyright (C) 2012-2015 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  * @author Martin Schanzenbach
22  * @file src/identity-provider/gnunet-service-identity-provider.c
23  * @brief Identity Token Service
24  *
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include <jansson.h>
30 #include "gnunet_signatures.h"
31
32 /**
33  * The token
34  */
35 static char* token;
36
37 /**
38  * Weather to print the token
39  */
40 static int print_token;
41
42 static void
43 run (void *cls,
44      char *const *args,
45      const char *cfgfile,
46      const struct GNUNET_CONFIGURATION_Handle *c)
47 {
48   char *payload;
49   char *header;
50   //Get token parts
51   const char *header_b64;
52   const char *payload_b64;
53   const char *signature_b32;
54   const char *keystring;
55   char *data;
56   json_t *payload_json;
57   json_t *keystring_json;
58   json_error_t error;
59   struct GNUNET_CRYPTO_EcdsaPublicKey key;
60   struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
61   struct GNUNET_CRYPTO_EcdsaSignature sig;
62
63   if (NULL == token)
64   {
65     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
66                 _("Option `-t' is required\n"));
67     return;
68   }
69   header_b64 = strtok (token, ".");
70   payload_b64 = strtok (NULL, ".");
71   signature_b32 = strtok (NULL, ".");
72   if ( (NULL == header_b64) ||
73        (NULL == payload_b64) ||
74        (NULL == signature_b32) )
75   {
76     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
77                 _("Token `%s' is malformed\n"),
78                 token);
79     GNUNET_free (token);
80     token = NULL;
81     return;
82   }
83
84   //Decode payload
85   GNUNET_STRINGS_base64_decode (payload_b64,
86                                 strlen (payload_b64),
87                                 &payload);
88   //Decode header
89   GNUNET_STRINGS_base64_decode (header_b64,
90                                 strlen (header_b64),
91                                 &header);
92
93
94   GNUNET_asprintf(&data,
95                   "%s,%s",
96                   header_b64,
97                   payload_b64);
98   char *val = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (data));
99   purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose*)val;
100   purpose->size = htonl(sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (data));
101   purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
102   GNUNET_memcpy (&purpose[1], data, strlen(data));
103   GNUNET_free (data);
104   GNUNET_free (token);
105   token = NULL;
106
107   if (print_token)
108     printf ("Token:\nHeader:\t\t%s\nPayload:\t%s\n",
109             header,
110             payload);
111   GNUNET_free (header);
112
113   payload_json = json_loads (payload, 0, &error);
114   GNUNET_free (payload);
115
116   if ((NULL == payload_json) || (! json_is_object (payload_json)) )
117   {
118     GNUNET_free (val);
119     return;
120   }
121   keystring_json =  json_object_get (payload_json, "iss");
122   if (! json_is_string (keystring_json))
123   {
124     GNUNET_free (val);
125     return;
126   }
127   keystring = json_string_value (keystring_json);
128   if (GNUNET_OK !=
129       GNUNET_CRYPTO_ecdsa_public_key_from_string (keystring,
130                                                   strlen (keystring),
131                                                   &key))
132   {
133     GNUNET_free (val);
134     return;
135   }
136   GNUNET_STRINGS_string_to_data (signature_b32,
137                                  strlen (signature_b32),
138                                  &sig,
139                                  sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
140
141   if (print_token)
142     printf ("Signature:\t%s\n",
143             keystring);
144
145   if (GNUNET_OK !=
146       GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN,
147                                  purpose,
148                                  &sig,
149                                  &key))
150     printf("Signature not OK!\n");
151   else
152     printf("Signature OK!\n");
153   GNUNET_free (val);
154   return;
155 }
156
157
158 int
159 main(int argc, char *const argv[])
160 {
161   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
162     {'t', "token", NULL,
163       gettext_noop ("GNUid token"), 1,
164       &GNUNET_GETOPT_set_string, &token},
165     {'p', "print", NULL,
166       gettext_noop ("Print token contents"), 0,
167       &GNUNET_GETOPT_set_one, &print_token},
168
169     GNUNET_GETOPT_OPTION_END
170   };
171   return GNUNET_PROGRAM_run (argc, argv, "ct",
172                              "ct", options,
173                              &run, NULL);
174 }