aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/credential/credential_serialization.c4
-rw-r--r--src/credential/gnunet-service-credential.c30
-rw-r--r--src/identity-provider/Makefile.am1
-rw-r--r--src/identity-provider/gnunet-service-identity-provider.c182
-rw-r--r--src/identity-provider/identity_provider.h5
-rw-r--r--src/identity-provider/identity_provider_api.c10
-rw-r--r--src/identity-provider/identity_token.c56
-rw-r--r--src/identity-provider/identity_token.h47
-rw-r--r--src/identity-provider/plugin_rest_identity_provider.c45
-rw-r--r--src/include/gnunet_identity_provider_service.h1
10 files changed, 333 insertions, 48 deletions
diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c
index 76bf491c9..1fc72c203 100644
--- a/src/credential/credential_serialization.c
+++ b/src/credential/credential_serialization.c
@@ -192,7 +192,7 @@ GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count,
192 c_rec.signature = cd[i].signature; 192 c_rec.signature = cd[i].signature;
193 c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); 193 c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
194 c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); 194 c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
195 c_rec.expiration = htonl ((uint32_t) cd[i].expiration.abs_value_us); 195 c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us);
196 if (off + sizeof (c_rec) > dest_size) 196 if (off + sizeof (c_rec) > dest_size)
197 return -1; 197 return -1;
198 GNUNET_memcpy (&dest[off], 198 GNUNET_memcpy (&dest[off],
@@ -241,7 +241,7 @@ GNUNET_CREDENTIAL_credentials_deserialize (size_t len,
241 cd[i].issuer_key = c_rec.issuer_key; 241 cd[i].issuer_key = c_rec.issuer_key;
242 cd[i].subject_key = c_rec.subject_key; 242 cd[i].subject_key = c_rec.subject_key;
243 cd[i].signature = c_rec.signature; 243 cd[i].signature = c_rec.signature;
244 cd[i].expiration.abs_value_us = ntohl((uint32_t) c_rec.expiration); 244 cd[i].expiration.abs_value_us = GNUNET_ntohll(c_rec.expiration);
245 off += sizeof (c_rec); 245 off += sizeof (c_rec);
246 if (off + cd[i].issuer_attribute_len > len) 246 if (off + cd[i].issuer_attribute_len > len)
247 return GNUNET_SYSERR; 247 return GNUNET_SYSERR;
diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c
index ec89da323..75ed6d5da 100644
--- a/src/credential/gnunet-service-credential.c
+++ b/src/credential/gnunet-service-credential.c
@@ -92,7 +92,11 @@ struct CredentialRecordEntry
92 * DLL 92 * DLL
93 */ 93 */
94 struct CredentialRecordEntry *prev; 94 struct CredentialRecordEntry *prev;
95 95
96 /**
97 * Number of references in delegation chains
98 */
99 uint32_t refcount;
96 100
97 /** 101 /**
98 * Payload 102 * Payload
@@ -485,6 +489,7 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
485 struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size]; 489 struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
486 struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size]; 490 struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
487 struct CredentialRecordEntry *cd; 491 struct CredentialRecordEntry *cd;
492 struct CredentialRecordEntry *tmp;
488 size_t size; 493 size_t size;
489 int i; 494 int i;
490 495
@@ -508,6 +513,26 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
508 } 513 }
509 514
510 /** 515 /**
516 * Remove all credentials not needed
517 */
518 for (cd = vrh->cred_chain_head; NULL != cd;)
519 {
520 if (cd->refcount > 0)
521 {
522 cd = cd->next;
523 continue;
524 }
525 tmp = cd;
526 cd = cd->next;
527 GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
528 vrh->cred_chain_tail,
529 tmp);
530 GNUNET_free (tmp->credential);
531 GNUNET_free (tmp);
532 vrh->cred_chain_size--;
533 }
534
535 /**
511 * Get serialized record data 536 * Get serialized record data
512 * Append at the end of rmsg 537 * Append at the end of rmsg
513 */ 538 */
@@ -681,7 +706,7 @@ backward_resolution (void* cls,
681 706
682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
683 "Found issuer\n"); 708 "Found issuer\n");
684 709 cred_pointer->refcount++;
685 //Backtrack 710 //Backtrack
686 for (tmp_set = ds_entry; 711 for (tmp_set = ds_entry;
687 NULL != tmp_set->parent_queue_entry; 712 NULL != tmp_set->parent_queue_entry;
@@ -796,6 +821,7 @@ delegation_chain_resolution_start (void* cls)
796 continue; 821 continue;
797 if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute)) 822 if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute))
798 continue; 823 continue;
824 cr_entry->refcount++;
799 //Found match prematurely 825 //Found match prematurely
800 send_lookup_response (vrh); 826 send_lookup_response (vrh);
801 return; 827 return;
diff --git a/src/identity-provider/Makefile.am b/src/identity-provider/Makefile.am
index 7c2bb9646..cc9692a9a 100644
--- a/src/identity-provider/Makefile.am
+++ b/src/identity-provider/Makefile.am
@@ -39,6 +39,7 @@ gnunet_service_identity_provider_LDADD = \
39 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 39 $(top_builddir)/src/namestore/libgnunetnamestore.la \
40 $(top_builddir)/src/identity/libgnunetidentity.la \ 40 $(top_builddir)/src/identity/libgnunetidentity.la \
41 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 41 $(top_builddir)/src/statistics/libgnunetstatistics.la \
42 $(top_builddir)/src/credential/libgnunetcredential.la \
42 $(top_builddir)/src/gns/libgnunetgns.la \ 43 $(top_builddir)/src/gns/libgnunetgns.la \
43 $(GN_LIBINTL) \ 44 $(GN_LIBINTL) \
44 -ljansson 45 -ljansson
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c
index d72b92c0f..e8ea487f4 100644
--- a/src/identity-provider/gnunet-service-identity-provider.c
+++ b/src/identity-provider/gnunet-service-identity-provider.c
@@ -30,6 +30,7 @@
30#include "gnunet_identity_service.h" 30#include "gnunet_identity_service.h"
31#include "gnunet_gnsrecord_lib.h" 31#include "gnunet_gnsrecord_lib.h"
32#include "gnunet_namestore_service.h" 32#include "gnunet_namestore_service.h"
33#include "gnunet_credential_service.h"
33#include "gnunet_statistics_service.h" 34#include "gnunet_statistics_service.h"
34#include "gnunet_gns_service.h" 35#include "gnunet_gns_service.h"
35#include "gnunet_signatures.h" 36#include "gnunet_signatures.h"
@@ -93,6 +94,11 @@ static struct GNUNET_NAMESTORE_Handle *ns_handle;
93static struct GNUNET_GNS_Handle *gns_handle; 94static struct GNUNET_GNS_Handle *gns_handle;
94 95
95/** 96/**
97 * Credential handle
98 */
99static struct GNUNET_CREDENTIAL_Handle *credential_handle;
100
101/**
96 * Namestore qe 102 * Namestore qe
97 */ 103 */
98static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; 104static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
@@ -153,6 +159,23 @@ static struct GNUNET_STATISTICS_Handle *stats;
153 */ 159 */
154static const struct GNUNET_CONFIGURATION_Handle *cfg; 160static const struct GNUNET_CONFIGURATION_Handle *cfg;
155 161
162struct VerifiedAttributeEntry
163{
164 /**
165 * DLL
166 */
167 struct VerifiedAttributeEntry *prev;
168
169 /**
170 * DLL
171 */
172 struct VerifiedAttributeEntry *next;
173
174 /**
175 * Attribute Name
176 */
177 char* name;
178};
156 179
157struct ExchangeHandle 180struct ExchangeHandle
158{ 181{
@@ -227,6 +250,16 @@ struct IssueHandle
227 char *scopes; 250 char *scopes;
228 251
229 /** 252 /**
253 * DLL
254 */
255 struct VerifiedAttributeEntry *v_attr_head;
256
257 /**
258 * DLL
259 */
260 struct VerifiedAttributeEntry *v_attr_tail;
261
262 /**
230 * nonce 263 * nonce
231 */ 264 */
232 uint64_t nonce; 265 uint64_t nonce;
@@ -237,6 +270,11 @@ struct IssueHandle
237 struct GNUNET_NAMESTORE_ZoneIterator *ns_it; 270 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
238 271
239 /** 272 /**
273 * Cred request
274 */
275 struct GNUNET_CREDENTIAL_Request *credential_request;
276
277 /**
240 * Attribute map 278 * Attribute map
241 */ 279 */
242 struct GNUNET_CONTAINER_MultiHashMap *attr_map; 280 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
@@ -876,6 +914,8 @@ cleanup()
876 GNUNET_IDENTITY_disconnect (identity_handle); 914 GNUNET_IDENTITY_disconnect (identity_handle);
877 if (NULL != gns_handle) 915 if (NULL != gns_handle)
878 GNUNET_GNS_disconnect (gns_handle); 916 GNUNET_GNS_disconnect (gns_handle);
917 if (NULL != credential_handle)
918 GNUNET_CREDENTIAL_disconnect (credential_handle);
879 if (NULL != ns_it) 919 if (NULL != ns_it)
880 GNUNET_NAMESTORE_zone_iteration_stop (ns_it); 920 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
881 if (NULL != ns_qe) 921 if (NULL != ns_qe)
@@ -1114,6 +1154,108 @@ sign_and_return_token (void *cls)
1114 GNUNET_free (token_metadata); 1154 GNUNET_free (token_metadata);
1115} 1155}
1116 1156
1157/**
1158 * Credential to JSON
1159 * @param cred the credential
1160 * @return the resulting json, NULL if failed
1161 */
1162static json_t*
1163credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred)
1164{
1165 char *issuer;
1166 char *subject;
1167 char *signature;
1168 char attribute[cred->issuer_attribute_len + 1];
1169 json_t *cred_obj;
1170
1171 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
1172 if (NULL == issuer)
1173 {
1174 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1175 "Issuer in credential malformed\n");
1176 return NULL;
1177 }
1178 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
1179 if (NULL == subject)
1180 {
1181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1182 "Subject in credential malformed\n");
1183 GNUNET_free (issuer);
1184 return NULL;
1185 }
1186 GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
1187 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
1188 &signature);
1189 memcpy (attribute,
1190 cred->issuer_attribute,
1191 cred->issuer_attribute_len);
1192 attribute[cred->issuer_attribute_len] = '\0';
1193 cred_obj = json_object ();
1194 json_object_set_new (cred_obj, "issuer", json_string (issuer));
1195 json_object_set_new (cred_obj, "subject", json_string (subject));
1196 json_object_set_new (cred_obj, "attribute", json_string (attribute));
1197 json_object_set_new (cred_obj, "signature", json_string (signature));
1198 json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us));
1199 GNUNET_free (issuer);
1200 GNUNET_free (subject);
1201 GNUNET_free (signature);
1202 return cred_obj;
1203}
1204
1205
1206static void
1207handle_vattr_collection (void* cls,
1208 unsigned int d_count,
1209 struct GNUNET_CREDENTIAL_Delegation *dc,
1210 unsigned int c_count,
1211 struct GNUNET_CREDENTIAL_Credential *cred)
1212{
1213 struct IssueHandle *handle = cls;
1214 struct VerifiedAttributeEntry *vattr;
1215 json_t *cred_json;
1216 json_t *cred_array;
1217 int i;
1218 handle->credential_request = NULL;
1219
1220 if (NULL == cred)
1221 {
1222 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1223 return;
1224 }
1225 cred_array = json_array();
1226 for (i=0;i<c_count;i++)
1227 {
1228 cred_json = credential_to_json (cred);
1229 if (NULL == cred_json)
1230 continue;
1231 json_array_append (cred_array, cred_json);
1232 token_add_attr_json (handle->token,
1233 handle->v_attr_head->name,
1234 cred_array);
1235 }
1236 json_decref (cred_array);
1237 vattr = handle->v_attr_head;
1238
1239 GNUNET_CONTAINER_DLL_remove (handle->v_attr_head,
1240 handle->v_attr_tail,
1241 vattr);
1242 GNUNET_free (vattr->name);
1243 GNUNET_free (vattr);
1244
1245 if (NULL == handle->v_attr_head)
1246 {
1247 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1248 return;
1249 }
1250 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
1251 &handle->aud_key,
1252 handle->v_attr_head->name,
1253 &handle->iss_key,
1254 &handle_vattr_collection,
1255 handle);
1256
1257}
1258
1117 1259
1118static void 1260static void
1119attr_collect_error (void *cls) 1261attr_collect_error (void *cls)
@@ -1133,10 +1275,19 @@ attr_collect_finished (void *cls)
1133 1275
1134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n"); 1276 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n");
1135 handle->ns_it = NULL; 1277 handle->ns_it = NULL;
1136 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1137}
1138
1139 1278
1279 if (NULL == handle->v_attr_head)
1280 {
1281 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1282 return;
1283 }
1284 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
1285 &handle->aud_key,
1286 handle->v_attr_head->name,
1287 &handle->iss_key,
1288 &handle_vattr_collection,
1289 handle);
1290}
1140/** 1291/**
1141 * Collect attributes for token 1292 * Collect attributes for token
1142 */ 1293 */
@@ -1532,11 +1683,14 @@ handle_issue_message (void *cls,
1532 const char *scopes; 1683 const char *scopes;
1533 char *scopes_tmp; 1684 char *scopes_tmp;
1534 char *scope; 1685 char *scope;
1686 const char *v_attrs;
1535 struct GNUNET_HashCode key; 1687 struct GNUNET_HashCode key;
1536 struct IssueHandle *issue_handle; 1688 struct IssueHandle *issue_handle;
1689 struct VerifiedAttributeEntry *vattr_entry;
1537 struct GNUNET_SERVICE_Client *client = cls; 1690 struct GNUNET_SERVICE_Client *client = cls;
1538 1691
1539 scopes = (const char *) &im[1]; 1692 scopes = (const char *) &im[1];
1693 v_attrs = (const char *) &im[1] + ntohl(im->scope_len);
1540 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle)); 1694 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle));
1541 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5, 1695 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
1542 GNUNET_NO); 1696 GNUNET_NO);
@@ -1553,6 +1707,22 @@ handle_issue_message (void *cls,
1553 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); 1707 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1554 } 1708 }
1555 GNUNET_free (scopes_tmp); 1709 GNUNET_free (scopes_tmp);
1710 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1711 "VATTRS: %s\n", v_attrs);
1712 scopes_tmp = GNUNET_strdup (v_attrs);
1713
1714 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ","))
1715 {
1716 vattr_entry = GNUNET_new (struct VerifiedAttributeEntry);
1717 vattr_entry->name = GNUNET_strdup (scope);
1718 GNUNET_CONTAINER_DLL_insert (issue_handle->v_attr_head,
1719 issue_handle->v_attr_tail,
1720 vattr_entry);
1721 }
1722 GNUNET_free (scopes_tmp);
1723
1724
1725
1556 issue_handle->r_id = im->id; 1726 issue_handle->r_id = im->id;
1557 issue_handle->aud_key = im->aud_key; 1727 issue_handle->aud_key = im->aud_key;
1558 issue_handle->iss_key = im->iss_key; 1728 issue_handle->iss_key = im->iss_key;
@@ -1606,7 +1776,11 @@ run (void *cls,
1606 { 1776 {
1607 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns"); 1777 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1608 } 1778 }
1609 1779 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
1780 if (NULL == credential_handle)
1781 {
1782 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
1783 }
1610 identity_handle = GNUNET_IDENTITY_connect (cfg, 1784 identity_handle = GNUNET_IDENTITY_connect (cfg,
1611 &list_ego, 1785 &list_ego,
1612 NULL); 1786 NULL);
diff --git a/src/identity-provider/identity_provider.h b/src/identity-provider/identity_provider.h
index 6fe6102c8..9d2675c35 100644
--- a/src/identity-provider/identity_provider.h
+++ b/src/identity-provider/identity_provider.h
@@ -134,6 +134,11 @@ struct IssueMessage
134 uint64_t nonce; 134 uint64_t nonce;
135 135
136 /** 136 /**
137 * Length of scopes
138 */
139 uint64_t scope_len;
140
141 /**
137 * Expiration of token in NBO. 142 * Expiration of token in NBO.
138 */ 143 */
139 struct GNUNET_TIME_AbsoluteNBO expiration; 144 struct GNUNET_TIME_AbsoluteNBO expiration;
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c
index 1d242f66a..abee41d17 100644
--- a/src/identity-provider/identity_provider_api.c
+++ b/src/identity-provider/identity_provider_api.c
@@ -430,6 +430,7 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
430 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, 430 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key,
431 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 431 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
432 const char* scopes, 432 const char* scopes,
433 const char* vattr,
433 struct GNUNET_TIME_Absolute expiration, 434 struct GNUNET_TIME_Absolute expiration,
434 uint64_t nonce, 435 uint64_t nonce,
435 GNUNET_IDENTITY_PROVIDER_IssueCallback cb, 436 GNUNET_IDENTITY_PROVIDER_IssueCallback cb,
@@ -440,6 +441,8 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
440 size_t slen; 441 size_t slen;
441 442
442 slen = strlen (scopes) + 1; 443 slen = strlen (scopes) + 1;
444 if (NULL != vattr)
445 slen += strlen (vattr) + 1;
443 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage)) 446 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage))
444 { 447 {
445 GNUNET_break (0); 448 GNUNET_break (0);
@@ -456,9 +459,14 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
456 im->id = op->r_id; 459 im->id = op->r_id;
457 im->iss_key = *iss_key; 460 im->iss_key = *iss_key;
458 im->aud_key = *aud_key; 461 im->aud_key = *aud_key;
462 im->scope_len = htonl (strlen(scopes)+1);
459 im->nonce = htonl (nonce); 463 im->nonce = htonl (nonce);
460 im->expiration = GNUNET_TIME_absolute_hton (expiration); 464 im->expiration = GNUNET_TIME_absolute_hton (expiration);
461 GNUNET_memcpy (&im[1], scopes, slen); 465 GNUNET_memcpy (&im[1], scopes, strlen(scopes));
466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
467 "VATTRAPI: %s\n", vattr);
468 if (NULL != vattr)
469 GNUNET_memcpy ((char*)&im[1]+strlen(scopes)+1, vattr, strlen(vattr));
462 GNUNET_CONTAINER_DLL_insert_tail (id->op_head, 470 GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
463 id->op_tail, 471 id->op_tail,
464 op); 472 op);
diff --git a/src/identity-provider/identity_token.c b/src/identity-provider/identity_token.c
index 31249840b..6794e373c 100644
--- a/src/identity-provider/identity_token.c
+++ b/src/identity-provider/identity_token.c
@@ -257,6 +257,38 @@ token_destroy (struct IdentityToken *token)
257} 257}
258 258
259void 259void
260token_add_attr_json (struct IdentityToken *token,
261 const char* key,
262 json_t* value)
263{
264 struct TokenAttr *attr;
265 struct TokenAttrValue *new_val;
266 GNUNET_assert (NULL != token);
267
268 new_val = GNUNET_malloc (sizeof (struct TokenAttrValue));
269 new_val->json_value = value;
270 json_incref(value);
271 for (attr = token->attr_head; NULL != attr; attr = attr->next)
272 {
273 if (0 == strcmp (key, attr->name))
274 break;
275 }
276
277 if (NULL == attr)
278 {
279 attr = GNUNET_malloc (sizeof (struct TokenAttr));
280 attr->name = GNUNET_strdup (key);
281 GNUNET_CONTAINER_DLL_insert (token->attr_head,
282 token->attr_tail,
283 attr);
284 }
285
286 GNUNET_CONTAINER_DLL_insert (attr->val_head,
287 attr->val_tail,
288 new_val);
289}
290
291void
260token_add_attr (struct IdentityToken *token, 292token_add_attr (struct IdentityToken *token,
261 const char* key, 293 const char* key,
262 const char* value) 294 const char* value)
@@ -345,17 +377,23 @@ parse_json_payload(const char* payload_base64,
345 if (json_is_integer (arr_value)) 377 if (json_is_integer (arr_value))
346 token_add_attr_int (token, key, 378 token_add_attr_int (token, key,
347 json_integer_value (arr_value)); 379 json_integer_value (arr_value));
348 else 380 else if (json_is_string (arr_value))
349 token_add_attr (token, 381 token_add_attr (token,
350 key, 382 key,
351 json_string_value (arr_value)); 383 json_string_value (arr_value));
384 else
385 token_add_attr_json (token,
386 key,
387 (json_t*)arr_value);
352 } 388 }
353 } else { 389 } else {
354 if (json_is_integer (value)) 390 if (json_is_integer (value))
355 token_add_attr_int (token, key, 391 token_add_attr_int (token, key,
356 json_integer_value (value)); 392 json_integer_value (value));
357 else 393 else if (json_is_string (value))
358 token_add_attr (token, key, json_string_value (value)); 394 token_add_attr (token, key, json_string_value (value));
395 else
396 token_add_attr_json (token, key, (json_t*)value);
359 } 397 }
360 } 398 }
361 399
@@ -424,7 +462,7 @@ token_parse (const char* raw_data,
424 GNUNET_asprintf (&tmp_buf, "%s", raw_data); 462 GNUNET_asprintf (&tmp_buf, "%s", raw_data);
425 ecdh_pubkey_str = strtok (tmp_buf, ","); 463 ecdh_pubkey_str = strtok (tmp_buf, ",");
426 enc_token_str = strtok (NULL, ","); 464 enc_token_str = strtok (NULL, ",");
427 465
428 GNUNET_assert (NULL != ecdh_pubkey_str); 466 GNUNET_assert (NULL != ecdh_pubkey_str);
429 GNUNET_assert (NULL != enc_token_str); 467 GNUNET_assert (NULL != enc_token_str);
430 468
@@ -476,7 +514,11 @@ create_json_payload (const struct IdentityToken *token)
476 json_object_set_new (root, 514 json_object_set_new (root,
477 attr->name, 515 attr->name,
478 json_string (val->value)); 516 json_string (val->value));
479 } else { 517 } else if (NULL != val->json_value) {
518 json_object_set (root,
519 attr->name,
520 val->json_value);
521 }else {
480 json_object_set_new (root, 522 json_object_set_new (root,
481 attr->name, 523 attr->name,
482 json_integer (val->int_value)); 524 json_integer (val->int_value));
@@ -715,8 +757,8 @@ ticket_serialize (struct TokenTicket *ticket,
715 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); 757 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET);
716 write_ptr = (char*) &purpose[1]; 758 write_ptr = (char*) &purpose[1];
717 GNUNET_memcpy (write_ptr, 759 GNUNET_memcpy (write_ptr,
718 &ticket->ecdh_pubkey, 760 &ticket->ecdh_pubkey,
719 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); 761 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
720 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); 762 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
721 GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str)); 763 GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str));
722 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key, 764 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key,
@@ -825,7 +867,7 @@ ticket_payload_parse(const char *raw_data,
825 867
826 nonce_str = json_string_value (nonce_json); 868 nonce_str = json_string_value (nonce_json);
827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str); 869 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str);
828 870
829 GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce)); 871 GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce));
830 872
831 *result = ticket_payload_create (nonce, 873 *result = ticket_payload_create (nonce,
diff --git a/src/identity-provider/identity_token.h b/src/identity-provider/identity_token.h
index 7ded6662e..5988bc668 100644
--- a/src/identity-provider/identity_token.h
+++ b/src/identity-provider/identity_token.h
@@ -103,6 +103,11 @@ struct TokenAttrValue
103 * used if NULL == value 103 * used if NULL == value
104 */ 104 */
105 uint64_t int_value; 105 uint64_t int_value;
106
107 /**
108 * Json value
109 */
110 json_t *json_value;
106}; 111};
107 112
108struct TokenTicketPayload 113struct TokenTicketPayload
@@ -213,10 +218,10 @@ token_add_attr_int (struct IdentityToken *token,
213 * @param value the value 218 * @param value the value
214 * 219 *
215 */ 220 */
216 void 221void
217 token_add_json (const struct IdentityToken *token, 222token_add_attr_json (struct IdentityToken *token,
218 const char* key, 223 const char* key,
219 json_t* value); 224 json_t* value);
220 225
221/** 226/**
222 * Serialize a token. The token will be signed and base64 according to the 227 * Serialize a token. The token will be signed and base64 according to the
@@ -234,11 +239,11 @@ token_add_attr_int (struct IdentityToken *token,
234 * 239 *
235 * @return GNUNET_OK on success 240 * @return GNUNET_OK on success
236 */ 241 */
237 int 242int
238 token_serialize (const struct IdentityToken*token, 243token_serialize (const struct IdentityToken*token,
239 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 244 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
240 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdhe_privkey, 245 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdhe_privkey,
241 char **result); 246 char **result);
242 247
243/** 248/**
244 * Parses the serialized token and returns a token 249 * Parses the serialized token and returns a token
@@ -249,10 +254,10 @@ token_add_attr_int (struct IdentityToken *token,
249 * 254 *
250 * @return GNUNET_OK on success 255 * @return GNUNET_OK on success
251 */ 256 */
252 int 257int
253 token_parse (const char* data, 258token_parse (const char* data,
254 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 259 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
255 struct IdentityToken **result); 260 struct IdentityToken **result);
256 261
257/** 262/**
258 * Parses the serialized token and returns a token 263 * Parses the serialized token and returns a token
@@ -283,10 +288,10 @@ token_parse2 (const char* data,
283 * 288 *
284 * @return GNUNET_OK on success 289 * @return GNUNET_OK on success
285 */ 290 */
286 int 291int
287 token_to_string (const struct IdentityToken *token, 292token_to_string (const struct IdentityToken *token,
288 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 293 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
289 char **result); 294 char **result);
290 295
291/** 296/**
292 * 297 *
@@ -316,10 +321,10 @@ ticket_create (uint64_t nonce,
316 * 321 *
317 * @return GNUNET_OK on success 322 * @return GNUNET_OK on success
318 */ 323 */
319 int 324int
320 ticket_serialize (struct TokenTicket *ticket, 325ticket_serialize (struct TokenTicket *ticket,
321 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, 326 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
322 char **result); 327 char **result);
323 328
324/** 329/**
325 * Destroys a ticket 330 * Destroys a ticket
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c
index e03f502ad..cd0c76989 100644
--- a/src/identity-provider/plugin_rest_identity_provider.c
+++ b/src/identity-provider/plugin_rest_identity_provider.c
@@ -110,6 +110,12 @@
110#define GNUNET_IDENTITY_TOKEN_ATTR_LIST "requested_attrs" 110#define GNUNET_IDENTITY_TOKEN_ATTR_LIST "requested_attrs"
111 111
112/** 112/**
113 * Attributes passed to issue request
114 */
115#define GNUNET_IDENTITY_TOKEN_V_ATTR_LIST "requested_verified_attrs"
116
117
118/**
113 * Token expiration string 119 * Token expiration string
114 */ 120 */
115#define GNUNET_IDENTITY_TOKEN_EXP_STRING "expiration" 121#define GNUNET_IDENTITY_TOKEN_EXP_STRING "expiration"
@@ -460,6 +466,7 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
460 char *exp_str; 466 char *exp_str;
461 char *nonce_str; 467 char *nonce_str;
462 char *scopes; 468 char *scopes;
469 char *vattrs;
463 uint64_t time; 470 uint64_t time;
464 uint64_t nonce; 471 uint64_t nonce;
465 472
@@ -536,6 +543,21 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
536 scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 543 scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
537 &key); 544 &key);
538 545
546 //vattrs
547 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST,
548 strlen (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST),
549 &key);
550
551 vattrs = NULL;
552 if ( GNUNET_YES ==
553 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
554 &key) )
555 {
556 vattrs = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
557 &key);
558 }
559
560
539 561
540 //Token audience 562 //Token audience
541 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST, 563 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST,
@@ -547,15 +569,15 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
547 &key) ) 569 &key) )
548 { 570 {
549 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 571 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
550 "Audience missing!\n"); 572 "Audience missing!\n");
551 GNUNET_SCHEDULER_add_now (&do_error, handle); 573 GNUNET_SCHEDULER_add_now (&do_error, handle);
552 return; 574 return;
553 } 575 }
554 audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 576 audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
555 &key); 577 &key);
556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
557 "Audience to issue token for: %s\n", 579 "Audience to issue token for: %s\n",
558 audience); 580 audience);
559 581
560 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 582 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
561 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, 583 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
@@ -581,8 +603,8 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
581 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 603 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
582 &key); 604 &key);
583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
584 "Request nonce: %s\n", 606 "Request nonce: %s\n",
585 nonce_str); 607 nonce_str);
586 GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce)); 608 GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce));
587 609
588 //Get expiration for token from URL parameter 610 //Get expiration for token from URL parameter
@@ -619,6 +641,7 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
619 priv_key, 641 priv_key,
620 &aud_key, 642 &aud_key,
621 scopes, 643 scopes,
644 vattrs,
622 exp_time, 645 exp_time,
623 nonce, 646 nonce,
624 &token_creat_cont, 647 &token_creat_cont,
@@ -739,16 +762,16 @@ token_collect (void *cls,
739 rd[i].data_size); 762 rd[i].data_size);
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data); 763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data);
741 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN, 764 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
742 label); 765 label);
743 issuer = json_string (handle->ego_head->identifier); 766 issuer = json_string (handle->ego_head->identifier);
744 GNUNET_JSONAPI_resource_add_attr (json_resource, 767 GNUNET_JSONAPI_resource_add_attr (json_resource,
745 GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, 768 GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
746 issuer); 769 issuer);
747 json_decref (issuer); 770 json_decref (issuer);
748 token = json_string (data); 771 token = json_string (data);
749 GNUNET_JSONAPI_resource_add_attr (json_resource, 772 GNUNET_JSONAPI_resource_add_attr (json_resource,
750 GNUNET_REST_JSONAPI_IDENTITY_TOKEN, 773 GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
751 token); 774 token);
752 json_decref (token); 775 json_decref (token);
753 776
754 GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); 777 GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
@@ -865,7 +888,7 @@ exchange_cont (void *cls,
865 return; 888 return;
866 } 889 }
867 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 890 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
868 &key); 891 &key);
869 GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &expected_nonce)); 892 GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &expected_nonce));
870 893
871 if (ticket_nonce != expected_nonce) 894 if (ticket_nonce != expected_nonce)
diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h
index e533f6f8c..ba727eb92 100644
--- a/src/include/gnunet_identity_provider_service.h
+++ b/src/include/gnunet_identity_provider_service.h
@@ -126,6 +126,7 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
126 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, 126 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key,
127 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 127 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
128 const char* scope, 128 const char* scope,
129 const char* vattr,
129 struct GNUNET_TIME_Absolute expiration, 130 struct GNUNET_TIME_Absolute expiration,
130 uint64_t nonce, 131 uint64_t nonce,
131 GNUNET_IDENTITY_PROVIDER_IssueCallback cb, 132 GNUNET_IDENTITY_PROVIDER_IssueCallback cb,