fix double free, bad use of strtok
[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", header, payload);
109   GNUNET_free (header);
110   GNUNET_free (payload);
111
112   payload_json = json_loads (payload, 0, &error);
113   if ((NULL == payload_json) || !json_is_object (payload_json))
114   {
115     GNUNET_free (val);
116     return;
117   }
118   keystring_json =  json_object_get (payload_json, "iss");
119   if (!json_is_string (keystring_json))
120   {
121     GNUNET_free (val);
122     return;
123   }
124   keystring = json_string_value (keystring_json);
125   if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (keystring,
126                                                                strlen (keystring),
127                                                                &key))
128   {
129     GNUNET_free (val);
130     return;
131   }
132   GNUNET_STRINGS_string_to_data (signature_b32,
133                                 strlen (signature_b32),
134                                 &sig,
135                                 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
136
137   if (print_token)
138     printf ("Signature:\t%s\n", keystring);
139
140   if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN,
141                                               purpose,
142                                               &sig,
143                                               &key))
144     printf("Signature not OK!\n");
145   else
146     printf("Signature OK!\n");
147   GNUNET_free (val);
148   return;
149 }
150
151
152 int
153 main(int argc, char *const argv[])
154 {
155   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
156     {'t', "token", NULL,
157       gettext_noop ("GNUid token"), 1,
158       &GNUNET_GETOPT_set_string, &token},
159     {'p', "print", NULL,
160       gettext_noop ("Print token contents"), 0,
161       &GNUNET_GETOPT_set_one, &print_token},
162
163     GNUNET_GETOPT_OPTION_END
164   };
165   return GNUNET_PROGRAM_run (argc, argv, "ct",
166                              "ct", options,
167                              &run, NULL);
168 }