aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-19 22:16:00 +0200
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-19 22:16:00 +0200
commit0f75e5c54c6e6c9087cf565539266514abd67e98 (patch)
treea2e486faeb5c87f388b9eba39d59f7ad0fc5089b
parent6f626ca4add69247a5af436c6745491a1eb0fb6e (diff)
downloadgnunet-0f75e5c54c6e6c9087cf565539266514abd67e98.tar.gz
gnunet-0f75e5c54c6e6c9087cf565539266514abd67e98.zip
change JWT algorithm to HMAC
-rw-r--r--src/identity-provider/identity-provider.conf1
-rw-r--r--src/identity-provider/jwt.c49
-rw-r--r--src/identity-provider/jwt.h3
-rw-r--r--src/identity-provider/plugin_rest_openid_connect.c26
4 files changed, 35 insertions, 44 deletions
diff --git a/src/identity-provider/identity-provider.conf b/src/identity-provider/identity-provider.conf
index cc50152a1..99c0a50be 100644
--- a/src/identity-provider/identity-provider.conf
+++ b/src/identity-provider/identity-provider.conf
@@ -16,6 +16,7 @@ DATABASE = sqlite
16#ADDRESS = https://identity.gnu:8000#/login 16#ADDRESS = https://identity.gnu:8000#/login
17ADDRESS = https://reclaim.ui/#/login 17ADDRESS = https://reclaim.ui/#/login
18PSW = secret 18PSW = secret
19JWT_SECRET = secret
19EXPIRATION_TIME = 3600 20EXPIRATION_TIME = 3600
20 21
21[identity-provider-sqlite] 22[identity-provider-sqlite]
diff --git a/src/identity-provider/jwt.c b/src/identity-provider/jwt.c
index 1a984f7b5..7ac4f0025 100644
--- a/src/identity-provider/jwt.c
+++ b/src/identity-provider/jwt.c
@@ -30,15 +30,14 @@
30 30
31#define JWT_ALG "alg" 31#define JWT_ALG "alg"
32 32
33/*TODO is this the correct way to define new algs? */ 33/* Use 512bit HMAC */
34#define JWT_ALG_VALUE "urn:org:gnunet:jwt:alg:ecdsa:ed25519" 34#define JWT_ALG_VALUE "HS512"
35 35
36#define JWT_TYP "typ" 36#define JWT_TYP "typ"
37 37
38#define JWT_TYP_VALUE "jwt" 38#define JWT_TYP_VALUE "jwt"
39 39
40//TODO change server address 40#define SERVER_ADDRESS "https://reclaim.id/api/openid/userinfo"
41#define SERVER_ADDRESS "https://localhost"
42 41
43static char* 42static char*
44create_jwt_header(void) 43create_jwt_header(void)
@@ -65,13 +64,12 @@ create_jwt_header(void)
65 */ 64 */
66char* 65char*
67jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 66jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
67 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
68 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, 68 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
69 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key) 69 const struct GNUNET_CRYPTO_AuthKey *priv_key)
70{ 70{
71 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; 71 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
72 struct GNUNET_CRYPTO_EcdsaPublicKey sub_key; 72 struct GNUNET_HashCode signature;
73 struct GNUNET_CRYPTO_EcdsaSignature signature;
74 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
75 char* audience; 73 char* audience;
76 char* subject; 74 char* subject;
77 char* header; 75 char* header;
@@ -90,32 +88,25 @@ jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
90 //auth_time only if max_age 88 //auth_time only if max_age
91 //nonce only if nonce 89 //nonce only if nonce
92 // OPTIONAL acr,amr,azp 90 // OPTIONAL acr,amr,azp
93 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &sub_key);
94 /* TODO maybe we should use a local identity here */
95 subject = GNUNET_STRINGS_data_to_string_alloc (&sub_key, 91 subject = GNUNET_STRINGS_data_to_string_alloc (&sub_key,
96 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 92 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
97 audience = GNUNET_STRINGS_data_to_string_alloc (aud_key, 93 audience = GNUNET_STRINGS_data_to_string_alloc (aud_key,
98 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 94 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
99 header = create_jwt_header (); 95 header = create_jwt_header ();
100 body = json_object (); 96 body = json_object ();
101 /* TODO who is the issuer? local IdP or subject ? See self-issued tokens? */ 97
102 //iss REQUIRED case sensitive server uri with https 98 //iss REQUIRED case sensitive server uri with https
99 //The issuer is the local reclaim instance (e.g. https://reclaim.id/api/openid)
103 json_object_set_new (body, 100 json_object_set_new (body,
104 "iss", json_string (SERVER_ADDRESS)); 101 "iss", json_string (SERVER_ADDRESS));
105 //sub REQUIRED public key identity, not exceed 255 ASCII length 102 //sub REQUIRED public key identity, not exceed 255 ASCII length
106 json_object_set_new (body, 103 json_object_set_new (body,
107 "sub", json_string (subject)); 104 "sub", json_string (subject));
108 /* TODO what should be in here exactly? */
109 //aud REQUIRED public key client_id must be there 105 //aud REQUIRED public key client_id must be there
110 json_object_set_new (body, 106 json_object_set_new (body,
111 "aud", json_string (audience)); 107 "aud", json_string (audience));
112 for (le = attrs->list_head; NULL != le; le = le->next) 108 for (le = attrs->list_head; NULL != le; le = le->next)
113 { 109 {
114 /**
115 * TODO here we should have a function that
116 * calls the Attribute plugins to create a
117 * json representation for its value
118 */
119 attr_val_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (le->claim->type, 110 attr_val_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (le->claim->type,
120 le->claim->data, 111 le->claim->data,
121 le->claim->data_size); 112 le->claim->data_size);
@@ -148,32 +139,13 @@ jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
148 GNUNET_free (audience); 139 GNUNET_free (audience);
149 140
150 /** 141 /**
151 * TODO
152 * Creating the JWT signature. This might not be 142 * Creating the JWT signature. This might not be
153 * standards compliant, check. 143 * standards compliant, check.
154 */ 144 */
155 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, body_base64); 145 GNUNET_asprintf (&signature_target, "%s,%s", header_base64, body_base64);
156 146 GNUNET_CRYPTO_hmac (priv_key, signature_target, strlen (signature_target), &signature);
157 purpose =
158 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
159 strlen (signature_target));
160 purpose->size =
161 htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
162 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
163 GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target));
164 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
165 purpose,
166 (struct GNUNET_CRYPTO_EcdsaSignature *)&signature))
167 {
168 GNUNET_free (signature_target);
169 GNUNET_free (body_str);
170 GNUNET_free (body_base64);
171 GNUNET_free (header_base64);
172 GNUNET_free (purpose);
173 return NULL;
174 }
175 GNUNET_STRINGS_base64_encode ((const char*)&signature, 147 GNUNET_STRINGS_base64_encode ((const char*)&signature,
176 sizeof (struct GNUNET_CRYPTO_EcdsaSignature), 148 sizeof (struct GNUNET_HashCode),
177 &signature_base64); 149 &signature_base64);
178 GNUNET_asprintf (&result, "%s.%s.%s", 150 GNUNET_asprintf (&result, "%s.%s.%s",
179 header_base64, body_base64, signature_base64); 151 header_base64, body_base64, signature_base64);
@@ -184,6 +156,5 @@ jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
184 GNUNET_free (signature_base64); 156 GNUNET_free (signature_base64);
185 GNUNET_free (body_base64); 157 GNUNET_free (body_base64);
186 GNUNET_free (header_base64); 158 GNUNET_free (header_base64);
187 GNUNET_free (purpose);
188 return result; 159 return result;
189} 160}
diff --git a/src/identity-provider/jwt.h b/src/identity-provider/jwt.h
index 072958973..80b6caa33 100644
--- a/src/identity-provider/jwt.h
+++ b/src/identity-provider/jwt.h
@@ -3,7 +3,8 @@
3 3
4char* 4char*
5jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 5jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
6 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
6 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, 7 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
7 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key); 8 const struct GNUNET_CRYPTO_AuthKey *priv_key);
8 9
9#endif 10#endif
diff --git a/src/identity-provider/plugin_rest_openid_connect.c b/src/identity-provider/plugin_rest_openid_connect.c
index 9c2f7fb3d..cc4b83dae 100644
--- a/src/identity-provider/plugin_rest_openid_connect.c
+++ b/src/identity-provider/plugin_rest_openid_connect.c
@@ -1412,6 +1412,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1412 json_t *root, *ticket_string, *nonce, *max_age; 1412 json_t *root, *ticket_string, *nonce, *max_age;
1413 json_error_t error; 1413 json_error_t error;
1414 char *json_response; 1414 char *json_response;
1415 char *jwt_secret;
1415 1416
1416 /* 1417 /*
1417 * Check Authorization 1418 * Check Authorization
@@ -1447,7 +1448,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1447 GNUNET_SCHEDULER_add_now (&do_error, handle); 1448 GNUNET_SCHEDULER_add_now (&do_error, handle);
1448 return; 1449 return;
1449 } 1450 }
1450 GNUNET_STRINGS_base64_decode (credentials, strlen (credentials), &user_psw); 1451 GNUNET_STRINGS_base64_decode (credentials, strlen (credentials), (void**)&user_psw);
1451 1452
1452 if ( NULL == user_psw ) 1453 if ( NULL == user_psw )
1453 { 1454 {
@@ -1598,7 +1599,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1598 } 1599 }
1599 1600
1600 //decode code 1601 //decode code
1601 GNUNET_STRINGS_base64_decode(code,strlen(code),&code_output); 1602 GNUNET_STRINGS_base64_decode(code,strlen(code), (void**)&code_output);
1602 root = json_loads (code_output, 0, &error); 1603 root = json_loads (code_output, 0, &error);
1603 GNUNET_free(code_output); 1604 GNUNET_free(code_output);
1604 ticket_string = json_object_get (root, "ticket"); 1605 ticket_string = json_object_get (root, "ticket");
@@ -1717,15 +1718,32 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1717 { 1718 {
1718 GNUNET_free_non_null(user_psw); 1719 GNUNET_free_non_null(user_psw);
1719 handle->emsg = GNUNET_strdup("invalid_request"); 1720 handle->emsg = GNUNET_strdup("invalid_request");
1720 handle->edesc = GNUNET_strdup("invalid code...."); 1721 handle->edesc = GNUNET_strdup("invalid code...");
1721 handle->response_code = MHD_HTTP_BAD_REQUEST; 1722 handle->response_code = MHD_HTTP_BAD_REQUEST;
1722 GNUNET_SCHEDULER_add_now (&do_error, handle); 1723 GNUNET_SCHEDULER_add_now (&do_error, handle);
1723 GNUNET_free(ticket); 1724 GNUNET_free(ticket);
1724 return; 1725 return;
1725 } 1726 }
1727 if ( GNUNET_OK
1728 != GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin",
1729 "jwt_secret", &jwt_secret) )
1730 {
1731 GNUNET_free_non_null(user_psw);
1732 handle->emsg = GNUNET_strdup("invalid_request");
1733 handle->edesc = GNUNET_strdup("No signing secret configured!");
1734 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1735 GNUNET_SCHEDULER_add_now (&do_error, handle);
1736 GNUNET_free(ticket);
1737 return;
1738 }
1739 struct GNUNET_CRYPTO_AuthKey jwt_sign_key;
1740 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1741 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pk);
1742 GNUNET_CRYPTO_hash (jwt_secret, strlen (jwt_secret), (struct GNUNET_HashCode*)jwt_sign_key.key);
1726 char *id_token = jwt_create_from_list(&ticket->audience, 1743 char *id_token = jwt_create_from_list(&ticket->audience,
1744 &pk,
1727 cl, 1745 cl,
1728 GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego)); 1746 &jwt_sign_key);
1729 1747
1730 //Create random access_token 1748 //Create random access_token
1731 char* access_token_number; 1749 char* access_token_number;