From: Schanzenbach, Martin Date: Fri, 26 Apr 2019 12:47:29 +0000 (+0200) Subject: RECLAIM/REST: simplify auth code; include attrs X-Git-Tag: v0.11.4~88 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=dba51d34726695de64bca656399ed8f82d225f53;p=oweals%2Fgnunet.git RECLAIM/REST: simplify auth code; include attrs --- diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 331bd2711..37387b5e0 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -52,7 +52,8 @@ static void replace_char (char *str, char find, char replace) { char *current_pos = strchr (str, find); - while (current_pos) { + while (current_pos) + { *current_pos = replace; current_pos = strchr (current_pos, find); } @@ -84,7 +85,8 @@ 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) + const char *nonce, + const char *secret_key) { struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; struct GNUNET_HashCode signature; @@ -110,9 +112,11 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, // nonce only if nonce // OPTIONAL acr,amr,azp subject = GNUNET_STRINGS_data_to_string_alloc ( - sub_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + sub_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); audience = GNUNET_STRINGS_data_to_string_alloc ( - aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + aud_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); header = create_jwt_header (); body = json_object (); @@ -125,21 +129,27 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, // aud REQUIRED public key client_id must be there json_object_set_new (body, "aud", json_string (audience)); // iat - json_object_set_new (body, "iat", + json_object_set_new (body, + "iat", json_integer (time_now.abs_value_us / (1000 * 1000))); // exp - json_object_set_new (body, "exp", + json_object_set_new (body, + "exp", json_integer (exp_time.abs_value_us / (1000 * 1000))); // nbf - json_object_set_new (body, "nbf", + 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)); - 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); + 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); } @@ -160,14 +170,20 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, * 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, + 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, + GNUNET_asprintf (&result, + "%s.%s.%s", + header_base64, + body_base64, signature_base64); GNUNET_free (signature_target); @@ -178,64 +194,125 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_free (header_base64); return result; } + + +/** + * Returns base64 encoded string urlencoded + * + * @param string the string to encode + * @return base64 encoded string + */ +static char * +base64_encode (const char *data, + size_t data_size) +{ + char *enc; + char *enc_urlencode; + char *tmp; + int i; + int num_pads = 0; + + GNUNET_STRINGS_base64_encode (data, data_size, &enc); + tmp = strchr (enc, '='); + num_pads = strlen (enc) - (tmp - enc); + GNUNET_assert ((3 > num_pads) && (0 <= num_pads)); + if (0 == num_pads) + return enc; + enc_urlencode = GNUNET_malloc (strlen (enc) + num_pads * 2); + strcpy (enc_urlencode, enc); + GNUNET_free (enc); + tmp = strchr (enc_urlencode, '='); + for (i = 0; i < num_pads; i++) { + strcpy (tmp, "%3D"); // replace '=' with '%3D' + tmp += 3; + } + return enc_urlencode; +} + + + + /** * Builds an OIDC authorization code including * a reclaim ticket and nonce * * @param issuer the issuer of the ticket, used to sign the ticket and nonce * @param ticket the ticket to include in the code + * @param attrs list of attributes whicha re shared * @param nonce the nonce to include in the code * @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, - const char *nonce) + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, + const char *nonce_str) { - char *ticket_str; - json_t *code_json; - char *signature_payload; - char *signature_str; - char *authz_code; + char *code_payload; + char *attrs_ser; + char *code_str; + char *buf_ptr; size_t signature_payload_len; + size_t attr_list_len; + size_t code_payload_len; + unsigned int nonce; + unsigned int nonce_tmp; struct GNUNET_CRYPTO_EcdsaSignature signature; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - signature_payload_len = sizeof (struct GNUNET_RECLAIM_Ticket); - if (NULL != nonce) - signature_payload_len += strlen (nonce); - - signature_payload = - GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - signature_payload_len); - purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *)signature_payload; + attrs_ser = NULL; + signature_payload_len = + sizeof (struct GNUNET_RECLAIM_Ticket) + sizeof (unsigned int); + if (NULL != attrs) + { + attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs); + signature_payload_len += attr_list_len; + attrs_ser = GNUNET_malloc (attr_list_len); + GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, attrs_ser); + } + code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + + signature_payload_len + sizeof (signature); + code_payload = GNUNET_malloc (code_payload_len); + 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); - memcpy (&purpose[1], ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); - if (NULL != nonce) - memcpy (((char *)&purpose[1]) + sizeof (struct GNUNET_RECLAIM_Ticket), - nonce, strlen (nonce)); - if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (issuer, purpose, &signature)) { - GNUNET_free (signature_payload); + // First, copy ticket + buf_ptr = (char *) &purpose[1]; + memcpy (buf_ptr, ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); + buf_ptr += sizeof (struct GNUNET_RECLAIM_Ticket); + // Then copy nonce + nonce = 0; + if (NULL != nonce_str) + { + if ((1 != SSCANF (nonce_str, "%u", &nonce)) || (nonce > UINT16_MAX)) + { + GNUNET_free (code_payload); + GNUNET_free_non_null (attrs_ser); + return NULL; + } + } + nonce_tmp = htons (nonce); + memcpy (buf_ptr, &nonce_tmp, sizeof (unsigned int)); + buf_ptr += sizeof (unsigned int); + // Finally, attributes + if (NULL != attrs_ser) + { + memcpy (buf_ptr, attrs_ser, attr_list_len); + buf_ptr += attr_list_len; + } + if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_sign (issuer, purpose, &signature)) + { + GNUNET_free (code_payload); + GNUNET_free_non_null (attrs_ser); return NULL; } - signature_str = - GNUNET_STRINGS_data_to_string_alloc (&signature, sizeof (signature)); - ticket_str = GNUNET_STRINGS_data_to_string_alloc ( - ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); - - code_json = json_object (); - json_object_set_new (code_json, "ticket", json_string (ticket_str)); - if (NULL != nonce) - json_object_set_new (code_json, "nonce", json_string (nonce)); - json_object_set_new (code_json, "signature", json_string (signature_str)); - authz_code = json_dumps (code_json, JSON_INDENT (0) | JSON_COMPACT); - GNUNET_free (signature_payload); - GNUNET_free (signature_str); - GNUNET_free (ticket_str); - json_decref (code_json); - return authz_code; + memcpy (buf_ptr, &signature, sizeof (signature)); + code_str = base64_encode ((const char *) &code_payload, + code_payload_len); + GNUNET_free (code_payload); + GNUNET_free_non_null (attrs_ser); + return code_str; } @@ -247,99 +324,70 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, * @param audience the expected audience of the code * @param code the string representation of the code * @param ticket where to store the ticket + * @param attrs the attributes in the code * @param nonce where to store the nonce * @return GNUNET_OK if successful, else GNUNET_SYSERR */ int OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, - const char *code, struct GNUNET_RECLAIM_Ticket **ticket, - char **nonce) + const char *code, + struct GNUNET_RECLAIM_Ticket *ticket, + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, + char **nonce_str) { - json_error_t error; - json_t *code_json; - json_t *ticket_json; - json_t *nonce_json; - json_t *signature_json; - const char *ticket_str; - const char *signature_str; - const char *nonce_str; - char *code_output; + char *code_payload; + char *attrs_ser; + char *ptr; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - struct GNUNET_CRYPTO_EcdsaSignature signature; - size_t signature_payload_len; - - code_output = NULL; - GNUNET_STRINGS_base64_decode (code, strlen (code), (void **)&code_output); - code_json = json_loads (code_output, 0, &error); - GNUNET_free (code_output); - ticket_json = json_object_get (code_json, "ticket"); - nonce_json = json_object_get (code_json, "nonce"); - signature_json = json_object_get (code_json, "signature"); - *ticket = NULL; - *nonce = NULL; - - if ((NULL == ticket_json || !json_is_string (ticket_json)) || - (NULL == signature_json || !json_is_string (signature_json))) { - json_decref (code_json); - return GNUNET_SYSERR; - } - ticket_str = json_string_value (ticket_json); - signature_str = json_string_value (signature_json); - nonce_str = NULL; - if (NULL != nonce_json) - nonce_str = json_string_value (nonce_json); - signature_payload_len = sizeof (struct GNUNET_RECLAIM_Ticket); - if (NULL != nonce_str) - signature_payload_len += strlen (nonce_str); - purpose = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - signature_payload_len); - purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - signature_payload_len); - purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); - if (GNUNET_OK != GNUNET_STRINGS_string_to_data ( - ticket_str, strlen (ticket_str), &purpose[1], - sizeof (struct GNUNET_RECLAIM_Ticket))) { - GNUNET_free (purpose); - json_decref (code_json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot parse ticket!\n"); - return GNUNET_SYSERR; - } - if (GNUNET_OK != GNUNET_STRINGS_string_to_data ( - signature_str, strlen (signature_str), &signature, - sizeof (struct GNUNET_CRYPTO_EcdsaSignature))) { - GNUNET_free (purpose); - json_decref (code_json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot parse signature!\n"); - return GNUNET_SYSERR; - } - *ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket); - memcpy (*ticket, &purpose[1], sizeof (struct GNUNET_RECLAIM_Ticket)); - if (0 != GNUNET_memcmp (audience, &(*ticket)->audience)) { - GNUNET_free (purpose); - GNUNET_free (*ticket); - json_decref (code_json); - *ticket = NULL; + struct GNUNET_CRYPTO_EcdsaSignature *signature; + size_t code_payload_len; + size_t attrs_ser_len; + size_t signature_offset; + unsigned int nonce; + + code_payload = NULL; + code_payload_len = + GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload); + purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; + attrs_ser_len = code_payload_len; + attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose); + *ticket = *((struct GNUNET_RECLAIM_Ticket*) &purpose[1]); + attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket); + nonce = ntohs (((unsigned int *) &ticket[1])); + attrs_ser_len -= sizeof (unsigned int); + ptr = code_payload; + signature_offset = + code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); + signature = (struct GNUNET_CRYPTO_EcdsaSignature *)&ptr[signature_offset]; + attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature); + attrs_ser = ((char *) &ticket[1]) + sizeof (unsigned int); + *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser, attrs_ser_len); + if (0 != GNUNET_memcmp (audience, &ticket->audience)) + { + GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs); + GNUNET_free (code_payload); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Audience in ticket does not match client!\n"); return GNUNET_SYSERR; } - if (NULL != nonce_str) - memcpy (((char *)&purpose[1]) + sizeof (struct GNUNET_RECLAIM_Ticket), - nonce_str, strlen (nonce_str)); if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, - purpose, &signature, &(*ticket)->identity)) { - GNUNET_free (purpose); - GNUNET_free (*ticket); - json_decref (code_json); - *ticket = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of authZ code invalid!\n"); + purpose, + signature, + &ticket->identity)) + { + GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs); + GNUNET_free (code_payload); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); return GNUNET_SYSERR; } - *nonce = GNUNET_strdup (nonce_str); + *nonce_str = NULL; + if (nonce != 0) + GNUNET_asprintf (nonce_str, "%u", nonce); return GNUNET_OK; } + /** * Build a token response for a token request * TODO: Maybe we should add the scope here? @@ -350,7 +398,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, * @param token_response where to store the response */ void -OIDC_build_token_response (const char *access_token, const char *id_token, +OIDC_build_token_response (const char *access_token, + const char *id_token, const struct GNUNET_TIME_Relative *expiration_time, char **token_response) { @@ -364,8 +413,9 @@ OIDC_build_token_response (const char *access_token, const char *id_token, 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))); + 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); @@ -382,9 +432,10 @@ OIDC_access_token_new () uint64_t random_number; random_number = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); + GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); GNUNET_asprintf (&access_token_number, "%" PRIu64, random_number); GNUNET_STRINGS_base64_encode (access_token_number, - strlen (access_token_number), &access_token); + strlen (access_token_number), + &access_token); return access_token; } diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index d718b7a78..3c57dc235 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -11,7 +11,7 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . @@ -62,12 +62,14 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, * * @param issuer the issuer of the ticket, used to sign the ticket and nonce * @param ticket the ticket to include in the code + * @param attrs list of attributes to share * @param nonce the nonce to include in the code * @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); /** @@ -78,13 +80,15 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, * @param audience the expected audience of the code * @param code the string representation of the code * @param ticket where to store the ticket + * @param attrs the attributes found in the code * @param nonce where to store the nonce * @return GNUNET_OK if successful, else GNUNET_SYSERR */ int OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, const char* code, - struct GNUNET_RECLAIM_Ticket **ticket, + struct GNUNET_RECLAIM_Ticket *ticket, + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, char **nonce); /** diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 6cf1ffdee..07cb55d79 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -676,37 +676,6 @@ return_userinfo_response (void *cls) cleanup_handle (handle); } -/** - * Returns base64 encoded string urlencoded - * - * @param string the string to encode - * @return base64 encoded string - */ -static char * -base64_encode (const char *s) -{ - char *enc; - char *enc_urlencode; - char *tmp; - int i; - int num_pads = 0; - - GNUNET_STRINGS_base64_encode (s, strlen (s), &enc); - tmp = strchr (enc, '='); - num_pads = strlen (enc) - (tmp - enc); - GNUNET_assert ((3 > num_pads) && (0 <= num_pads)); - if (0 == num_pads) - return enc; - enc_urlencode = GNUNET_malloc (strlen (enc) + num_pads * 2); - strcpy (enc_urlencode, enc); - GNUNET_free (enc); - tmp = strchr (enc_urlencode, '='); - for (i = 0; i < num_pads; i++) { - strcpy (tmp, "%3D"); // replace '=' with '%3D' - tmp += 3; - } - return enc_urlencode; -} /** * Respond to OPTIONS request @@ -870,8 +839,7 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) struct MHD_Response *resp; char *ticket_str; char *redirect_uri; - char *code_json_string; - char *code_base64_final_string; + char *code_string; handle->idp_op = NULL; handle->ticket = *ticket; @@ -884,20 +852,20 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) ticket_str = GNUNET_STRINGS_data_to_string_alloc ( &handle->ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); // TODO change if more attributes are needed (see max_age) - code_json_string = OIDC_build_authz_code (&handle->priv_key, &handle->ticket, + code_string = OIDC_build_authz_code (&handle->priv_key, &handle->ticket, + handle->attr_list, handle->oidc->nonce); - code_base64_final_string = base64_encode (code_json_string); if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) && (NULL != handle->tld)) { GNUNET_asprintf (&redirect_uri, "%s.%s/%s?%s=%s&state=%s", handle->redirect_prefix, handle->tld, handle->redirect_suffix, handle->oidc->response_type, - code_base64_final_string, handle->oidc->state); + code_string, handle->oidc->state); } else { GNUNET_asprintf (&redirect_uri, "%s?%s=%s&state=%s", handle->oidc->redirect_uri, handle->oidc->response_type, - code_base64_final_string, handle->oidc->state); + code_string, handle->oidc->state); } resp = GNUNET_REST_create_response (""); MHD_add_response_header (resp, "Location", redirect_uri); @@ -905,8 +873,7 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); GNUNET_free (redirect_uri); GNUNET_free (ticket_str); - GNUNET_free (code_json_string); - GNUNET_free (code_base64_final_string); + GNUNET_free (code_string); } static void @@ -1653,7 +1620,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, } // decode code - if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, &ticket, &nonce)) { + ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket); + if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, ticket, &cl, &nonce)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); handle->edesc = GNUNET_strdup ("invalid code"); handle->response_code = MHD_HTTP_BAD_REQUEST; @@ -1692,7 +1660,6 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, return; } // TODO We should collect the attributes here. cl always empty - cl = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); id_token = OIDC_id_token_new (&ticket->audience, &ticket->identity, cl, &expiration_time, (NULL != nonce) ? nonce : NULL, jwt_secret);