Add KeyChain Test API for the credential manager

* Add setCredentialManagementApp and
  removeCredentialManagementApp
  to KeyChain
* Add permission to manage credential
  management app, which is to be used in
  CTS tests

Bug: 165641221
Test: atest android.devicepolicy.cts.CredentialManagementAppTest
Change-Id: I8487ebc13758a31639d55c8e380faa51d1cfd843
This commit is contained in:
Alex Johnston
2021-01-11 10:13:54 +00:00
parent 8bf124b0d1
commit ad53ef61e7
4 changed files with 69 additions and 0 deletions

View File

@@ -1585,6 +1585,11 @@ package android.provider {
package android.security { package android.security {
public final class KeyChain {
method @RequiresPermission("android.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP") public static boolean removeCredentialManagementApp(@NonNull android.content.Context);
method @RequiresPermission("android.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP") public static boolean setCredentialManagementApp(@NonNull android.content.Context, @NonNull String, @NonNull android.security.AppUriAuthenticationPolicy);
}
public class KeyStoreException extends java.lang.Exception { public class KeyStoreException extends java.lang.Exception {
ctor public KeyStoreException(int, String); ctor public KeyStoreException(int, String);
method public int getErrorCode(); method public int getErrorCode();

View File

@@ -3147,6 +3147,11 @@
<permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" <permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES"
android:protectionLevel="signature|privileged" /> android:protectionLevel="signature|privileged" />
<!-- Allows an application to set, update and remove the credential management app.
@hide -->
<permission android:name="android.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP"
android:protectionLevel="signature" />
<!-- ========================================= --> <!-- ========================================= -->
<!-- Permissions for special development tools --> <!-- Permissions for special development tools -->
<!-- ========================================= --> <!-- ========================================= -->

View File

@@ -17,10 +17,13 @@ package android.security;
import static android.security.Credentials.ACTION_MANAGE_CREDENTIALS; import static android.security.Credentials.ACTION_MANAGE_CREDENTIALS;
import android.Manifest;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant; import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.TestApi;
import android.annotation.WorkerThread; import android.annotation.WorkerThread;
import android.app.Activity; import android.app.Activity;
import android.app.PendingIntent; import android.app.PendingIntent;
@@ -41,6 +44,7 @@ import android.os.UserManager;
import android.security.keystore.AndroidKeyStoreProvider; import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyPermanentlyInvalidatedException; import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties; import android.security.keystore.KeyProperties;
import android.util.Log;
import com.android.org.conscrypt.TrustedCertificateStore; import com.android.org.conscrypt.TrustedCertificateStore;
@@ -104,6 +108,11 @@ import javax.security.auth.x500.X500Principal;
// TODO reference intent for credential installation when public // TODO reference intent for credential installation when public
public final class KeyChain { public final class KeyChain {
/**
* @hide
*/
public static final String LOG = "KeyChain";
/** /**
* @hide Also used by KeyChainService implementation * @hide Also used by KeyChainService implementation
*/ */
@@ -579,6 +588,55 @@ public final class KeyChain {
activity.startActivity(intent); activity.startActivity(intent);
} }
/**
* Set a credential management app. The credential management app has the ability to manage
* the user's KeyChain credentials on unmanaged devices.
*
* <p>There can only be one credential management on the device. If another app requests to
* become the credential management app, then the existing credential management app will
* no longer be able to manage credentials.
*
* @param packageName The package name of the credential management app
* @param authenticationPolicy The authentication policy of the credential management app. This
* policy determines which alias for a private key and certificate
* pair should be used for authentication.
* @return {@code true} if the credential management app was successfully added.
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP)
public static boolean setCredentialManagementApp(@NonNull Context context,
@NonNull String packageName, @NonNull AppUriAuthenticationPolicy authenticationPolicy) {
try (KeyChainConnection keyChainConnection = KeyChain.bind(context)) {
keyChainConnection.getService()
.setCredentialManagementApp(packageName, authenticationPolicy);
return true;
} catch (RemoteException | InterruptedException e) {
Log.w(LOG, "Set credential management app failed", e);
Thread.currentThread().interrupt();
return false;
}
}
/**
* Remove the user's KeyChain credentials on unmanaged devices.
*
* @return {@code true} if the credential management app was successfully removed.
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP)
public static boolean removeCredentialManagementApp(@NonNull Context context) {
try (KeyChainConnection keyChainConnection = KeyChain.bind(context)) {
keyChainConnection.getService().removeCredentialManagementApp();
return true;
} catch (RemoteException | InterruptedException e) {
Log.w(LOG, "Remove credential management app failed", e);
Thread.currentThread().interrupt();
return false;
}
}
private static class AliasResponse extends IKeyChainAliasCallback.Stub { private static class AliasResponse extends IKeyChainAliasCallback.Stub {
private final KeyChainAliasCallback keyChainAliasResponse; private final KeyChainAliasCallback keyChainAliasResponse;
private AliasResponse(KeyChainAliasCallback keyChainAliasResponse) { private AliasResponse(KeyChainAliasCallback keyChainAliasResponse) {

View File

@@ -119,6 +119,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.CREATE_USERS" /> <uses-permission android:name="android.permission.CREATE_USERS" />
<uses-permission android:name="android.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" /> <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
<uses-permission android:name="android.permission.ACCESS_LOWPAN_STATE"/> <uses-permission android:name="android.permission.ACCESS_LOWPAN_STATE"/>
<uses-permission android:name="android.permission.CHANGE_LOWPAN_STATE"/> <uses-permission android:name="android.permission.CHANGE_LOWPAN_STATE"/>