1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 package android.security;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.util.Log;
22 
23 import org.xmlpull.v1.XmlPullParser;
24 import org.xmlpull.v1.XmlPullParserException;
25 import org.xmlpull.v1.XmlSerializer;
26 
27 import java.io.IOException;
28 import java.util.Objects;
29 
30 /**
31  * The credential management app has the ability to manage the user's KeyChain credentials on
32  * unmanaged devices. {@link KeyChain#createManageCredentialsIntent} should be used by an app to
33  * request to become the credential management app. The user must approve this request before the
34  * app can manage the user's credentials.
35  * <p>
36  * Note: there can only be one credential management on the device. If another app requests to
37  * become the credential management app and the user approves, then the existing credential
38  * management app will no longer be able to manage credentials.
39  * <p>
40  * The requesting credential management app should include its authentication policy in the
41  * requesting intent. The authentication policy declares which certificates should be used for a
42  * given list of apps and URIs.
43  *
44  * @hide
45  * @see AppUriAuthenticationPolicy
46  */
47 public class CredentialManagementApp {
48 
49     private static final String TAG = "CredentialManagementApp";
50     private static final String KEY_PACKAGE_NAME = "package_name";
51 
52     /**
53      * The credential management app's package name
54      */
55     @NonNull
56     private final String mPackageName;
57 
58     /**
59      * The mappings from an app and list of URIs to a list of aliases, which will be used for
60      * authentication.
61      * <p>
62      * appPackageName -> uri -> alias
63      */
64     @NonNull
65     private AppUriAuthenticationPolicy mAuthenticationPolicy;
66 
CredentialManagementApp(@onNull String packageName, @NonNull AppUriAuthenticationPolicy authenticationPolicy)67     public CredentialManagementApp(@NonNull String packageName,
68             @NonNull AppUriAuthenticationPolicy authenticationPolicy) {
69         Objects.requireNonNull(packageName);
70         Objects.requireNonNull(authenticationPolicy);
71         mPackageName = packageName;
72         mAuthenticationPolicy = authenticationPolicy;
73     }
74 
75     /**
76      * Returns the package name of the credential management app.
77      */
78     @NonNull
getPackageName()79     public String getPackageName() {
80         return mPackageName;
81     }
82 
83     /**
84      * Returns the authentication policy of the credential management app.
85      */
86     @NonNull
getAuthenticationPolicy()87     public AppUriAuthenticationPolicy getAuthenticationPolicy() {
88         return mAuthenticationPolicy;
89     }
90 
91     /**
92      * Sets the authentication policy of the credential management app.
93      */
setAuthenticationPolicy(@ullable AppUriAuthenticationPolicy authenticationPolicy)94     public void setAuthenticationPolicy(@Nullable AppUriAuthenticationPolicy authenticationPolicy) {
95         Objects.requireNonNull(authenticationPolicy);
96         mAuthenticationPolicy = authenticationPolicy;
97     }
98 
99     /**
100      * Restore a previously saved {@link CredentialManagementApp} from XML.
101      */
102     @Nullable
readFromXml(@onNull XmlPullParser parser)103     public static CredentialManagementApp readFromXml(@NonNull XmlPullParser parser) {
104         try {
105             String packageName = parser.getAttributeValue(null, KEY_PACKAGE_NAME);
106             AppUriAuthenticationPolicy policy = AppUriAuthenticationPolicy.readFromXml(parser);
107             return new CredentialManagementApp(packageName, policy);
108         } catch (XmlPullParserException | IOException e) {
109             Log.w(TAG, "Reading from xml failed", e);
110         }
111         return null;
112     }
113 
114     /**
115      * Save the {@link CredentialManagementApp} to XML.
116      */
writeToXml(@onNull XmlSerializer out)117     public void writeToXml(@NonNull XmlSerializer out) throws IOException {
118         out.attribute(null, KEY_PACKAGE_NAME, mPackageName);
119         if (mAuthenticationPolicy != null) {
120             mAuthenticationPolicy.writeToXml(out);
121         }
122     }
123 }
124