11#include <stdio.h>
22#include <string.h>
3+ #include <stdbool.h>
34
45#include "../base64.h"
56#include "../dcql.h"
@@ -24,7 +25,22 @@ int AddAllClaims(cJSON *matched_claim_names, cJSON *candidate_paths)
2425 return 0 ;
2526}
2627
27- cJSON * MatchCredential (cJSON * credential , cJSON * credential_store )
28+ cJSON * CreateSingleStringArrayJson (char * string )
29+ {
30+ cJSON * array = cJSON_CreateArray ();
31+ cJSON_AddItemReferenceToArray (array , cJSON_CreateString (string ));
32+ return array ;
33+ }
34+
35+ enum ClaimMatchResult
36+ {
37+ CLAIM_MATCH_UNKNOWN = 0 ,
38+ CLAIM_MATCH_YES = 1 ,
39+ CLAIM_MATCH_NO = -1 ,
40+ };
41+
42+ cJSON *
43+ MatchCredential (cJSON * credential , cJSON * credential_store )
2844{
2945 cJSON * matched_credentials = cJSON_CreateArray ();
3046 char * format = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (credential , "format" ));
@@ -86,14 +102,16 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
86102 cJSON_AddItemReferenceToArray (candidates , curr_candidate );
87103 }
88104 else
89- {
105+ {
90106 cJSON * allowed_iss ;
91- cJSON_ArrayForEach (allowed_iss , iss_allowlist ) {
92- if (cJSON_Compare (allowed_iss , iss_value , cJSON_True )) {
93- printf ("A candidate credential of type %s passed iss allowlist check.\n" , cJSON_GetStringValue (vct_value ));
94- cJSON_AddItemReferenceToArray (candidates , curr_candidate );
95- break ;
96- }
107+ cJSON_ArrayForEach (allowed_iss , iss_allowlist )
108+ {
109+ if (cJSON_Compare (allowed_iss , iss_value , cJSON_True ))
110+ {
111+ printf ("A candidate credential of type %s passed iss allowlist check.\n" , cJSON_GetStringValue (vct_value ));
112+ cJSON_AddItemReferenceToArray (candidates , curr_candidate );
113+ break ;
114+ }
97115 }
98116 }
99117 }
@@ -155,6 +173,19 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
155173 }
156174 else
157175 {
176+ cJSON * matched_claim_paths = cJSON_CreateArray ();
177+
178+ cJSON * phone_number_matched_candidates = cJSON_CreateArray ();
179+ cJSON * carrier_and_subscription_matched_candidates = cJSON_CreateArray ();
180+ cJSON * carrier_matched_candidates = cJSON_CreateArray ();
181+ cJSON * sub_matched_candidates = cJSON_CreateArray ();
182+ cJSON * other_candidates = cJSON_CreateArray ();
183+
184+ cJSON * phone_number_hint_paths = CreateSingleStringArrayJson ("phone_number_hint" );
185+ cJSON * subscription_hint_paths = CreateSingleStringArrayJson ("subscription_hint" );
186+ cJSON * carrier_hint_paths = CreateSingleStringArrayJson ("carrier_hint" );
187+ cJSON * android_carrier_hint_paths = CreateSingleStringArrayJson ("android_carrier_hint" );
188+
158189 if (claim_sets == NULL )
159190 {
160191 printf ("Matching based on provided claims\n" );
@@ -176,7 +207,10 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
176207
177208 cJSON * claim ;
178209 cJSON * candidate_claims = cJSON_GetObjectItemCaseSensitive (candidate , "paths" );
179- int matched_claim_count = 0 ;
210+ enum ClaimMatchResult phone_number_matched = CLAIM_MATCH_UNKNOWN ;
211+ enum ClaimMatchResult carrier_matched = CLAIM_MATCH_UNKNOWN ;
212+ enum ClaimMatchResult android_carrier_matched = CLAIM_MATCH_UNKNOWN ;
213+ enum ClaimMatchResult subscription_matched = CLAIM_MATCH_UNKNOWN ;
180214 cJSON_ArrayForEach (claim , claims )
181215 {
182216 cJSON * claim_values = cJSON_GetObjectItemCaseSensitive (claim , "values" );
@@ -201,6 +235,7 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
201235 break ;
202236 }
203237 }
238+ bool match_claim = 0 ;
204239 if (matched != 0 && curr_claim != NULL )
205240 {
206241 if (claim_values != NULL )
@@ -211,27 +246,63 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
211246 if (cJSON_Compare (v , cJSON_GetObjectItemCaseSensitive (curr_claim , "value" ), cJSON_True ))
212247 {
213248 printf ("- claim value matched.\n" );
214- ++ matched_claim_count ;
249+ match_claim = 1 ;
215250 break ;
216251 }
217252 }
218253 }
219254 else
220255 {
221256 printf ("- claim matched.\n" );
222- ++ matched_claim_count ;
257+ match_claim = 1 ;
223258 }
224- } else {
259+ }
260+ else
261+ {
225262 printf ("- claim did not match\n." );
226263 }
264+ if (matched )
265+ {
266+ enum ClaimMatchResult result = match_claim ? CLAIM_MATCH_YES : CLAIM_MATCH_NO ;
267+ if (cJSON_Compare (paths , phone_number_hint_paths , cJSON_True ))
268+ {
269+ phone_number_matched = result ;
270+ }
271+ else if (cJSON_Compare (paths , subscription_hint_paths , cJSON_True ))
272+ {
273+ subscription_matched = result ;
274+ }
275+ else if (cJSON_Compare (paths , carrier_hint_paths , cJSON_True ))
276+ {
277+ carrier_matched = result ;
278+ }
279+ else if (cJSON_Compare (paths , android_carrier_hint_paths , cJSON_True ))
280+ {
281+ android_carrier_matched = result ;
282+ }
283+ }
227284 }
285+ bool carrier_matched_final = carrier_matched + android_carrier_matched >= 1 ;
228286 cJSON_AddItemReferenceToObject (matched_credential , "matched_claim_names" , matched_claim_names );
229- if (matched_claim_count == cJSON_GetArraySize (claims ))
287+ if (phone_number_matched == CLAIM_MATCH_YES )
288+ {
289+ cJSON_AddItemReferenceToArray (phone_number_matched_candidates , matched_credential );
290+ }
291+ else if (carrier_matched_final && subscription_matched == CLAIM_MATCH_YES )
292+ {
293+ cJSON_AddItemReferenceToArray (carrier_and_subscription_matched_candidates , matched_credential );
294+ }
295+ else if (carrier_matched_final )
296+ {
297+ cJSON_AddItemReferenceToArray (carrier_matched_candidates , matched_credential );
298+ }
299+ else if (subscription_matched == CLAIM_MATCH_YES )
230300 {
231- printf ("Cred matched.\n" );
232- cJSON_AddItemReferenceToArray (matched_credentials , matched_credential );
233- } else {
234- printf ("Cred did not match. Matched claim count: %d, Expected match count: %d\n." , matched_claim_count , cJSON_GetArraySize (claims ));
301+ cJSON_AddItemReferenceToArray (sub_matched_candidates , matched_credential );
302+ }
303+ else
304+ {
305+ cJSON_AddItemReferenceToArray (other_candidates , matched_credential );
235306 }
236307 }
237308 }
@@ -255,6 +326,10 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
255326
256327 cJSON * claim ;
257328 cJSON * candidate_claims = cJSON_GetObjectItemCaseSensitive (candidate , "paths" );
329+ enum ClaimMatchResult phone_number_matched = CLAIM_MATCH_UNKNOWN ;
330+ enum ClaimMatchResult carrier_matched = CLAIM_MATCH_UNKNOWN ;
331+ enum ClaimMatchResult android_carrier_matched = CLAIM_MATCH_UNKNOWN ;
332+ enum ClaimMatchResult subscription_matched = CLAIM_MATCH_UNKNOWN ;
258333 cJSON_ArrayForEach (claim , claims )
259334 {
260335 cJSON * claim_values = cJSON_GetObjectItemCaseSensitive (claim , "values" );
@@ -276,6 +351,7 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
276351 break ;
277352 }
278353 }
354+ bool match_claim = 0 ;
279355 if (matched != 0 && curr_claim != NULL )
280356 {
281357 if (claim_values != NULL )
@@ -285,17 +361,41 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
285361 {
286362 if (cJSON_Compare (v , cJSON_GetObjectItemCaseSensitive (curr_claim , "value" ), cJSON_True ))
287363 {
288- cJSON_AddItemReferenceToObject ( matched_claim_ids , claim_id , cJSON_CreateString ( "PLACEHOLDER" )) ;
364+ match_claim = 1 ;
289365 break ;
290366 }
291367 }
292368 }
293369 else
294370 {
295- cJSON_AddItemReferenceToObject (matched_claim_ids , claim_id , cJSON_CreateString ("PLACEHOLDER" ));
371+ match_claim = 1 ;
372+ }
373+ }
374+ if (matched )
375+ {
376+ enum ClaimMatchResult result = CLAIM_MATCH_YES ;
377+ cJSON_AddItemReferenceToObject (matched_claim_ids , claim_id , cJSON_CreateString ("PLACEHOLDER" ));
378+ if (cJSON_Compare (paths , phone_number_hint_paths , cJSON_True ))
379+ {
380+ phone_number_matched = result ;
381+ }
382+ else if (cJSON_Compare (paths , subscription_hint_paths , cJSON_True ))
383+ {
384+ subscription_matched = result ;
385+ }
386+ else if (cJSON_Compare (paths , carrier_hint_paths , cJSON_True ))
387+ {
388+ carrier_matched = result ;
389+ }
390+ else if (cJSON_Compare (paths , android_carrier_hint_paths , cJSON_True ))
391+ {
392+ android_carrier_matched = result ;
296393 }
297394 }
298395 }
396+
397+ bool carrier_matched_final = carrier_matched + android_carrier_matched >= 1 ;
398+
299399 cJSON * claim_set ;
300400 cJSON_ArrayForEach (claim_set , claim_sets )
301401 {
@@ -317,8 +417,50 @@ cJSON *MatchCredential(cJSON *credential, cJSON *credential_store)
317417 break ;
318418 }
319419 }
420+ if (phone_number_matched == CLAIM_MATCH_YES )
421+ {
422+ cJSON_AddItemReferenceToArray (phone_number_matched_candidates , matched_credential );
423+ }
424+ else if (carrier_matched_final && subscription_matched == CLAIM_MATCH_YES )
425+ {
426+ cJSON_AddItemReferenceToArray (carrier_and_subscription_matched_candidates , matched_credential );
427+ }
428+ else if (carrier_matched_final )
429+ {
430+ cJSON_AddItemReferenceToArray (carrier_matched_candidates , matched_credential );
431+ }
432+ else if (subscription_matched == CLAIM_MATCH_YES )
433+ {
434+ cJSON_AddItemReferenceToArray (sub_matched_candidates , matched_credential );
435+ }
436+ else
437+ {
438+ cJSON_AddItemReferenceToArray (other_candidates , matched_credential );
439+ }
320440 }
321441 }
442+
443+ cJSON * c ;
444+ cJSON_ArrayForEach (c , phone_number_matched_candidates )
445+ {
446+ cJSON_AddItemReferenceToArray (matched_credentials , c );
447+ }
448+ cJSON_ArrayForEach (c , carrier_and_subscription_matched_candidates )
449+ {
450+ cJSON_AddItemReferenceToArray (matched_credentials , c );
451+ }
452+ cJSON_ArrayForEach (c , carrier_matched_candidates )
453+ {
454+ cJSON_AddItemReferenceToArray (matched_credentials , c );
455+ }
456+ cJSON_ArrayForEach (c , sub_matched_candidates )
457+ {
458+ cJSON_AddItemReferenceToArray (matched_credentials , c );
459+ }
460+ cJSON_ArrayForEach (c , other_candidates )
461+ {
462+ cJSON_AddItemReferenceToArray (matched_credentials , c );
463+ }
322464 }
323465
324466 return matched_credentials ;
0 commit comments