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