aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2017-10-07 18:51:31 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2017-10-07 18:51:31 +0200
commit40fa67d024c8d7cc7d6f2af1a557e0ecc59e60f0 (patch)
tree2065893fa7b9c61ce89e2b9687404be723f25ec2 /src
parent0729d3ff0b209fe2da270d98c967ad0acbdd49cb (diff)
downloadgnunet-40fa67d024c8d7cc7d6f2af1a557e0ecc59e60f0.tar.gz
gnunet-40fa67d024c8d7cc7d6f2af1a557e0ecc59e60f0.zip
-add new jwt handling
Diffstat (limited to 'src')
-rw-r--r--src/identity-provider/jwt.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/identity-provider/jwt.c b/src/identity-provider/jwt.c
new file mode 100644
index 000000000..c8bc67806
--- /dev/null
+++ b/src/identity-provider/jwt.c
@@ -0,0 +1,172 @@
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
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.
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 General Public License for more details.
14
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.
19 */
20
21/**
22 * @file identity-provider/jwt.c
23 * @brief helper library for JSON-Web-Tokens
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h"
29#include "identity_attribute.h"
30#include <jansson.h>
31
32
33#define JWT_ALG "alg"
34
35/*TODO is this the correct way to define new algs? */
36#define JWT_ALG_VALUE "ED512"
37
38#define JWT_TYP "typ"
39
40#define JWT_TYP_VALUE "jwt"
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 a ticket and attributes
59 *
60 * @param ticket the ticket
61 * @param attrs the attribute list
62 * @return a new base64-encoded JWT string.
63 */
64char*
65jwt_create (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
66 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
67 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key)
68{
69 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
70 struct GNUNET_CRYPTO_EcdsaSignature signature;
71 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
72 char* audience;
73 char* issuer;
74 char* header;
75 char* padding;
76 char* body_str;
77 char* result;
78 char* header_base64;
79 char* body_base64;
80 char* signature_target;
81 char* signature_base64;
82 json_t* body;
83
84 /* TODO maybe we should use a local identity here */
85 issuer = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity,
86 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
87 audience = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience,
88 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
89 header = create_jwt_header ();
90 body = json_object ();
91 /* TODO who is the issuer? local IdP or subject ? See self-issued tokens? */
92 json_object_set_new (body,
93 "iss", json_string (issuer));
94 json_object_set_new (body,
95 "sub", json_string (issuer));
96 /* TODO what should be in here exactly? */
97 json_object_set_new (body,
98 "aud", json_string (audience));
99 for (le = attrs->list_head; NULL != le; le = le->next)
100 {
101 /**
102 * TODO here we should have a function that
103 * calls the Attribute plugins to create a
104 * json representation for its value
105 */
106 json_object_set_new (body,
107 le->attribute->name,
108 json_string (le->attribute->data));
109 }
110 body_str = json_dumps (body, JSON_INDENT(0));
111 json_decref (body);
112
113 GNUNET_STRINGS_base64_encode (header,
114 strlen (header),
115 &header_base64);
116 //Remove GNUNET padding of base64
117 padding = strtok(header_base64, "=");
118 while (NULL != padding)
119 padding = strtok(NULL, "=");
120
121 GNUNET_STRINGS_base64_encode (body_str,
122 strlen (body_str),
123 &body_base64);
124
125 //Remove GNUNET padding of base64
126 padding = strtok(body_base64, "=");
127 while (NULL != padding)
128 padding = strtok(NULL, "=");
129
130 GNUNET_free (issuer);
131 GNUNET_free (audience);
132
133 /**
134 * TODO
135 * Creating the JWT signature. This might not be
136 * standards compliant, check.
137 */
138 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, body_base64);
139
140 purpose =
141 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
142 strlen (signature_target));
143 purpose->size =
144 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
145 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
146 GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target));
147 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
148 purpose,
149 (struct GNUNET_CRYPTO_EcdsaSignature *)&signature))
150 {
151 GNUNET_free (signature_target);
152 GNUNET_free (body_str);
153 GNUNET_free (body_base64);
154 GNUNET_free (header_base64);
155 GNUNET_free (purpose);
156 return NULL;
157 }
158 GNUNET_STRINGS_base64_encode ((const char*)&signature,
159 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
160 &signature_base64);
161 GNUNET_asprintf (&result, "%s.%s.%s",
162 header_base64, body_base64, signature_base64);
163
164 GNUNET_free (signature_target);
165 GNUNET_free (header);
166 GNUNET_free (body_str);
167 GNUNET_free (signature_base64);
168 GNUNET_free (body_base64);
169 GNUNET_free (header_base64);
170 GNUNET_free (purpose);
171 return result;
172}