2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @file identity-provider/jwt.c
23 * @brief helper library for JSON-Web-Tokens
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_signatures.h"
29 #include "gnunet_identity_attribute_lib.h"
35 /*TODO is this the correct way to define new algs? */
36 #define JWT_ALG_VALUE "ED512"
40 #define JWT_TYP_VALUE "jwt"
43 create_jwt_header(void)
48 root = json_object ();
49 json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE));
50 json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE));
52 json_str = json_dumps (root, JSON_INDENT(1));
58 * Create a JWT from attributes
60 * @param sub_key the public of the subject
61 * @param attrs the attribute list
62 * @param priv_key the key used to sign the JWT
63 * @return a new base64-encoded JWT string.
66 jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
67 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
68 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key)
70 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
71 struct GNUNET_CRYPTO_EcdsaPublicKey iss_key;
72 struct GNUNET_CRYPTO_EcdsaSignature signature;
73 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
82 char* signature_target;
83 char* signature_base64;
87 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &iss_key);
88 /* TODO maybe we should use a local identity here */
89 issuer = GNUNET_STRINGS_data_to_string_alloc (&iss_key,
90 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
91 audience = GNUNET_STRINGS_data_to_string_alloc (sub_key,
92 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
93 header = create_jwt_header ();
94 body = json_object ();
95 /* TODO who is the issuer? local IdP or subject ? See self-issued tokens? */
96 json_object_set_new (body,
97 "iss", json_string (issuer));
98 json_object_set_new (body,
99 "sub", json_string (issuer));
100 /* TODO what should be in here exactly? */
101 json_object_set_new (body,
102 "aud", json_string (audience));
103 for (le = attrs->list_head; NULL != le; le = le->next)
106 * TODO here we should have a function that
107 * calls the Attribute plugins to create a
108 * json representation for its value
110 attr_val_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (le->claim->type,
112 le->claim->data_size);
113 json_object_set_new (body,
115 json_string (attr_val_str));
116 GNUNET_free (attr_val_str);
118 body_str = json_dumps (body, JSON_INDENT(0));
121 GNUNET_STRINGS_base64_encode (header,
124 //Remove GNUNET padding of base64
125 padding = strtok(header_base64, "=");
126 while (NULL != padding)
127 padding = strtok(NULL, "=");
129 GNUNET_STRINGS_base64_encode (body_str,
133 //Remove GNUNET padding of base64
134 padding = strtok(body_base64, "=");
135 while (NULL != padding)
136 padding = strtok(NULL, "=");
138 GNUNET_free (issuer);
139 GNUNET_free (audience);
143 * Creating the JWT signature. This might not be
144 * standards compliant, check.
146 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, body_base64);
149 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
150 strlen (signature_target));
152 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
153 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
154 GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target));
155 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
157 (struct GNUNET_CRYPTO_EcdsaSignature *)&signature))
159 GNUNET_free (signature_target);
160 GNUNET_free (body_str);
161 GNUNET_free (body_base64);
162 GNUNET_free (header_base64);
163 GNUNET_free (purpose);
166 GNUNET_STRINGS_base64_encode ((const char*)&signature,
167 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
169 GNUNET_asprintf (&result, "%s.%s.%s",
170 header_base64, body_base64, signature_base64);
172 GNUNET_free (signature_target);
173 GNUNET_free (header);
174 GNUNET_free (body_str);
175 GNUNET_free (signature_base64);
176 GNUNET_free (body_base64);
177 GNUNET_free (header_base64);
178 GNUNET_free (purpose);