X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fidentity-provider%2Fidentity_token.c;h=31249840b0ff989ac4b5375601549336adf9b4fe;hb=2105059516320800eaa8fff1196b58f29a50ba7c;hp=caf1a784818c54ca5748818615bc757e86d79954;hpb=3014465481e5c883ba1ab41cd4ff70a428e27b24;p=oweals%2Fgnunet.git diff --git a/src/identity-provider/identity_token.c b/src/identity-provider/identity_token.c index caf1a7848..31249840b 100644 --- a/src/identity-provider/identity_token.c +++ b/src/identity-provider/identity_token.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2010-2015 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -19,7 +19,7 @@ */ /** - * @file identity-token/identity_token.c + * @file identity-provider/identity_token.c * @brief helper library to manage identity tokens * @author Martin Schanzenbach */ @@ -28,6 +28,7 @@ #include "gnunet_signatures.h" #include "identity_token.h" #include +#include #define JWT_ALG "alg" @@ -50,7 +51,7 @@ create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, GNUNET_CRYPTO_hash_to_enc (new_key_hash, &new_key_hash_str); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); static const char ctx_key[] = "gnuid-aes-ctx-key"; GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), new_key_hash, sizeof (struct GNUNET_HashCode), @@ -67,7 +68,7 @@ create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, /** - * Decrypts metainfo part from a token code + * Decrypts data part from a token code */ static int decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, @@ -97,7 +98,10 @@ decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, &enc_key, &enc_iv, str_buf); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: %d\n", str_size, cyphertext_len); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Decrypted bytes: %zd Expected bytes: %zd\n", + str_size, + cyphertext_len); if (-1 == str_size) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n"); @@ -105,7 +109,7 @@ decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, return GNUNET_SYSERR; } *result_str = GNUNET_malloc (str_size+1); - memcpy (*result_str, str_buf, str_size); + GNUNET_memcpy (*result_str, str_buf, str_size); (*result_str)[str_size] = '\0'; GNUNET_free (str_buf); return GNUNET_OK; @@ -171,14 +175,14 @@ encrypt_str_ecdhe (const char *plaintext, pub_key, &new_key_hash)); create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypting string %s\n (len=%d)", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%zd)", plaintext, strlen (plaintext)); enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext, strlen (plaintext), &skey, &iv, *cyphertext); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypted (len=%d)", enc_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%zd)", enc_size); return GNUNET_OK; } @@ -238,7 +242,8 @@ token_destroy (struct IdentityToken *token) GNUNET_CONTAINER_DLL_remove (attr->val_head, attr->val_tail, val); - GNUNET_free (val->value); + if (NULL != val->value) + GNUNET_free (val->value); GNUNET_free (val); val = tmp_val; } @@ -282,6 +287,37 @@ token_add_attr (struct IdentityToken *token, new_val); } +void +token_add_attr_int (struct IdentityToken *token, + const char* key, + uint64_t value) +{ + struct TokenAttr *attr; + struct TokenAttrValue *new_val; + GNUNET_assert (NULL != token); + + new_val = GNUNET_malloc (sizeof (struct TokenAttrValue)); + new_val->int_value = value; + for (attr = token->attr_head; NULL != attr; attr = attr->next) + { + if (0 == strcmp (key, attr->name)) + break; + } + + if (NULL == attr) + { + attr = GNUNET_malloc (sizeof (struct TokenAttr)); + attr->name = GNUNET_strdup (key); + GNUNET_CONTAINER_DLL_insert (token->attr_head, + token->attr_tail, + attr); + } + + GNUNET_CONTAINER_DLL_insert (attr->val_head, + attr->val_tail, + new_val); +} + static void parse_json_payload(const char* payload_base64, struct IdentityToken *token) @@ -306,15 +342,24 @@ parse_json_payload(const char* payload_base64, { json_array_foreach (value, idx, arr_value) { - token_add_attr (token, - key, - json_string_value (arr_value)); + if (json_is_integer (arr_value)) + token_add_attr_int (token, key, + json_integer_value (arr_value)); + else + token_add_attr (token, + key, + json_string_value (arr_value)); } } else { - token_add_attr (token, key, json_string_value (value)); + if (json_is_integer (value)) + token_add_attr_int (token, key, + json_integer_value (value)); + else + token_add_attr (token, key, json_string_value (value)); } } + json_decref (payload_json); GNUNET_free (payload); } @@ -379,6 +424,9 @@ token_parse (const char* raw_data, GNUNET_asprintf (&tmp_buf, "%s", raw_data); ecdh_pubkey_str = strtok (tmp_buf, ","); enc_token_str = strtok (NULL, ","); + + GNUNET_assert (NULL != ecdh_pubkey_str); + GNUNET_assert (NULL != enc_token_str); GNUNET_STRINGS_string_to_data (ecdh_pubkey_str, strlen (ecdh_pubkey_str), @@ -423,9 +471,16 @@ create_json_payload (const struct IdentityToken *token) { for (val = attr->val_head; NULL != val; val = val->next) { - json_object_set_new (root, - attr->name, - json_string (val->value)); + if (NULL != val->value) + { + json_object_set_new (root, + attr->name, + json_string (val->value)); + } else { + json_object_set_new (root, + attr->name, + json_integer (val->int_value)); + } } } json_str = json_dumps (root, JSON_INDENT(1)); @@ -487,7 +542,7 @@ token_to_string (const struct IdentityToken *token, purpose->size = htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); - memcpy (&purpose[1], signature_target, strlen (signature_target)); + GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target)); if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, purpose, (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature)) @@ -495,6 +550,7 @@ token_to_string (const struct IdentityToken *token, GNUNET_free (signature_target); GNUNET_free (payload_str); GNUNET_free (payload_base64); + GNUNET_free (header_base64); GNUNET_free (purpose); return GNUNET_SYSERR; } @@ -549,14 +605,14 @@ token_serialize (const struct IdentityToken *token, } struct TokenTicketPayload* -ticket_payload_create (const char* nonce, +ticket_payload_create (uint64_t nonce, const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, const char* lbl_str) { struct TokenTicketPayload* payload; payload = GNUNET_malloc (sizeof (struct TokenTicketPayload)); - GNUNET_asprintf (&payload->nonce, nonce, strlen (nonce)); + payload->nonce = nonce; payload->identity_key = *identity_pkey; GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str)); return payload; @@ -565,8 +621,6 @@ ticket_payload_create (const char* nonce, void ticket_payload_destroy (struct TokenTicketPayload* payload) { - if (NULL != payload->nonce) - GNUNET_free (payload->nonce); if (NULL != payload->label) GNUNET_free (payload->label); GNUNET_free (payload); @@ -582,7 +636,7 @@ ticket_payload_serialize (struct TokenTicketPayload *payload, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); GNUNET_asprintf (result, - "{\"nonce\": \"%u\",\"identity\": \"%s\",\"label\": \"%s\"}", + "{\"nonce\": \"%"SCNu64"\",\"identity\": \"%s\",\"label\": \"%s\"}", payload->nonce, identity_key_str, payload->label); GNUNET_free (identity_key_str); @@ -591,13 +645,13 @@ ticket_payload_serialize (struct TokenTicketPayload *payload, /** * Create the token code - * The metadata is encrypted with a share ECDH derived secret using B (aud_key) + * The data is encrypted with a share ECDH derived secret using B (aud_key) * and e (ecdh_privkey) * The ticket also contains E (ecdh_pubkey) and a signature over the - * metadata and E + * data and E */ struct TokenTicket* -ticket_create (const char* nonce_str, +ticket_create (uint64_t nonce, const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, const char* lbl_str, const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key) @@ -606,7 +660,7 @@ ticket_create (const char* nonce_str, struct TokenTicketPayload *code_payload; ticket = GNUNET_malloc (sizeof (struct TokenTicket)); - code_payload = ticket_payload_create (nonce_str, + code_payload = ticket_payload_create (nonce, identity_pkey, lbl_str); ticket->aud_key = *aud_key; @@ -660,11 +714,11 @@ ticket_serialize (struct TokenTicket *ticket, strlen (code_payload_str)); purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); write_ptr = (char*) &purpose[1]; - memcpy (write_ptr, + GNUNET_memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); - memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str)); + GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str)); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key, purpose, &ticket->signature)); @@ -676,8 +730,8 @@ ticket_serialize (struct TokenTicket *ticket, dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s to encrypt\n", dh_key_str); - GNUNET_asprintf (&ticket_str, "{\"meta\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str); + GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}", ticket_payload_str, dh_key_str, ticket_sig_str); GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result); GNUNET_free (dh_key_str); @@ -706,26 +760,27 @@ ticket_payload_parse(const char *raw_data, json_t *identity_json; json_t *nonce_json; json_error_t err_json; - char* meta_str; + char* data_str; + uint64_t nonce; struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey; if (GNUNET_OK != decrypt_str_ecdhe (priv_key, ecdhe_pkey, raw_data, data_len, - &meta_str)) + &data_str)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata decryption failed\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n"); return GNUNET_SYSERR; } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata: %s\n", meta_str); - root = json_loads (meta_str, JSON_DECODE_ANY, &err_json); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str); + root = json_loads (data_str, JSON_DECODE_ANY, &err_json); if (!root) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing metadata: %s\n", err_json.text); - GNUNET_free (meta_str); + "Error parsing data: %s\n", err_json.text); + GNUNET_free (data_str); return GNUNET_SYSERR; } @@ -733,9 +788,9 @@ ticket_payload_parse(const char *raw_data, if (!json_is_string (identity_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing metadata: %s\n", err_json.text); + "Error parsing data: %s\n", err_json.text); json_decref (root); - GNUNET_free (meta_str); + GNUNET_free (data_str); return GNUNET_SYSERR; } identity_key_str = json_string_value (identity_json); @@ -749,32 +804,34 @@ ticket_payload_parse(const char *raw_data, if (!json_is_string (label_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing metadata: %s\n", err_json.text); + "Error parsing data: %s\n", err_json.text); json_decref (root); - GNUNET_free (meta_str); + GNUNET_free (data_str); return GNUNET_SYSERR; } label_str = json_string_value (label_json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found label: %s\n", label_str); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str); nonce_json = json_object_get (root, "nonce"); if (!json_is_string (label_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error parsing metadata: %s\n", err_json.text); + "Error parsing data: %s\n", err_json.text); json_decref (root); - GNUNET_free (meta_str); + GNUNET_free (data_str); return GNUNET_SYSERR; } nonce_str = json_string_value (nonce_json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found nonce: %s\n", nonce_str); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str); + + GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce)); - *result = ticket_payload_create (nonce_str, + *result = ticket_payload_create (nonce, (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey, label_str); - GNUNET_free (meta_str); + GNUNET_free (data_str); json_decref (root); return GNUNET_OK; @@ -785,26 +842,26 @@ ticket_parse (const char *raw_data, const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, struct TokenTicket **result) { - const char* enc_meta_str; + const char* enc_data_str; const char* ecdh_enc_str; const char* signature_enc_str; json_t *root; json_t *signature_json; json_t *ecdh_json; - json_t *enc_meta_json; + json_t *enc_data_json; json_error_t err_json; - char* enc_meta; + char* enc_data; char* ticket_decoded; char* write_ptr; - size_t enc_meta_len; + size_t enc_data_len; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; struct TokenTicket *ticket; struct TokenTicketPayload *ticket_payload; ticket_decoded = NULL; GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Token Code: %s\n", ticket_decoded); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded); root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json); if (!root) { @@ -815,11 +872,11 @@ ticket_parse (const char *raw_data, signature_json = json_object_get (root, "signature"); ecdh_json = json_object_get (root, "ecdh"); - enc_meta_json = json_object_get (root, "meta"); + enc_data_json = json_object_get (root, "data"); signature_enc_str = json_string_value (signature_json); ecdh_enc_str = json_string_value (ecdh_json); - enc_meta_str = json_string_value (enc_meta_json); + enc_data_str = json_string_value (enc_data_json); ticket = GNUNET_malloc (sizeof (struct TokenTicket)); @@ -828,12 +885,12 @@ ticket_parse (const char *raw_data, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey))) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in metadata\n", ecdh_enc_str); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str); json_decref (root); GNUNET_free (ticket); return GNUNET_SYSERR; } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s for metadata decryption\n", ecdh_enc_str); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str); if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str, strlen (signature_enc_str), &ticket->signature, @@ -842,43 +899,42 @@ ticket_parse (const char *raw_data, json_decref (root); GNUNET_free (ticket_decoded); GNUNET_free (ticket); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in metadata\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n"); return GNUNET_SYSERR; } - enc_meta_len = GNUNET_STRINGS_base64_decode (enc_meta_str, - strlen (enc_meta_str), - &enc_meta); + enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str, + strlen (enc_data_str), + &enc_data); - if (GNUNET_OK != ticket_payload_parse (enc_meta, - enc_meta_len, + if (GNUNET_OK != ticket_payload_parse (enc_data, + enc_data_len, priv_key, (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey, &ticket_payload)) { json_decref (root); - GNUNET_free (enc_meta); + GNUNET_free (enc_data); GNUNET_free (ticket_decoded); GNUNET_free (ticket); return GNUNET_SYSERR; } ticket->payload = ticket_payload; - //TODO: check signature here purpose = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E - enc_meta_len); // E_K (code_str) + enc_data_len); // E_K (code_str) purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + - enc_meta_len); + enc_data_len); purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); write_ptr = (char*) &purpose[1]; - memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); + GNUNET_memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); - memcpy (write_ptr, enc_meta, enc_meta_len); + GNUNET_memcpy (write_ptr, enc_data, enc_data_len); if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET, purpose, @@ -890,13 +946,13 @@ ticket_parse (const char *raw_data, json_decref (root); GNUNET_free (purpose); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error verifying signature for token code\n"); + "Error verifying signature for ticket\n"); return GNUNET_SYSERR; } *result = ticket; GNUNET_free (purpose); - GNUNET_free (enc_meta); + GNUNET_free (enc_data); GNUNET_free (ticket_decoded); json_decref (root); return GNUNET_OK;