diff options
-rw-r--r-- | src/include/gnunet_strings_lib.h | 26 | ||||
-rw-r--r-- | src/reclaim/oidc_helper.c | 149 | ||||
-rw-r--r-- | src/util/strings.c | 85 |
3 files changed, 119 insertions, 141 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 5e8892c0d..4003590fc 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -349,6 +349,19 @@ GNUNET_STRINGS_base64_encode (const void *in, | |||
349 | 349 | ||
350 | 350 | ||
351 | /** | 351 | /** |
352 | * Encode into Base64url. RFC7515 | ||
353 | * | ||
354 | * @param in the data to encode | ||
355 | * @param len the length of the input | ||
356 | * @param output where to write the output (*output should be NULL, | ||
357 | * is allocated) | ||
358 | * @return the size of the output | ||
359 | */ | ||
360 | size_t | ||
361 | GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output); | ||
362 | |||
363 | |||
364 | /** | ||
352 | * Decode from Base64. | 365 | * Decode from Base64. |
353 | * | 366 | * |
354 | * @param data the data to encode | 367 | * @param data the data to encode |
@@ -364,6 +377,19 @@ GNUNET_STRINGS_base64_decode (const char *data, | |||
364 | 377 | ||
365 | 378 | ||
366 | /** | 379 | /** |
380 | * Decode from Base64url. RFC7515 | ||
381 | * | ||
382 | * @param data the data to decode | ||
383 | * @param len the length of the input | ||
384 | * @param output where to write the output (*output should be NULL, | ||
385 | * is allocated) | ||
386 | * @return the size of the output | ||
387 | */ | ||
388 | size_t | ||
389 | GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out); | ||
390 | |||
391 | |||
392 | /** | ||
367 | * Convert a peer path to a human-readable string. | 393 | * Convert a peer path to a human-readable string. |
368 | * | 394 | * |
369 | * @param pids array of PIDs to convert to a string | 395 | * @param pids array of PIDs to convert to a string |
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 487aa5695..92b4b69cc 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -287,10 +287,10 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
287 | json_decref (body); | 287 | json_decref (body); |
288 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str); | 288 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str); |
289 | 289 | ||
290 | GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64); | 290 | GNUNET_STRINGS_base64url_encode (header, strlen (header), &header_base64); |
291 | fix_base64 (header_base64); | 291 | fix_base64 (header_base64); |
292 | 292 | ||
293 | GNUNET_STRINGS_base64_encode (body_str, strlen (body_str), &body_base64); | 293 | GNUNET_STRINGS_base64url_encode (body_str, strlen (body_str), &body_base64); |
294 | fix_base64 (body_base64); | 294 | fix_base64 (body_base64); |
295 | 295 | ||
296 | GNUNET_free (subject); | 296 | GNUNET_free (subject); |
@@ -306,9 +306,9 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
306 | signature_target, | 306 | signature_target, |
307 | strlen (signature_target), | 307 | strlen (signature_target), |
308 | &signature); | 308 | &signature); |
309 | GNUNET_STRINGS_base64_encode ((const char *) &signature, | 309 | GNUNET_STRINGS_base64url_encode ((const char *) &signature, |
310 | sizeof(struct GNUNET_HashCode), | 310 | sizeof(struct GNUNET_HashCode), |
311 | &signature_base64); | 311 | &signature_base64); |
312 | fix_base64 (signature_base64); | 312 | fix_base64 (signature_base64); |
313 | 313 | ||
314 | GNUNET_asprintf (&result, | 314 | GNUNET_asprintf (&result, |
@@ -333,138 +333,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | |||
333 | } | 333 | } |
334 | 334 | ||
335 | 335 | ||
336 | /* Converts a hex character to its integer value */ | ||
337 | static char | ||
338 | from_hex (char ch) | ||
339 | { | ||
340 | return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10; | ||
341 | } | ||
342 | |||
343 | |||
344 | /* Converts an integer value to its hex character*/ | ||
345 | static char | ||
346 | to_hex (char code) | ||
347 | { | ||
348 | static char hex[] = "0123456789abcdef"; | ||
349 | |||
350 | return hex[code & 15]; | ||
351 | } | ||
352 | |||
353 | |||
354 | /* Returns a url-encoded version of str */ | ||
355 | /* IMPORTANT: be sure to free() the returned string after use */ | ||
356 | static char * | ||
357 | url_encode (const char *str) | ||
358 | { | ||
359 | char *pstr = (char *) str; | ||
360 | char *buf = GNUNET_malloc (strlen (str) * 3 + 1); | ||
361 | char *pbuf = buf; | ||
362 | |||
363 | while (*pstr) | ||
364 | { | ||
365 | if (isalnum (*pstr) || (*pstr == '-') || (*pstr == '_') || (*pstr == '.') || | ||
366 | (*pstr == '~') ) | ||
367 | *pbuf++ = *pstr; | ||
368 | else if (*pstr == ' ') | ||
369 | *pbuf++ = '+'; | ||
370 | else | ||
371 | { | ||
372 | *pbuf++ = '%'; | ||
373 | *pbuf++ = to_hex (*pstr >> 4); | ||
374 | *pbuf++ = to_hex (*pstr & 15); | ||
375 | } | ||
376 | pstr++; | ||
377 | } | ||
378 | *pbuf = '\0'; | ||
379 | return buf; | ||
380 | } | ||
381 | |||
382 | |||
383 | /* Returns a url-decoded version of str */ | ||
384 | /* IMPORTANT: be sure to free() the returned string after use */ | ||
385 | static char * | ||
386 | url_decode (const char *str) | ||
387 | { | ||
388 | char *pstr = (char *) str; | ||
389 | char *buf = GNUNET_malloc (strlen (str) + 1); | ||
390 | char *pbuf = buf; | ||
391 | |||
392 | while (*pstr) | ||
393 | { | ||
394 | if (*pstr == '%') | ||
395 | { | ||
396 | if (pstr[1] && pstr[2]) | ||
397 | { | ||
398 | *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]); | ||
399 | pstr += 2; | ||
400 | } | ||
401 | } | ||
402 | else if (*pstr == '+') | ||
403 | { | ||
404 | *pbuf++ = ' '; | ||
405 | } | ||
406 | else | ||
407 | { | ||
408 | *pbuf++ = *pstr; | ||
409 | } | ||
410 | pstr++; | ||
411 | } | ||
412 | *pbuf = '\0'; | ||
413 | return buf; | ||
414 | } | ||
415 | |||
416 | |||
417 | /** | ||
418 | * Returns base64 encoded string urlencoded | ||
419 | * | ||
420 | * @param string the string to encode | ||
421 | * @return base64 encoded string | ||
422 | */ | ||
423 | static char * | ||
424 | base64_and_urlencode (const char *data, size_t data_size) | ||
425 | { | ||
426 | char *enc; | ||
427 | char *urlenc; | ||
428 | |||
429 | GNUNET_STRINGS_base64_encode (data, data_size, &enc); | ||
430 | urlenc = url_encode (enc); | ||
431 | GNUNET_free (enc); | ||
432 | return urlenc; | ||
433 | } | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Returns base64 encoded string urlencoded | ||
438 | * | ||
439 | * @param string the string to encode | ||
440 | * @return base64 encoded string | ||
441 | */ | ||
442 | static char * | ||
443 | base64url_encode (const char *data, size_t data_size) | ||
444 | { | ||
445 | char *enc; | ||
446 | size_t pos; | ||
447 | |||
448 | GNUNET_STRINGS_base64_encode (data, data_size, &enc); | ||
449 | // Replace with correct characters for base64url | ||
450 | pos = 0; | ||
451 | while ('\0' != enc[pos]) | ||
452 | { | ||
453 | if ('+' == enc[pos]) | ||
454 | enc[pos] = '-'; | ||
455 | if ('/' == enc[pos]) | ||
456 | enc[pos] = '_'; | ||
457 | if ('=' == enc[pos]) | ||
458 | { | ||
459 | enc[pos] = '\0'; | ||
460 | break; | ||
461 | } | ||
462 | pos++; | ||
463 | } | ||
464 | return enc; | ||
465 | } | ||
466 | |||
467 | |||
468 | static void | 336 | static void |
469 | derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | 337 | derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, |
470 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 338 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, |
@@ -693,7 +561,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
693 | GNUNET_free (code_payload); | 561 | GNUNET_free (code_payload); |
694 | return NULL; | 562 | return NULL; |
695 | } | 563 | } |
696 | code_str = base64_and_urlencode (code_payload, code_payload_len); | 564 | GNUNET_STRINGS_base64url_encode (code_payload, code_payload_len, &code_str); |
697 | GNUNET_free (code_payload); | 565 | GNUNET_free (code_payload); |
698 | return code_str; | 566 | return code_str; |
699 | } | 567 | } |
@@ -742,7 +610,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
742 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); | 610 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); |
743 | code_payload = NULL; | 611 | code_payload = NULL; |
744 | code_payload_len = | 612 | code_payload_len = |
745 | GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload); | 613 | GNUNET_STRINGS_base64url_decode (code, strlen (code), |
614 | (void **) &code_payload); | ||
746 | if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 615 | if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
747 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) | 616 | + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) |
748 | + sizeof(struct OIDC_Parameters) | 617 | + sizeof(struct OIDC_Parameters) |
@@ -789,7 +658,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
789 | code_verifier, | 658 | code_verifier, |
790 | strlen (code_verifier)); | 659 | strlen (code_verifier)); |
791 | // encode code verifier | 660 | // encode code verifier |
792 | expected_code_challenge = base64url_encode (code_verifier_hash, 256 / 8); | 661 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, &expected_code_challenge); |
793 | code_challenge = (char *) ¶ms[1]; | 662 | code_challenge = (char *) ¶ms[1]; |
794 | GNUNET_free (code_verifier_hash); | 663 | GNUNET_free (code_verifier_hash); |
795 | if ((strlen (expected_code_challenge) != code_challenge_len) || | 664 | if ((strlen (expected_code_challenge) != code_challenge_len) || |
diff --git a/src/util/strings.c b/src/util/strings.c index 4e7451283..a291dc4e1 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -1897,6 +1897,41 @@ GNUNET_STRINGS_base64_encode (const void *in, size_t len, char **output) | |||
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | 1899 | ||
1900 | /** | ||
1901 | * Encode into Base64url. RFC7515 | ||
1902 | * | ||
1903 | * @param in the data to encode | ||
1904 | * @param len the length of the input | ||
1905 | * @param output where to write the output (*output should be NULL, | ||
1906 | * is allocated) | ||
1907 | * @return the size of the output | ||
1908 | */ | ||
1909 | size_t | ||
1910 | GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output) | ||
1911 | { | ||
1912 | char *enc; | ||
1913 | size_t pos; | ||
1914 | |||
1915 | GNUNET_STRINGS_base64_encode (in, len, output); | ||
1916 | enc = *output; | ||
1917 | // Replace with correct characters for base64url | ||
1918 | pos = 0; | ||
1919 | while ('\0' != enc[pos]) | ||
1920 | { | ||
1921 | if ('+' == enc[pos]) | ||
1922 | enc[pos] = '-'; | ||
1923 | if ('/' == enc[pos]) | ||
1924 | enc[pos] = '_'; | ||
1925 | if ('=' == enc[pos]) | ||
1926 | { | ||
1927 | enc[pos] = '\0'; | ||
1928 | break; | ||
1929 | } | ||
1930 | pos++; | ||
1931 | } | ||
1932 | return strlen (enc); | ||
1933 | } | ||
1934 | |||
1900 | #define cvtfind(a) \ | 1935 | #define cvtfind(a) \ |
1901 | ((((a) >= 'A') && ((a) <= 'Z')) \ | 1936 | ((((a) >= 'A') && ((a) <= 'Z')) \ |
1902 | ? (a) - 'A' \ | 1937 | ? (a) - 'A' \ |
@@ -1929,7 +1964,7 @@ GNUNET_STRINGS_base64_decode (const char *data, size_t len, void **out) | |||
1929 | "ignoring CR/LF\n"); \ | 1964 | "ignoring CR/LF\n"); \ |
1930 | i++; \ | 1965 | i++; \ |
1931 | if (i >= len) \ | 1966 | if (i >= len) \ |
1932 | goto END; \ | 1967 | goto END; \ |
1933 | } | 1968 | } |
1934 | 1969 | ||
1935 | output = GNUNET_malloc ((len * 3 / 4) + 8); | 1970 | output = GNUNET_malloc ((len * 3 / 4) + 8); |
@@ -1978,4 +2013,52 @@ END: | |||
1978 | } | 2013 | } |
1979 | 2014 | ||
1980 | 2015 | ||
2016 | /** | ||
2017 | * Decode from Base64url. RFC7515 | ||
2018 | * | ||
2019 | * @param data the data to decode | ||
2020 | * @param len the length of the input | ||
2021 | * @param output where to write the output (*output should be NULL, | ||
2022 | * is allocated) | ||
2023 | * @return the size of the output | ||
2024 | */ | ||
2025 | size_t | ||
2026 | GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out) | ||
2027 | { | ||
2028 | char *s; | ||
2029 | int padding; | ||
2030 | size_t ret; | ||
2031 | |||
2032 | /* make enough space for padding */ | ||
2033 | s = GNUNET_malloc (len + 3); | ||
2034 | memcpy (s, data, len); | ||
2035 | |||
2036 | for (int i = 0; i < strlen (s); i++) | ||
2037 | { | ||
2038 | if (s[i] == '-') | ||
2039 | s[i] = '+'; | ||
2040 | if (s[i] == '_') | ||
2041 | s[i] = '/'; | ||
2042 | } | ||
2043 | padding = len % 4; | ||
2044 | switch (padding) // Pad with trailing '='s | ||
2045 | { | ||
2046 | case 0: | ||
2047 | break; // No pad chars in this case | ||
2048 | case 2: | ||
2049 | strncpy (&s[len], "==", 2); | ||
2050 | break; // Two pad chars | ||
2051 | case 3: | ||
2052 | s[len] = '='; | ||
2053 | break; // One pad char | ||
2054 | default: | ||
2055 | GNUNET_assert (0); | ||
2056 | break; | ||
2057 | } | ||
2058 | ret = GNUNET_STRINGS_base64_decode (s, strlen (s), out); | ||
2059 | GNUNET_free (s); | ||
2060 | return ret; | ||
2061 | } | ||
2062 | |||
2063 | |||
1981 | /* end of strings.c */ | 2064 | /* end of strings.c */ |