|
@@ -31,7 +31,7 @@
|
|
|
#include "gnunet_reclaim_service.h"
|
|
|
#include "gnunet_signatures.h"
|
|
|
#include "oidc_helper.h"
|
|
|
-//#include "benchmark.h"
|
|
|
+// #include "benchmark.h"
|
|
|
#include <gcrypt.h>
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_BEGIN
|
|
@@ -39,7 +39,8 @@ GNUNET_NETWORK_STRUCT_BEGIN
|
|
|
/**
|
|
|
* The signature used to generate the authorization code
|
|
|
*/
|
|
|
-struct OIDC_Parameters {
|
|
|
+struct OIDC_Parameters
|
|
|
+{
|
|
|
/**
|
|
|
* The reclaim ticket
|
|
|
*/
|
|
@@ -64,41 +65,41 @@ struct OIDC_Parameters {
|
|
|
GNUNET_NETWORK_STRUCT_END
|
|
|
|
|
|
static char *
|
|
|
-create_jwt_header(void)
|
|
|
+create_jwt_header (void)
|
|
|
{
|
|
|
json_t *root;
|
|
|
char *json_str;
|
|
|
|
|
|
- root = json_object();
|
|
|
- json_object_set_new(root, JWT_ALG, json_string(JWT_ALG_VALUE));
|
|
|
- json_object_set_new(root, JWT_TYP, json_string(JWT_TYP_VALUE));
|
|
|
+ root = json_object ();
|
|
|
+ json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
|
|
|
+ json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
|
|
|
|
|
|
- json_str = json_dumps(root, JSON_INDENT(0) | JSON_COMPACT);
|
|
|
- json_decref(root);
|
|
|
+ json_str = json_dumps (root, JSON_INDENT (0) | JSON_COMPACT);
|
|
|
+ json_decref (root);
|
|
|
return json_str;
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-replace_char(char *str, char find, char replace)
|
|
|
+replace_char (char *str, char find, char replace)
|
|
|
{
|
|
|
- char *current_pos = strchr(str, find);
|
|
|
+ char *current_pos = strchr (str, find);
|
|
|
|
|
|
while (current_pos)
|
|
|
- {
|
|
|
- *current_pos = replace;
|
|
|
- current_pos = strchr(current_pos, find);
|
|
|
- }
|
|
|
+ {
|
|
|
+ *current_pos = replace;
|
|
|
+ current_pos = strchr (current_pos, find);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// RFC4648
|
|
|
static void
|
|
|
-fix_base64(char *str)
|
|
|
+fix_base64 (char *str)
|
|
|
{
|
|
|
// Replace + with -
|
|
|
- replace_char(str, '+', '-');
|
|
|
+ replace_char (str, '+', '-');
|
|
|
|
|
|
// Replace / with _
|
|
|
- replace_char(str, '/', '_');
|
|
|
+ replace_char (str, '/', '_');
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -112,12 +113,12 @@ fix_base64(char *str)
|
|
|
* @return a new base64-encoded JWT string.
|
|
|
*/
|
|
|
char *
|
|
|
-OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
|
|
|
- const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
|
|
|
- const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
|
|
|
- const struct GNUNET_TIME_Relative *expiration_time,
|
|
|
- const char *nonce,
|
|
|
- const char *secret_key)
|
|
|
+OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
|
|
|
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
|
|
|
+ const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
|
|
|
+ const struct GNUNET_TIME_Relative *expiration_time,
|
|
|
+ const char *nonce,
|
|
|
+ const char *secret_key)
|
|
|
{
|
|
|
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
|
|
|
struct GNUNET_HashCode signature;
|
|
@@ -136,108 +137,108 @@ OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
|
|
|
json_t *body;
|
|
|
|
|
|
// iat REQUIRED time now
|
|
|
- time_now = GNUNET_TIME_absolute_get();
|
|
|
+ time_now = GNUNET_TIME_absolute_get ();
|
|
|
// exp REQUIRED time expired from config
|
|
|
- exp_time = GNUNET_TIME_absolute_add(time_now, *expiration_time);
|
|
|
+ exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
|
|
|
// auth_time only if max_age
|
|
|
// nonce only if nonce
|
|
|
// OPTIONAL acr,amr,azp
|
|
|
subject =
|
|
|
- GNUNET_STRINGS_data_to_string_alloc(sub_key,
|
|
|
- sizeof(struct
|
|
|
- GNUNET_CRYPTO_EcdsaPublicKey));
|
|
|
+ GNUNET_STRINGS_data_to_string_alloc (sub_key,
|
|
|
+ sizeof(struct
|
|
|
+ GNUNET_CRYPTO_EcdsaPublicKey));
|
|
|
audience =
|
|
|
- GNUNET_STRINGS_data_to_string_alloc(aud_key,
|
|
|
- sizeof(struct
|
|
|
- GNUNET_CRYPTO_EcdsaPublicKey));
|
|
|
- header = create_jwt_header();
|
|
|
- body = json_object();
|
|
|
+ GNUNET_STRINGS_data_to_string_alloc (aud_key,
|
|
|
+ sizeof(struct
|
|
|
+ GNUNET_CRYPTO_EcdsaPublicKey));
|
|
|
+ header = create_jwt_header ();
|
|
|
+ body = json_object ();
|
|
|
|
|
|
// iss REQUIRED case sensitive server uri with https
|
|
|
// The issuer is the local reclaim instance (e.g.
|
|
|
// https://reclaim.id/api/openid)
|
|
|
- json_object_set_new(body, "iss", json_string(SERVER_ADDRESS));
|
|
|
+ json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
|
|
|
// sub REQUIRED public key identity, not exceed 255 ASCII length
|
|
|
- json_object_set_new(body, "sub", json_string(subject));
|
|
|
+ json_object_set_new (body, "sub", json_string (subject));
|
|
|
// aud REQUIRED public key client_id must be there
|
|
|
- json_object_set_new(body, "aud", json_string(audience));
|
|
|
+ json_object_set_new (body, "aud", json_string (audience));
|
|
|
// iat
|
|
|
- json_object_set_new(body,
|
|
|
- "iat",
|
|
|
- json_integer(time_now.abs_value_us / (1000 * 1000)));
|
|
|
+ json_object_set_new (body,
|
|
|
+ "iat",
|
|
|
+ json_integer (time_now.abs_value_us / (1000 * 1000)));
|
|
|
// exp
|
|
|
- json_object_set_new(body,
|
|
|
- "exp",
|
|
|
- json_integer(exp_time.abs_value_us / (1000 * 1000)));
|
|
|
+ json_object_set_new (body,
|
|
|
+ "exp",
|
|
|
+ json_integer (exp_time.abs_value_us / (1000 * 1000)));
|
|
|
// nbf
|
|
|
- json_object_set_new(body,
|
|
|
- "nbf",
|
|
|
- json_integer(time_now.abs_value_us / (1000 * 1000)));
|
|
|
+ json_object_set_new (body,
|
|
|
+ "nbf",
|
|
|
+ json_integer (time_now.abs_value_us / (1000 * 1000)));
|
|
|
// nonce
|
|
|
if (NULL != nonce)
|
|
|
- json_object_set_new(body, "nonce", json_string(nonce));
|
|
|
+ json_object_set_new (body, "nonce", json_string (nonce));
|
|
|
|
|
|
for (le = attrs->list_head; NULL != le; le = le->next)
|
|
|
- {
|
|
|
- attr_val_str =
|
|
|
- GNUNET_RECLAIM_ATTRIBUTE_value_to_string(le->claim->type,
|
|
|
- le->claim->data,
|
|
|
- le->claim->data_size);
|
|
|
- json_object_set_new(body, le->claim->name, json_string(attr_val_str));
|
|
|
- GNUNET_free(attr_val_str);
|
|
|
- }
|
|
|
- body_str = json_dumps(body, JSON_INDENT(0) | JSON_COMPACT);
|
|
|
- json_decref(body);
|
|
|
-
|
|
|
- GNUNET_STRINGS_base64_encode(header, strlen(header), &header_base64);
|
|
|
- fix_base64(header_base64);
|
|
|
-
|
|
|
- GNUNET_STRINGS_base64_encode(body_str, strlen(body_str), &body_base64);
|
|
|
- fix_base64(body_base64);
|
|
|
-
|
|
|
- GNUNET_free(subject);
|
|
|
- GNUNET_free(audience);
|
|
|
+ {
|
|
|
+ attr_val_str =
|
|
|
+ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
|
|
|
+ le->claim->data,
|
|
|
+ le->claim->data_size);
|
|
|
+ json_object_set_new (body, le->claim->name, json_string (attr_val_str));
|
|
|
+ GNUNET_free (attr_val_str);
|
|
|
+ }
|
|
|
+ body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
|
|
|
+ json_decref (body);
|
|
|
+
|
|
|
+ GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64);
|
|
|
+ fix_base64 (header_base64);
|
|
|
+
|
|
|
+ GNUNET_STRINGS_base64_encode (body_str, strlen (body_str), &body_base64);
|
|
|
+ fix_base64 (body_base64);
|
|
|
+
|
|
|
+ GNUNET_free (subject);
|
|
|
+ GNUNET_free (audience);
|
|
|
|
|
|
/**
|
|
|
* Creating the JWT signature. This might not be
|
|
|
* standards compliant, check.
|
|
|
*/
|
|
|
- GNUNET_asprintf(&signature_target, "%s.%s", header_base64, body_base64);
|
|
|
- GNUNET_CRYPTO_hmac_raw(secret_key,
|
|
|
- strlen(secret_key),
|
|
|
- signature_target,
|
|
|
- strlen(signature_target),
|
|
|
- &signature);
|
|
|
- GNUNET_STRINGS_base64_encode((const char *)&signature,
|
|
|
- sizeof(struct GNUNET_HashCode),
|
|
|
- &signature_base64);
|
|
|
- fix_base64(signature_base64);
|
|
|
-
|
|
|
- GNUNET_asprintf(&result,
|
|
|
- "%s.%s.%s",
|
|
|
- header_base64,
|
|
|
- body_base64,
|
|
|
- signature_base64);
|
|
|
-
|
|
|
- GNUNET_free(signature_target);
|
|
|
- GNUNET_free(header);
|
|
|
- GNUNET_free(body_str);
|
|
|
- GNUNET_free(signature_base64);
|
|
|
- GNUNET_free(body_base64);
|
|
|
- GNUNET_free(header_base64);
|
|
|
+ GNUNET_asprintf (&signature_target, "%s.%s", header_base64, body_base64);
|
|
|
+ GNUNET_CRYPTO_hmac_raw (secret_key,
|
|
|
+ strlen (secret_key),
|
|
|
+ signature_target,
|
|
|
+ strlen (signature_target),
|
|
|
+ &signature);
|
|
|
+ GNUNET_STRINGS_base64_encode ((const char *) &signature,
|
|
|
+ sizeof(struct GNUNET_HashCode),
|
|
|
+ &signature_base64);
|
|
|
+ fix_base64 (signature_base64);
|
|
|
+
|
|
|
+ GNUNET_asprintf (&result,
|
|
|
+ "%s.%s.%s",
|
|
|
+ header_base64,
|
|
|
+ body_base64,
|
|
|
+ signature_base64);
|
|
|
+
|
|
|
+ GNUNET_free (signature_target);
|
|
|
+ GNUNET_free (header);
|
|
|
+ GNUNET_free (body_str);
|
|
|
+ GNUNET_free (signature_base64);
|
|
|
+ GNUNET_free (body_base64);
|
|
|
+ GNUNET_free (header_base64);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/* Converts a hex character to its integer value */
|
|
|
static char
|
|
|
-from_hex(char ch)
|
|
|
+from_hex (char ch)
|
|
|
{
|
|
|
- return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
|
|
+ return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10;
|
|
|
}
|
|
|
|
|
|
/* Converts an integer value to its hex character*/
|
|
|
static char
|
|
|
-to_hex(char code)
|
|
|
+to_hex (char code)
|
|
|
{
|
|
|
static char hex[] = "0123456789abcdef";
|
|
|
|
|
@@ -247,27 +248,27 @@ to_hex(char code)
|
|
|
/* Returns a url-encoded version of str */
|
|
|
/* IMPORTANT: be sure to free() the returned string after use */
|
|
|
static char *
|
|
|
-url_encode(const char *str)
|
|
|
+url_encode (const char *str)
|
|
|
{
|
|
|
- char *pstr = (char *)str;
|
|
|
- char *buf = GNUNET_malloc(strlen(str) * 3 + 1);
|
|
|
+ char *pstr = (char *) str;
|
|
|
+ char *buf = GNUNET_malloc (strlen (str) * 3 + 1);
|
|
|
char *pbuf = buf;
|
|
|
|
|
|
while (*pstr)
|
|
|
+ {
|
|
|
+ if (isalnum (*pstr) || (*pstr == '-') || (*pstr == '_') || (*pstr == '.') ||
|
|
|
+ (*pstr == '~') )
|
|
|
+ *pbuf++ = *pstr;
|
|
|
+ else if (*pstr == ' ')
|
|
|
+ *pbuf++ = '+';
|
|
|
+ else
|
|
|
{
|
|
|
- if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' ||
|
|
|
- *pstr == '~')
|
|
|
- *pbuf++ = *pstr;
|
|
|
- else if (*pstr == ' ')
|
|
|
- *pbuf++ = '+';
|
|
|
- else
|
|
|
- {
|
|
|
- *pbuf++ = '%';
|
|
|
- *pbuf++ = to_hex(*pstr >> 4);
|
|
|
- *pbuf++ = to_hex(*pstr & 15);
|
|
|
- }
|
|
|
- pstr++;
|
|
|
+ *pbuf++ = '%';
|
|
|
+ *pbuf++ = to_hex (*pstr >> 4);
|
|
|
+ *pbuf++ = to_hex (*pstr & 15);
|
|
|
}
|
|
|
+ pstr++;
|
|
|
+ }
|
|
|
*pbuf = '\0';
|
|
|
return buf;
|
|
|
}
|
|
@@ -276,32 +277,32 @@ url_encode(const char *str)
|
|
|
/* Returns a url-decoded version of str */
|
|
|
/* IMPORTANT: be sure to free() the returned string after use */
|
|
|
static char *
|
|
|
-url_decode(const char *str)
|
|
|
+url_decode (const char *str)
|
|
|
{
|
|
|
- char *pstr = (char *)str;
|
|
|
- char *buf = GNUNET_malloc(strlen(str) + 1);
|
|
|
+ char *pstr = (char *) str;
|
|
|
+ char *buf = GNUNET_malloc (strlen (str) + 1);
|
|
|
char *pbuf = buf;
|
|
|
|
|
|
while (*pstr)
|
|
|
+ {
|
|
|
+ if (*pstr == '%')
|
|
|
+ {
|
|
|
+ if (pstr[1] && pstr[2])
|
|
|
+ {
|
|
|
+ *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]);
|
|
|
+ pstr += 2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (*pstr == '+')
|
|
|
+ {
|
|
|
+ *pbuf++ = ' ';
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- if (*pstr == '%')
|
|
|
- {
|
|
|
- if (pstr[1] && pstr[2])
|
|
|
- {
|
|
|
- *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
|
|
|
- pstr += 2;
|
|
|
- }
|
|
|
- }
|
|
|
- else if (*pstr == '+')
|
|
|
- {
|
|
|
- *pbuf++ = ' ';
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *pbuf++ = *pstr;
|
|
|
- }
|
|
|
- pstr++;
|
|
|
+ *pbuf++ = *pstr;
|
|
|
}
|
|
|
+ pstr++;
|
|
|
+ }
|
|
|
*pbuf = '\0';
|
|
|
return buf;
|
|
|
}
|
|
@@ -313,14 +314,14 @@ url_decode(const char *str)
|
|
|
* @return base64 encoded string
|
|
|
*/
|
|
|
static char *
|
|
|
-base64_and_urlencode(const char *data, size_t data_size)
|
|
|
+base64_and_urlencode (const char *data, size_t data_size)
|
|
|
{
|
|
|
char *enc;
|
|
|
char *urlenc;
|
|
|
|
|
|
- GNUNET_STRINGS_base64_encode(data, data_size, &enc);
|
|
|
- urlenc = url_encode(enc);
|
|
|
- GNUNET_free(enc);
|
|
|
+ GNUNET_STRINGS_base64_encode (data, data_size, &enc);
|
|
|
+ urlenc = url_encode (enc);
|
|
|
+ GNUNET_free (enc);
|
|
|
return urlenc;
|
|
|
}
|
|
|
|
|
@@ -332,111 +333,111 @@ base64_and_urlencode(const char *data, size_t data_size)
|
|
|
* @return base64 encoded string
|
|
|
*/
|
|
|
static char *
|
|
|
-base64url_encode(const char *data, size_t data_size)
|
|
|
+base64url_encode (const char *data, size_t data_size)
|
|
|
{
|
|
|
char *enc;
|
|
|
size_t pos;
|
|
|
|
|
|
- GNUNET_STRINGS_base64_encode(data, data_size, &enc);
|
|
|
- //Replace with correct characters for base64url
|
|
|
+ GNUNET_STRINGS_base64_encode (data, data_size, &enc);
|
|
|
+ // Replace with correct characters for base64url
|
|
|
pos = 0;
|
|
|
while ('\0' != enc[pos])
|
|
|
+ {
|
|
|
+ if ('+' == enc[pos])
|
|
|
+ enc[pos] = '-';
|
|
|
+ if ('/' == enc[pos])
|
|
|
+ enc[pos] = '_';
|
|
|
+ if ('=' == enc[pos])
|
|
|
{
|
|
|
- if ('+' == enc[pos])
|
|
|
- enc[pos] = '-';
|
|
|
- if ('/' == enc[pos])
|
|
|
- enc[pos] = '_';
|
|
|
- if ('=' == enc[pos])
|
|
|
- {
|
|
|
- enc[pos] = '\0';
|
|
|
- break;
|
|
|
- }
|
|
|
- pos++;
|
|
|
+ enc[pos] = '\0';
|
|
|
+ break;
|
|
|
}
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
return enc;
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
-derive_aes_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key,
|
|
|
- struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
|
- struct GNUNET_HashCode *key_material)
|
|
|
+derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
|
|
|
+ struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
|
+ struct GNUNET_HashCode *key_material)
|
|
|
{
|
|
|
static const char ctx_key[] = "reclaim-aes-ctx-key";
|
|
|
static const char ctx_iv[] = "reclaim-aes-ctx-iv";
|
|
|
|
|
|
- GNUNET_CRYPTO_kdf(key,
|
|
|
- sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
|
|
|
- ctx_key,
|
|
|
- strlen(ctx_key),
|
|
|
- key_material,
|
|
|
- sizeof(struct GNUNET_HashCode),
|
|
|
- NULL);
|
|
|
- GNUNET_CRYPTO_kdf(iv,
|
|
|
- sizeof(
|
|
|
- struct GNUNET_CRYPTO_SymmetricInitializationVector),
|
|
|
- ctx_iv,
|
|
|
- strlen(ctx_iv),
|
|
|
- key_material,
|
|
|
- sizeof(struct GNUNET_HashCode),
|
|
|
- NULL);
|
|
|
+ GNUNET_CRYPTO_kdf (key,
|
|
|
+ sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
|
|
|
+ ctx_key,
|
|
|
+ strlen (ctx_key),
|
|
|
+ key_material,
|
|
|
+ sizeof(struct GNUNET_HashCode),
|
|
|
+ NULL);
|
|
|
+ GNUNET_CRYPTO_kdf (iv,
|
|
|
+ sizeof(
|
|
|
+ struct GNUNET_CRYPTO_SymmetricInitializationVector),
|
|
|
+ ctx_iv,
|
|
|
+ strlen (ctx_iv),
|
|
|
+ key_material,
|
|
|
+ sizeof(struct GNUNET_HashCode),
|
|
|
+ NULL);
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
-calculate_key_priv(struct GNUNET_CRYPTO_SymmetricSessionKey *key,
|
|
|
- struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
|
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
- const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
|
|
|
+calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
|
|
|
+ struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
|
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
+ const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
|
|
|
{
|
|
|
struct GNUNET_HashCode key_material;
|
|
|
|
|
|
- GNUNET_CRYPTO_ecdsa_ecdh(ecdsa_priv, ecdh_pub, &key_material);
|
|
|
- derive_aes_key(key, iv, &key_material);
|
|
|
+ GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material);
|
|
|
+ derive_aes_key (key, iv, &key_material);
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
-calculate_key_pub(struct GNUNET_CRYPTO_SymmetricSessionKey *key,
|
|
|
- struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
|
- const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
|
|
|
- const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
|
|
|
+calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
|
|
|
+ struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
|
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
|
|
|
+ const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
|
|
|
{
|
|
|
struct GNUNET_HashCode key_material;
|
|
|
|
|
|
- GNUNET_CRYPTO_ecdh_ecdsa(ecdh_priv, ecdsa_pub, &key_material);
|
|
|
- derive_aes_key(key, iv, &key_material);
|
|
|
+ GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material);
|
|
|
+ derive_aes_key (key, iv, &key_material);
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
-decrypt_payload(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
- const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub,
|
|
|
- const char *ct,
|
|
|
- size_t ct_len,
|
|
|
- char *buf)
|
|
|
+decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
+ const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub,
|
|
|
+ const char *ct,
|
|
|
+ size_t ct_len,
|
|
|
+ char *buf)
|
|
|
{
|
|
|
struct GNUNET_CRYPTO_SymmetricSessionKey key;
|
|
|
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
|
|
|
|
|
|
- calculate_key_priv(&key, &iv, ecdsa_priv, ecdh_pub);
|
|
|
- GNUNET_break(GNUNET_CRYPTO_symmetric_decrypt(ct, ct_len, &key, &iv, buf));
|
|
|
+ calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub);
|
|
|
+ GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf));
|
|
|
}
|
|
|
|
|
|
|
|
|
static void
|
|
|
-encrypt_payload(const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
|
|
|
- const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv,
|
|
|
- const char *payload,
|
|
|
- size_t payload_len,
|
|
|
- char *buf)
|
|
|
+encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
|
|
|
+ const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv,
|
|
|
+ const char *payload,
|
|
|
+ size_t payload_len,
|
|
|
+ char *buf)
|
|
|
{
|
|
|
struct GNUNET_CRYPTO_SymmetricSessionKey key;
|
|
|
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
|
|
|
|
|
|
- calculate_key_pub(&key, &iv, ecdsa_pub, ecdh_priv);
|
|
|
- GNUNET_break(
|
|
|
- GNUNET_CRYPTO_symmetric_encrypt(payload, payload_len, &key, &iv, buf));
|
|
|
+ calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
|
|
|
+ GNUNET_break (
|
|
|
+ GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -451,11 +452,11 @@ encrypt_payload(const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
|
|
|
* @return a new authorization code (caller must free)
|
|
|
*/
|
|
|
char *
|
|
|
-OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
|
|
|
- const struct GNUNET_RECLAIM_Ticket *ticket,
|
|
|
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
|
|
|
- const char *nonce_str,
|
|
|
- const char *code_challenge)
|
|
|
+OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
|
|
|
+ const struct GNUNET_RECLAIM_Ticket *ticket,
|
|
|
+ struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
|
|
|
+ const char *nonce_str,
|
|
|
+ const char *code_challenge)
|
|
|
{
|
|
|
struct OIDC_Parameters params;
|
|
|
char *code_payload;
|
|
@@ -475,98 +476,99 @@ OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
|
|
|
|
|
|
/** PLAINTEXT **/
|
|
|
// Assign ticket
|
|
|
- memset(¶ms, 0, sizeof(params));
|
|
|
+ memset (¶ms, 0, sizeof(params));
|
|
|
params.ticket = *ticket;
|
|
|
// Assign nonce
|
|
|
nonce = 0;
|
|
|
payload_len = sizeof(struct OIDC_Parameters);
|
|
|
- if (NULL != nonce_str && strcmp("", nonce_str) != 0)
|
|
|
+ if ((NULL != nonce_str)&& (strcmp ("", nonce_str) != 0))
|
|
|
+ {
|
|
|
+ if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
|
|
|
{
|
|
|
- if ((1 != sscanf(nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
|
|
|
- {
|
|
|
- GNUNET_break(0);
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
|
|
|
- "Got nonce: %u from %s\n",
|
|
|
- nonce,
|
|
|
- nonce_str);
|
|
|
+ GNUNET_break (0);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
- nonce_tmp = htonl(nonce);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
+ "Got nonce: %u from %s\n",
|
|
|
+ nonce,
|
|
|
+ nonce_str);
|
|
|
+ }
|
|
|
+ nonce_tmp = htonl (nonce);
|
|
|
params.nonce = nonce_tmp;
|
|
|
// Assign code challenge
|
|
|
if (NULL != code_challenge)
|
|
|
- code_challenge_len = strlen(code_challenge);
|
|
|
+ code_challenge_len = strlen (code_challenge);
|
|
|
payload_len += code_challenge_len;
|
|
|
- params.code_challenge_len = htonl(code_challenge_len);
|
|
|
+ params.code_challenge_len = htonl (code_challenge_len);
|
|
|
// Assign attributes
|
|
|
if (NULL != attrs)
|
|
|
- {
|
|
|
- // Get length
|
|
|
- attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size(attrs);
|
|
|
- params.attr_list_len = htonl(attr_list_len);
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
|
|
|
- "Length of serialized attributes: %lu\n",
|
|
|
- attr_list_len);
|
|
|
- // Get serialized attributes
|
|
|
- payload_len += attr_list_len;
|
|
|
- }
|
|
|
+ {
|
|
|
+ // Get length
|
|
|
+ attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
|
|
|
+ params.attr_list_len = htonl (attr_list_len);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
+ "Length of serialized attributes: %lu\n",
|
|
|
+ attr_list_len);
|
|
|
+ // Get serialized attributes
|
|
|
+ payload_len += attr_list_len;
|
|
|
+ }
|
|
|
// Get plaintext length
|
|
|
- payload = GNUNET_malloc(payload_len);
|
|
|
- memcpy(payload, ¶ms, sizeof(params));
|
|
|
+ payload = GNUNET_malloc (payload_len);
|
|
|
+ memcpy (payload, ¶ms, sizeof(params));
|
|
|
tmp = payload + sizeof(params);
|
|
|
if (0 < code_challenge_len)
|
|
|
- {
|
|
|
- memcpy(tmp, code_challenge, code_challenge_len);
|
|
|
- tmp += code_challenge_len;
|
|
|
- }
|
|
|
+ {
|
|
|
+ memcpy (tmp, code_challenge, code_challenge_len);
|
|
|
+ tmp += code_challenge_len;
|
|
|
+ }
|
|
|
if (0 < attr_list_len)
|
|
|
- GNUNET_RECLAIM_ATTRIBUTE_list_serialize(attrs, tmp);
|
|
|
+ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, tmp);
|
|
|
/** END **/
|
|
|
|
|
|
/** ENCRYPT **/
|
|
|
// Get length
|
|
|
- code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) +
|
|
|
- sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) +
|
|
|
- payload_len + sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
|
|
|
- "Length of data to encode: %lu\n",
|
|
|
- code_payload_len);
|
|
|
+ code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
|
|
|
+ + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
|
|
|
+ + payload_len + sizeof(struct
|
|
|
+ GNUNET_CRYPTO_EcdsaSignature);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
+ "Length of data to encode: %lu\n",
|
|
|
+ code_payload_len);
|
|
|
|
|
|
// Generate ECDH key
|
|
|
- ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create();
|
|
|
- GNUNET_CRYPTO_ecdhe_key_get_public(ecdh_priv, &ecdh_pub);
|
|
|
+ ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create ();
|
|
|
+ GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub);
|
|
|
// Initialize code payload
|
|
|
- code_payload = GNUNET_malloc(code_payload_len);
|
|
|
- GNUNET_assert(NULL != code_payload);
|
|
|
- purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)code_payload;
|
|
|
- purpose->size = htonl(sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) +
|
|
|
- sizeof(ecdh_pub) + payload_len);
|
|
|
- purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
|
|
|
+ code_payload = GNUNET_malloc (code_payload_len);
|
|
|
+ GNUNET_assert (NULL != code_payload);
|
|
|
+ purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
|
|
|
+ purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
|
|
|
+ + sizeof(ecdh_pub) + payload_len);
|
|
|
+ purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
|
|
|
// Store pubkey
|
|
|
- buf_ptr = (char *)&purpose[1];
|
|
|
- memcpy(buf_ptr, &ecdh_pub, sizeof(ecdh_pub));
|
|
|
+ buf_ptr = (char *) &purpose[1];
|
|
|
+ memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub));
|
|
|
buf_ptr += sizeof(ecdh_pub);
|
|
|
// Encrypt plaintext and store
|
|
|
- encrypt_payload(&ticket->audience, ecdh_priv, payload, payload_len, buf_ptr);
|
|
|
- GNUNET_free(ecdh_priv);
|
|
|
- GNUNET_free(payload);
|
|
|
+ encrypt_payload (&ticket->audience, ecdh_priv, payload, payload_len, buf_ptr);
|
|
|
+ GNUNET_free (ecdh_priv);
|
|
|
+ GNUNET_free (payload);
|
|
|
buf_ptr += payload_len;
|
|
|
// Sign and store signature
|
|
|
if (GNUNET_SYSERR ==
|
|
|
- GNUNET_CRYPTO_ecdsa_sign(issuer,
|
|
|
- purpose,
|
|
|
- (struct GNUNET_CRYPTO_EcdsaSignature *)
|
|
|
- buf_ptr))
|
|
|
- {
|
|
|
- GNUNET_break(0);
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
|
|
|
- GNUNET_free(code_payload);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- code_str = base64_and_urlencode(code_payload, code_payload_len);
|
|
|
- GNUNET_free(code_payload);
|
|
|
+ GNUNET_CRYPTO_ecdsa_sign (issuer,
|
|
|
+ purpose,
|
|
|
+ (struct GNUNET_CRYPTO_EcdsaSignature *)
|
|
|
+ buf_ptr))
|
|
|
+ {
|
|
|
+ GNUNET_break (0);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
|
|
|
+ GNUNET_free (code_payload);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ code_str = base64_and_urlencode (code_payload, code_payload_len);
|
|
|
+ GNUNET_free (code_payload);
|
|
|
return code_str;
|
|
|
}
|
|
|
|
|
@@ -585,12 +587,12 @@ OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
|
|
|
* @return GNUNET_OK if successful, else GNUNET_SYSERR
|
|
|
*/
|
|
|
int
|
|
|
-OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
- const char *code,
|
|
|
- const char *code_verifier,
|
|
|
- struct GNUNET_RECLAIM_Ticket *ticket,
|
|
|
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
|
|
|
- char **nonce_str)
|
|
|
+OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
+ const char *code,
|
|
|
+ const char *code_verifier,
|
|
|
+ struct GNUNET_RECLAIM_Ticket *ticket,
|
|
|
+ struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
|
|
|
+ char **nonce_str)
|
|
|
{
|
|
|
char *code_payload;
|
|
|
char *ptr;
|
|
@@ -610,103 +612,110 @@ OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
uint32_t nonce = 0;
|
|
|
struct OIDC_Parameters *params;
|
|
|
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
|
|
|
code_payload = NULL;
|
|
|
code_payload_len =
|
|
|
- GNUNET_STRINGS_base64_decode(code, strlen(code), (void **)&code_payload);
|
|
|
- if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) +
|
|
|
- sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) +
|
|
|
- sizeof(struct OIDC_Parameters) +
|
|
|
- sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
|
|
|
- {
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
|
|
|
- GNUNET_free_non_null(code_payload);
|
|
|
- return GNUNET_SYSERR;
|
|
|
- }
|
|
|
-
|
|
|
- purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)code_payload;
|
|
|
+ GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload);
|
|
|
+ if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
|
|
|
+ + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
|
|
|
+ + sizeof(struct OIDC_Parameters)
|
|
|
+ + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
|
|
|
+ {
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
|
|
|
+ GNUNET_free_non_null (code_payload);
|
|
|
+ return GNUNET_SYSERR;
|
|
|
+ }
|
|
|
+
|
|
|
+ purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
|
|
|
plaintext_len = code_payload_len;
|
|
|
plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose);
|
|
|
- ptr = (char *)&purpose[1];
|
|
|
+ ptr = (char *) &purpose[1];
|
|
|
// Public ECDH key
|
|
|
- ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *)ptr;
|
|
|
+ ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
|
|
|
ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
|
|
|
plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
|
|
|
|
|
|
// Decrypt ciphertext
|
|
|
plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
|
|
|
- plaintext = GNUNET_malloc(plaintext_len);
|
|
|
- decrypt_payload(ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
|
|
|
- //ptr = plaintext;
|
|
|
+ plaintext = GNUNET_malloc (plaintext_len);
|
|
|
+ decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
|
|
|
+ // ptr = plaintext;
|
|
|
ptr += plaintext_len;
|
|
|
- signature = (struct GNUNET_CRYPTO_EcdsaSignature *)ptr;
|
|
|
- params = (struct OIDC_Parameters *)plaintext;
|
|
|
+ signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr;
|
|
|
+ params = (struct OIDC_Parameters *) plaintext;
|
|
|
|
|
|
// cmp code_challenge code_verifier
|
|
|
- code_challenge_len = ntohl(params->code_challenge_len);
|
|
|
+ code_challenge_len = ntohl (params->code_challenge_len);
|
|
|
if (0 != code_challenge_len) /* Only check if this code requires a CV */
|
|
|
+ {
|
|
|
+ if (NULL == code_verifier)
|
|
|
{
|
|
|
- code_verifier_hash = GNUNET_malloc(256 / 8);
|
|
|
- // hash code verifier
|
|
|
- gcry_md_hash_buffer(GCRY_MD_SHA256,
|
|
|
- code_verifier_hash,
|
|
|
- code_verifier,
|
|
|
- strlen(code_verifier));
|
|
|
- // encode code verifier
|
|
|
- expected_code_challenge = base64url_encode(code_verifier_hash, 256 / 8);
|
|
|
- code_challenge = (char *)¶ms[1];
|
|
|
- GNUNET_free(code_verifier_hash);
|
|
|
- if ((strlen(expected_code_challenge) != code_challenge_len) ||
|
|
|
- (0 !=
|
|
|
- strncmp(expected_code_challenge, code_challenge, code_challenge_len)))
|
|
|
- {
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
|
|
|
- "Invalid code verifier! Expected: %s, Got: %.*s\n",
|
|
|
- expected_code_challenge,
|
|
|
- code_challenge_len,
|
|
|
- code_challenge);
|
|
|
- GNUNET_free_non_null(code_payload);
|
|
|
- GNUNET_free(expected_code_challenge);
|
|
|
- return GNUNET_SYSERR;
|
|
|
- }
|
|
|
- GNUNET_free(expected_code_challenge);
|
|
|
- }
|
|
|
- // Ticket
|
|
|
- memcpy(ticket, ¶ms->ticket, sizeof(params->ticket));
|
|
|
- // Nonce
|
|
|
- nonce = ntohl(params->nonce); //ntohl (*((uint32_t *) ptr));
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
|
|
|
- // Signature
|
|
|
- GNUNET_CRYPTO_ecdsa_key_get_public(ecdsa_priv, &ecdsa_pub);
|
|
|
- if (0 != GNUNET_memcmp(&ecdsa_pub, &ticket->audience))
|
|
|
- {
|
|
|
- GNUNET_free(code_payload);
|
|
|
- GNUNET_free(plaintext);
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
|
|
|
- "Audience in ticket does not match client!\n");
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
|
+ "Expected code verifier!\n");
|
|
|
+ GNUNET_free_non_null (code_payload);
|
|
|
return GNUNET_SYSERR;
|
|
|
}
|
|
|
- if (GNUNET_OK !=
|
|
|
- GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN,
|
|
|
- purpose,
|
|
|
- signature,
|
|
|
- &ticket->identity))
|
|
|
+ code_verifier_hash = GNUNET_malloc (256 / 8);
|
|
|
+ // hash code verifier
|
|
|
+ gcry_md_hash_buffer (GCRY_MD_SHA256,
|
|
|
+ code_verifier_hash,
|
|
|
+ code_verifier,
|
|
|
+ strlen (code_verifier));
|
|
|
+ // encode code verifier
|
|
|
+ expected_code_challenge = base64url_encode (code_verifier_hash, 256 / 8);
|
|
|
+ code_challenge = (char *) ¶ms[1];
|
|
|
+ GNUNET_free (code_verifier_hash);
|
|
|
+ if ((strlen (expected_code_challenge) != code_challenge_len) ||
|
|
|
+ (0 !=
|
|
|
+ strncmp (expected_code_challenge, code_challenge, code_challenge_len)))
|
|
|
{
|
|
|
- GNUNET_free(code_payload);
|
|
|
- GNUNET_free(plaintext);
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
|
+ "Invalid code verifier! Expected: %s, Got: %.*s\n",
|
|
|
+ expected_code_challenge,
|
|
|
+ code_challenge_len,
|
|
|
+ code_challenge);
|
|
|
+ GNUNET_free_non_null (code_payload);
|
|
|
+ GNUNET_free (expected_code_challenge);
|
|
|
return GNUNET_SYSERR;
|
|
|
}
|
|
|
+ GNUNET_free (expected_code_challenge);
|
|
|
+ }
|
|
|
+ // Ticket
|
|
|
+ memcpy (ticket, ¶ms->ticket, sizeof(params->ticket));
|
|
|
+ // Nonce
|
|
|
+ nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr));
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
|
|
|
+ // Signature
|
|
|
+ GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
|
|
|
+ if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
|
|
|
+ {
|
|
|
+ GNUNET_free (code_payload);
|
|
|
+ GNUNET_free (plaintext);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
|
+ "Audience in ticket does not match client!\n");
|
|
|
+ return GNUNET_SYSERR;
|
|
|
+ }
|
|
|
+ if (GNUNET_OK !=
|
|
|
+ GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN,
|
|
|
+ purpose,
|
|
|
+ signature,
|
|
|
+ &ticket->identity))
|
|
|
+ {
|
|
|
+ GNUNET_free (code_payload);
|
|
|
+ GNUNET_free (plaintext);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
|
|
|
+ return GNUNET_SYSERR;
|
|
|
+ }
|
|
|
// Attributes
|
|
|
- attrs_ser = ((char *)¶ms[1]) + code_challenge_len;
|
|
|
- attrs_ser_len = ntohl(params->attr_list_len);
|
|
|
- *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize(attrs_ser, attrs_ser_len);
|
|
|
+ attrs_ser = ((char *) ¶ms[1]) + code_challenge_len;
|
|
|
+ attrs_ser_len = ntohl (params->attr_list_len);
|
|
|
+ *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser, attrs_ser_len);
|
|
|
|
|
|
*nonce_str = NULL;
|
|
|
if (nonce != 0)
|
|
|
- GNUNET_asprintf(nonce_str, "%u", nonce);
|
|
|
- GNUNET_free(code_payload);
|
|
|
- GNUNET_free(plaintext);
|
|
|
+ GNUNET_asprintf (nonce_str, "%u", nonce);
|
|
|
+ GNUNET_free (code_payload);
|
|
|
+ GNUNET_free (plaintext);
|
|
|
return GNUNET_OK;
|
|
|
}
|
|
|
|
|
@@ -721,42 +730,42 @@ OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
|
|
|
* @param token_response where to store the response
|
|
|
*/
|
|
|
void
|
|
|
-OIDC_build_token_response(const char *access_token,
|
|
|
- const char *id_token,
|
|
|
- const struct GNUNET_TIME_Relative *expiration_time,
|
|
|
- char **token_response)
|
|
|
+OIDC_build_token_response (const char *access_token,
|
|
|
+ const char *id_token,
|
|
|
+ const struct GNUNET_TIME_Relative *expiration_time,
|
|
|
+ char **token_response)
|
|
|
{
|
|
|
json_t *root_json;
|
|
|
|
|
|
- root_json = json_object();
|
|
|
-
|
|
|
- GNUNET_assert(NULL != access_token);
|
|
|
- GNUNET_assert(NULL != id_token);
|
|
|
- GNUNET_assert(NULL != expiration_time);
|
|
|
- json_object_set_new(root_json, "access_token", json_string(access_token));
|
|
|
- json_object_set_new(root_json, "token_type", json_string("Bearer"));
|
|
|
- json_object_set_new(root_json,
|
|
|
- "expires_in",
|
|
|
- json_integer(expiration_time->rel_value_us /
|
|
|
- (1000 * 1000)));
|
|
|
- json_object_set_new(root_json, "id_token", json_string(id_token));
|
|
|
- *token_response = json_dumps(root_json, JSON_INDENT(0) | JSON_COMPACT);
|
|
|
- json_decref(root_json);
|
|
|
+ root_json = json_object ();
|
|
|
+
|
|
|
+ GNUNET_assert (NULL != access_token);
|
|
|
+ GNUNET_assert (NULL != id_token);
|
|
|
+ GNUNET_assert (NULL != expiration_time);
|
|
|
+ json_object_set_new (root_json, "access_token", json_string (access_token));
|
|
|
+ json_object_set_new (root_json, "token_type", json_string ("Bearer"));
|
|
|
+ json_object_set_new (root_json,
|
|
|
+ "expires_in",
|
|
|
+ json_integer (expiration_time->rel_value_us
|
|
|
+ / (1000 * 1000)));
|
|
|
+ json_object_set_new (root_json, "id_token", json_string (id_token));
|
|
|
+ *token_response = json_dumps (root_json, JSON_INDENT (0) | JSON_COMPACT);
|
|
|
+ json_decref (root_json);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Generate a new access token
|
|
|
*/
|
|
|
char *
|
|
|
-OIDC_access_token_new()
|
|
|
+OIDC_access_token_new ()
|
|
|
{
|
|
|
char *access_token;
|
|
|
uint64_t random_number;
|
|
|
|
|
|
random_number =
|
|
|
- GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
|
|
|
- GNUNET_STRINGS_base64_encode(&random_number,
|
|
|
- sizeof(uint64_t),
|
|
|
- &access_token);
|
|
|
+ GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
|
|
|
+ GNUNET_STRINGS_base64_encode (&random_number,
|
|
|
+ sizeof(uint64_t),
|
|
|
+ &access_token);
|
|
|
return access_token;
|
|
|
}
|