aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-02-05 13:58:16 +0100
committerPhil <phil.buschmann@tum.de>2018-02-05 13:58:16 +0100
commitddbd4e85b1128d2547d551b885eef01bfab5046d (patch)
tree4e68e52c3db665482e2d1dacc6e4f00465aecdb8 /src
parent3f5460f210d697748fef7623213ec4799d8917a5 (diff)
downloadgnunet-ddbd4e85b1128d2547d551b885eef01bfab5046d.tar.gz
gnunet-ddbd4e85b1128d2547d551b885eef01bfab5046d.zip
-changes for using token endpoint & added token endpoint
Diffstat (limited to 'src')
-rw-r--r--src/identity-attribute/identity_attribute.c28
-rw-r--r--src/identity-provider/jwt.c31
-rw-r--r--src/identity-provider/jwt.h9
-rw-r--r--src/identity-provider/plugin_rest_identity_provider.c449
-rw-r--r--src/identity-provider/test_idp.conf5
-rw-r--r--src/include/gnunet_identity_attribute_lib.h6
6 files changed, 254 insertions, 274 deletions
diff --git a/src/identity-attribute/identity_attribute.c b/src/identity-attribute/identity_attribute.c
index cf50d058e..0111668fe 100644
--- a/src/identity-attribute/identity_attribute.c
+++ b/src/identity-attribute/identity_attribute.c
@@ -240,6 +240,34 @@ GNUNET_IDENTITY_ATTRIBUTE_claim_new (const char* attr_name,
240 return attr; 240 return attr;
241} 241}
242 242
243/**
244 * Add a new claim list entry.
245 *
246 * @param claim_list the attribute name
247 * @param attr_name the attribute name
248 * @param type the attribute type
249 * @param data the attribute value
250 * @param data_size the attribute value size
251 * @return
252 */
253void
254GNUNET_IDENTITY_ATTRIBUTE_list_add (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *claim_list,
255 const char* attr_name,
256 uint32_t type,
257 const void* data,
258 size_t data_size)
259{
260 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
261 le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
262 le->claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name,
263 type,
264 data,
265 data_size);
266 GNUNET_CONTAINER_DLL_insert (claim_list->list_head,
267 claim_list->list_tail,
268 le);
269}
270
243size_t 271size_t
244GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) 272GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
245{ 273{
diff --git a/src/identity-provider/jwt.c b/src/identity-provider/jwt.c
index 2f1e3240b..02a920f14 100644
--- a/src/identity-provider/jwt.c
+++ b/src/identity-provider/jwt.c
@@ -39,6 +39,8 @@
39 39
40#define JWT_TYP_VALUE "jwt" 40#define JWT_TYP_VALUE "jwt"
41 41
42#define SERVER_ADDRESS "https://localhost"
43
42static char* 44static char*
43create_jwt_header(void) 45create_jwt_header(void)
44{ 46{
@@ -57,22 +59,22 @@ create_jwt_header(void)
57/** 59/**
58 * Create a JWT from attributes 60 * Create a JWT from attributes
59 * 61 *
60 * @param sub_key the public of the subject 62 * @param aud_key the public of the subject
61 * @param attrs the attribute list 63 * @param attrs the attribute list
62 * @param priv_key the key used to sign the JWT 64 * @param priv_key the key used to sign the JWT
63 * @return a new base64-encoded JWT string. 65 * @return a new base64-encoded JWT string.
64 */ 66 */
65char* 67char*
66jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, 68jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
67 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, 69 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
68 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key) 70 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key)
69{ 71{
70 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; 72 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
71 struct GNUNET_CRYPTO_EcdsaPublicKey iss_key; 73 struct GNUNET_CRYPTO_EcdsaPublicKey sub_key;
72 struct GNUNET_CRYPTO_EcdsaSignature signature; 74 struct GNUNET_CRYPTO_EcdsaSignature signature;
73 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 75 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
74 char* audience; 76 char* audience;
75 char* issuer; 77 char* subject;
76 char* header; 78 char* header;
77 char* padding; 79 char* padding;
78 char* body_str; 80 char* body_str;
@@ -84,20 +86,29 @@ jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
84 char* attr_val_str; 86 char* attr_val_str;
85 json_t* body; 87 json_t* body;
86 88
87 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &iss_key); 89 //exp REQUIRED time expired from config
90 //iat REQUIRED time now
91 //auth_time only if max_age
92 //nonce only if nonce
93 // OPTIONAL acr,amr,azp
94 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &sub_key);
88 /* TODO maybe we should use a local identity here */ 95 /* TODO maybe we should use a local identity here */
89 issuer = GNUNET_STRINGS_data_to_string_alloc (&iss_key, 96 subject = GNUNET_STRINGS_data_to_string_alloc (&sub_key,
90 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 97 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
91 audience = GNUNET_STRINGS_data_to_string_alloc (sub_key, 98 audience = GNUNET_STRINGS_data_to_string_alloc (aud_key,
92 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 99 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
93 header = create_jwt_header (); 100 header = create_jwt_header ();
94 body = json_object (); 101 body = json_object ();
95 /* TODO who is the issuer? local IdP or subject ? See self-issued tokens? */ 102 /* TODO who is the issuer? local IdP or subject ? See self-issued tokens? */
103 //iss REQUIRED case sensitive server uri with https
104 //TODO change server address
96 json_object_set_new (body, 105 json_object_set_new (body,
97 "iss", json_string (issuer)); 106 "iss", json_string (SERVER_ADDRESS));
107 //sub REQUIRED public key identity, not exceed 255 ASCII length
98 json_object_set_new (body, 108 json_object_set_new (body,
99 "sub", json_string (issuer)); 109 "sub", json_string (subject));
100 /* TODO what should be in here exactly? */ 110 /* TODO what should be in here exactly? */
111 //aud REQUIRED public key client_id must be there
101 json_object_set_new (body, 112 json_object_set_new (body,
102 "aud", json_string (audience)); 113 "aud", json_string (audience));
103 for (le = attrs->list_head; NULL != le; le = le->next) 114 for (le = attrs->list_head; NULL != le; le = le->next)
@@ -135,7 +146,7 @@ jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
135 while (NULL != padding) 146 while (NULL != padding)
136 padding = strtok(NULL, "="); 147 padding = strtok(NULL, "=");
137 148
138 GNUNET_free (issuer); 149 GNUNET_free (subject);
139 GNUNET_free (audience); 150 GNUNET_free (audience);
140 151
141 /** 152 /**
diff --git a/src/identity-provider/jwt.h b/src/identity-provider/jwt.h
new file mode 100644
index 000000000..072958973
--- /dev/null
+++ b/src/identity-provider/jwt.h
@@ -0,0 +1,9 @@
1#ifndef JWT_H
2#define JWT_H
3
4char*
5jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
6 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
7 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key);
8
9#endif
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c
index 119476bb9..a0adf1b38 100644
--- a/src/identity-provider/plugin_rest_identity_provider.c
+++ b/src/identity-provider/plugin_rest_identity_provider.c
@@ -39,6 +39,7 @@
39#include "gnunet_signatures.h" 39#include "gnunet_signatures.h"
40#include "gnunet_identity_attribute_lib.h" 40#include "gnunet_identity_attribute_lib.h"
41#include "gnunet_identity_provider_service.h" 41#include "gnunet_identity_provider_service.h"
42#include "jwt.h"
42 43
43/** 44/**
44 * REST root namespace 45 * REST root namespace
@@ -226,7 +227,6 @@ struct OIDC_Variables
226 227
227 char *login_identity; 228 char *login_identity;
228 229
229 json_t *post_object;
230}; 230};
231 231
232/** 232/**
@@ -439,8 +439,6 @@ cleanup_handle (struct RequestHandle *handle)
439 GNUNET_free(handle->oidc->scope); 439 GNUNET_free(handle->oidc->scope);
440 if (NULL != handle->oidc->state) 440 if (NULL != handle->oidc->state)
441 GNUNET_free(handle->oidc->state); 441 GNUNET_free(handle->oidc->state);
442 if (NULL != handle->oidc->post_object)
443 json_decref(handle->oidc->post_object);
444 GNUNET_free(handle->oidc); 442 GNUNET_free(handle->oidc);
445 } 443 }
446 if ( NULL != handle->attr_list ) 444 if ( NULL != handle->attr_list )
@@ -501,6 +499,7 @@ do_error (void *cls)
501 handle->response_code = MHD_HTTP_BAD_REQUEST; 499 handle->response_code = MHD_HTTP_BAD_REQUEST;
502 } 500 }
503 resp = GNUNET_REST_create_response (json_error); 501 resp = GNUNET_REST_create_response (json_error);
502 MHD_add_response_header (resp, "Content-Type", "application/json");
504 handle->proc (handle->proc_cls, resp, handle->response_code); 503 handle->proc (handle->proc_cls, resp, handle->response_code);
505 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 504 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
506 GNUNET_free (json_error); 505 GNUNET_free (json_error);
@@ -1346,37 +1345,40 @@ oidc_ticket_issue_cb (void* cls,
1346{ 1345{
1347 struct RequestHandle *handle = cls; 1346 struct RequestHandle *handle = cls;
1348 struct MHD_Response *resp; 1347 struct MHD_Response *resp;
1349 struct GNUNET_HashCode cache_key; 1348 char *ticket_str;
1350 char* ticket_str; 1349 char *redirect_uri;
1351 char* redirect_uri; 1350 char *code_json_string;
1352 char* jwt; 1351 char *code_base64_final_string;
1353 handle->idp_op = NULL; 1352 handle->idp_op = NULL;
1354 resp = GNUNET_REST_create_response (""); 1353 resp = GNUNET_REST_create_response ("");
1355 if (NULL != ticket) { 1354 if (NULL != ticket) {
1356 ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket, 1355 ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket,
1357 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); 1356 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1358 1357
1359 1358// json_t *object=json_object();
1360 //TODO Check if this is right: 1359// json_object_set_new(object,"ticket",json_string(ticket_str));
1361// GNUNET_CRYPTO_hash (ticket_str, strlen (ticket_str), &cache_key); 1360// if(NULL != handle->oidc->nonce)
1362// jwt = jwt_create_from_list (handle->oidc->client_pkey, 1361// {
1363// handle->attr_list, 1362// json_object_set_new(object,"nonce",json_string(handle->oidc->nonce));
1364// handle->priv_key); 1363// }
1365// //TODO Check success of function 1364 GNUNET_asprintf (&code_json_string, "{\"ticket\":\"%s\"%s%s%s}",
1366// GNUNET_CONTAINER_multihashmap_put ( 1365 ticket_str,
1367// OIDC_identity_grants, &cache_key, jwt, 1366 (NULL != handle->oidc->nonce) ? ", \"nonce\":\"" : "",
1368// GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1367 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
1369 1368 (NULL != handle->oidc->nonce) ? "\"" : "");
1369 GNUNET_STRINGS_base64_encode(code_json_string,strlen(code_json_string),&code_base64_final_string);
1370 1370
1371 GNUNET_asprintf (&redirect_uri, "%s?%s=%s&state=%s", 1371 GNUNET_asprintf (&redirect_uri, "%s?%s=%s&state=%s",
1372 handle->oidc->redirect_uri, 1372 handle->oidc->redirect_uri,
1373 handle->oidc->response_type, 1373 handle->oidc->response_type,
1374 ticket_str, handle->oidc->state); 1374 code_base64_final_string, handle->oidc->state);
1375 MHD_add_response_header (resp, "Location", redirect_uri); 1375 MHD_add_response_header (resp, "Location", redirect_uri);
1376 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 1376 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1377 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1377 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
1378 GNUNET_free (redirect_uri); 1378 GNUNET_free (redirect_uri);
1379 GNUNET_free (ticket_str); 1379 GNUNET_free (ticket_str);
1380 GNUNET_free (code_json_string);
1381 GNUNET_free (code_base64_final_string);
1380 return; 1382 return;
1381 } 1383 }
1382 handle->emsg = GNUNET_strdup("server_error"); 1384 handle->emsg = GNUNET_strdup("server_error");
@@ -1578,7 +1580,7 @@ namestore_iteration_callback (
1578 * 1580 *
1579 * @param cls the `struct RequestHandle` 1581 * @param cls the `struct RequestHandle`
1580 */ 1582 */
1581static void namestore_iteration_finished_GET (void *cls) 1583static void namestore_iteration_finished (void *cls)
1582{ 1584{
1583 struct RequestHandle *handle = cls; 1585 struct RequestHandle *handle = cls;
1584 struct GNUNET_HashCode cache_key; 1586 struct GNUNET_HashCode cache_key;
@@ -1596,7 +1598,7 @@ static void namestore_iteration_finished_GET (void *cls)
1596 handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); 1598 handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1597 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->priv_key, 1599 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->priv_key,
1598 &oidc_iteration_error, handle, &namestore_iteration_callback, handle, 1600 &oidc_iteration_error, handle, &namestore_iteration_callback, handle,
1599 &namestore_iteration_finished_GET, handle); 1601 &namestore_iteration_finished, handle);
1600 return; 1602 return;
1601 } 1603 }
1602 if (GNUNET_NO == handle->oidc->is_client_trusted) 1604 if (GNUNET_NO == handle->oidc->is_client_trusted)
@@ -1735,14 +1737,14 @@ static void namestore_iteration_finished_GET (void *cls)
1735} 1737}
1736 1738
1737/** 1739/**
1738 * Responds to authorization GET request 1740 * Responds to authorization GET and url-encoded POST request
1739 * 1741 *
1740 * @param con_handle the connection handle 1742 * @param con_handle the connection handle
1741 * @param url the url 1743 * @param url the url
1742 * @param cls the RequestHandle 1744 * @param cls the RequestHandle
1743 */ 1745 */
1744static void 1746static void
1745authorize_GET_cont (struct GNUNET_REST_RequestHandle *con_handle, 1747authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1746 const char* url, 1748 const char* url,
1747 void *cls) 1749 void *cls)
1748{ 1750{
@@ -1808,233 +1810,9 @@ authorize_GET_cont (struct GNUNET_REST_RequestHandle *con_handle,
1808 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start ( 1810 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (
1809 handle->namestore_handle, &handle->priv_key, &oidc_iteration_error, 1811 handle->namestore_handle, &handle->priv_key, &oidc_iteration_error,
1810 handle, &namestore_iteration_callback, handle, 1812 handle, &namestore_iteration_callback, handle,
1811 &namestore_iteration_finished_GET, handle); 1813 &namestore_iteration_finished, handle);
1812} 1814}
1813 1815
1814///**
1815// * Iteration over all results finished, build final
1816// * response.
1817// *
1818// * @param cls the `struct RequestHandle`
1819// */
1820//static void namestore_iteration_finished_POST (void *cls)
1821//{
1822// struct RequestHandle *handle = cls;
1823// json_t *cache_object;
1824// char *expected_redirect_uri;
1825// char *expected_scope;
1826// char delimiter[]=" ";
1827// int number_of_ignored_parameter, iterator;
1828//
1829//
1830// handle->ego_entry = handle->ego_entry->next;
1831//
1832// if(NULL != handle->ego_entry){
1833// handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1834// handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->priv_key,
1835// &oidc_iteration_error, handle, &namestore_iteration_callback, handle,
1836// &namestore_iteration_finished_POST, handle);
1837// return;
1838// }
1839// if (GNUNET_YES != handle->oidc->is_client_trusted)
1840// {
1841// handle->emsg = GNUNET_strdup("unauthorized_client");
1842// handle->edesc = GNUNET_strdup("The client is not authorized to request an "
1843// "authorization code using this method.");
1844// GNUNET_SCHEDULER_add_now (&do_error, handle);
1845// return;
1846// }
1847//
1848// // REQUIRED value: redirect_uri
1849// cache_object = json_object_get (handle->oidc->post_object, OIDC_REDIRECT_URI_KEY);
1850// if ( NULL == cache_object || !json_is_string(cache_object) )
1851// {
1852// handle->emsg=GNUNET_strdup("invalid_request");
1853// handle->edesc=GNUNET_strdup("missing parameter redirect_uri");
1854// GNUNET_SCHEDULER_add_now (&do_error, handle);
1855// return;
1856// }
1857// handle->oidc->redirect_uri = json_string_value (cache_object);
1858//
1859// GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", handle->oidc->client_id);
1860// // verify the redirect uri matches https://<client_id>.zkey[/xyz]
1861// if( 0 != strncmp( expected_redirect_uri, handle->oidc->redirect_uri, strlen(expected_redirect_uri)) )
1862// {
1863// handle->emsg=GNUNET_strdup("invalid_request");
1864// handle->edesc=GNUNET_strdup("Invalid redirect_uri");
1865// GNUNET_SCHEDULER_add_now (&do_error, handle);
1866// GNUNET_free(expected_redirect_uri);
1867// return;
1868// }
1869// handle->oidc->redirect_uri = GNUNET_strdup(handle->oidc->redirect_uri);
1870// GNUNET_free(expected_redirect_uri);
1871//
1872// // REQUIRED value: response_type
1873// cache_object = json_object_get (handle->oidc->post_object, OIDC_RESPONSE_TYPE_KEY);
1874// if ( NULL == cache_object || !json_is_string(cache_object) )
1875// {
1876// handle->emsg=GNUNET_strdup("invalid_request");
1877// handle->edesc=GNUNET_strdup("missing parameter response_type");
1878// GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1879// return;
1880// }
1881// handle->oidc->response_type = json_string_value (cache_object);
1882// handle->oidc->response_type = GNUNET_strdup (handle->oidc->response_type);
1883//
1884// // REQUIRED value: scope
1885// cache_object = json_object_get (handle->oidc->post_object, OIDC_SCOPE_KEY);
1886// if ( NULL == cache_object || !json_is_string(cache_object) )
1887// {
1888// handle->emsg=GNUNET_strdup("invalid_request");
1889// handle->edesc=GNUNET_strdup("missing parameter scope");
1890// GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1891// return;
1892// }
1893// handle->oidc->scope = json_string_value (cache_object);
1894// handle->oidc->scope = GNUNET_strdup(handle->oidc->scope);
1895//
1896// //OPTIONAL value: nonce
1897// cache_object = json_object_get (handle->oidc->post_object, OIDC_NONCE_KEY);
1898// if ( NULL != cache_object && json_is_string(cache_object) )
1899// {
1900// handle->oidc->nonce = json_string_value (cache_object);
1901// //TODO: what do we do with the nonce?
1902// handle->oidc->nonce = GNUNET_strdup (handle->oidc->nonce);
1903// }
1904//
1905// //TODO check other values and use them accordingly
1906// number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1907// for( iterator = 0; iterator < number_of_ignored_parameter; iterator++ )
1908// {
1909// cache_object = json_object_get (handle->oidc->post_object, OIDC_ignored_parameter_array[iterator]);
1910// if( NULL != cache_object && json_is_string(cache_object) )
1911// {
1912// handle->emsg=GNUNET_strdup("access_denied");
1913// GNUNET_asprintf (&handle->edesc, "Server will not handle parameter: %s",
1914// OIDC_ignored_parameter_array[iterator]);
1915// GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1916// return;
1917// }
1918// }
1919//
1920// // Checks if response_type is 'code'
1921// if( 0 != strcmp( handle->oidc->response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) )
1922// {
1923// handle->emsg=GNUNET_strdup("unsupported_response_type");
1924// handle->edesc=GNUNET_strdup("The authorization server does not support "
1925// "obtaining this authorization code.");
1926// GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1927// return;
1928// }
1929//
1930// // Checks if scope contains 'openid'
1931// expected_scope = GNUNET_strdup(handle->oidc->scope);
1932// expected_scope = strtok (expected_scope, delimiter);
1933// while (NULL != expected_scope)
1934// {
1935// if ( 0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope) )
1936// {
1937// break;
1938// }
1939// expected_scope = strtok (NULL, delimiter);
1940// }
1941// if (NULL == expected_scope)
1942// {
1943// handle->emsg = GNUNET_strdup("invalid_scope");
1944// handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or "
1945// "malformed.");
1946// GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1947// return;
1948// }
1949//
1950// GNUNET_free(expected_scope);
1951//
1952// if( NULL != handle->oidc->login_identity )
1953// {
1954// GNUNET_SCHEDULER_add_now(&login_check,handle);
1955// return;
1956// }
1957//
1958// GNUNET_SCHEDULER_add_now(&login_redirection,handle);
1959//}
1960//
1961//
1962///**
1963// * Responds to authorization POST request
1964// *
1965// * @param con_handle the connection handle
1966// * @param url the url
1967// * @param cls the RequestHandle
1968// */
1969//static void
1970//authorize_POST_cont (struct GNUNET_REST_RequestHandle *con_handle,
1971// const char* url,
1972// void *cls)
1973//{
1974// struct RequestHandle *handle = cls;
1975// json_t *cache_object;
1976// json_error_t error;
1977// handle->oidc->post_object = json_loads (handle->rest_handle->data, 0, &error);
1978//
1979// //gets identity of login try with cookie
1980// cookie_identity_interpretation(handle);
1981//
1982// //RECOMMENDED value: state - REQUIRED for answers
1983// cache_object = json_object_get (handle->oidc->post_object, OIDC_STATE_KEY);
1984// if ( NULL != cache_object && json_is_string(cache_object) )
1985// {
1986// handle->oidc->state = json_string_value (cache_object);
1987// handle->oidc->state = GNUNET_strdup(handle->oidc->state);
1988// }
1989//
1990// // REQUIRED value: client_id
1991// cache_object = json_object_get (handle->oidc->post_object,
1992// OIDC_CLIENT_ID_KEY);
1993// if ( NULL == cache_object || !json_is_string(cache_object) )
1994// {
1995// handle->emsg = GNUNET_strdup("invalid_request");
1996// handle->edesc = GNUNET_strdup("missing parameter client_id");
1997// handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1998// GNUNET_SCHEDULER_add_now (&do_error, handle);
1999// return;
2000// }
2001// handle->oidc->client_id = json_string_value (cache_object);
2002// handle->oidc->client_id = GNUNET_strdup(handle->oidc->client_id);
2003//
2004// if ( GNUNET_OK
2005// != GNUNET_CRYPTO_ecdsa_public_key_from_string (
2006// handle->oidc->client_id, strlen (handle->oidc->client_id),
2007// &handle->oidc->client_pkey) )
2008// {
2009// handle->emsg = GNUNET_strdup("unauthorized_client");
2010// handle->edesc = GNUNET_strdup("The client is not authorized to request an "
2011// "authorization code using this method.");
2012// handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2013// GNUNET_SCHEDULER_add_now (&do_error, handle);
2014// return;
2015// }
2016//
2017// if ( NULL == handle->ego_head )
2018// {
2019// //TODO throw error or ignore if egos are missing?
2020// handle->emsg = GNUNET_strdup("server_error");
2021// handle->edesc = GNUNET_strdup ("Egos are missing");
2022// handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2023// GNUNET_SCHEDULER_add_now (&do_error, handle);
2024// return;
2025// }
2026//
2027// handle->ego_entry = handle->ego_head;
2028// handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego);
2029// handle->oidc->is_client_trusted = GNUNET_NO;
2030//
2031// // Checks if client_id is valid:
2032// handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (
2033// handle->namestore_handle, &handle->priv_key, &oidc_iteration_error,
2034// handle, &namestore_iteration_callback, handle,
2035// &namestore_iteration_finished_POST, handle);
2036//}
2037
2038/** 1816/**
2039 * Combines an identity with a login time and responds OK to login request 1817 * Combines an identity with a login time and responds OK to login request
2040 * 1818 *
@@ -2097,6 +1875,7 @@ token_cont(struct GNUNET_REST_RequestHandle *con_handle,
2097 //TODO static strings 1875 //TODO static strings
2098 //TODO Unauthorized with Header Field 1876 //TODO Unauthorized with Header Field
2099 //TODO Do not allow multiple equal parameter names 1877 //TODO Do not allow multiple equal parameter names
1878 //TODO free
2100 1879
2101 struct RequestHandle *handle = cls; 1880 struct RequestHandle *handle = cls;
2102 struct GNUNET_HashCode cache_key; 1881 struct GNUNET_HashCode cache_key;
@@ -2107,9 +1886,11 @@ token_cont(struct GNUNET_REST_RequestHandle *con_handle,
2107 char *user_psw = NULL, *client_id, *psw; 1886 char *user_psw = NULL, *client_id, *psw;
2108 char *expected_psw; 1887 char *expected_psw;
2109 int client_exists = GNUNET_NO; 1888 int client_exists = GNUNET_NO;
1889 struct MHD_Response *resp;
2110 1890
2111 //Check Authorization Header 1891 //Check Authorization Header
2112 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, strlen (OIDC_AUTHORIZATION_HEADER_KEY), 1892 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
1893 strlen (OIDC_AUTHORIZATION_HEADER_KEY),
2113 &cache_key); 1894 &cache_key);
2114 if ( GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->header_param_map, 1895 if ( GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->header_param_map,
2115 &cache_key) ) 1896 &cache_key) )
@@ -2229,7 +2010,6 @@ token_cont(struct GNUNET_REST_RequestHandle *con_handle,
2229 redirect_uri = GNUNET_CONTAINER_multihashmap_get ( 2010 redirect_uri = GNUNET_CONTAINER_multihashmap_get (
2230 handle->rest_handle->url_param_map, &cache_key); 2011 handle->rest_handle->url_param_map, &cache_key);
2231 2012
2232
2233 //check client_id 2013 //check client_id
2234 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry->next; ) 2014 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry->next; )
2235 { 2015 {
@@ -2248,8 +2028,6 @@ token_cont(struct GNUNET_REST_RequestHandle *con_handle,
2248 return; 2028 return;
2249 } 2029 }
2250 2030
2251
2252
2253 //Check parameter grant_type == "authorization_code" 2031 //Check parameter grant_type == "authorization_code"
2254 if (0 != strcmp("authorization_code", grant_type)) 2032 if (0 != strcmp("authorization_code", grant_type))
2255 { 2033 {
@@ -2259,12 +2037,6 @@ token_cont(struct GNUNET_REST_RequestHandle *con_handle,
2259 return; 2037 return;
2260 } 2038 }
2261 2039
2262
2263
2264 //TODO consume code
2265
2266
2267
2268 // check redirect_uri 2040 // check redirect_uri
2269 GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", client_id); 2041 GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", client_id);
2270 // verify the redirect uri matches https://<client_id>.zkey[/xyz] 2042 // verify the redirect uri matches https://<client_id>.zkey[/xyz]
@@ -2278,10 +2050,163 @@ token_cont(struct GNUNET_REST_RequestHandle *con_handle,
2278 } 2050 }
2279 GNUNET_free(expected_redirect_uri); 2051 GNUNET_free(expected_redirect_uri);
2280 2052
2281 //return something 2053 char* output;
2054 GNUNET_STRINGS_base64_decode(code,strlen(code),&output);
2055
2056 json_t *root;
2057 json_error_t error;
2058 json_t *ticket_string;
2059 json_t *nonce;
2060 root = json_loads (output, 0, &error);
2061 ticket_string = json_object_get (root, "ticket");
2062 nonce = json_object_get (root, "nonce");
2063
2064
2065 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket = GNUNET_new(struct GNUNET_IDENTITY_PROVIDER_Ticket);
2066 if(ticket_string == NULL && !json_is_string(ticket_string))
2067 {
2068 handle->emsg = GNUNET_strdup("invalid_request");
2069 handle->edesc = GNUNET_strdup("invalid code.");
2070 GNUNET_SCHEDULER_add_now (&do_error, handle);
2071 return;
2072 }
2073 if ( GNUNET_OK
2074 != GNUNET_STRINGS_string_to_data (json_string_value(ticket_string),
2075 strlen (json_string_value(ticket_string)),
2076 ticket,
2077 sizeof(struct GNUNET_IDENTITY_PROVIDER_Ticket)))
2078 {
2079 handle->emsg = GNUNET_strdup("invalid_request");
2080 handle->edesc = GNUNET_strdup("invalid code..");
2081 GNUNET_SCHEDULER_add_now (&do_error, handle);
2082 return;
2083 }
2084 //TODO lookup if audience is the current client
2085 //TODO change
2086 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
2087 GNUNET_IDENTITY_ego_get_public_key(handle->ego_entry->ego,&pub_key);
2088 if (0 != memcmp(&pub_key,&ticket->audience,sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
2089 {
2090 handle->emsg = GNUNET_strdup("invalid_request");
2091 handle->edesc = GNUNET_strdup("invalid code...");
2092 GNUNET_SCHEDULER_add_now (&do_error, handle);
2093 return;
2094 }
2095
2096 //create jwt
2097 unsigned long long int expiration_time;
2098 if ( GNUNET_OK
2099 != GNUNET_CONFIGURATION_get_value_number(cfg, "identity-rest-plugin",
2100 "expiration_time", &expiration_time) )
2101 {
2102 handle->emsg = GNUNET_strdup("server_error");
2103 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2104 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2105 GNUNET_SCHEDULER_add_now (&do_error, handle);
2106 return;
2107 }
2108
2109 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *cl = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
2110 //aud REQUIRED public key client_id must be there
2111 GNUNET_IDENTITY_ATTRIBUTE_list_add(cl,
2112 "aud",
2113 GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING,
2114 client_id,
2115 strlen(client_id));
2116 //exp REQUIRED time expired from config
2117 //TODO time as seconds
2118 struct GNUNET_TIME_Absolute exp_time = GNUNET_TIME_relative_to_absolute (
2119 GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_second_ (),
2120 expiration_time));
2121 const char* exp_time_string = GNUNET_STRINGS_absolute_time_to_string(exp_time);
2122 GNUNET_IDENTITY_ATTRIBUTE_list_add (cl,
2123 "exp",
2124 GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING,
2125 exp_time_string,
2126 strlen(exp_time_string));
2127 //iat REQUIRED time now
2128 //TODO time as seconds
2129 struct GNUNET_TIME_Absolute time_now = GNUNET_TIME_absolute_get();
2130 const char* time_now_string = GNUNET_STRINGS_absolute_time_to_string(time_now);
2131 GNUNET_IDENTITY_ATTRIBUTE_list_add (cl,
2132 "iat",
2133 GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING,
2134 time_now_string,
2135 strlen(time_now_string));
2136 //nonce only if nonce
2137 if ( NULL != nonce && json_is_string(nonce) )
2138 {
2139 GNUNET_IDENTITY_ATTRIBUTE_list_add (cl,
2140 "nonce",
2141 GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING,
2142 json_string_value(nonce),
2143 strlen(json_string_value(nonce)));
2144 }
2145
2146 //TODO auth_time only if max_age
2147 //TODO OPTIONAL acr,amr,azp
2148
2149 //TODO lookup client for client == audience of ticket
2150 struct EgoEntry *ego_entry;
2151 for (ego_entry = handle->ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
2152 {
2153 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
2154 if (0 == memcmp (&pub_key, &ticket->audience, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
2155 {
2156 break;
2157 }
2158 }
2159 if ( NULL == ego_entry )
2160 {
2161 handle->emsg = GNUNET_strdup("invalid_request");
2162 handle->edesc = GNUNET_strdup("invalid code....");
2163 GNUNET_SCHEDULER_add_now (&do_error, handle);
2164 return;
2165 }
2166 char *id_token = jwt_create_from_list(&ticket->audience,
2167 cl,
2168 GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego));
2169
2170 // random access_token
2171 char* access_token_number;
2172 char* access_token;
2173 uint64_t random_number;
2174 random_number = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
2175 GNUNET_asprintf(&access_token_number, "%" PRIu64, random_number);
2176 GNUNET_STRINGS_base64_encode(access_token_number,strlen(access_token_number),&access_token);
2177
2178
2179 char *json_error;
2180 //TODO optional refresh_token and scope
2181 GNUNET_asprintf (&json_error,
2182 "{ \"access_token\" : \"%s\", "
2183 "\"token_type\" : \"Bearer\", "
2184 "\"expires_in\" : %d, "
2185 "\"id_token\" : \"%s\"}",
2186 access_token,
2187 expiration_time,
2188 id_token);
2189
2190 resp = GNUNET_REST_create_response (json_error);
2191
2192 MHD_add_response_header (resp, "Cache-Control", "no-store");
2193 MHD_add_response_header (resp, "Pragma", "no-cache");
2194 MHD_add_response_header (resp, "Content-Type", "application/json");
2195 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2196 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
2282 2197
2198 //necessary? should be
2199// handle->idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume(handle->idp,GNUNET_IDENTITY_ego_get_private_key(handle->ego_entry->ego),ticket,consume_cont, handle);
2200 GNUNET_IDENTITY_ATTRIBUTE_list_destroy(cl);
2201 //TODO write method
2202 handle->idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume(handle->idp,GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego),ticket,consume_cont,handle);
2203 GNUNET_free(access_token_number);
2204 GNUNET_free(credentials);
2205 GNUNET_free(access_token);
2283 GNUNET_free(user_psw); 2206 GNUNET_free(user_psw);
2284 json_decref(handle->oidc->post_object); 2207 GNUNET_free(code);
2208 GNUNET_free(id_token);
2209 json_decref(root);
2285} 2210}
2286 2211
2287/** 2212/**
@@ -2297,8 +2222,8 @@ init_cont (struct RequestHandle *handle)
2297 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont}, 2222 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont},
2298 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, 2223 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont},
2299 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, 2224 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
2300 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_GET_cont}, 2225 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont},
2301 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_GET_cont}, 2226 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, //url-encoded
2302 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont}, 2227 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont},
2303 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_cont}, 2228 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_cont},
2304 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, 2229 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
diff --git a/src/identity-provider/test_idp.conf b/src/identity-provider/test_idp.conf
index b4bb448df..b11b43ae2 100644
--- a/src/identity-provider/test_idp.conf
+++ b/src/identity-provider/test_idp.conf
@@ -28,5 +28,6 @@ ZONE_PUBLISH_TIME_WINDOW = 1 h
28DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0 28DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0
29 29
30[identity-rest-plugin] 30[identity-rest-plugin]
31address = http://localhost:8000/#/identities 31address = http://localhost:8000/#/login
32psw = mysupersecretpassword \ No newline at end of file 32psw = mysupersecretpassword
33expiration_time = 3600 \ No newline at end of file
diff --git a/src/include/gnunet_identity_attribute_lib.h b/src/include/gnunet_identity_attribute_lib.h
index 316b0bf95..8879ba925 100644
--- a/src/include/gnunet_identity_attribute_lib.h
+++ b/src/include/gnunet_identity_attribute_lib.h
@@ -148,6 +148,12 @@ GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_
148void 148void
149GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); 149GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs);
150 150
151void
152GNUNET_IDENTITY_ATTRIBUTE_list_add (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
153 const char* attr_name,
154 uint32_t type,
155 const void* data,
156 size_t data_size);
151 157
152/** 158/**
153 * Serialize an attribute list 159 * Serialize an attribute list