Separate encryption key storage from device
Fixes: 147887130
Test: Unit tests pass and association successful
Change-Id: I99b91ce01a3dca6c376b0519ff42ae500266400f
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java
index 7d085c5..4745fdb 100644
--- a/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/CarBlePeripheralManager.java
@@ -30,7 +30,6 @@
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.car.encryptionrunner.EncryptionRunnerFactory;
-import android.car.encryptionrunner.Key;
import android.os.ParcelUuid;
import com.android.car.connecteddevice.AssociationCallback;
@@ -418,7 +417,7 @@
private final SecureBleChannel.Callback mSecureChannelCallback =
new SecureBleChannel.Callback() {
@Override
- public void onSecureChannelEstablished(Key encryptionKey) {
+ public void onSecureChannelEstablished() {
BleDevice connectedDevice = getConnectedDevice();
if (connectedDevice == null || connectedDevice.mDeviceId == null) {
disconnectWithError("Null device id found when secure channel "
@@ -436,8 +435,7 @@
+ "association of that device for current user.");
mStorage.addAssociatedDeviceForActiveUser(
new AssociatedDevice(deviceId, mClientDeviceAddress,
- mClientDeviceName),
- encryptionKey.asBytes());
+ mClientDeviceName));
if (mAssociationCallback != null) {
mAssociationCallback.onAssociationCompleted(deviceId);
mAssociationCallback = null;
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java b/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java
index 1730af8..a821186 100644
--- a/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java
+++ b/connected-device-lib/src/com/android/car/connecteddevice/ble/SecureBleChannel.java
@@ -226,7 +226,7 @@
mStorage.saveEncryptionKey(mDeviceId, newKey.asBytes());
mEncryptionKey.set(newKey);
sendServerAuthToClient(handshakeMessage.getNextMessage());
- notifyCallback(callback -> callback.onSecureChannelEstablished(newKey));
+ notifyCallback(callback -> callback.onSecureChannelEstablished());
}
private void sendUniqueIdToClient() {
@@ -314,6 +314,7 @@
}
mState = message.getHandshakeState();
+ mStorage.saveEncryptionKey(mDeviceId, localKey.asBytes());
mEncryptionKey.set(localKey);
if (mDeviceId == null) {
loge(TAG, "Unable to finish association, device id is null.");
@@ -322,7 +323,7 @@
}
logd(TAG, "Pairing code successfully verified and encryption key saved. Sending "
+ "confirmation to device.");
- notifyCallback(callback -> callback.onSecureChannelEstablished(localKey));
+ notifyCallback(Callback::onSecureChannelEstablished);
DeviceMessage deviceMessage = new DeviceMessage(/* recipient = */ null,
/* isMessageEncrypted = */ false, CONFIRMATION_SIGNAL);
mStream.writeMessage(deviceMessage, OperationType.ENCRYPTION_HANDSHAKE);
@@ -429,10 +430,8 @@
interface Callback {
/**
* Invoked when secure channel has been established successfully.
- *
- * @param encryptionKey The new key generated in handshake.
*/
- void onSecureChannelEstablished(Key encryptionKey);
+ void onSecureChannelEstablished();
/**
* Invoked when a {@link ChannelError} has been encountered in attempting to establish
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java
index a1fd6e1..c041d58 100644
--- a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceDao.java
@@ -43,9 +43,24 @@
* device id.
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
- void addOrUpdateAssociatedDevice(AssociatedDeviceEntity associatedDevice);
+ void addOrReplaceAssociatedDevice(AssociatedDeviceEntity associatedDevice);
/** Remove a {@link AssociatedDeviceEntity}. */
@Delete
void removeAssociatedDevice(AssociatedDeviceEntity connectedDevice);
+
+ /** Get the key associated with a device id. */
+ @Query("SELECT * FROM associated_device_keys WHERE id LIKE :deviceId LIMIT 1")
+ AssociatedDeviceKeyEntity getAssociatedDeviceKey(String deviceId);
+
+ /**
+ * Add a {@link AssociatedDeviceKeyEntity}. Replace if a device key already exists with the
+ * same device id.
+ */
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void addOrReplaceAssociatedDeviceKey(AssociatedDeviceKeyEntity keyEntity);
+
+ /** Remove a {@link AssociatedDeviceKeyEntity}. */
+ @Delete
+ void removeAssociatedDeviceKey(AssociatedDeviceKeyEntity keyEntity);
}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java
index c7a950e..cc97717 100644
--- a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceEntity.java
@@ -43,10 +43,6 @@
@Nullable
public String name;
- /** Encrypted key for secure session. */
- @NonNull
- public String encryptedKey;
-
public AssociatedDeviceEntity() { }
public AssociatedDeviceEntity(int userId, AssociatedDevice associatedDevice) {
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceKeyEntity.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceKeyEntity.java
new file mode 100644
index 0000000..6cd791f
--- /dev/null
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/AssociatedDeviceKeyEntity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.connecteddevice.storage;
+
+import androidx.annotation.NonNull;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+/** Table entity representing a key for an associated device. */
+@Entity(tableName = "associated_device_keys")
+public class AssociatedDeviceKeyEntity {
+
+ /** Id of the device. */
+ @PrimaryKey
+ @NonNull
+ public String id;
+
+ @NonNull
+ public String encryptedKey;
+
+ public AssociatedDeviceKeyEntity() { }
+
+ public AssociatedDeviceKeyEntity(String deviceId, String encryptedKey) {
+ id = deviceId;
+ this.encryptedKey = encryptedKey;
+ }
+}
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java
index 42804b1..3671440 100644
--- a/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceDatabase.java
@@ -20,7 +20,8 @@
import androidx.room.RoomDatabase;
/** Database for connected devices. */
-@Database(entities = { AssociatedDeviceEntity.class }, version = 1, exportSchema = false)
+@Database(entities = { AssociatedDeviceEntity.class, AssociatedDeviceKeyEntity.class }, version = 1,
+ exportSchema = false)
public abstract class ConnectedDeviceDatabase extends RoomDatabase {
/** Return the DAO for the associated device table. */
public abstract AssociatedDeviceDao associatedDeviceDao();
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java
index cc60e03..7b05981 100644
--- a/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java
+++ b/connected-device-lib/src/com/android/car/connecteddevice/storage/ConnectedDeviceStorage.java
@@ -116,8 +116,9 @@
*/
@Nullable
public byte[] getEncryptionKey(@NonNull String deviceId) {
- AssociatedDeviceEntity entity = mAssociatedDeviceDatabase.getAssociatedDevice(deviceId);
- if (entity == null || entity.encryptedKey == null) {
+ AssociatedDeviceKeyEntity entity =
+ mAssociatedDeviceDatabase.getAssociatedDeviceKey(deviceId);
+ if (entity == null) {
logd(TAG, "Encryption key not found!");
return null;
}
@@ -141,13 +142,8 @@
*/
public void saveEncryptionKey(@NonNull String deviceId, @NonNull byte[] encryptionKey) {
String encryptedKey = encryptWithKeyStore(KEY_ALIAS, encryptionKey);
- AssociatedDeviceEntity entity = mAssociatedDeviceDatabase.getAssociatedDevice(deviceId);
- if (entity == null) {
- entity = new AssociatedDeviceEntity();
- entity.id = deviceId;
- }
- entity.encryptedKey = encryptedKey;
- mAssociatedDeviceDatabase.addOrUpdateAssociatedDevice(entity);
+ AssociatedDeviceKeyEntity entity = new AssociatedDeviceKeyEntity(deviceId, encryptedKey);
+ mAssociatedDeviceDatabase.addOrReplaceAssociatedDeviceKey(entity);
logd(TAG, "Successfully wrote encryption key.");
}
@@ -362,11 +358,9 @@
* Add the associated device of the given deviceId for the currently active user.
*
* @param device New associated device to be added.
- * @param encryptionKey They encryption key used for association.
*/
- public void addAssociatedDeviceForActiveUser(@NonNull AssociatedDevice device,
- @NonNull byte[] encryptionKey) {
- addAssociatedDeviceForUser(ActivityManager.getCurrentUser(), device, encryptionKey);
+ public void addAssociatedDeviceForActiveUser(@NonNull AssociatedDevice device) {
+ addAssociatedDeviceForUser(ActivityManager.getCurrentUser(), device);
if (mAssociatedDeviceCallback != null) {
mAssociatedDeviceCallback.onAssociatedDeviceAdded(device.getDeviceId());
}
@@ -378,13 +372,10 @@
*
* @param userId The identifier of the user.
* @param device New associated device to be added.
- * @param encryptionKey They encryption key used for association.
*/
- public void addAssociatedDeviceForUser(int userId, @NonNull AssociatedDevice device,
- @NonNull byte[] encryptionKey) {
+ public void addAssociatedDeviceForUser(int userId, @NonNull AssociatedDevice device) {
AssociatedDeviceEntity entity = new AssociatedDeviceEntity(userId, device);
- entity.encryptedKey = encryptWithKeyStore(KEY_ALIAS, encryptionKey);
- mAssociatedDeviceDatabase.addOrUpdateAssociatedDevice(entity);
+ mAssociatedDeviceDatabase.addOrReplaceAssociatedDevice(entity);
}
/**
@@ -401,7 +392,7 @@
return;
}
entity.name = name;
- mAssociatedDeviceDatabase.addOrUpdateAssociatedDevice(entity);
+ mAssociatedDeviceDatabase.addOrReplaceAssociatedDevice(entity);
if (mAssociatedDeviceCallback != null) {
mAssociatedDeviceCallback.onAssociatedDeviceUpdated(
new AssociatedDevice(deviceId, entity.address, name));
diff --git a/connected-device-lib/src/com/android/car/connecteddevice/util/IdManager.kt b/connected-device-lib/src/com/android/car/connecteddevice/util/IdManager.kt
deleted file mode 100644
index 91d06b7..0000000
--- a/connected-device-lib/src/com/android/car/connecteddevice/util/IdManager.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.car.connecteddevice.util
-
-import com.android.internal.annotations.GuardedBy
-
-/** Class for managing unique numeric ids. */
-internal class IdManager {
-
- private val lock = object
- @Volatile
- @GuardedBy("lock")
- private var nextVal = 0
-
- private var openVals = 0
-
- /**
- * Returns the next available id from the pool and reserves it from future use until released.
- */
- fun reserve(): Int {
- synchronized(lock) {
- return nextVal++
- }
- }
-
- /** Release the [value] back to id pool. */
- fun releaseReservation(value: Int) {
- synchronized(lock) {
- if (value == nextVal - 1) {
- nextVal = value
- } else {
- openVals++
- }
- if (nextVal == openVals) {
- nextVal = 0
- openVals = 0
- }
- }
- }
-}
\ No newline at end of file