KeyStore: change migrate to duplicate

After discussion, it was determined that duplicate would be less
disruptive and it still fit in the current HAL model.

Change-Id: I2f9cae48d38ec7146511e876450fa39fc92cda55
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
index 2ae3c64..a890d9b 100644
--- a/core/java/android/security/IKeystoreService.java
+++ b/core/java/android/security/IKeystoreService.java
@@ -407,15 +407,18 @@
             }
 
             @Override
-            public int migrate(String name, int targetUid) throws RemoteException {
+            public int duplicate(String srcKey, int srcUid, String destKey, int destUid)
+                    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);
+                    _data.writeString(srcKey);
+                    _data.writeInt(srcUid);
+                    _data.writeString(destKey);
+                    _data.writeInt(destUid);
+                    mRemote.transact(Stub.TRANSACTION_duplicate, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.readInt();
                 } finally {
@@ -448,7 +451,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;
+        static final int TRANSACTION_duplicate = IBinder.FIRST_CALL_TRANSACTION + 20;
 
         /**
          * Cast an IBinder object into an IKeystoreService interface, generating
@@ -534,5 +537,6 @@
 
     public long getmtime(String name) throws RemoteException;
 
-    public int migrate(String name, int targetUid) throws RemoteException;
+    public int duplicate(String srcKey, int srcUid, String destKey, int destUid)
+            throws RemoteException;
 }
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 4dc0beb..12c0ed8 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -287,9 +287,9 @@
         }
     }
 
-    public boolean migrate(String key, int uid) {
+    public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) {
         try {
-            return mBinder.migrate(key, uid) == NO_ERROR;
+            return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 8f8ee92..1de1eaf 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -553,7 +553,7 @@
                 mKeyStore.ungrant(TEST_KEYNAME, 0));
     }
 
-    public void testMigrate_grantedUid_Wifi_Success() throws Exception {
+    public void testDuplicate_grantedUid_Wifi_Success() throws Exception {
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -563,13 +563,35 @@
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
 
-        assertTrue(mKeyStore.migrate(TEST_KEYNAME, Process.WIFI_UID));
+        // source doesn't exist
+        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, -1, TEST_KEYNAME1, Process.WIFI_UID));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
 
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
+        // Copy from current UID to granted UID
+        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
+        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
+
+        // Copy from granted UID to same granted UID
+        assertTrue(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
+                Process.WIFI_UID));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME2, Process.WIFI_UID));
+        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
+                Process.WIFI_UID));
+
+        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME2));
+        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
     }
 
-    public void testMigrate_ungrantedUid_Bluetooth_Failure() throws Exception {
+    public void testDuplicate_ungrantedUid_Bluetooth_Failure() throws Exception {
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -579,7 +601,9 @@
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
-        assertFalse(mKeyStore.migrate(TEST_KEYNAME, Process.BLUETOOTH_UID));
+        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, Process.BLUETOOTH_UID));
+        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, Process.BLUETOOTH_UID, TEST_KEYNAME2,
+                Process.BLUETOOTH_UID));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));