KeyStore: add "migrate" command
To support the WiFi service, we need to support migration from the
system UID to the wifi UID. This adds a command to achieve the
migration.
Bug: 8122243
Change-Id: I65f7a91504c1d2a2aac22b9c3051adffd28d66c1
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
index af4cdfa..2ae3c64 100644
--- a/core/java/android/security/IKeystoreService.java
+++ b/core/java/android/security/IKeystoreService.java
@@ -405,6 +405,25 @@
}
return _result;
}
+
+ @Override
+ public int migrate(String name, int targetUid) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeInt(targetUid);
+ mRemote.transact(Stub.TRANSACTION_migrate, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
}
private static final String DESCRIPTOR = "android.security.keystore";
@@ -429,6 +448,7 @@
static final int TRANSACTION_grant = IBinder.FIRST_CALL_TRANSACTION + 17;
static final int TRANSACTION_ungrant = IBinder.FIRST_CALL_TRANSACTION + 18;
static final int TRANSACTION_getmtime = IBinder.FIRST_CALL_TRANSACTION + 19;
+ static final int TRANSACTION_migrate = IBinder.FIRST_CALL_TRANSACTION + 20;
/**
* Cast an IBinder object into an IKeystoreService interface, generating
@@ -513,4 +533,6 @@
public int ungrant(String name, int granteeUid) throws RemoteException;
public long getmtime(String name) throws RemoteException;
+
+ public int migrate(String name, int targetUid) throws RemoteException;
}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 9000668..4dc0beb 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -287,6 +287,15 @@
}
}
+ public boolean migrate(String key, int uid) {
+ try {
+ return mBinder.migrate(key, uid) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
+ }
+
public int getLastError() {
return mError;
}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 6ce3ed3..8f8ee92 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -553,6 +553,38 @@
mKeyStore.ungrant(TEST_KEYNAME, 0));
}
+ public void testMigrate_grantedUid_Wifi_Success() throws Exception {
+ assertTrue(mKeyStore.password(TEST_PASSWD));
+
+ assertFalse(mKeyStore.contains(TEST_KEYNAME));
+
+ assertTrue(mKeyStore.generate(TEST_KEYNAME));
+
+ assertTrue(mKeyStore.contains(TEST_KEYNAME));
+ assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
+
+ assertTrue(mKeyStore.migrate(TEST_KEYNAME, Process.WIFI_UID));
+
+ assertFalse(mKeyStore.contains(TEST_KEYNAME));
+ assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
+ }
+
+ public void testMigrate_ungrantedUid_Bluetooth_Failure() throws Exception {
+ assertTrue(mKeyStore.password(TEST_PASSWD));
+
+ assertFalse(mKeyStore.contains(TEST_KEYNAME));
+
+ assertTrue(mKeyStore.generate(TEST_KEYNAME));
+
+ assertTrue(mKeyStore.contains(TEST_KEYNAME));
+ assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
+
+ assertFalse(mKeyStore.migrate(TEST_KEYNAME, Process.BLUETOOTH_UID));
+
+ assertTrue(mKeyStore.contains(TEST_KEYNAME));
+ assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
+ }
+
/**
* The amount of time to allow before and after expected time for variance
* in timing tests.