Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3a125dd authored by Omer Ozer's avatar Omer Ozer
Browse files

Change the flat request matching logic

Currently the flattened request matching logic
does not support subset checks. We need that to
fully support mdoc element matching.

Bug: 272334103
Test: atest FrameworksServicesTests:com.android.server.credentials.CredentialDescriptionRegistryTest
Change-Id: I7904570146426d33dbf8325c01a825787d1648f0
parent 3fd4802d
Loading
Loading
Loading
Loading
+33 −5
Original line number Diff line number Diff line
@@ -25,17 +25,19 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;


import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/** Contains information on what CredentialProvider has what provisioned Credential. */
public class CredentialDescriptionRegistry {

    private static final String FLAT_STRING_SPLIT_REGEX = ";";
    private static final int MAX_ALLOWED_CREDENTIAL_DESCRIPTIONS = 128;
    private static final int MAX_ALLOWED_ENTRIES_PER_PROVIDER = 16;
    @GuardedBy("sLock")
@@ -164,14 +166,16 @@ public class CredentialDescriptionRegistry {
    /** Returns package names and entries of a CredentialProviders that can satisfy a given
     * {@link CredentialDescription}. */
    public Set<FilterResult> getFilteredResultForProvider(String packageName,
            String flatRequestStrings) {
            String flatRequestString) {
        Set<FilterResult> result = new HashSet<>();
        if (!mCredentialDescriptions.containsKey(packageName)) {
            return result;
        }
        Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
        Set<String> unflattenedRequestString = flatStringToSet(flatRequestString);
        for (CredentialDescription containedDescription: currentSet) {
            if (flatRequestStrings.equals(containedDescription.getFlattenedRequestString())) {
            if (checkForMatch(flatStringToSet(containedDescription.getFlattenedRequestString()),
                    unflattenedRequestString)) {
                result.add(new FilterResult(packageName,
                        containedDescription.getFlattenedRequestString(), containedDescription
                        .getCredentialEntries()));
@@ -182,12 +186,16 @@ public class CredentialDescriptionRegistry {

    /** Returns package names of CredentialProviders that can satisfy a given
     * {@link CredentialDescription}. */
    public Set<FilterResult> getMatchingProviders(Set<String> flatRequestString) {
    public Set<FilterResult> getMatchingProviders(Set<String> flatRequestStrings) {
        Set<FilterResult> result = new HashSet<>();
        Set<Set<String>> unflattenedRequestStrings = flatRequestStrings.stream().map(
                CredentialDescriptionRegistry::flatStringToSet).collect(Collectors.toSet());
        for (String packageName: mCredentialDescriptions.keySet()) {
            Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
            for (CredentialDescription containedDescription : currentSet) {
                if (flatRequestString.contains(containedDescription.getFlattenedRequestString())) {
                if (canProviderSatisfyAny(flatStringToSet(containedDescription
                                .getFlattenedRequestString()),
                        unflattenedRequestStrings)) {
                    result.add(new FilterResult(packageName,
                            containedDescription.getFlattenedRequestString(), containedDescription
                            .getCredentialEntries()));
@@ -203,4 +211,24 @@ public class CredentialDescriptionRegistry {
        }
    }

    private static boolean canProviderSatisfyAny(Set<String> registeredUnflattenedStrings,
            Set<Set<String>> requestedUnflattenedStrings) {
        for (Set<String> requestedUnflattenedString : requestedUnflattenedStrings) {
            if (registeredUnflattenedStrings.containsAll(requestedUnflattenedString)) {
                return true;
            }
        }
        return false;
    }

    private static boolean checkForMatch(Set<String> registeredUnflattenedStrings,
            Set<String> requestedUnflattenedString) {
        return registeredUnflattenedStrings.containsAll(requestedUnflattenedString);
    }

    private static Set<String> flatStringToSet(String flatString) {
        return new HashSet<>(Arrays
                .asList(flatString.split(FLAT_STRING_SPLIT_REGEX)));
    }

}
+10 −8
Original line number Diff line number Diff line
@@ -52,8 +52,10 @@ public class CredentialDescriptionRegistryTest {
    private static final String CALLING_PACKAGE_NAME_2 = "com.credman.app2";
    private static final String MDOC_CREDENTIAL_TYPE = "MDOC";
    private static final String PASSKEY_CREDENTIAL_TYPE = "PASSKEY";
    private static final String FLATTENED_REQUEST = "FLATTENED_REQ";
    private static final String FLATTENED_REQUEST_2 = "FLATTENED_REQ_2";
    private static final String FLATTENED_REGISTRY =
            "FLATTENED_REQ;FLATTENED_REQ123;FLATTENED_REQa";
    private static final String FLATTENED_REGISTRY_2 = "FLATTENED_REQ_2";
    private static final String FLATTENED_REQUEST = "FLATTENED_REQ;FLATTENED_REQ123";

    private CredentialDescriptionRegistry mCredentialDescriptionRegistry;
    private CredentialEntry mEntry;
@@ -104,12 +106,12 @@ public class CredentialDescriptionRegistryTest {
    @Test
    public void testEvictProvider_existingProviders_succeeds() {
        final CredentialDescription credentialDescription =
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST,
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY,
                        Collections.emptyList());
        final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest =
                new RegisterCredentialDescriptionRequest(credentialDescription);
        final CredentialDescription credentialDescription2 =
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST_2,
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY_2,
                        Collections.emptyList());
        final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 =
                new RegisterCredentialDescriptionRequest(credentialDescription2);
@@ -130,12 +132,12 @@ public class CredentialDescriptionRegistryTest {
    @Test
    public void testGetMatchingProviders_existingProviders_succeeds() {
        final CredentialDescription credentialDescription =
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST,
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY,
                        Collections.emptyList());
        final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest =
                new RegisterCredentialDescriptionRequest(credentialDescription);
        final CredentialDescription credentialDescription2 =
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REQUEST,
                new CredentialDescription(MDOC_CREDENTIAL_TYPE, FLATTENED_REGISTRY,
                        Collections.emptyList());
        final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest2 =
                new RegisterCredentialDescriptionRequest(credentialDescription2);
@@ -171,11 +173,11 @@ public class CredentialDescriptionRegistryTest {
    public void testExecuteRegisterRequest_existingProviders_filterSucceeds() {
        final CredentialDescription credentialDescription =
                new CredentialDescription(MDOC_CREDENTIAL_TYPE,
                        FLATTENED_REQUEST,
                        FLATTENED_REGISTRY,
                        List.of(mEntry, mEntry2));
        final CredentialDescription credentialDescription2 =
                new CredentialDescription(PASSKEY_CREDENTIAL_TYPE,
                        FLATTENED_REQUEST_2,
                        FLATTENED_REGISTRY_2,
                        List.of(mEntry3));
        final RegisterCredentialDescriptionRequest registerCredentialDescriptionRequest =
                new RegisterCredentialDescriptionRequest(Set.of(credentialDescription,