aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2017-10-09 14:45:42 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2017-10-09 14:45:42 +0200
commit44f8117be5a2aca8b303943ff016927a35621ed9 (patch)
tree9dbbc53e8c6aecf0429916d33bb79b5bf2cf9da4 /src
parent037bf3d5a227287e4b2e9c4dbb2583f39bd8fa20 (diff)
downloadgnunet-44f8117be5a2aca8b303943ff016927a35621ed9.tar.gz
gnunet-44f8117be5a2aca8b303943ff016927a35621ed9.zip
-improve revocation handling
Diffstat (limited to 'src')
-rw-r--r--src/identity-provider/gnunet-service-identity-provider.c283
-rw-r--r--src/identity-provider/identity_attribute.c25
-rw-r--r--src/identity-provider/identity_attribute.h2
-rw-r--r--src/identity-provider/plugin_identity_provider_sqlite.c54
-rwxr-xr-xsrc/identity-provider/test_idp_attribute.sh5
-rwxr-xr-xsrc/identity-provider/test_idp_issue.sh4
-rw-r--r--src/include/gnunet_identity_provider_plugin.h5
-rw-r--r--src/include/gnunet_identity_provider_service.h5
8 files changed, 228 insertions, 155 deletions
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c
index 2f477370e..364c097b5 100644
--- a/src/identity-provider/gnunet-service-identity-provider.c
+++ b/src/identity-provider/gnunet-service-identity-provider.c
@@ -424,7 +424,8 @@ struct ConsumeTicketHandle
424 * Attributes 424 * Attributes
425 */ 425 */
426 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs; 426 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
427 427
428
428 /** 429 /**
429 * request id 430 * request id
430 */ 431 */
@@ -671,9 +672,11 @@ bootstrap_store_task (void *cls)
671{ 672{
672 struct AbeBootstrapHandle *abh = cls; 673 struct AbeBootstrapHandle *abh = cls;
673 struct GNUNET_GNSRECORD_Data rd[1]; 674 struct GNUNET_GNSRECORD_Data rd[1];
675 char *key;
674 676
675 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key, 677 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
676 (void**)&rd[0].data); 678 (void**)&key);
679 rd[0].data = key;
677 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER; 680 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
678 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; 681 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
679 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? 682 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
@@ -684,7 +687,7 @@ bootstrap_store_task (void *cls)
684 rd, 687 rd,
685 &bootstrap_store_cont, 688 &bootstrap_store_cont,
686 abh); 689 abh);
687 GNUNET_free ((void*)rd[0].data); 690 GNUNET_free (key);
688} 691}
689 692
690/** 693/**
@@ -717,7 +720,7 @@ bootstrap_abe_result (void *cls,
717 for (i=0;i<rd_count;i++) { 720 for (i=0;i<rd_count;i++) {
718 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type) 721 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
719 continue; 722 continue;
720 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data, 723 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key (rd[i].data,
721 rd[i].data_size); 724 rd[i].data_size);
722 abh->proc (abh->proc_cls, abe_key); 725 abh->proc (abh->proc_cls, abe_key);
723 GNUNET_free (abh); 726 GNUNET_free (abh);
@@ -1125,12 +1128,12 @@ reissue_ticket_cont (void *cls,
1125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continue DB iteration\n"); 1128 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continue DB iteration\n");
1126 rh->offset++; 1129 rh->offset++;
1127 GNUNET_assert (GNUNET_SYSERR != (ret = 1130 GNUNET_assert (GNUNET_SYSERR != (ret =
1128 TKT_database->iterate_tickets (TKT_database->cls, 1131 TKT_database->iterate_tickets (TKT_database->cls,
1129 &rh->ticket.identity, 1132 &rh->ticket.identity,
1130 GNUNET_NO, 1133 GNUNET_NO,
1131 rh->offset, 1134 rh->offset,
1132 &ticket_reissue_proc, 1135 &ticket_reissue_proc,
1133 rh))); 1136 rh)));
1134 if (GNUNET_NO == ret) 1137 if (GNUNET_NO == ret)
1135 { 1138 {
1136 send_revocation_finished (rh, GNUNET_OK); 1139 send_revocation_finished (rh, GNUNET_OK);
@@ -1138,6 +1141,8 @@ reissue_ticket_cont (void *cls,
1138 } 1141 }
1139} 1142}
1140 1143
1144static void
1145revocation_reissue_tickets (struct TicketRevocationHandle *rh);
1141 1146
1142 1147
1143/** 1148/**
@@ -1154,14 +1159,17 @@ ticket_reissue_proc (void *cls,
1154{ 1159{
1155 struct TicketRevocationHandle *rh = cls; 1160 struct TicketRevocationHandle *rh = cls;
1156 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; 1161 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1162 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le_rollover;
1157 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; 1163 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1158 struct GNUNET_GNSRECORD_Data code_record[1]; 1164 struct GNUNET_GNSRECORD_Data code_record[1];
1159 struct GNUNET_CRYPTO_AbeKey *rp_key; 1165 struct GNUNET_CRYPTO_AbeKey *rp_key;
1160 char *code_record_data; 1166 char *code_record_data;
1161 char **attr_arr; 1167 char **attr_arr;
1162 char *label; 1168 char *label;
1169 char *policy;
1163 int attrs_len; 1170 int attrs_len;
1164 int i; 1171 int i;
1172 int reissue_ticket;
1165 size_t code_record_len; 1173 size_t code_record_len;
1166 1174
1167 1175
@@ -1173,6 +1181,37 @@ ticket_reissue_proc (void *cls,
1173 cleanup_revoke_ticket_handle (rh); 1181 cleanup_revoke_ticket_handle (rh);
1174 return; 1182 return;
1175 } 1183 }
1184
1185 /*
1186 * Check if any attribute of this ticket intersects with a rollover attribute
1187 */
1188 reissue_ticket = GNUNET_NO;
1189 for (le = attrs->list_head; NULL != le; le = le->next)
1190 {
1191 for (le_rollover = rh->rvk_attrs->list_head;
1192 NULL != le_rollover;
1193 le_rollover = le_rollover->next)
1194 {
1195 if (0 == strcmp (le_rollover->attribute->name,
1196 le->attribute->name))
1197 {
1198 reissue_ticket = GNUNET_YES;
1199 break;
1200 }
1201 }
1202 if (GNUNET_YES == reissue_ticket)
1203 break;
1204 }
1205
1206 if (GNUNET_NO == reissue_ticket)
1207 {
1208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1209 "Skipping ticket.\n");
1210 rh->offset++;
1211 revocation_reissue_tickets (rh);
1212 return;
1213 }
1214
1176 //Create new ABE key for RP 1215 //Create new ABE key for RP
1177 attrs_len = 0; 1216 attrs_len = 0;
1178 1217
@@ -1183,9 +1222,12 @@ ticket_reissue_proc (void *cls,
1183 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); 1222 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1184 i = 0; 1223 i = 0;
1185 for (le = attrs->list_head; NULL != le; le = le->next) { 1224 for (le = attrs->list_head; NULL != le; le = le->next) {
1225 GNUNET_asprintf (&policy, "%s:%lu",
1226 le->attribute->name,
1227 le->attribute->attribute_version);
1186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1187 "Recreating key with %s\n", (char*) le->attribute->name); 1229 "Recreating key with %s\n", policy);
1188 attr_arr[i] = (char*) le->attribute->name; 1230 attr_arr[i] = policy;
1189 i++; 1231 i++;
1190 } 1232 }
1191 attr_arr[i] = NULL; 1233 attr_arr[i] = NULL;
@@ -1214,6 +1256,8 @@ ticket_reissue_proc (void *cls,
1214 code_record, 1256 code_record,
1215 &reissue_ticket_cont, 1257 &reissue_ticket_cont,
1216 rh); 1258 rh);
1259 for (; i > 0; i--)
1260 GNUNET_free (attr_arr[i]);
1217 GNUNET_free (ecdhe_privkey); 1261 GNUNET_free (ecdhe_privkey);
1218 GNUNET_free (label); 1262 GNUNET_free (label);
1219 GNUNET_free (attr_arr); 1263 GNUNET_free (attr_arr);
@@ -1262,30 +1306,43 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
1262 struct GNUNET_GNSRECORD_Data rd[1]; 1306 struct GNUNET_GNSRECORD_Data rd[1];
1263 char* buf; 1307 char* buf;
1264 char* enc_buf; 1308 char* enc_buf;
1309 size_t enc_size;
1310 char* rd_buf;
1265 size_t buf_size; 1311 size_t buf_size;
1312 char* policy;
1313 uint32_t attr_ver;
1266 1314
1267 if (NULL == rh->attrs->list_head) 1315 if (NULL == rh->attrs->list_head)
1268 { 1316 {
1269 revocation_reissue_tickets (rh); 1317 revocation_reissue_tickets (rh);
1270 return; 1318 return;
1271 } 1319 }
1272
1273 buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute); 1320 buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
1274 buf = GNUNET_malloc (buf_size); 1321 buf = GNUNET_malloc (buf_size);
1275
1276 attribute_serialize (rh->attrs->list_head->attribute, 1322 attribute_serialize (rh->attrs->list_head->attribute,
1277 buf); 1323 buf);
1278 1324 rh->attrs->list_head->attribute->attribute_version++;
1325 GNUNET_asprintf (&policy, "%s:%lu", rh->attrs->list_head->attribute->name, rh->attrs->list_head->attribute->attribute_version);
1279 /** 1326 /**
1280 * Encrypt the attribute value and store in namestore 1327 * Encrypt the attribute value and store in namestore
1281 */ 1328 */
1282 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf, 1329 enc_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1283 buf_size, 1330 buf_size,
1284 rh->attrs->list_head->attribute->name, //Policy 1331 policy, //Policy
1285 rh->abe_key, 1332 rh->abe_key,
1286 (void**)&enc_buf); 1333 (void**)&enc_buf);
1287 GNUNET_free (buf); 1334 GNUNET_free (buf);
1288 rd[0].data = enc_buf; 1335 GNUNET_free (policy);
1336 rd[0].data_size = enc_size + sizeof (uint32_t);
1337 rd_buf = GNUNET_malloc (rd[0].data_size);
1338 attr_ver = htonl (rh->attrs->list_head->attribute->attribute_version);
1339 GNUNET_memcpy (rd_buf,
1340 &attr_ver,
1341 sizeof (uint32_t));
1342 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1343 enc_buf,
1344 enc_size);
1345 rd[0].data = rd_buf;
1289 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; 1346 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1290 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; 1347 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1291 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? 1348 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
@@ -1297,7 +1354,7 @@ reenc_next_attribute (struct TicketRevocationHandle *rh)
1297 &attr_reenc_cont, 1354 &attr_reenc_cont,
1298 rh); 1355 rh);
1299 GNUNET_free (enc_buf); 1356 GNUNET_free (enc_buf);
1300 1357 GNUNET_free (rd_buf);
1301} 1358}
1302 1359
1303/** 1360/**
@@ -1329,8 +1386,9 @@ attr_reenc_cont (void *cls,
1329 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, 1386 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1330 rh->attrs->list_tail, 1387 rh->attrs->list_tail,
1331 le); 1388 le);
1332 GNUNET_free (le->attribute); 1389 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1333 GNUNET_free (le); 1390 rh->rvk_attrs->list_tail,
1391 le);
1334 1392
1335 1393
1336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1339,18 +1397,17 @@ attr_reenc_cont (void *cls,
1339} 1397}
1340 1398
1341 1399
1342/**
1343 * Start reencryption with newly generated ABE master
1344 */
1345static void 1400static void
1346reenc_after_abe_bootstrap (void *cls, 1401process_attributes_to_update (void *cls,
1347 struct GNUNET_CRYPTO_AbeMasterKey *abe_key) 1402 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1403 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
1348{ 1404{
1349 struct TicketRevocationHandle *rh = cls; 1405 struct TicketRevocationHandle *rh = cls;
1350 GNUNET_free (rh->abe_key);
1351 GNUNET_assert (NULL != abe_key);
1352 rh->abe_key = abe_key;
1353 1406
1407 rh->attrs = attribute_list_dup (attrs);
1408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1409 "Revocation Phase I: Collecting attributes\n");
1410 /* Reencrypt all attributes with new key */
1354 if (NULL == rh->attrs->list_head) 1411 if (NULL == rh->attrs->list_head)
1355 { 1412 {
1356 /* No attributes to reencrypt */ 1413 /* No attributes to reencrypt */
@@ -1359,111 +1416,9 @@ reenc_after_abe_bootstrap (void *cls,
1359 return; 1416 return;
1360 } else { 1417 } else {
1361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1362 "Revocation Phase III: Re-encrypting attributes\n"); 1419 "Revocation Phase II: Re-encrypting attributes\n");
1363 reenc_next_attribute (rh); 1420 reenc_next_attribute (rh);
1364 } 1421 }
1365}
1366
1367
1368/**
1369 * Collecting attributes failed... abort.
1370 */
1371static void
1372revoke_collect_iter_error (void *cls)
1373{
1374 struct TicketRevocationHandle *rh = cls;
1375
1376 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1377 "Failed to iterate over attributes\n");
1378 rh->ns_it = NULL;
1379 send_revocation_finished (rh, GNUNET_SYSERR);
1380 cleanup_revoke_ticket_handle (rh);
1381}
1382
1383/**
1384 * Done decrypting existing attributes.
1385 */
1386static void
1387revoke_collect_iter_finished (void *cls)
1388{
1389 struct TicketRevocationHandle *rh = cls;
1390 rh->ns_it = NULL;
1391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1392 "Revocation Phase II: Invalidating old ABE Master\n");
1393 /* Bootstrap new abe key */
1394 bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES);
1395}
1396
1397/**
1398 * Decrypt existing attribute and store it
1399 * We will revoke it by reencrypting it with a new ABE master key.
1400 */
1401static void
1402revoke_collect_iter_cb (void *cls,
1403 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1404 const char *label,
1405 unsigned int rd_count,
1406 const struct GNUNET_GNSRECORD_Data *rd)
1407{
1408 struct TicketRevocationHandle *rh = cls;
1409 struct GNUNET_CRYPTO_AbeKey *key;
1410 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1411 ssize_t attr_len;
1412 char* attr_ser;
1413 char* attrs[2];
1414
1415 if (rd_count != 1)
1416 {
1417 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1418 return;
1419 }
1420
1421 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1422 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1423 return;
1424 }
1425 attrs[0] = (char*)label;
1426 attrs[1] = 0;
1427 key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key,
1428 attrs);
1429 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1430 rd->data_size,
1431 key,
1432 (void**)&attr_ser);
1433 GNUNET_CRYPTO_cpabe_delete_key (key);
1434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1435 "Attribute to reencrypt: %s\n", label);
1436 le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1437 le->attribute = attribute_deserialize (attr_ser, attr_len);
1438 GNUNET_free (attr_ser);
1439 GNUNET_CONTAINER_DLL_insert_tail (rh->attrs->list_head,
1440 rh->attrs->list_tail,
1441 le);
1442 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1443}
1444
1445/**
1446 * Start attribute collection for revocation
1447 */
1448static void
1449collect_after_abe_bootstrap (void *cls,
1450 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1451{
1452 struct TicketRevocationHandle *rh = cls;
1453
1454 rh->abe_key = abe_key;
1455 GNUNET_assert (NULL != abe_key);
1456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1457 "Revocation Phase I: Collecting attributes\n");
1458 /* Reencrypt all attributes with new key */
1459 rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1460 &rh->identity,
1461 &revoke_collect_iter_error,
1462 rh,
1463 &revoke_collect_iter_cb,
1464 rh,
1465 &revoke_collect_iter_finished,
1466 rh);
1467 1422
1468} 1423}
1469 1424
@@ -1490,7 +1445,6 @@ check_revoke_ticket_message(void *cls,
1490 return GNUNET_OK; 1445 return GNUNET_OK;
1491} 1446}
1492 1447
1493
1494/** 1448/**
1495 * 1449 *
1496 * Handler for ticket revocation message 1450 * Handler for ticket revocation message
@@ -1513,7 +1467,7 @@ handle_revoke_ticket_message (void *cls,
1513 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1]; 1467 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
1514 if (0 < attrs_len) 1468 if (0 < attrs_len)
1515 rh->rvk_attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len); 1469 rh->rvk_attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len);
1516 rh->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); 1470 rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
1517 rh->ticket = *ticket; 1471 rh->ticket = *ticket;
1518 rh->r_id = ntohl (rm->id); 1472 rh->r_id = ntohl (rm->id);
1519 rh->client = idp; 1473 rh->client = idp;
@@ -1523,7 +1477,11 @@ handle_revoke_ticket_message (void *cls,
1523 GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head, 1477 GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head,
1524 idp->revocation_list_tail, 1478 idp->revocation_list_tail,
1525 rh); 1479 rh);
1526 bootstrap_abe (&rh->identity, &collect_after_abe_bootstrap, rh, GNUNET_NO); 1480 TKT_database->get_ticket_attributes (TKT_database->cls,
1481 &rh->ticket,
1482 &process_attributes_to_update,
1483 rh);
1484 //bootstrap_abe (&rh->identity, &collect_after_abe_bootstrap, rh, GNUNET_NO);
1527 GNUNET_SERVICE_client_continue (idp->client); 1485 GNUNET_SERVICE_client_continue (idp->client);
1528 1486
1529} 1487}
@@ -1586,13 +1544,14 @@ process_parallel_lookup2 (void *cls, uint32_t rd_count,
1586 GNUNET_break(0);//TODO 1544 GNUNET_break(0);//TODO
1587 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) 1545 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1588 { 1546 {
1589 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data, 1547 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data + sizeof (uint32_t),
1590 rd->data_size, 1548 rd->data_size - sizeof (uint32_t),
1591 handle->key, 1549 handle->key,
1592 (void**)&data); 1550 (void**)&data);
1593 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry); 1551 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1594 attr_le->attribute = attribute_deserialize (data, 1552 attr_le->attribute = attribute_deserialize (data,
1595 attr_len); 1553 attr_len);
1554 attr_le->attribute->attribute_version = ntohl(*(uint32_t*)rd->data);
1596 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head, 1555 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1597 handle->attrs->list_tail, 1556 handle->attrs->list_tail,
1598 attr_le); 1557 attr_le);
@@ -1829,7 +1788,12 @@ attr_store_task (void *cls)
1829 struct AttributeStoreHandle *as_handle = cls; 1788 struct AttributeStoreHandle *as_handle = cls;
1830 struct GNUNET_GNSRECORD_Data rd[1]; 1789 struct GNUNET_GNSRECORD_Data rd[1];
1831 char* buf; 1790 char* buf;
1791 char* policy;
1792 char* enc_buf;
1793 char* rd_buf;
1794 size_t enc_size;
1832 size_t buf_size; 1795 size_t buf_size;
1796 uint32_t attr_ver;
1833 1797
1834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1835 "Storing attribute\n"); 1799 "Storing attribute\n");
@@ -1839,15 +1803,30 @@ attr_store_task (void *cls)
1839 attribute_serialize (as_handle->attribute, 1803 attribute_serialize (as_handle->attribute,
1840 buf); 1804 buf);
1841 1805
1806 GNUNET_asprintf (&policy,
1807 "%s:%lu",
1808 as_handle->attribute->name,
1809 as_handle->attribute->attribute_version);
1842 /** 1810 /**
1843 * Encrypt the attribute value and store in namestore 1811 * Encrypt the attribute value and store in namestore
1844 */ 1812 */
1845 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf, 1813 enc_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1846 buf_size, 1814 buf_size,
1847 as_handle->attribute->name, //Policy 1815 policy, //Policy
1848 as_handle->abe_key, 1816 as_handle->abe_key,
1849 (void**)&rd[0].data); 1817 (void**)&enc_buf);
1850 GNUNET_free (buf); 1818 GNUNET_free (buf);
1819 GNUNET_free (policy);
1820 rd[0].data_size = enc_size + sizeof (uint32_t);
1821 rd_buf = GNUNET_malloc (rd[0].data_size);
1822 attr_ver = htonl (as_handle->attribute->attribute_version);
1823 GNUNET_memcpy (rd_buf,
1824 &attr_ver,
1825 sizeof (uint32_t));
1826 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1827 enc_buf,
1828 enc_size);
1829 rd[0].data = rd_buf;
1851 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; 1830 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1852 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; 1831 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1853 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? 1832 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
@@ -1858,8 +1837,8 @@ attr_store_task (void *cls)
1858 rd, 1837 rd,
1859 &attr_store_cont, 1838 &attr_store_cont,
1860 as_handle); 1839 as_handle);
1861 GNUNET_free ((void*)rd[0].data); 1840 GNUNET_free (enc_buf);
1862 1841 GNUNET_free (rd_buf);
1863} 1842}
1864 1843
1865 1844
@@ -1982,6 +1961,7 @@ attr_iter_cb (void *cls,
1982 char* attr_ser; 1961 char* attr_ser;
1983 char* attrs[2]; 1962 char* attrs[2];
1984 char* data_tmp; 1963 char* data_tmp;
1964 char* policy;
1985 1965
1986 if (rd_count != 1) 1966 if (rd_count != 1)
1987 { 1967 {
@@ -1993,15 +1973,18 @@ attr_iter_cb (void *cls,
1993 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it); 1973 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1994 return; 1974 return;
1995 } 1975 }
1996 attrs[0] = (char*)label; 1976 GNUNET_asprintf (&policy, "%s:%lu",
1977 label, *(uint32_t*)rd->data);
1978 attrs[0] = policy;
1997 attrs[1] = 0; 1979 attrs[1] = 0;
1998 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key, 1980 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
1999 attrs); 1981 attrs);
2000 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data, 1982 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data+sizeof (uint32_t),
2001 rd->data_size, 1983 rd->data_size-sizeof (uint32_t),
2002 key, 1984 key,
2003 (void**)&attr_ser); 1985 (void**)&attr_ser);
2004 GNUNET_CRYPTO_cpabe_delete_key (key); 1986 GNUNET_CRYPTO_cpabe_delete_key (key);
1987 GNUNET_free (policy);
2005 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2006 "Found attribute: %s\n", label); 1989 "Found attribute: %s\n", label);
2007 env = GNUNET_MQ_msg_extra (arm, 1990 env = GNUNET_MQ_msg_extra (arm,
diff --git a/src/identity-provider/identity_attribute.c b/src/identity-provider/identity_attribute.c
index b90a08e3e..a8d2b27e6 100644
--- a/src/identity-provider/identity_attribute.c
+++ b/src/identity-provider/identity_attribute.c
@@ -125,6 +125,31 @@ attribute_list_deserialize (const char* data,
125 return attrs; 125 return attrs;
126} 126}
127 127
128struct GNUNET_IDENTITY_PROVIDER_AttributeList*
129attribute_list_dup (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
130{
131 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
132 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *result_le;
133 struct GNUNET_IDENTITY_PROVIDER_AttributeList *result;
134 size_t len;
135
136 result = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
137 for (le = attrs->list_head; NULL != le; le = le->next)
138 {
139 result_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
140 len = sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute) + le->attribute->data_size;
141 result_le->attribute = GNUNET_malloc (len);
142 GNUNET_memcpy (result_le->attribute,
143 le->attribute,
144 len);
145 GNUNET_CONTAINER_DLL_insert (result->list_head,
146 result->list_tail,
147 result_le);
148 }
149 return result;
150}
151
152
128void 153void
129attribute_list_destroy (struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) 154attribute_list_destroy (struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
130{ 155{
diff --git a/src/identity-provider/identity_attribute.h b/src/identity-provider/identity_attribute.h
index d44f4c17f..8a8da12f1 100644
--- a/src/identity-provider/identity_attribute.h
+++ b/src/identity-provider/identity_attribute.h
@@ -138,5 +138,7 @@ attribute_new (const char* attr_name,
138 const void* data, 138 const void* data,
139 size_t data_size); 139 size_t data_size);
140 140
141struct GNUNET_IDENTITY_PROVIDER_AttributeList*
142attribute_list_dup (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs);
141 143
142#endif 144#endif
diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c
index c55366214..c87f30e1c 100644
--- a/src/identity-provider/plugin_identity_provider_sqlite.c
+++ b/src/identity-provider/plugin_identity_provider_sqlite.c
@@ -88,6 +88,11 @@ struct Plugin
88 sqlite3_stmt *iterate_tickets; 88 sqlite3_stmt *iterate_tickets;
89 89
90 /** 90 /**
91 * Precompiled SQL to get ticket attributes.
92 */
93 sqlite3_stmt *get_ticket_attrs;
94
95 /**
91 * Precompiled SQL to iterate tickets by audience. 96 * Precompiled SQL to iterate tickets by audience.
92 */ 97 */
93 sqlite3_stmt *iterate_tickets_by_audience; 98 sqlite3_stmt *iterate_tickets_by_audience;
@@ -279,6 +284,11 @@ database_setup (struct Plugin *plugin)
279 (SQLITE_OK != 284 (SQLITE_OK !=
280 sq_prepare (plugin->dbh, 285 sq_prepare (plugin->dbh,
281 "SELECT identity,audience,rnd,attributes" 286 "SELECT identity,audience,rnd,attributes"
287 " FROM identity001tickets WHERE identity=? AND rnd=?",
288 &plugin->get_ticket_attrs)) ||
289 (SQLITE_OK !=
290 sq_prepare (plugin->dbh,
291 "SELECT identity,audience,rnd,attributes"
282 " FROM identity001tickets WHERE identity=?" 292 " FROM identity001tickets WHERE identity=?"
283 " ORDER BY rnd LIMIT 1 OFFSET ?", 293 " ORDER BY rnd LIMIT 1 OFFSET ?",
284 &plugin->iterate_tickets)) || 294 &plugin->iterate_tickets)) ||
@@ -317,6 +327,8 @@ database_shutdown (struct Plugin *plugin)
317 sqlite3_finalize (plugin->iterate_tickets); 327 sqlite3_finalize (plugin->iterate_tickets);
318 if (NULL != plugin->iterate_tickets_by_audience) 328 if (NULL != plugin->iterate_tickets_by_audience)
319 sqlite3_finalize (plugin->iterate_tickets_by_audience); 329 sqlite3_finalize (plugin->iterate_tickets_by_audience);
330 if (NULL != plugin->get_ticket_attrs)
331 sqlite3_finalize (plugin->get_ticket_attrs);
320 result = sqlite3_close (plugin->dbh); 332 result = sqlite3_close (plugin->dbh);
321 if (result == SQLITE_BUSY) 333 if (result == SQLITE_BUSY)
322 { 334 {
@@ -564,6 +576,47 @@ get_ticket_and_call_iterator (struct Plugin *plugin,
564 return ret; 576 return ret;
565} 577}
566 578
579
580/**
581 * Lookup tickets in the datastore.
582 *
583 * @param cls closure (internal context for the plugin)
584 * @param zone private key of the zone
585 * @param label name of the record in the zone
586 * @param iter function to call with the result
587 * @param iter_cls closure for @a iter
588 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
589 */
590static int
591identity_provider_sqlite_ticket_get_attrs (void *cls,
592 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
593 GNUNET_IDENTITY_PROVIDER_TicketIterator iter,
594 void *iter_cls)
595{
596 struct Plugin *plugin = cls;
597 struct GNUNET_SQ_QueryParam params[] = {
598 GNUNET_SQ_query_param_auto_from_type (&ticket->identity),
599 GNUNET_SQ_query_param_uint64 (&ticket->rnd),
600 GNUNET_SQ_query_param_end
601 };
602
603 if (GNUNET_OK !=
604 GNUNET_SQ_bind (plugin->get_ticket_attrs,
605 params))
606 {
607 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
608 "sqlite3_bind_XXXX");
609 GNUNET_SQ_reset (plugin->dbh,
610 plugin->get_ticket_attrs);
611 return GNUNET_SYSERR;
612 }
613 return get_ticket_and_call_iterator (plugin,
614 plugin->get_ticket_attrs,
615 iter,
616 iter_cls);
617}
618
619
567/** 620/**
568 * Iterate over the results for a particular key and zone in the 621 * Iterate over the results for a particular key and zone in the
569 * datastore. Will return at most one result to the iterator. 622 * datastore. Will return at most one result to the iterator.
@@ -653,6 +706,7 @@ libgnunet_plugin_identity_provider_sqlite_init (void *cls)
653 api->store_ticket = &identity_provider_sqlite_store_ticket; 706 api->store_ticket = &identity_provider_sqlite_store_ticket;
654 api->delete_ticket = &identity_provider_sqlite_delete_ticket; 707 api->delete_ticket = &identity_provider_sqlite_delete_ticket;
655 api->iterate_tickets = &identity_provider_sqlite_iterate_tickets; 708 api->iterate_tickets = &identity_provider_sqlite_iterate_tickets;
709 api->get_ticket_attributes = &identity_provider_sqlite_ticket_get_attrs;
656 LOG (GNUNET_ERROR_TYPE_INFO, 710 LOG (GNUNET_ERROR_TYPE_INFO,
657 _("Sqlite database running\n")); 711 _("Sqlite database running\n"));
658 return api; 712 return api;
diff --git a/src/identity-provider/test_idp_attribute.sh b/src/identity-provider/test_idp_attribute.sh
index 0b0436ede..7e86ae532 100755
--- a/src/identity-provider/test_idp_attribute.sh
+++ b/src/identity-provider/test_idp_attribute.sh
@@ -24,11 +24,12 @@ which timeout &> /dev/null && DO_TIMEOUT="timeout 30"
24 24
25TEST_ATTR="test" 25TEST_ATTR="test"
26gnunet-arm -s -c test_idp.conf 26gnunet-arm -s -c test_idp.conf
27gnunet-arm -i rest -c test_idp.conf 27#gnunet-arm -i rest -c test_idp.conf
28gnunet-identity -C testego -c test_idp.conf 28gnunet-identity -C testego -c test_idp.conf
29gnunet-identity -C rpego -c test_idp.conf 29gnunet-identity -C rpego -c test_idp.conf
30TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}') 30TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}')
31gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf 31gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf
32gnunet-idp -e testego -a name -V John -c test_idp.conf 32gnunet-idp -e testego -a name -V John -c test_idp.conf
33curl localhost:7776/idp/attributes/testego 33gnunet-idp -e testego -D -c test_idp.conf
34#curl localhost:7776/idp/attributes/testego
34gnunet-arm -e -c test_idp.conf 35gnunet-arm -e -c test_idp.conf
diff --git a/src/identity-provider/test_idp_issue.sh b/src/identity-provider/test_idp_issue.sh
index bf5783c9d..26c490c76 100755
--- a/src/identity-provider/test_idp_issue.sh
+++ b/src/identity-provider/test_idp_issue.sh
@@ -24,7 +24,7 @@ which timeout &> /dev/null && DO_TIMEOUT="timeout 30"
24 24
25TEST_ATTR="test" 25TEST_ATTR="test"
26gnunet-arm -s -c test_idp.conf 26gnunet-arm -s -c test_idp.conf
27#gnunet-arm -i rest -c test_idp.conf 27gnunet-arm -i rest -c test_idp.conf
28gnunet-identity -C testego -c test_idp.conf 28gnunet-identity -C testego -c test_idp.conf
29gnunet-identity -C rpego -c test_idp.conf 29gnunet-identity -C rpego -c test_idp.conf
30SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}') 30SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}')
@@ -35,4 +35,4 @@ gnunet-idp -e testego -a name -V John -c test_idp.conf > /dev/null 2>&1
35TICKET=$(gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf | awk '{print $1}') 35TICKET=$(gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf | awk '{print $1}')
36#curl http://localhost:7776/idp/attributes/testego 36#curl http://localhost:7776/idp/attributes/testego
37echo "Ticket: $TICKET" 37echo "Ticket: $TICKET"
38gnunet-arm -e -c test_idp.conf 38#gnunet-arm -e -c test_idp.conf
diff --git a/src/include/gnunet_identity_provider_plugin.h b/src/include/gnunet_identity_provider_plugin.h
index e34ed3f1a..c0a258ab6 100644
--- a/src/include/gnunet_identity_provider_plugin.h
+++ b/src/include/gnunet_identity_provider_plugin.h
@@ -105,7 +105,10 @@ struct GNUNET_IDENTITY_PROVIDER_PluginFunctions
105 uint64_t offset, 105 uint64_t offset,
106 GNUNET_IDENTITY_PROVIDER_TicketIterator iter, void *iter_cls); 106 GNUNET_IDENTITY_PROVIDER_TicketIterator iter, void *iter_cls);
107 107
108 108 int (*get_ticket_attributes) (void* cls,
109 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
110 GNUNET_IDENTITY_PROVIDER_TicketIterator iter,
111 void *iter_cls);
109}; 112};
110 113
111 114
diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h
index fa4d4536c..d17a1cc9c 100644
--- a/src/include/gnunet_identity_provider_service.h
+++ b/src/include/gnunet_identity_provider_service.h
@@ -114,6 +114,11 @@ struct GNUNET_IDENTITY_PROVIDER_Attribute
114 uint32_t attribute_type; 114 uint32_t attribute_type;
115 115
116 /** 116 /**
117 * Attribute version
118 */
119 uint32_t attribute_version;
120
121 /**
117 * Number of bytes in @e data. 122 * Number of bytes in @e data.
118 */ 123 */
119 size_t data_size; 124 size_t data_size;