[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [gnunet] branch master updated: RECLAIM/OIDC: encrypt autho
From: |
gnunet |
Subject: |
[GNUnet-SVN] [gnunet] branch master updated: RECLAIM/OIDC: encrypt authorizaion code payload |
Date: |
Sat, 27 Apr 2019 21:01:27 +0200 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new f7e0dfea0 RECLAIM/OIDC: encrypt authorizaion code payload
f7e0dfea0 is described below
commit f7e0dfea0966f0ae9a4185206885d3a61895b759
Author: Schanzenbach, Martin <address@hidden>
AuthorDate: Sat Apr 27 21:01:13 2019 +0200
RECLAIM/OIDC: encrypt authorizaion code payload
---
src/reclaim/oidc_helper.c | 160 +++++++++++++++++++++++++++----
src/reclaim/oidc_helper.h | 4 +-
src/reclaim/plugin_rest_openid_connect.c | 52 +++++-----
3 files changed, 167 insertions(+), 49 deletions(-)
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index 56a4b17a4..89e0920f0 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -292,6 +292,86 @@ base64_encode (const char *data, size_t data_size)
}
+static void
+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 (key_material),
+ NULL);
+ GNUNET_CRYPTO_kdf (iv,
+ sizeof (
+ struct GNUNET_CRYPTO_SymmetricInitializationVector),
+ ctx_iv,
+ strlen (ctx_iv),
+ &key_material,
+ sizeof (key_material),
+ 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)
+{
+ struct GNUNET_HashCode 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)
+{
+ struct GNUNET_HashCode 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)
+{
+ 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));
+}
+
+
+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)
+{
+ 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));
+}
+
+
/**
* Builds an OIDC authorization code including
* a reclaim ticket and nonce
@@ -309,6 +389,7 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
const char *nonce_str)
{
char *code_payload;
+ char *plaintext;
char *attrs_ser;
char *code_str;
char *buf_ptr;
@@ -318,6 +399,8 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
uint32_t nonce;
uint32_t nonce_tmp;
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv;
+ struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
attrs_ser = NULL;
signature_payload_len =
@@ -333,19 +416,15 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, attrs_ser);
}
code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
+ sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
signature_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 = 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) +
- signature_payload_len);
- purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
+ plaintext = GNUNET_malloc (signature_payload_len);
// First, copy ticket
- buf_ptr = (char *) &purpose[1];
+ buf_ptr = plaintext;
memcpy (buf_ptr, ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
buf_ptr += sizeof (struct GNUNET_RECLAIM_Ticket);
// Then copy nonce
@@ -356,12 +435,14 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
- GNUNET_free (code_payload);
+ GNUNET_free (plaintext);
GNUNET_free_non_null (attrs_ser);
return NULL;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got nonce: %u from %s\n", nonce, nonce_str);
+ "Got nonce: %u from %s\n",
+ nonce,
+ nonce_str);
}
nonce_tmp = htonl (nonce);
memcpy (buf_ptr, &nonce_tmp, sizeof (uint32_t));
@@ -371,7 +452,32 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
{
memcpy (buf_ptr, attrs_ser, attr_list_len);
buf_ptr += attr_list_len;
+ GNUNET_free (attrs_ser);
}
+ // Generate ECDH key
+ 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) + signature_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 += sizeof (ecdh_pub);
+ // Encrypt plaintext and store
+ encrypt_payload (&ticket->audience,
+ ecdh_priv,
+ plaintext,
+ signature_payload_len,
+ buf_ptr);
+ GNUNET_free (ecdh_priv);
+ GNUNET_free (plaintext);
+ buf_ptr += signature_payload_len;
+ // Sign and store signature
if (GNUNET_SYSERR ==
GNUNET_CRYPTO_ecdsa_sign (issuer,
purpose,
@@ -381,12 +487,10 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
GNUNET_free (code_payload);
- GNUNET_free_non_null (attrs_ser);
return NULL;
}
code_str = base64_encode (code_payload, code_payload_len);
GNUNET_free (code_payload);
- GNUNET_free_non_null (attrs_ser);
return code_str;
}
@@ -404,7 +508,7 @@ 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_EcdsaPublicKey *audience,
+OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
const char *code,
struct GNUNET_RECLAIM_Ticket *ticket,
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
@@ -412,19 +516,23 @@ OIDC_parse_authz_code (const struct
GNUNET_CRYPTO_EcdsaPublicKey *audience,
{
char *code_payload;
char *ptr;
+ char *plaintext;
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
struct GNUNET_CRYPTO_EcdsaSignature *signature;
+ struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
+ struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
size_t code_payload_len;
size_t attrs_ser_len;
size_t signature_offset;
+ size_t plaintext_len;
uint32_t nonce = 0;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "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 GNUNET_RECLAIM_Ticket) +
sizeof (uint32_t) +
sizeof (struct GNUNET_CRYPTO_EcdsaSignature))
@@ -438,24 +546,39 @@ OIDC_parse_authz_code (const struct
GNUNET_CRYPTO_EcdsaPublicKey *audience,
attrs_ser_len = code_payload_len;
attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose);
ptr = (char *) &purpose[1];
+ // Public ECDH key
+ ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
+ ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
+ attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
+
+ // Decrypt ciphertext
+ plaintext_len = attrs_ser_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
+ plaintext = GNUNET_malloc (plaintext_len);
+ decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
+ ptr = plaintext;
+ // Ticket
*ticket = *((struct GNUNET_RECLAIM_Ticket *) ptr);
attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket);
ptr += sizeof (struct GNUNET_RECLAIM_Ticket);
+ // Nonce
nonce = ntohl (*((uint32_t *) ptr));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got nonce: %u\n", nonce);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
attrs_ser_len -= sizeof (uint32_t);
ptr += sizeof (uint32_t);
+ // Attributes
attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
*attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (ptr, attrs_ser_len);
+ // Signature
signature_offset =
code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
signature =
(struct GNUNET_CRYPTO_EcdsaSignature *) &code_payload[signature_offset];
- if (0 != GNUNET_memcmp (audience, &ticket->audience))
+ GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
+ if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
{
GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs);
GNUNET_free (code_payload);
+ GNUNET_free (plaintext);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Audience in ticket does not match client!\n");
return GNUNET_SYSERR;
@@ -468,12 +591,15 @@ OIDC_parse_authz_code (const struct
GNUNET_CRYPTO_EcdsaPublicKey *audience,
{
GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs);
GNUNET_free (code_payload);
+ GNUNET_free (plaintext);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
return GNUNET_SYSERR;
}
*nonce_str = NULL;
if (nonce != 0)
GNUNET_asprintf (nonce_str, "%u", nonce);
+ GNUNET_free (code_payload);
+ GNUNET_free (plaintext);
return GNUNET_OK;
}
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h
index 3c57dc235..6fe1721d3 100644
--- a/src/reclaim/oidc_helper.h
+++ b/src/reclaim/oidc_helper.h
@@ -77,7 +77,7 @@ OIDC_build_authz_code (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
* authorization code.
* This also verifies the signature in the code.
*
- * @param audience the expected audience of the code
+ * @param ecdsa_priv the audience of the ticket
* @param code the string representation of the code
* @param ticket where to store the ticket
* @param attrs the attributes found in the code
@@ -85,7 +85,7 @@ 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_EcdsaPublicKey *audience,
+OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
const char* code,
struct GNUNET_RECLAIM_Ticket *ticket,
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
diff --git a/src/reclaim/plugin_rest_openid_connect.c
b/src/reclaim/plugin_rest_openid_connect.c
index 0ef621536..753c3fcae 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -1600,9 +1600,9 @@ check_authorization (struct RequestHandle *handle,
return GNUNET_OK;
}
-static int
-ego_exists (struct RequestHandle *handle,
- struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
+const struct EgoEntry *
+find_ego (struct RequestHandle *handle,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
{
struct EgoEntry *ego_entry;
struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
@@ -1612,11 +1612,9 @@ ego_exists (struct RequestHandle *handle,
{
GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
if (0 == GNUNET_memcmp (&pub_key, test_key))
- break;
+ return ego_entry;
}
- if (NULL == ego_entry)
- return GNUNET_NO;
- return GNUNET_YES;
+ return NULL;
}
static void
@@ -1650,10 +1648,12 @@ token_endpoint (struct GNUNET_REST_RequestHandle
*con_handle,
void *cls)
{
struct RequestHandle *handle = cls;
+ const struct EgoEntry *ego_entry;
struct GNUNET_TIME_Relative expiration_time;
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *cl;
struct GNUNET_RECLAIM_Ticket ticket;
struct GNUNET_CRYPTO_EcdsaPublicKey cid;
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
struct GNUNET_HashCode cache_key;
struct MHD_Response *resp;
char *grant_type;
@@ -1713,9 +1713,17 @@ token_endpoint (struct GNUNET_REST_RequestHandle
*con_handle,
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
-
+ ego_entry = find_ego (handle, &cid);
+ if (NULL == ego_entry)
+ {
+ handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
+ handle->edesc = GNUNET_strdup ("Unknown client");
+ handle->response_code = MHD_HTTP_BAD_REQUEST;
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ }
+ privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
// decode code
- if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, &ticket, &cl, &nonce))
+ if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, &ticket, &cl, &nonce))
{
handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
handle->edesc = GNUNET_strdup ("invalid code");
@@ -1739,13 +1747,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle
*con_handle,
// TODO OPTIONAL acr,amr,azp
- if (GNUNET_NO == ego_exists (handle, &ticket.audience))
- {
- handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
- handle->edesc = GNUNET_strdup ("invalid code...");
- handle->response_code = MHD_HTTP_BAD_REQUEST;
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- }
if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
"reclaim-rest-plugin",
"jwt_secret",
@@ -1827,9 +1828,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle
*con_handle,
char *authorization_type;
char *authorization_access_token;
struct GNUNET_RECLAIM_Ticket *ticket;
+ const struct EgoEntry *ego_entry;
const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
- struct GNUNET_CRYPTO_EcdsaPublicKey pk;
-
GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
strlen (OIDC_AUTHORIZATION_HEADER_KEY),
@@ -1888,15 +1888,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle
*con_handle,
ticket =
GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key);
GNUNET_assert (NULL != ticket);
-
- for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
- handle->ego_entry = handle->ego_entry->next)
- {
- GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &pk);
- if (0 == GNUNET_memcmp (&pk, &ticket->audience))
- break; // Found
- }
- if (NULL == handle->ego_entry)
+ ego_entry = find_ego (handle, &ticket->audience);
+ if (NULL == ego_entry)
{
handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN);
handle->edesc = GNUNET_strdup ("The access token expired");
@@ -1910,9 +1903,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle
*con_handle,
handle->oidc->response = json_object ();
json_object_set_new (handle->oidc->response,
"sub",
- json_string (handle->ego_entry->keystring));
- privkey = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
-
+ json_string (ego_entry->keystring));
+ privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
privkey,
ticket,
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [gnunet] branch master updated: RECLAIM/OIDC: encrypt authorizaion code payload,
gnunet <=