aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2020-05-10 11:28:00 +0200
committerMartin Schanzenbach <mschanzenbach@posteo.de>2020-05-10 11:28:00 +0200
commit63c371cfbd8c6297a17dab9190ad650e93ad9053 (patch)
treedb3c57f53788aa55d36991a200a2688edf664eee /src/reclaim
parent9a323e17b449ff2ac09336e11263c6cca00a45ea (diff)
downloadgnunet-63c371cfbd8c6297a17dab9190ad650e93ad9053.tar.gz
gnunet-63c371cfbd8c6297a17dab9190ad650e93ad9053.zip
separate id_token and userinfo claims requests
Diffstat (limited to 'src/reclaim')
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c238
1 files changed, 190 insertions, 48 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index ad8e373fe..563bdd749 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -426,9 +426,14 @@ struct RequestHandle
426 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; 426 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it;
427 427
428 /** 428 /**
429 * Attribute claim list 429 * Attribute claim list for id_token
430 */ 430 */
431 struct GNUNET_RECLAIM_AttributeList *attr_list; 431 struct GNUNET_RECLAIM_AttributeList *attr_idtoken_list;
432
433 /**
434 * Attribute claim list for userinfo
435 */
436 struct GNUNET_RECLAIM_AttributeList *attr_userinfo_list;
432 437
433 /** 438 /**
434 * Attestation list 439 * Attestation list
@@ -577,8 +582,10 @@ cleanup_handle (struct RequestHandle *handle)
577 json_decref (handle->oidc->response); 582 json_decref (handle->oidc->response);
578 GNUNET_free (handle->oidc); 583 GNUNET_free (handle->oidc);
579 } 584 }
580 if (NULL!=handle->attr_list) 585 if (NULL!=handle->attr_idtoken_list)
581 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list); 586 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_idtoken_list);
587 if (NULL!=handle->attr_userinfo_list)
588 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_userinfo_list);
582 if (NULL!=handle->attests_list) 589 if (NULL!=handle->attests_list)
583 GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list); 590 GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list);
584 591
@@ -935,7 +942,7 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
935 sizeof(struct GNUNET_RECLAIM_Ticket)); 942 sizeof(struct GNUNET_RECLAIM_Ticket));
936 code_string = OIDC_build_authz_code (&handle->priv_key, 943 code_string = OIDC_build_authz_code (&handle->priv_key,
937 &handle->ticket, 944 &handle->ticket,
938 handle->attr_list, 945 handle->attr_idtoken_list,
939 handle->attests_list, 946 handle->attests_list,
940 handle->oidc->nonce, 947 handle->oidc->nonce,
941 handle->oidc->code_challenge); 948 handle->oidc->code_challenge);
@@ -970,18 +977,77 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
970} 977}
971 978
972 979
980static struct GNUNET_RECLAIM_AttributeList*
981attribute_list_merge (struct GNUNET_RECLAIM_AttributeList *list_a,
982 struct GNUNET_RECLAIM_AttributeList *list_b)
983{
984 struct GNUNET_RECLAIM_AttributeList *merged_list;
985 struct GNUNET_RECLAIM_AttributeListEntry *le_a;
986 struct GNUNET_RECLAIM_AttributeListEntry *le_b;
987 struct GNUNET_RECLAIM_AttributeListEntry *le_m;
988
989 merged_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
990 for (le_a = list_a->list_head; NULL != le_a; le_a = le_a->next)
991 {
992 le_m = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
993 le_m->attribute = GNUNET_RECLAIM_attribute_new (le_a->attribute->name,
994 &le_a->attribute->
995 attestation,
996 le_a->attribute->type,
997 le_a->attribute->data,
998 le_a->attribute->data_size);
999 le_m->attribute->id = le_a->attribute->id;
1000 le_m->attribute->flag = le_a->attribute->flag;
1001 le_m->attribute->attestation = le_a->attribute->attestation;
1002 GNUNET_CONTAINER_DLL_insert (merged_list->list_head,
1003 merged_list->list_tail,
1004 le_m);
1005 }
1006 le_m = NULL;
1007 for (le_b = list_b->list_head; NULL != le_b; le_b = le_b->next)
1008 {
1009 for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1010 {
1011 if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (&le_m->attribute->id,
1012 &le_b->attribute->id))
1013 break; /** Attribute already in list **/
1014 }
1015 if (NULL != le_m)
1016 continue; /** Attribute already in list **/
1017 le_m = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
1018 le_m->attribute = GNUNET_RECLAIM_attribute_new (le_b->attribute->name,
1019 &le_b->attribute->
1020 attestation,
1021 le_b->attribute->type,
1022 le_b->attribute->data,
1023 le_b->attribute->data_size);
1024 le_m->attribute->id = le_b->attribute->id;
1025 le_m->attribute->flag = le_b->attribute->flag;
1026 le_m->attribute->attestation = le_b->attribute->attestation;
1027 GNUNET_CONTAINER_DLL_insert (merged_list->list_head,
1028 merged_list->list_tail,
1029 le_m);
1030 }
1031 return merged_list;
1032}
1033
1034
973static void 1035static void
974oidc_attest_collect_finished_cb (void *cls) 1036oidc_attest_collect_finished_cb (void *cls)
975{ 1037{
976 struct RequestHandle *handle = cls; 1038 struct RequestHandle *handle = cls;
1039 struct GNUNET_RECLAIM_AttributeList *merged_list;
977 1040
978 handle->attest_it = NULL; 1041 handle->attest_it = NULL;
1042 merged_list = attribute_list_merge (handle->attr_idtoken_list,
1043 handle->attr_userinfo_list);
979 handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp, 1044 handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
980 &handle->priv_key, 1045 &handle->priv_key,
981 &handle->oidc->client_pkey, 1046 &handle->oidc->client_pkey,
982 handle->attr_list, 1047 merged_list,
983 &oidc_ticket_issue_cb, 1048 &oidc_ticket_issue_cb,
984 handle); 1049 handle);
1050 GNUNET_RECLAIM_attribute_list_destroy (merged_list);
985} 1051}
986 1052
987 1053
@@ -995,22 +1061,32 @@ oidc_attest_collect (void *cls,
995{ 1061{
996 struct RequestHandle *handle = cls; 1062 struct RequestHandle *handle = cls;
997 struct GNUNET_RECLAIM_AttributeListEntry *le; 1063 struct GNUNET_RECLAIM_AttributeListEntry *le;
1064 struct GNUNET_RECLAIM_AttestationListEntry *ale;
998 1065
999 for (le = handle->attr_list->list_head; NULL != le; le = le->next) 1066 for (ale = handle->attests_list->list_head; NULL != ale; ale = ale->next)
1067 {
1068 if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&ale->attestation->id,
1069 &attest->id))
1070 continue;
1071 /** Attestation already in list **/
1072 GNUNET_RECLAIM_get_attestations_next (handle->attest_it);
1073 return;
1074 }
1075
1076 for (le = handle->attr_idtoken_list->list_head; NULL != le; le = le->next)
1000 { 1077 {
1001 if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&le->attribute->attestation, 1078 if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&le->attribute->attestation,
1002 &attest->id)) 1079 &attest->id))
1003 { 1080 continue;
1004 struct GNUNET_RECLAIM_AttestationListEntry *ale; 1081 /** Attestation matches for attribute, add **/
1005 ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry); 1082 ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
1006 ale->attestation = GNUNET_RECLAIM_attestation_new (attest->name, 1083 ale->attestation = GNUNET_RECLAIM_attestation_new (attest->name,
1007 attest->type, 1084 attest->type,
1008 attest->data, 1085 attest->data,
1009 attest->data_size); 1086 attest->data_size);
1010 GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head, 1087 GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head,
1011 handle->attests_list->list_tail, 1088 handle->attests_list->list_tail,
1012 ale); 1089 ale);
1013 }
1014 } 1090 }
1015 GNUNET_RECLAIM_get_attestations_next (handle->attest_it); 1091 GNUNET_RECLAIM_get_attestations_next (handle->attest_it);
1016} 1092}
@@ -1023,7 +1099,7 @@ oidc_attr_collect_finished_cb (void *cls)
1023 1099
1024 handle->attr_it = NULL; 1100 handle->attr_it = NULL;
1025 handle->ticket_it = NULL; 1101 handle->ticket_it = NULL;
1026 if (NULL == handle->attr_list->list_head) 1102 if (NULL == handle->attr_idtoken_list->list_head)
1027 { 1103 {
1028 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_SCOPE); 1104 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_SCOPE);
1029 handle->edesc = GNUNET_strdup ("The requested scope is not available."); 1105 handle->edesc = GNUNET_strdup ("The requested scope is not available.");
@@ -1044,48 +1120,112 @@ oidc_attr_collect_finished_cb (void *cls)
1044} 1120}
1045 1121
1046 1122
1047/** 1123static int
1048 * Collects all attributes for an ego if in scope parameter 1124attr_in_claims_request (struct RequestHandle *handle,
1049 */ 1125 const char *attr_name,
1050static void 1126 const char *claims_parameter)
1051oidc_attr_collect (void *cls,
1052 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1053 const struct GNUNET_RECLAIM_Attribute *attr)
1054{ 1127{
1055 struct RequestHandle *handle = cls;
1056 struct GNUNET_RECLAIM_AttributeListEntry *le;
1057 char *scope_variables; 1128 char *scope_variables;
1058 char *scope_variable; 1129 char *scope_variable;
1059 char delimiter[] = " "; 1130 char delimiter[] = " ";
1131 int ret = GNUNET_NO;
1132 json_t *root;
1133 json_error_t error;
1134 json_t *claims_j;
1135 const char *key;
1136 json_t *value;
1060 1137
1061 scope_variables = GNUNET_strdup (handle->oidc->scope); 1138 scope_variables = GNUNET_strdup (handle->oidc->scope);
1062 scope_variable = strtok (scope_variables, delimiter); 1139 scope_variable = strtok (scope_variables, delimiter);
1063 while (NULL != scope_variable) 1140 while (NULL != scope_variable)
1064 { 1141 {
1065 if (0 == strcmp (attr->name, scope_variable)) 1142 if (0 == strcmp (attr_name, scope_variable))
1066 break; 1143 break;
1067 scope_variable = strtok (NULL, delimiter); 1144 scope_variable = strtok (NULL, delimiter);
1068 } 1145 }
1069 if (NULL == scope_variable) 1146 if (NULL != scope_variable)
1147 ret = GNUNET_YES;
1148 GNUNET_free (scope_variables);
1149
1150 /** Try claims parameter if no in scope */
1151 if ((NULL != handle->oidc->claims) &&
1152 (GNUNET_YES != ret))
1070 { 1153 {
1071 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1154 root = json_loads (handle->oidc->claims, JSON_DECODE_ANY, &error);
1072 GNUNET_free (scope_variables); 1155 claims_j = json_object_get (root, claims_parameter);
1073 // We can ignore this 1156 /* obj is a JSON object */
1074 return; 1157 if (NULL != claims_j)
1158 {
1159 json_object_foreach (claims_j, key, value) {
1160 if (0 != strcmp (attr_name, key))
1161 continue;
1162 ret = GNUNET_YES;
1163 break;
1164 }
1165 }
1166 json_decref (root);
1075 } 1167 }
1076 GNUNET_free (scope_variables); 1168 return ret;
1077 le = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry); 1169}
1078 le->attribute = GNUNET_RECLAIM_attribute_new (attr->name, 1170
1079 &attr->attestation, 1171
1080 attr->type, 1172static int
1081 attr->data, 1173attr_in_idtoken_request (struct RequestHandle *handle,
1082 attr->data_size); 1174 const char *attr_name)
1083 le->attribute->id = attr->id; 1175{
1084 le->attribute->flag = attr->flag; 1176 return attr_in_claims_request (handle, attr_name, "id_token");
1085 le->attribute->attestation = attr->attestation; 1177}
1086 GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, 1178
1087 handle->attr_list->list_tail, 1179
1088 le); 1180static int
1181attr_in_userinfo_request (struct RequestHandle *handle,
1182 const char *attr_name)
1183{
1184 return attr_in_claims_request (handle, attr_name, "userinfo");
1185}
1186
1187
1188/**
1189 * Collects all attributes for an ego if in scope parameter
1190 */
1191static void
1192oidc_attr_collect (void *cls,
1193 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1194 const struct GNUNET_RECLAIM_Attribute *attr)
1195{
1196 struct RequestHandle *handle = cls;
1197 struct GNUNET_RECLAIM_AttributeListEntry *le;
1198 if (GNUNET_YES == attr_in_idtoken_request (handle, attr->name))
1199 {
1200 le = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
1201 le->attribute = GNUNET_RECLAIM_attribute_new (attr->name,
1202 &attr->attestation,
1203 attr->type,
1204 attr->data,
1205 attr->data_size);
1206 le->attribute->id = attr->id;
1207 le->attribute->flag = attr->flag;
1208 le->attribute->attestation = attr->attestation;
1209 GNUNET_CONTAINER_DLL_insert (handle->attr_idtoken_list->list_head,
1210 handle->attr_idtoken_list->list_tail,
1211 le);
1212 }
1213 if (GNUNET_YES == attr_in_userinfo_request (handle, attr->name))
1214 {
1215 le = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
1216 le->attribute = GNUNET_RECLAIM_attribute_new (attr->name,
1217 &attr->attestation,
1218 attr->type,
1219 attr->data,
1220 attr->data_size);
1221 le->attribute->id = attr->id;
1222 le->attribute->flag = attr->flag;
1223 le->attribute->attestation = attr->attestation;
1224 GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head,
1225 handle->attr_userinfo_list->list_tail,
1226 le);
1227 }
1228
1089 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1229 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1090} 1230}
1091 1231
@@ -1143,7 +1283,9 @@ code_redirect (void *cls)
1143 handle->priv_key = 1283 handle->priv_key =
1144 *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); 1284 *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1145 handle->idp = GNUNET_RECLAIM_connect (cfg); 1285 handle->idp = GNUNET_RECLAIM_connect (cfg);
1146 handle->attr_list = 1286 handle->attr_idtoken_list =
1287 GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1288 handle->attr_userinfo_list =
1147 GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 1289 GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1148 handle->attr_it = 1290 handle->attr_it =
1149 GNUNET_RECLAIM_get_attributes_start (handle->idp, 1291 GNUNET_RECLAIM_get_attributes_start (handle->idp,