aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/jwt.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-19 23:28:53 +0200
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-19 23:28:53 +0200
commit4fd677cec39e5621d16bc2c63926b803b31582e3 (patch)
treeb1ed7c7544c1a8a721308d67c908e0f3cd758486 /src/reclaim/jwt.c
parent0f75e5c54c6e6c9087cf565539266514abd67e98 (diff)
downloadgnunet-4fd677cec39e5621d16bc2c63926b803b31582e3.tar.gz
gnunet-4fd677cec39e5621d16bc2c63926b803b31582e3.zip
renamed identity-provider subsystem to reclaim
Diffstat (limited to 'src/reclaim/jwt.c')
-rw-r--r--src/reclaim/jwt.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/reclaim/jwt.c b/src/reclaim/jwt.c
new file mode 100644
index 000000000..45b5d73f6
--- /dev/null
+++ b/src/reclaim/jwt.c
@@ -0,0 +1,160 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file reclaim/jwt.c
21 * @brief helper library for JSON-Web-Tokens
22 * @author Martin Schanzenbach
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_signatures.h"
27#include "gnunet_reclaim_attribute_lib.h"
28#include <jansson.h>
29
30
31#define JWT_ALG "alg"
32
33/* Use 512bit HMAC */
34#define JWT_ALG_VALUE "HS512"
35
36#define JWT_TYP "typ"
37
38#define JWT_TYP_VALUE "jwt"
39
40#define SERVER_ADDRESS "https://reclaim.id/api/openid/userinfo"
41
42static char*
43create_jwt_header(void)
44{
45 json_t *root;
46 char *json_str;
47
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));
51
52 json_str = json_dumps (root, JSON_INDENT(1));
53 json_decref (root);
54 return json_str;
55}
56
57/**
58 * Create a JWT from attributes
59 *
60 * @param aud_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.
64 */
65char*
66jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
67 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
68 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
69 const struct GNUNET_CRYPTO_AuthKey *priv_key)
70{
71 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
72 struct GNUNET_HashCode signature;
73 char* audience;
74 char* subject;
75 char* header;
76 char* padding;
77 char* body_str;
78 char* result;
79 char* header_base64;
80 char* body_base64;
81 char* signature_target;
82 char* signature_base64;
83 char* attr_val_str;
84 json_t* body;
85
86 //exp REQUIRED time expired from config
87 //iat REQUIRED time now
88 //auth_time only if max_age
89 //nonce only if nonce
90 // OPTIONAL acr,amr,azp
91 subject = GNUNET_STRINGS_data_to_string_alloc (&sub_key,
92 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
93 audience = GNUNET_STRINGS_data_to_string_alloc (aud_key,
94 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
95 header = create_jwt_header ();
96 body = json_object ();
97
98 //iss REQUIRED case sensitive server uri with https
99 //The issuer is the local reclaim instance (e.g. https://reclaim.id/api/openid)
100 json_object_set_new (body,
101 "iss", json_string (SERVER_ADDRESS));
102 //sub REQUIRED public key identity, not exceed 255 ASCII length
103 json_object_set_new (body,
104 "sub", json_string (subject));
105 //aud REQUIRED public key client_id must be there
106 json_object_set_new (body,
107 "aud", json_string (audience));
108 for (le = attrs->list_head; NULL != le; le = le->next)
109 {
110 attr_val_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
111 le->claim->data,
112 le->claim->data_size);
113 json_object_set_new (body,
114 le->claim->name,
115 json_string (attr_val_str));
116 GNUNET_free (attr_val_str);
117 }
118 body_str = json_dumps (body, JSON_INDENT(0));
119 json_decref (body);
120
121 GNUNET_STRINGS_base64_encode (header,
122 strlen (header),
123 &header_base64);
124 //Remove GNUNET padding of base64
125 padding = strtok(header_base64, "=");
126 while (NULL != padding)
127 padding = strtok(NULL, "=");
128
129 GNUNET_STRINGS_base64_encode (body_str,
130 strlen (body_str),
131 &body_base64);
132
133 //Remove GNUNET padding of base64
134 padding = strtok(body_base64, "=");
135 while (NULL != padding)
136 padding = strtok(NULL, "=");
137
138 GNUNET_free (subject);
139 GNUNET_free (audience);
140
141 /**
142 * Creating the JWT signature. This might not be
143 * standards compliant, check.
144 */
145 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, body_base64);
146 GNUNET_CRYPTO_hmac (priv_key, signature_target, strlen (signature_target), &signature);
147 GNUNET_STRINGS_base64_encode ((const char*)&signature,
148 sizeof (struct GNUNET_HashCode),
149 &signature_base64);
150 GNUNET_asprintf (&result, "%s.%s.%s",
151 header_base64, body_base64, signature_base64);
152
153 GNUNET_free (signature_target);
154 GNUNET_free (header);
155 GNUNET_free (body_str);
156 GNUNET_free (signature_base64);
157 GNUNET_free (body_base64);
158 GNUNET_free (header_base64);
159 return result;
160}