diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-09-17 16:10:56 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-09-17 16:10:56 +0200 |
commit | 97164b43a8b69cc1bf07c3384586f58c99873ce8 (patch) | |
tree | 61b89e161d2a833dab4b7c95471d24923396ece6 /src/reclaim/oidc_helper.c | |
parent | 65349f5c1bbd7ffdf798224689d247a03bf5e3cb (diff) | |
download | gnunet-97164b43a8b69cc1bf07c3384586f58c99873ce8.tar.gz gnunet-97164b43a8b69cc1bf07c3384586f58c99873ce8.zip |
gracely handle missing PKCE params in token request
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r-- | src/reclaim/oidc_helper.c | 725 |
1 files changed, 367 insertions, 358 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 83b8e8cb3..6bcae21d4 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "gnunet_reclaim_service.h" | 31 | #include "gnunet_reclaim_service.h" |
32 | #include "gnunet_signatures.h" | 32 | #include "gnunet_signatures.h" |
33 | #include "oidc_helper.h" | 33 | #include "oidc_helper.h" |
34 | //#include "benchmark.h" | 34 | // #include "benchmark.h" |
35 | #include <gcrypt.h> | 35 | #include <gcrypt.h> |
36 | 36 | ||
37 | GNUNET_NETWORK_STRUCT_BEGIN | 37 | GNUNET_NETWORK_STRUCT_BEGIN |
@@ -39,7 +39,8 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
39 | /** | 39 | /** |
40 | * The signature used to generate the authorization code | 40 | * The signature used to generate the authorization code |
41 | */ | 41 | */ |
42 | struct OIDC_Parameters { | 42 | struct OIDC_Parameters |
43 | { | ||
43 | /** | 44 | /** |
44 | * The reclaim ticket | 45 | * The reclaim ticket |
45 | */ | 46 | */ |
@@ -64,41 +65,41 @@ struct OIDC_Parameters { | |||
64 | GNUNET_NETWORK_STRUCT_END | 65 | GNUNET_NETWORK_STRUCT_END |
65 | 66 | ||
66 | static char * | 67 | static char * |
67 | create_jwt_header(void) | 68 | create_jwt_header (void) |
68 | { | 69 | { |
69 | json_t *root; | 70 | json_t *root; |
70 | char *json_str; | 71 | char *json_str; |
71 | 72 | ||
72 | root = json_object(); | 73 | root = json_object (); |
73 | json_object_set_new(root, JWT_ALG, json_string(JWT_ALG_VALUE)); | 74 | json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE)); |
74 | json_object_set_new(root, JWT_TYP, json_string(JWT_TYP_VALUE)); | 75 | json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE)); |
75 | 76 | ||
76 | json_str = json_dumps(root, JSON_INDENT(0) | JSON_COMPACT); | 77 | json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT); |
77 | json_decref(root); | 78 | json_decref (root); |
78 | return json_str; | 79 | return json_str; |
79 | } | 80 | } |
80 | 81 | ||
81 | static void | 82 | static void |
82 | replace_char(char *str, char find, char replace) | 83 | replace_char (char *str, char find, char replace) |
83 | { | 84 | { |
84 | char *current_pos = strchr(str, find); | 85 | char *current_pos = strchr (str, find); |
85 | 86 | ||
86 | while (current_pos) | 87 | while (current_pos) |
87 | { | 88 | { |
88 | *current_pos = replace; | 89 | *current_pos = replace; |
89 | current_pos = strchr(current_pos, find); | 90 | current_pos = strchr (current_pos, find); |
90 | } | 91 | } |
91 | } | 92 | } |
92 | 93 | ||
93 | // RFC4648 | 94 | // RFC4648 |
94 | static void | 95 | static void |
95 | fix_base64(char *str) | 96 | fix_base64 (char *str) |
96 | { | 97 | { |
97 | // Replace + with - | 98 | // Replace + with - |
98 | replace_char(str, '+', '-'); | 99 | replace_char (str, '+', '-'); |
99 | 100 | ||
100 | // Replace / with _ | 101 | // Replace / with _ |
101 | replace_char(str, '/', '_'); | 102 | replace_char (str, '/', '_'); |
102 | } | 103 | } |
103 | 104 | ||
104 | /** | 105 | /** |
@@ -112,12 +113,12 @@ fix_base64(char *str) | |||
112 | * @return a new base64-encoded JWT string. | 113 | * @return a new base64-encoded JWT string. |
113 | */ | 114 | */ |
114 | char * | 115 | char * |
115 | OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | 116 | OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, |
116 | const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | 117 | const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, |
117 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, | 118 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, |
118 | const struct GNUNET_TIME_Relative *expiration_time, | 119 | const struct GNUNET_TIME_Relative *expiration_time, |
119 | const char *nonce, | 120 | const char *nonce, |
120 | const char *secret_key) | 121 | const char *secret_key) |
121 | { | 122 | { |
122 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | 123 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; |
123 | struct GNUNET_HashCode signature; | 124 | struct GNUNET_HashCode signature; |
@@ -136,108 +137,108 @@ OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
136 | json_t *body; | 137 | json_t *body; |
137 | 138 | ||
138 | // iat REQUIRED time now | 139 | // iat REQUIRED time now |
139 | time_now = GNUNET_TIME_absolute_get(); | 140 | time_now = GNUNET_TIME_absolute_get (); |
140 | // exp REQUIRED time expired from config | 141 | // exp REQUIRED time expired from config |
141 | exp_time = GNUNET_TIME_absolute_add(time_now, *expiration_time); | 142 | exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); |
142 | // auth_time only if max_age | 143 | // auth_time only if max_age |
143 | // nonce only if nonce | 144 | // nonce only if nonce |
144 | // OPTIONAL acr,amr,azp | 145 | // OPTIONAL acr,amr,azp |
145 | subject = | 146 | subject = |
146 | GNUNET_STRINGS_data_to_string_alloc(sub_key, | 147 | GNUNET_STRINGS_data_to_string_alloc (sub_key, |
147 | sizeof(struct | 148 | sizeof(struct |
148 | GNUNET_CRYPTO_EcdsaPublicKey)); | 149 | GNUNET_CRYPTO_EcdsaPublicKey)); |
149 | audience = | 150 | audience = |
150 | GNUNET_STRINGS_data_to_string_alloc(aud_key, | 151 | GNUNET_STRINGS_data_to_string_alloc (aud_key, |
151 | sizeof(struct | 152 | sizeof(struct |
152 | GNUNET_CRYPTO_EcdsaPublicKey)); | 153 | GNUNET_CRYPTO_EcdsaPublicKey)); |
153 | header = create_jwt_header(); | 154 | header = create_jwt_header (); |
154 | body = json_object(); | 155 | body = json_object (); |
155 | 156 | ||
156 | // iss REQUIRED case sensitive server uri with https | 157 | // iss REQUIRED case sensitive server uri with https |
157 | // The issuer is the local reclaim instance (e.g. | 158 | // The issuer is the local reclaim instance (e.g. |
158 | // https://reclaim.id/api/openid) | 159 | // https://reclaim.id/api/openid) |
159 | json_object_set_new(body, "iss", json_string(SERVER_ADDRESS)); | 160 | json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); |
160 | // sub REQUIRED public key identity, not exceed 255 ASCII length | 161 | // sub REQUIRED public key identity, not exceed 255 ASCII length |
161 | json_object_set_new(body, "sub", json_string(subject)); | 162 | json_object_set_new (body, "sub", json_string (subject)); |
162 | // aud REQUIRED public key client_id must be there | 163 | // aud REQUIRED public key client_id must be there |
163 | json_object_set_new(body, "aud", json_string(audience)); | 164 | json_object_set_new (body, "aud", json_string (audience)); |
164 | // iat | 165 | // iat |
165 | json_object_set_new(body, | 166 | json_object_set_new (body, |
166 | "iat", | 167 | "iat", |
167 | json_integer(time_now.abs_value_us / (1000 * 1000))); | 168 | json_integer (time_now.abs_value_us / (1000 * 1000))); |
168 | // exp | 169 | // exp |
169 | json_object_set_new(body, | 170 | json_object_set_new (body, |
170 | "exp", | 171 | "exp", |
171 | json_integer(exp_time.abs_value_us / (1000 * 1000))); | 172 | json_integer (exp_time.abs_value_us / (1000 * 1000))); |
172 | // nbf | 173 | // nbf |
173 | json_object_set_new(body, | 174 | json_object_set_new (body, |
174 | "nbf", | 175 | "nbf", |
175 | json_integer(time_now.abs_value_us / (1000 * 1000))); | 176 | json_integer (time_now.abs_value_us / (1000 * 1000))); |
176 | // nonce | 177 | // nonce |
177 | if (NULL != nonce) | 178 | if (NULL != nonce) |
178 | json_object_set_new(body, "nonce", json_string(nonce)); | 179 | json_object_set_new (body, "nonce", json_string (nonce)); |
179 | 180 | ||
180 | for (le = attrs->list_head; NULL != le; le = le->next) | 181 | for (le = attrs->list_head; NULL != le; le = le->next) |
181 | { | 182 | { |
182 | attr_val_str = | 183 | attr_val_str = |
183 | GNUNET_RECLAIM_ATTRIBUTE_value_to_string(le->claim->type, | 184 | GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type, |
184 | le->claim->data, | 185 | le->claim->data, |
185 | le->claim->data_size); | 186 | le->claim->data_size); |
186 | json_object_set_new(body, le->claim->name, json_string(attr_val_str)); | 187 | json_object_set_new (body, le->claim->name, json_string (attr_val_str)); |
187 | GNUNET_free(attr_val_str); | 188 | GNUNET_free (attr_val_str); |
188 | } | 189 | } |
189 | body_str = json_dumps(body, JSON_INDENT(0) | JSON_COMPACT); | 190 | body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); |
190 | json_decref(body); | 191 | json_decref (body); |
191 | 192 | ||
192 | GNUNET_STRINGS_base64_encode(header, strlen(header), &header_base64); | 193 | GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64); |
193 | fix_base64(header_base64); | 194 | fix_base64 (header_base64); |
194 | 195 | ||
195 | GNUNET_STRINGS_base64_encode(body_str, strlen(body_str), &body_base64); | 196 | GNUNET_STRINGS_base64_encode (body_str, strlen (body_str), &body_base64); |
196 | fix_base64(body_base64); | 197 | fix_base64 (body_base64); |
197 | 198 | ||
198 | GNUNET_free(subject); | 199 | GNUNET_free (subject); |
199 | GNUNET_free(audience); | 200 | GNUNET_free (audience); |
200 | 201 | ||
201 | /** | 202 | /** |
202 | * Creating the JWT signature. This might not be | 203 | * Creating the JWT signature. This might not be |
203 | * standards compliant, check. | 204 | * standards compliant, check. |
204 | */ | 205 | */ |
205 | GNUNET_asprintf(&signature_target, "%s.%s", header_base64, body_base64); | 206 | GNUNET_asprintf (&signature_target, "%s.%s", header_base64, body_base64); |
206 | GNUNET_CRYPTO_hmac_raw(secret_key, | 207 | GNUNET_CRYPTO_hmac_raw (secret_key, |
207 | strlen(secret_key), | 208 | strlen (secret_key), |
208 | signature_target, | 209 | signature_target, |
209 | strlen(signature_target), | 210 | strlen (signature_target), |
210 | &signature); | 211 | &signature); |
211 | GNUNET_STRINGS_base64_encode((const char *)&signature, | 212 | GNUNET_STRINGS_base64_encode ((const char *) &signature, |
212 | sizeof(struct GNUNET_HashCode), | 213 | sizeof(struct GNUNET_HashCode), |
213 | &signature_base64); | 214 | &signature_base64); |
214 | fix_base64(signature_base64); | 215 | fix_base64 (signature_base64); |
215 | 216 | ||
216 | GNUNET_asprintf(&result, | 217 | GNUNET_asprintf (&result, |
217 | "%s.%s.%s", | 218 | "%s.%s.%s", |
218 | header_base64, | 219 | header_base64, |
219 | body_base64, | 220 | body_base64, |
220 | signature_base64); | 221 | signature_base64); |
221 | 222 | ||
222 | GNUNET_free(signature_target); | 223 | GNUNET_free (signature_target); |
223 | GNUNET_free(header); | 224 | GNUNET_free (header); |
224 | GNUNET_free(body_str); | 225 | GNUNET_free (body_str); |
225 | GNUNET_free(signature_base64); | 226 | GNUNET_free (signature_base64); |
226 | GNUNET_free(body_base64); | 227 | GNUNET_free (body_base64); |
227 | GNUNET_free(header_base64); | 228 | GNUNET_free (header_base64); |
228 | return result; | 229 | return result; |
229 | } | 230 | } |
230 | 231 | ||
231 | /* Converts a hex character to its integer value */ | 232 | /* Converts a hex character to its integer value */ |
232 | static char | 233 | static char |
233 | from_hex(char ch) | 234 | from_hex (char ch) |
234 | { | 235 | { |
235 | return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; | 236 | return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10; |
236 | } | 237 | } |
237 | 238 | ||
238 | /* Converts an integer value to its hex character*/ | 239 | /* Converts an integer value to its hex character*/ |
239 | static char | 240 | static char |
240 | to_hex(char code) | 241 | to_hex (char code) |
241 | { | 242 | { |
242 | static char hex[] = "0123456789abcdef"; | 243 | static char hex[] = "0123456789abcdef"; |
243 | 244 | ||
@@ -247,27 +248,27 @@ to_hex(char code) | |||
247 | /* Returns a url-encoded version of str */ | 248 | /* Returns a url-encoded version of str */ |
248 | /* IMPORTANT: be sure to free() the returned string after use */ | 249 | /* IMPORTANT: be sure to free() the returned string after use */ |
249 | static char * | 250 | static char * |
250 | url_encode(const char *str) | 251 | url_encode (const char *str) |
251 | { | 252 | { |
252 | char *pstr = (char *)str; | 253 | char *pstr = (char *) str; |
253 | char *buf = GNUNET_malloc(strlen(str) * 3 + 1); | 254 | char *buf = GNUNET_malloc (strlen (str) * 3 + 1); |
254 | char *pbuf = buf; | 255 | char *pbuf = buf; |
255 | 256 | ||
256 | while (*pstr) | 257 | while (*pstr) |
258 | { | ||
259 | if (isalnum (*pstr) || (*pstr == '-') || (*pstr == '_') || (*pstr == '.') || | ||
260 | (*pstr == '~') ) | ||
261 | *pbuf++ = *pstr; | ||
262 | else if (*pstr == ' ') | ||
263 | *pbuf++ = '+'; | ||
264 | else | ||
257 | { | 265 | { |
258 | if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || | 266 | *pbuf++ = '%'; |
259 | *pstr == '~') | 267 | *pbuf++ = to_hex (*pstr >> 4); |
260 | *pbuf++ = *pstr; | 268 | *pbuf++ = to_hex (*pstr & 15); |
261 | else if (*pstr == ' ') | ||
262 | *pbuf++ = '+'; | ||
263 | else | ||
264 | { | ||
265 | *pbuf++ = '%'; | ||
266 | *pbuf++ = to_hex(*pstr >> 4); | ||
267 | *pbuf++ = to_hex(*pstr & 15); | ||
268 | } | ||
269 | pstr++; | ||
270 | } | 269 | } |
270 | pstr++; | ||
271 | } | ||
271 | *pbuf = '\0'; | 272 | *pbuf = '\0'; |
272 | return buf; | 273 | return buf; |
273 | } | 274 | } |
@@ -276,32 +277,32 @@ url_encode(const char *str) | |||
276 | /* Returns a url-decoded version of str */ | 277 | /* Returns a url-decoded version of str */ |
277 | /* IMPORTANT: be sure to free() the returned string after use */ | 278 | /* IMPORTANT: be sure to free() the returned string after use */ |
278 | static char * | 279 | static char * |
279 | url_decode(const char *str) | 280 | url_decode (const char *str) |
280 | { | 281 | { |
281 | char *pstr = (char *)str; | 282 | char *pstr = (char *) str; |
282 | char *buf = GNUNET_malloc(strlen(str) + 1); | 283 | char *buf = GNUNET_malloc (strlen (str) + 1); |
283 | char *pbuf = buf; | 284 | char *pbuf = buf; |
284 | 285 | ||
285 | while (*pstr) | 286 | while (*pstr) |
287 | { | ||
288 | if (*pstr == '%') | ||
289 | { | ||
290 | if (pstr[1] && pstr[2]) | ||
291 | { | ||
292 | *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]); | ||
293 | pstr += 2; | ||
294 | } | ||
295 | } | ||
296 | else if (*pstr == '+') | ||
297 | { | ||
298 | *pbuf++ = ' '; | ||
299 | } | ||
300 | else | ||
286 | { | 301 | { |
287 | if (*pstr == '%') | 302 | *pbuf++ = *pstr; |
288 | { | ||
289 | if (pstr[1] && pstr[2]) | ||
290 | { | ||
291 | *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); | ||
292 | pstr += 2; | ||
293 | } | ||
294 | } | ||
295 | else if (*pstr == '+') | ||
296 | { | ||
297 | *pbuf++ = ' '; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | *pbuf++ = *pstr; | ||
302 | } | ||
303 | pstr++; | ||
304 | } | 303 | } |
304 | pstr++; | ||
305 | } | ||
305 | *pbuf = '\0'; | 306 | *pbuf = '\0'; |
306 | return buf; | 307 | return buf; |
307 | } | 308 | } |
@@ -313,14 +314,14 @@ url_decode(const char *str) | |||
313 | * @return base64 encoded string | 314 | * @return base64 encoded string |
314 | */ | 315 | */ |
315 | static char * | 316 | static char * |
316 | base64_and_urlencode(const char *data, size_t data_size) | 317 | base64_and_urlencode (const char *data, size_t data_size) |
317 | { | 318 | { |
318 | char *enc; | 319 | char *enc; |
319 | char *urlenc; | 320 | char *urlenc; |
320 | 321 | ||
321 | GNUNET_STRINGS_base64_encode(data, data_size, &enc); | 322 | GNUNET_STRINGS_base64_encode (data, data_size, &enc); |
322 | urlenc = url_encode(enc); | 323 | urlenc = url_encode (enc); |
323 | GNUNET_free(enc); | 324 | GNUNET_free (enc); |
324 | return urlenc; | 325 | return urlenc; |
325 | } | 326 | } |
326 | 327 | ||
@@ -332,111 +333,111 @@ base64_and_urlencode(const char *data, size_t data_size) | |||
332 | * @return base64 encoded string | 333 | * @return base64 encoded string |
333 | */ | 334 | */ |
334 | static char * | 335 | static char * |
335 | base64url_encode(const char *data, size_t data_size) | 336 | base64url_encode (const char *data, size_t data_size) |
336 | { | 337 | { |
337 | char *enc; | 338 | char *enc; |
338 | size_t pos; | 339 | size_t pos; |
339 | 340 | ||
340 | GNUNET_STRINGS_base64_encode(data, data_size, &enc); | 341 | GNUNET_STRINGS_base64_encode (data, data_size, &enc); |
341 | //Replace with correct characters for base64url | 342 | // Replace with correct characters for base64url |
342 | pos = 0; | 343 | pos = 0; |
343 | while ('\0' != enc[pos]) | 344 | while ('\0' != enc[pos]) |
345 | { | ||
346 | if ('+' == enc[pos]) | ||
347 | enc[pos] = '-'; | ||
348 | if ('/' == enc[pos]) | ||
349 | enc[pos] = '_'; | ||
350 | if ('=' == enc[pos]) | ||
344 | { | 351 | { |
345 | if ('+' == enc[pos]) | 352 | enc[pos] = '\0'; |
346 | enc[pos] = '-'; | 353 | break; |
347 | if ('/' == enc[pos]) | ||
348 | enc[pos] = '_'; | ||
349 | if ('=' == enc[pos]) | ||
350 | { | ||
351 | enc[pos] = '\0'; | ||
352 | break; | ||
353 | } | ||
354 | pos++; | ||
355 | } | 354 | } |
355 | pos++; | ||
356 | } | ||
356 | return enc; | 357 | return enc; |
357 | } | 358 | } |
358 | 359 | ||
359 | 360 | ||
360 | static void | 361 | static void |
361 | derive_aes_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key, | 362 | derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, |
362 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 363 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, |
363 | struct GNUNET_HashCode *key_material) | 364 | struct GNUNET_HashCode *key_material) |
364 | { | 365 | { |
365 | static const char ctx_key[] = "reclaim-aes-ctx-key"; | 366 | static const char ctx_key[] = "reclaim-aes-ctx-key"; |
366 | static const char ctx_iv[] = "reclaim-aes-ctx-iv"; | 367 | static const char ctx_iv[] = "reclaim-aes-ctx-iv"; |
367 | 368 | ||
368 | GNUNET_CRYPTO_kdf(key, | 369 | GNUNET_CRYPTO_kdf (key, |
369 | sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | 370 | sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), |
370 | ctx_key, | 371 | ctx_key, |
371 | strlen(ctx_key), | 372 | strlen (ctx_key), |
372 | key_material, | 373 | key_material, |
373 | sizeof(struct GNUNET_HashCode), | 374 | sizeof(struct GNUNET_HashCode), |
374 | NULL); | 375 | NULL); |
375 | GNUNET_CRYPTO_kdf(iv, | 376 | GNUNET_CRYPTO_kdf (iv, |
376 | sizeof( | 377 | sizeof( |
377 | struct GNUNET_CRYPTO_SymmetricInitializationVector), | 378 | struct GNUNET_CRYPTO_SymmetricInitializationVector), |
378 | ctx_iv, | 379 | ctx_iv, |
379 | strlen(ctx_iv), | 380 | strlen (ctx_iv), |
380 | key_material, | 381 | key_material, |
381 | sizeof(struct GNUNET_HashCode), | 382 | sizeof(struct GNUNET_HashCode), |
382 | NULL); | 383 | NULL); |
383 | } | 384 | } |
384 | 385 | ||
385 | 386 | ||
386 | static void | 387 | static void |
387 | calculate_key_priv(struct GNUNET_CRYPTO_SymmetricSessionKey *key, | 388 | calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key, |
388 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 389 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, |
389 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 390 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, |
390 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub) | 391 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub) |
391 | { | 392 | { |
392 | struct GNUNET_HashCode key_material; | 393 | struct GNUNET_HashCode key_material; |
393 | 394 | ||
394 | GNUNET_CRYPTO_ecdsa_ecdh(ecdsa_priv, ecdh_pub, &key_material); | 395 | GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material); |
395 | derive_aes_key(key, iv, &key_material); | 396 | derive_aes_key (key, iv, &key_material); |
396 | } | 397 | } |
397 | 398 | ||
398 | 399 | ||
399 | static void | 400 | static void |
400 | calculate_key_pub(struct GNUNET_CRYPTO_SymmetricSessionKey *key, | 401 | calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key, |
401 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 402 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, |
402 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | 403 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, |
403 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv) | 404 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv) |
404 | { | 405 | { |
405 | struct GNUNET_HashCode key_material; | 406 | struct GNUNET_HashCode key_material; |
406 | 407 | ||
407 | GNUNET_CRYPTO_ecdh_ecdsa(ecdh_priv, ecdsa_pub, &key_material); | 408 | GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material); |
408 | derive_aes_key(key, iv, &key_material); | 409 | derive_aes_key (key, iv, &key_material); |
409 | } | 410 | } |
410 | 411 | ||
411 | 412 | ||
412 | static void | 413 | static void |
413 | decrypt_payload(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 414 | decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, |
414 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, | 415 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, |
415 | const char *ct, | 416 | const char *ct, |
416 | size_t ct_len, | 417 | size_t ct_len, |
417 | char *buf) | 418 | char *buf) |
418 | { | 419 | { |
419 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | 420 | struct GNUNET_CRYPTO_SymmetricSessionKey key; |
420 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 421 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
421 | 422 | ||
422 | calculate_key_priv(&key, &iv, ecdsa_priv, ecdh_pub); | 423 | calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub); |
423 | GNUNET_break(GNUNET_CRYPTO_symmetric_decrypt(ct, ct_len, &key, &iv, buf)); | 424 | GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf)); |
424 | } | 425 | } |
425 | 426 | ||
426 | 427 | ||
427 | static void | 428 | static void |
428 | encrypt_payload(const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | 429 | encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, |
429 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, | 430 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, |
430 | const char *payload, | 431 | const char *payload, |
431 | size_t payload_len, | 432 | size_t payload_len, |
432 | char *buf) | 433 | char *buf) |
433 | { | 434 | { |
434 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | 435 | struct GNUNET_CRYPTO_SymmetricSessionKey key; |
435 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 436 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
436 | 437 | ||
437 | calculate_key_pub(&key, &iv, ecdsa_pub, ecdh_priv); | 438 | calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv); |
438 | GNUNET_break( | 439 | GNUNET_break ( |
439 | GNUNET_CRYPTO_symmetric_encrypt(payload, payload_len, &key, &iv, buf)); | 440 | GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); |
440 | } | 441 | } |
441 | 442 | ||
442 | /** | 443 | /** |
@@ -451,11 +452,11 @@ encrypt_payload(const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | |||
451 | * @return a new authorization code (caller must free) | 452 | * @return a new authorization code (caller must free) |
452 | */ | 453 | */ |
453 | char * | 454 | char * |
454 | OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | 455 | OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, |
455 | const struct GNUNET_RECLAIM_Ticket *ticket, | 456 | const struct GNUNET_RECLAIM_Ticket *ticket, |
456 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, | 457 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, |
457 | const char *nonce_str, | 458 | const char *nonce_str, |
458 | const char *code_challenge) | 459 | const char *code_challenge) |
459 | { | 460 | { |
460 | struct OIDC_Parameters params; | 461 | struct OIDC_Parameters params; |
461 | char *code_payload; | 462 | char *code_payload; |
@@ -475,98 +476,99 @@ OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
475 | 476 | ||
476 | /** PLAINTEXT **/ | 477 | /** PLAINTEXT **/ |
477 | // Assign ticket | 478 | // Assign ticket |
478 | memset(¶ms, 0, sizeof(params)); | 479 | memset (¶ms, 0, sizeof(params)); |
479 | params.ticket = *ticket; | 480 | params.ticket = *ticket; |
480 | // Assign nonce | 481 | // Assign nonce |
481 | nonce = 0; | 482 | nonce = 0; |
482 | payload_len = sizeof(struct OIDC_Parameters); | 483 | payload_len = sizeof(struct OIDC_Parameters); |
483 | if (NULL != nonce_str && strcmp("", nonce_str) != 0) | 484 | if ((NULL != nonce_str)&& (strcmp ("", nonce_str) != 0)) |
485 | { | ||
486 | if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) | ||
484 | { | 487 | { |
485 | if ((1 != sscanf(nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) | 488 | GNUNET_break (0); |
486 | { | 489 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); |
487 | GNUNET_break(0); | 490 | return NULL; |
488 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); | ||
489 | return NULL; | ||
490 | } | ||
491 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
492 | "Got nonce: %u from %s\n", | ||
493 | nonce, | ||
494 | nonce_str); | ||
495 | } | 491 | } |
496 | nonce_tmp = htonl(nonce); | 492 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
493 | "Got nonce: %u from %s\n", | ||
494 | nonce, | ||
495 | nonce_str); | ||
496 | } | ||
497 | nonce_tmp = htonl (nonce); | ||
497 | params.nonce = nonce_tmp; | 498 | params.nonce = nonce_tmp; |
498 | // Assign code challenge | 499 | // Assign code challenge |
499 | if (NULL != code_challenge) | 500 | if (NULL != code_challenge) |
500 | code_challenge_len = strlen(code_challenge); | 501 | code_challenge_len = strlen (code_challenge); |
501 | payload_len += code_challenge_len; | 502 | payload_len += code_challenge_len; |
502 | params.code_challenge_len = htonl(code_challenge_len); | 503 | params.code_challenge_len = htonl (code_challenge_len); |
503 | // Assign attributes | 504 | // Assign attributes |
504 | if (NULL != attrs) | 505 | if (NULL != attrs) |
505 | { | 506 | { |
506 | // Get length | 507 | // Get length |
507 | attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size(attrs); | 508 | attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs); |
508 | params.attr_list_len = htonl(attr_list_len); | 509 | params.attr_list_len = htonl (attr_list_len); |
509 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 510 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
510 | "Length of serialized attributes: %lu\n", | 511 | "Length of serialized attributes: %lu\n", |
511 | attr_list_len); | 512 | attr_list_len); |
512 | // Get serialized attributes | 513 | // Get serialized attributes |
513 | payload_len += attr_list_len; | 514 | payload_len += attr_list_len; |
514 | } | 515 | } |
515 | // Get plaintext length | 516 | // Get plaintext length |
516 | payload = GNUNET_malloc(payload_len); | 517 | payload = GNUNET_malloc (payload_len); |
517 | memcpy(payload, ¶ms, sizeof(params)); | 518 | memcpy (payload, ¶ms, sizeof(params)); |
518 | tmp = payload + sizeof(params); | 519 | tmp = payload + sizeof(params); |
519 | if (0 < code_challenge_len) | 520 | if (0 < code_challenge_len) |
520 | { | 521 | { |
521 | memcpy(tmp, code_challenge, code_challenge_len); | 522 | memcpy (tmp, code_challenge, code_challenge_len); |
522 | tmp += code_challenge_len; | 523 | tmp += code_challenge_len; |
523 | } | 524 | } |
524 | if (0 < attr_list_len) | 525 | if (0 < attr_list_len) |
525 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize(attrs, tmp); | 526 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, tmp); |
526 | /** END **/ | 527 | /** END **/ |
527 | 528 | ||
528 | /** ENCRYPT **/ | 529 | /** ENCRYPT **/ |
529 | // Get length | 530 | // Get length |
530 | code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + | 531 | code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
531 | sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) + | 532 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) |
532 | payload_len + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); | 533 | + payload_len + sizeof(struct |
533 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 534 | GNUNET_CRYPTO_EcdsaSignature); |
534 | "Length of data to encode: %lu\n", | 535 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
535 | code_payload_len); | 536 | "Length of data to encode: %lu\n", |
537 | code_payload_len); | ||
536 | 538 | ||
537 | // Generate ECDH key | 539 | // Generate ECDH key |
538 | ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create(); | 540 | ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create (); |
539 | GNUNET_CRYPTO_ecdhe_key_get_public(ecdh_priv, &ecdh_pub); | 541 | GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub); |
540 | // Initialize code payload | 542 | // Initialize code payload |
541 | code_payload = GNUNET_malloc(code_payload_len); | 543 | code_payload = GNUNET_malloc (code_payload_len); |
542 | GNUNET_assert(NULL != code_payload); | 544 | GNUNET_assert (NULL != code_payload); |
543 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)code_payload; | 545 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; |
544 | purpose->size = htonl(sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + | 546 | purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
545 | sizeof(ecdh_pub) + payload_len); | 547 | + sizeof(ecdh_pub) + payload_len); |
546 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); | 548 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); |
547 | // Store pubkey | 549 | // Store pubkey |
548 | buf_ptr = (char *)&purpose[1]; | 550 | buf_ptr = (char *) &purpose[1]; |
549 | memcpy(buf_ptr, &ecdh_pub, sizeof(ecdh_pub)); | 551 | memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub)); |
550 | buf_ptr += sizeof(ecdh_pub); | 552 | buf_ptr += sizeof(ecdh_pub); |
551 | // Encrypt plaintext and store | 553 | // Encrypt plaintext and store |
552 | encrypt_payload(&ticket->audience, ecdh_priv, payload, payload_len, buf_ptr); | 554 | encrypt_payload (&ticket->audience, ecdh_priv, payload, payload_len, buf_ptr); |
553 | GNUNET_free(ecdh_priv); | 555 | GNUNET_free (ecdh_priv); |
554 | GNUNET_free(payload); | 556 | GNUNET_free (payload); |
555 | buf_ptr += payload_len; | 557 | buf_ptr += payload_len; |
556 | // Sign and store signature | 558 | // Sign and store signature |
557 | if (GNUNET_SYSERR == | 559 | if (GNUNET_SYSERR == |
558 | GNUNET_CRYPTO_ecdsa_sign(issuer, | 560 | GNUNET_CRYPTO_ecdsa_sign (issuer, |
559 | purpose, | 561 | purpose, |
560 | (struct GNUNET_CRYPTO_EcdsaSignature *) | 562 | (struct GNUNET_CRYPTO_EcdsaSignature *) |
561 | buf_ptr)) | 563 | buf_ptr)) |
562 | { | 564 | { |
563 | GNUNET_break(0); | 565 | GNUNET_break (0); |
564 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); | 566 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); |
565 | GNUNET_free(code_payload); | 567 | GNUNET_free (code_payload); |
566 | return NULL; | 568 | return NULL; |
567 | } | 569 | } |
568 | code_str = base64_and_urlencode(code_payload, code_payload_len); | 570 | code_str = base64_and_urlencode (code_payload, code_payload_len); |
569 | GNUNET_free(code_payload); | 571 | GNUNET_free (code_payload); |
570 | return code_str; | 572 | return code_str; |
571 | } | 573 | } |
572 | 574 | ||
@@ -585,12 +587,12 @@ OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
585 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 587 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
586 | */ | 588 | */ |
587 | int | 589 | int |
588 | OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 590 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, |
589 | const char *code, | 591 | const char *code, |
590 | const char *code_verifier, | 592 | const char *code_verifier, |
591 | struct GNUNET_RECLAIM_Ticket *ticket, | 593 | struct GNUNET_RECLAIM_Ticket *ticket, |
592 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, | 594 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, |
593 | char **nonce_str) | 595 | char **nonce_str) |
594 | { | 596 | { |
595 | char *code_payload; | 597 | char *code_payload; |
596 | char *ptr; | 598 | char *ptr; |
@@ -610,103 +612,110 @@ OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
610 | uint32_t nonce = 0; | 612 | uint32_t nonce = 0; |
611 | struct OIDC_Parameters *params; | 613 | struct OIDC_Parameters *params; |
612 | 614 | ||
613 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); | 615 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); |
614 | code_payload = NULL; | 616 | code_payload = NULL; |
615 | code_payload_len = | 617 | code_payload_len = |
616 | GNUNET_STRINGS_base64_decode(code, strlen(code), (void **)&code_payload); | 618 | GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload); |
617 | if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + | 619 | if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
618 | sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) + | 620 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) |
619 | sizeof(struct OIDC_Parameters) + | 621 | + sizeof(struct OIDC_Parameters) |
620 | sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) | 622 | + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) |
621 | { | 623 | { |
622 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n"); | 624 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n"); |
623 | GNUNET_free_non_null(code_payload); | 625 | GNUNET_free_non_null (code_payload); |
624 | return GNUNET_SYSERR; | 626 | return GNUNET_SYSERR; |
625 | } | 627 | } |
626 | 628 | ||
627 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)code_payload; | 629 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; |
628 | plaintext_len = code_payload_len; | 630 | plaintext_len = code_payload_len; |
629 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); | 631 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); |
630 | ptr = (char *)&purpose[1]; | 632 | ptr = (char *) &purpose[1]; |
631 | // Public ECDH key | 633 | // Public ECDH key |
632 | ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *)ptr; | 634 | ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr; |
633 | ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); | 635 | ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); |
634 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); | 636 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); |
635 | 637 | ||
636 | // Decrypt ciphertext | 638 | // Decrypt ciphertext |
637 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); | 639 | plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); |
638 | plaintext = GNUNET_malloc(plaintext_len); | 640 | plaintext = GNUNET_malloc (plaintext_len); |
639 | decrypt_payload(ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); | 641 | decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); |
640 | //ptr = plaintext; | 642 | // ptr = plaintext; |
641 | ptr += plaintext_len; | 643 | ptr += plaintext_len; |
642 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *)ptr; | 644 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; |
643 | params = (struct OIDC_Parameters *)plaintext; | 645 | params = (struct OIDC_Parameters *) plaintext; |
644 | 646 | ||
645 | // cmp code_challenge code_verifier | 647 | // cmp code_challenge code_verifier |
646 | code_challenge_len = ntohl(params->code_challenge_len); | 648 | code_challenge_len = ntohl (params->code_challenge_len); |
647 | if (0 != code_challenge_len) /* Only check if this code requires a CV */ | 649 | if (0 != code_challenge_len) /* Only check if this code requires a CV */ |
650 | { | ||
651 | if (NULL == code_verifier) | ||
648 | { | 652 | { |
649 | code_verifier_hash = GNUNET_malloc(256 / 8); | 653 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
650 | // hash code verifier | 654 | "Expected code verifier!\n"); |
651 | gcry_md_hash_buffer(GCRY_MD_SHA256, | 655 | GNUNET_free_non_null (code_payload); |
652 | code_verifier_hash, | ||
653 | code_verifier, | ||
654 | strlen(code_verifier)); | ||
655 | // encode code verifier | ||
656 | expected_code_challenge = base64url_encode(code_verifier_hash, 256 / 8); | ||
657 | code_challenge = (char *)¶ms[1]; | ||
658 | GNUNET_free(code_verifier_hash); | ||
659 | if ((strlen(expected_code_challenge) != code_challenge_len) || | ||
660 | (0 != | ||
661 | strncmp(expected_code_challenge, code_challenge, code_challenge_len))) | ||
662 | { | ||
663 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
664 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | ||
665 | expected_code_challenge, | ||
666 | code_challenge_len, | ||
667 | code_challenge); | ||
668 | GNUNET_free_non_null(code_payload); | ||
669 | GNUNET_free(expected_code_challenge); | ||
670 | return GNUNET_SYSERR; | ||
671 | } | ||
672 | GNUNET_free(expected_code_challenge); | ||
673 | } | ||
674 | // Ticket | ||
675 | memcpy(ticket, ¶ms->ticket, sizeof(params->ticket)); | ||
676 | // Nonce | ||
677 | nonce = ntohl(params->nonce); //ntohl (*((uint32_t *) ptr)); | ||
678 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); | ||
679 | // Signature | ||
680 | GNUNET_CRYPTO_ecdsa_key_get_public(ecdsa_priv, &ecdsa_pub); | ||
681 | if (0 != GNUNET_memcmp(&ecdsa_pub, &ticket->audience)) | ||
682 | { | ||
683 | GNUNET_free(code_payload); | ||
684 | GNUNET_free(plaintext); | ||
685 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
686 | "Audience in ticket does not match client!\n"); | ||
687 | return GNUNET_SYSERR; | 656 | return GNUNET_SYSERR; |
688 | } | 657 | } |
689 | if (GNUNET_OK != | 658 | code_verifier_hash = GNUNET_malloc (256 / 8); |
690 | GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, | 659 | // hash code verifier |
691 | purpose, | 660 | gcry_md_hash_buffer (GCRY_MD_SHA256, |
692 | signature, | 661 | code_verifier_hash, |
693 | &ticket->identity)) | 662 | code_verifier, |
663 | strlen (code_verifier)); | ||
664 | // encode code verifier | ||
665 | expected_code_challenge = base64url_encode (code_verifier_hash, 256 / 8); | ||
666 | code_challenge = (char *) ¶ms[1]; | ||
667 | GNUNET_free (code_verifier_hash); | ||
668 | if ((strlen (expected_code_challenge) != code_challenge_len) || | ||
669 | (0 != | ||
670 | strncmp (expected_code_challenge, code_challenge, code_challenge_len))) | ||
694 | { | 671 | { |
695 | GNUNET_free(code_payload); | 672 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
696 | GNUNET_free(plaintext); | 673 | "Invalid code verifier! Expected: %s, Got: %.*s\n", |
697 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); | 674 | expected_code_challenge, |
675 | code_challenge_len, | ||
676 | code_challenge); | ||
677 | GNUNET_free_non_null (code_payload); | ||
678 | GNUNET_free (expected_code_challenge); | ||
698 | return GNUNET_SYSERR; | 679 | return GNUNET_SYSERR; |
699 | } | 680 | } |
681 | GNUNET_free (expected_code_challenge); | ||
682 | } | ||
683 | // Ticket | ||
684 | memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); | ||
685 | // Nonce | ||
686 | nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr)); | ||
687 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); | ||
688 | // Signature | ||
689 | GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); | ||
690 | if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) | ||
691 | { | ||
692 | GNUNET_free (code_payload); | ||
693 | GNUNET_free (plaintext); | ||
694 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
695 | "Audience in ticket does not match client!\n"); | ||
696 | return GNUNET_SYSERR; | ||
697 | } | ||
698 | if (GNUNET_OK != | ||
699 | GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, | ||
700 | purpose, | ||
701 | signature, | ||
702 | &ticket->identity)) | ||
703 | { | ||
704 | GNUNET_free (code_payload); | ||
705 | GNUNET_free (plaintext); | ||
706 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); | ||
707 | return GNUNET_SYSERR; | ||
708 | } | ||
700 | // Attributes | 709 | // Attributes |
701 | attrs_ser = ((char *)¶ms[1]) + code_challenge_len; | 710 | attrs_ser = ((char *) ¶ms[1]) + code_challenge_len; |
702 | attrs_ser_len = ntohl(params->attr_list_len); | 711 | attrs_ser_len = ntohl (params->attr_list_len); |
703 | *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize(attrs_ser, attrs_ser_len); | 712 | *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser, attrs_ser_len); |
704 | 713 | ||
705 | *nonce_str = NULL; | 714 | *nonce_str = NULL; |
706 | if (nonce != 0) | 715 | if (nonce != 0) |
707 | GNUNET_asprintf(nonce_str, "%u", nonce); | 716 | GNUNET_asprintf (nonce_str, "%u", nonce); |
708 | GNUNET_free(code_payload); | 717 | GNUNET_free (code_payload); |
709 | GNUNET_free(plaintext); | 718 | GNUNET_free (plaintext); |
710 | return GNUNET_OK; | 719 | return GNUNET_OK; |
711 | } | 720 | } |
712 | 721 | ||
@@ -721,42 +730,42 @@ OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
721 | * @param token_response where to store the response | 730 | * @param token_response where to store the response |
722 | */ | 731 | */ |
723 | void | 732 | void |
724 | OIDC_build_token_response(const char *access_token, | 733 | OIDC_build_token_response (const char *access_token, |
725 | const char *id_token, | 734 | const char *id_token, |
726 | const struct GNUNET_TIME_Relative *expiration_time, | 735 | const struct GNUNET_TIME_Relative *expiration_time, |
727 | char **token_response) | 736 | char **token_response) |
728 | { | 737 | { |
729 | json_t *root_json; | 738 | json_t *root_json; |
730 | 739 | ||
731 | root_json = json_object(); | 740 | root_json = json_object (); |
732 | 741 | ||
733 | GNUNET_assert(NULL != access_token); | 742 | GNUNET_assert (NULL != access_token); |
734 | GNUNET_assert(NULL != id_token); | 743 | GNUNET_assert (NULL != id_token); |
735 | GNUNET_assert(NULL != expiration_time); | 744 | GNUNET_assert (NULL != expiration_time); |
736 | json_object_set_new(root_json, "access_token", json_string(access_token)); | 745 | json_object_set_new (root_json, "access_token", json_string (access_token)); |
737 | json_object_set_new(root_json, "token_type", json_string("Bearer")); | 746 | json_object_set_new (root_json, "token_type", json_string ("Bearer")); |
738 | json_object_set_new(root_json, | 747 | json_object_set_new (root_json, |
739 | "expires_in", | 748 | "expires_in", |
740 | json_integer(expiration_time->rel_value_us / | 749 | json_integer (expiration_time->rel_value_us |
741 | (1000 * 1000))); | 750 | / (1000 * 1000))); |
742 | json_object_set_new(root_json, "id_token", json_string(id_token)); | 751 | json_object_set_new (root_json, "id_token", json_string (id_token)); |
743 | *token_response = json_dumps(root_json, JSON_INDENT(0) | JSON_COMPACT); | 752 | *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT); |
744 | json_decref(root_json); | 753 | json_decref (root_json); |
745 | } | 754 | } |
746 | 755 | ||
747 | /** | 756 | /** |
748 | * Generate a new access token | 757 | * Generate a new access token |
749 | */ | 758 | */ |
750 | char * | 759 | char * |
751 | OIDC_access_token_new() | 760 | OIDC_access_token_new () |
752 | { | 761 | { |
753 | char *access_token; | 762 | char *access_token; |
754 | uint64_t random_number; | 763 | uint64_t random_number; |
755 | 764 | ||
756 | random_number = | 765 | random_number = |
757 | GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); | 766 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); |
758 | GNUNET_STRINGS_base64_encode(&random_number, | 767 | GNUNET_STRINGS_base64_encode (&random_number, |
759 | sizeof(uint64_t), | 768 | sizeof(uint64_t), |
760 | &access_token); | 769 | &access_token); |
761 | return access_token; | 770 | return access_token; |
762 | } | 771 | } |