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