2 * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include "fido_keys.h"
22 #include "fido_logs.h"
23 #include "fido_uaf_policy_checker.h"
24 #include "fido_json_handler.h"
26 //static _fido_asm_proxy_t*
27 //__dup_asm_proxy(const _fido_asm_proxy_t *src)
29 // _fido_asm_proxy_t *dest = calloc(1, sizeof(_fido_asm_proxy_t));
30 // dest->bin_path = strdup(src->bin_path);
31 // dest->dbus_info = strdup(src->dbus_info);
32 // dest->dbus_interface_name = strdup(src->dbus_interface_name);
33 // dest->dbus_method_name = strdup(src->dbus_method_name);
34 // dest->dbus_obj_path = strdup(src->dbus_obj_path);
35 // dest->vendor = strdup(src->vendor);
37 // dest->dbus_proxy = src->dbus_proxy;
43 _int_cmp(gconstpointer a, gconstpointer b)
45 int int1 = GPOINTER_TO_INT(a);
46 int int2 = GPOINTER_TO_INT(b);
51 _policy_checker_is_matched(_match_criteria_t *match_criteria, fido_authenticator_s *auth_info)
53 _INFO("_policy_checker_is_matched");
55 /* -1 means the int value is not present, so we should ignore that. */
57 /* 1. If any AAID is mentioned in match_criteria, then atleast one AAID should match */
58 GList *aaid_list = match_criteria->aaid_list;
61 (g_list_length(aaid_list)) &&
63 (strlen(auth_info->aaid) > 0)) {
64 aaid_list = g_list_first(aaid_list);
65 if (g_list_find_custom(aaid_list, auth_info->aaid, (GCompareFunc)strcmp) == NULL) {
66 _ERR("AAID match failed");
72 /* 2. If any Vendor ID is mentioned in match_criteria, then atleast one Vendor ID should match */
73 GList *vendor_list = match_criteria->vendor_list;
75 if (vendor_list && auth_info->aaid) {
76 char *auth_aaid = strdup(auth_info->aaid);
77 char *auth_vendor = strtok(auth_aaid, "#");
80 (g_list_length(vendor_list)) &&
82 (strlen(auth_vendor) > 0)) {
83 vendor_list = g_list_first(vendor_list);
84 if (g_list_find_custom(vendor_list, auth_vendor, (GCompareFunc)strcmp) == NULL) {
85 _ERR("Vendor ID match failed");
87 SAFE_DELETE(auth_aaid);
91 SAFE_DELETE(auth_aaid);
94 _INFO("keyid matching");
96 /* 3. If any Key ID is mentioned in match_criteria, then atleast one Key ID should match */
97 GList *key_id_list = match_criteria->key_id_list;
99 if (key_id_list != NULL) {
101 if (auth_info->key_ids == NULL) {
102 _ERR("keyID match failed");
106 GList *auth_key_ids = auth_info->key_ids;
108 GList *common_key_id_list = NULL;
110 key_id_list = g_list_first(key_id_list);
111 auth_key_ids = g_list_first(auth_key_ids);
113 _INFO("match_criteria keyid count = [%d]", g_list_length(key_id_list));
114 _INFO("auth info keyid count = [%d]", g_list_length(auth_key_ids));
116 GList *key_id_iter = g_list_first(key_id_list);
117 while (key_id_iter != NULL) {
118 char *key_id = (char*) (key_id_iter->data);
120 if (g_list_find_custom(auth_key_ids, key_id, (GCompareFunc)strcmp) != NULL) {
121 _INFO("keyid matched [%s]", key_id);
122 common_key_id_list = g_list_append(common_key_id_list, strdup(key_id));
125 key_id_iter = key_id_iter->next;
128 if (common_key_id_list == NULL) {
129 _ERR("keyID match failed");
133 common_key_id_list = g_list_first(common_key_id_list);
135 /*Set common keyIds in match*/
136 g_list_free_full(match_criteria->key_id_list, free);
137 match_criteria->key_id_list = common_key_id_list;
139 _INFO("keyID matched count [%d]", g_list_length(match_criteria->key_id_list));
143 _INFO("User verification matching");
145 /* 4. User verification match */
146 if (match_criteria->user_verification != -1) {
147 if ((match_criteria->user_verification == auth_info->user_verification)
150 ((auth_info->user_verification & _USER_VER_METHOD_ALL) == 0)
152 ((match_criteria->user_verification & _USER_VER_METHOD_ALL) == 0)
154 ((auth_info->user_verification & match_criteria->user_verification) != 0)
157 _INFO("User verification match passed");
159 _ERR("User verification match failed");
164 /* 5. Key protection field bit matching */
165 if ((match_criteria->key_protection != -1) && auth_info->key_protection) {
166 if (((match_criteria->key_protection) && (auth_info->key_protection)) == 0) {
167 _ERR("Key protection match failed");
172 /* 6. Matcher Protection field bit matching */
173 if ((match_criteria->matcher_protection != -1) && auth_info->matcher_protection) {
174 if (((match_criteria->matcher_protection) && (auth_info->matcher_protection)) == 0) {
175 _ERR("Matcher protection match failed");
180 /* 7. Attachment hint field bit matching */
181 if ((match_criteria->attachement_hint != -1) && auth_info->attachment_hint) {
182 if (((match_criteria->attachement_hint) && (auth_info->attachment_hint)) == 0) {
183 _ERR("Attachment hint match failed");
188 /* 8. TC Display field bit matching */
189 if ((match_criteria->tc_display != -1) && auth_info->tc_display) {
190 if (((match_criteria->tc_display) && (auth_info->tc_display)) == 0) {
191 _ERR("Attachment hint match failed");
196 /* 9. If any algo is mentioned in match_criteria, then atleast one algo should match */
197 GList *match_algo_list = match_criteria->auth_algo_list;
198 if (match_algo_list && (g_list_length(match_algo_list))
199 && (auth_info->authentication_algorithm)) {
200 match_algo_list = g_list_first(match_algo_list);
201 if (g_list_find_custom(match_algo_list, GINT_TO_POINTER(auth_info->authentication_algorithm), (GCompareFunc)_int_cmp) == NULL) {
202 _ERR("Algorithm match failed");
207 /* 10. If any assertion scheme is mentioned in match_criteria, then atleast one assertion scheme should match */
208 GList *assertion_list = match_criteria->assertion_scheme_list;
209 if (assertion_list && (g_list_length(assertion_list))
210 && (auth_info->assertion_scheme) && (strlen(auth_info->assertion_scheme) > 0)) {
211 assertion_list = g_list_first(assertion_list);
212 if (g_list_find_custom(assertion_list, auth_info->assertion_scheme, (GCompareFunc)strcmp) == NULL)
214 _ERR("Assertion scheme match failed");
219 /* 11. If any attestation type is mentioned in match_criteria, then atleast one attestation type should match */
220 GList *attestation_type_list = match_criteria->attestation_type_list;
221 if (attestation_type_list && (g_list_length(attestation_type_list))
222 && (auth_info->attestation_types)) {
223 attestation_type_list = g_list_first(attestation_type_list);
224 if (g_list_find_custom(attestation_type_list, GINT_TO_POINTER(auth_info->attestation_types), (GCompareFunc)_int_cmp) == NULL) {
225 _ERR("Attestation type match failed");
230 /* TODO : 12. Auth version */
232 /* TODO : 13. Extension */
234 _INFO("_policy_checker_is_matched true");
240 _get_attestation_type(_match_criteria_t *match_criteria, fido_authenticator_s *auth_info)
242 _INFO("_get_attestation_type");
244 if (match_criteria && match_criteria->attestation_type_list) {
246 GList *match_att_list_iter = g_list_first(match_criteria->attestation_type_list);
247 while (match_att_list_iter != NULL) {
249 int match_att_type = GPOINTER_TO_INT(match_att_list_iter->data);
251 if (auth_info && auth_info->attestation_types) {
253 GList *auth_att_list_iter = g_list_first(auth_info->attestation_types);
254 while (auth_att_list_iter != NULL) {
256 int auth_att_type = GPOINTER_TO_INT(auth_att_list_iter->data);
258 if (match_att_type == auth_att_type) {
259 _INFO("_get_attestation_type end [%d]", match_att_type);
260 return match_att_type;
264 match_att_list_iter = match_att_list_iter->data;
268 if (auth_info->attestation_types != NULL) {
269 GList *att_type_iter = g_list_first(auth_info->attestation_types);
271 /*Returning first attestation type in case policy does not mandate any*/
272 while (att_type_iter != NULL) {
273 int auth_att_type = GPOINTER_TO_INT(att_type_iter->data);
274 _INFO("Returning first attestation type in case policy does not mandate any [%d]", auth_att_type);
275 return auth_att_type;
280 _ERR("_get_attestation_type end");
285 __get_verification_method_string(unsigned long int ver_method)
287 char *ver_str = calloc(1, 128);
289 switch (ver_method) {
291 case _USER_VER_METHOD_PRESENCE:
292 snprintf(ver_str, 127, "%s", "Presence Authenticator");
295 case _USER_VER_METHOD_FINGERPRINT:
296 snprintf(ver_str, 127, "%s", "Fingerprint Authenticator");
299 case _USER_VER_METHOD_PASSCODE:
300 snprintf(ver_str, 127, "%s", "Passcode Authenticator");
303 case _USER_VER_METHOD_VOICE_PRINT:
304 snprintf(ver_str, 127, "%s", "Voice Print Authenticator");
307 case _USER_VER_METHOD_FACE_PRINT:
308 snprintf(ver_str, 127, "%s", "Face Print Authenticator");
311 case _USER_VER_METHOD_LOCATION:
312 snprintf(ver_str, 127, "%s", "Location Authenticator");
315 case _USER_VER_METHOD_EYE_PRINT:
316 snprintf(ver_str, 127, "%s", "Eye Print Authenticator");
319 case _USER_VER_METHOD_PATTERN:
320 snprintf(ver_str, 127, "%s", "Pattern Authenticator");
323 case _USER_VER_METHOD_HAND_PRINT:
324 snprintf(ver_str, 127, "%s", "Hand Print Authenticator");
327 // case _USER_VER_METHOD_NONE:
328 // snprintf(ver_str, "%s", "");
331 case _USER_VER_METHOD_ALL:
332 snprintf(ver_str, 127, "%s", "All Authenticator");
336 snprintf(ver_str, 127, "%s", "Other Type");
344 __copy_string_list(GList *src)
346 RET_IF_FAIL(src != NULL, NULL);
350 GList *iter = g_list_first(src);
351 while (iter != NULL) {
352 char *str = (char*)(iter->data);
353 dest = g_list_append(dest, strdup(str));
362 __copy_png_list(GList *src_list)
364 RET_IF_FAIL(src_list != NULL, NULL);
368 /*fido_display_png_characteristics_descriptor_s list*/
369 GList *iter = g_list_first(src_list);
371 while (iter != NULL) {
372 fido_display_png_characteristics_descriptor_s *src_data =
373 (fido_display_png_characteristics_descriptor_s *)(iter->data);
375 if (src_data != NULL) {
376 fido_display_png_characteristics_descriptor_s *dest_data =
377 calloc(1, sizeof(fido_display_png_characteristics_descriptor_s));
379 dest_data->bit_depth = src_data->bit_depth;
380 dest_data->color_type = src_data->color_type;
381 dest_data->compression = src_data->compression;
382 dest_data->filter = src_data->filter;
383 dest_data->height = src_data->height;
384 dest_data->interlace = src_data->interlace;
385 dest_data->width = src_data->width;
386 /*TODO: dest_data->plte clone*/
387 if (src_data->plte != NULL) {
388 GList *p_iter = g_list_first(src_data->plte);
389 while (p_iter != NULL) {
391 fido_rgb_pallette_entry_s *plte_src_data = (fido_rgb_pallette_entry_s*)(p_iter->data);
392 if (plte_src_data != NULL) {
393 fido_rgb_pallette_entry_s *plte_dest_data = calloc(1, sizeof(fido_rgb_pallette_entry_s));
394 plte_dest_data->r = plte_src_data->r;
395 plte_dest_data->g = plte_src_data->g;
396 plte_dest_data->b = plte_src_data->b;
398 dest_data->plte = g_list_append(dest_data->plte, plte_dest_data);
400 p_iter = p_iter->next;
404 if (dest_data->plte != NULL)
405 dest_data->plte = g_list_first(dest_data->plte);
408 dest = g_list_append(dest, dest_data);
415 dest = g_list_first(dest);
420 /* Returns _matched_auth_data_t list*/
422 _policy_checker_get_matched_auth_list(_policy_t *policy, GList *auth_list)
424 _INFO("_policy_checker_get_matched_auth_list");
427 _INFO("policy is NULL");
429 if (auth_list == NULL)
430 _INFO("auth_list is NULL");
432 RET_IF_FAIL(policy != NULL, NULL);
433 RET_IF_FAIL(auth_list != NULL, NULL);
435 // _match_criteria_t *match_criteria_or = NULL;
436 GList *allowed_list = NULL;
437 GList *disallowed_list = policy->disallowed_list;
438 GList *accepted_list = policy->accepted_list;
440 if (accepted_list != NULL)
441 _INFO("accepted_list count = [%d]", g_list_length(accepted_list));
443 if (disallowed_list != NULL)
444 _INFO("allowed_list count = [%d]", g_list_length(disallowed_list));
446 GList *accepted_list_iter = g_list_first(accepted_list);
447 while (accepted_list_iter != NULL) {
449 GList *accepted_list_internal = (GList *) accepted_list_iter->data;
450 GList *accepted_list_internal_iter = g_list_first(accepted_list_internal);
451 while (accepted_list_internal_iter != NULL) {
452 _match_criteria_t *match_info = (_match_criteria_t *) accepted_list_internal_iter->data;
454 GList *auth_list_iter = g_list_first(auth_list);
455 while (auth_list_iter != NULL) {
456 fido_authenticator_s *authenticator = (fido_authenticator_s*) (auth_list_iter->data);
458 if (_policy_checker_is_matched(match_info, authenticator)) {
459 _INFO("[%s] is matched from allowed list", authenticator->aaid);
461 /*Disallowed list can be NULL, which means put all which are matching with accepted list*/
463 if (disallowed_list != NULL) {
465 GList *disallowed_list_iter = g_list_first(disallowed_list);
466 while (disallowed_list_iter != NULL) {
467 _match_criteria_t *disallowed_match_info = (_match_criteria_t *) disallowed_list_iter->data;
469 if (!_policy_checker_is_matched(disallowed_match_info, authenticator)) {
470 _INFO("[%s] is not in disallowed list", authenticator->aaid);
471 _matched_auth_data_t *matched_auth_data = (_matched_auth_data_t*) calloc(1, sizeof(_matched_auth_data_t));
472 RET_IF_FAIL(matched_auth_data, NULL);
474 /*TODO : ASM must send auth index*/
475 if (authenticator->auth_index != NULL)
476 matched_auth_data->auth_index = strdup(authenticator->auth_index);
478 _ERR("auth index missing");
480 matched_auth_data->att_type = _get_attestation_type(match_info, authenticator);
482 if (authenticator->title != NULL)
483 matched_auth_data->label = strdup(authenticator->title);
485 _ERR("title missing, putting ver method");
486 /*If label is null, set verification method name instead*/
487 matched_auth_data->label = __get_verification_method_string(authenticator->user_verification);
491 if (authenticator->asm_id != NULL)
492 matched_auth_data->asm_id = strdup(authenticator->asm_id);
494 _ERR("Authenticator does not have any ASM ID!!");
496 matched_auth_data->key_ids = __copy_string_list(match_info->key_id_list);
497 /*fido_display_png_characteristics_descriptor_s list*/
498 matched_auth_data->tc_display_png_characteristics =
499 __copy_png_list(authenticator->tc_display_png_characteristics);
501 allowed_list = g_list_append(allowed_list, matched_auth_data);
503 disallowed_list_iter = disallowed_list_iter->next;
507 _INFO("[%s] adding since no disallowed list", authenticator->aaid);
508 _matched_auth_data_t *matched_auth_data = (_matched_auth_data_t*) calloc(1, sizeof(_matched_auth_data_t));
509 RET_IF_FAIL(matched_auth_data, NULL);
511 matched_auth_data->auth_index = strdup(authenticator->auth_index);
512 matched_auth_data->att_type = _get_attestation_type(match_info, authenticator);
513 if (authenticator->title != NULL)
514 matched_auth_data->label = strdup(authenticator->title);
516 _ERR("title missing, putting ver method");
517 /*If label is null, set verification method name instead*/
518 matched_auth_data->label = __get_verification_method_string(authenticator->user_verification);
521 if (authenticator->asm_id != NULL)
522 matched_auth_data->asm_id = strdup(authenticator->asm_id);
524 _ERR("Authenticator does not have any ASM ID!!");
526 matched_auth_data->key_ids = __copy_string_list(match_info->key_id_list);
528 allowed_list = g_list_append(allowed_list, matched_auth_data);
531 auth_list_iter = auth_list_iter->next;
533 accepted_list_internal_iter = accepted_list_internal_iter->next;
535 accepted_list_iter = accepted_list_iter->next;
538 if (allowed_list != NULL)
539 allowed_list = g_list_first(allowed_list);
544 /* Returns _matched_auth_dereg_t list */
546 _policy_checker_get_matched_auth_list_dereg(const char *app_id, GList *input_auth_list, GList *available_auth_list)
550 RET_IF_FAIL(app_id, NULL);
551 RET_IF_FAIL(input_auth_list, NULL);
552 RET_IF_FAIL(available_auth_list, NULL);
556 GList *matched_auth_dereg_list = NULL;
558 GList *input_auth_list_iter = g_list_first(input_auth_list);
559 while (input_auth_list_iter != NULL) {
560 _dereg_auth_info_t *dereg_auth_info = (_dereg_auth_info_t*) (input_auth_list_iter->data);
562 GList *available_auth_list_iter = g_list_first(available_auth_list);
563 while (available_auth_list_iter != NULL) {
564 fido_authenticator_s *authenticator = (fido_authenticator_s*) (available_auth_list_iter->data);
566 if (dereg_auth_info->aaid != NULL)
567 _INFO("Input AAID = [%s]", dereg_auth_info->aaid);
569 if (authenticator->aaid != NULL)
570 _INFO("Authenticator AAID = [%s]", authenticator->aaid);
572 if (dereg_auth_info->aaid && authenticator->aaid && !strcmp(dereg_auth_info->aaid, authenticator->aaid)) {
573 _matched_auth_dereg_t *matched_auth_dereg = (_matched_auth_dereg_t*) calloc(1, sizeof(_matched_auth_dereg_t));
574 RET_IF_FAIL(matched_auth_dereg, NULL);
576 matched_auth_dereg->auth_index = strdup(authenticator->auth_index);
577 matched_auth_dereg->app_id = strdup(app_id);
578 matched_auth_dereg->key_id = strdup(dereg_auth_info->key_id);
579 if (authenticator->asm_id != NULL)
580 matched_auth_dereg->asm_id = strdup(authenticator->asm_id);
582 _ERR("Authenticator does not have any ASM ID!!");
585 matched_auth_dereg_list = g_list_append(matched_auth_dereg_list, matched_auth_dereg);
587 available_auth_list_iter = available_auth_list_iter->next;
589 input_auth_list_iter = input_auth_list_iter->next;
592 return matched_auth_dereg_list;