summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTucker Sylvestro <tuckeris@google.com>2016-08-05 18:02:47 -0400
committerTucker Sylvestro <tuckeris@google.com>2016-10-05 18:38:42 -0400
commit0ab28b78bd06a06a0ffa150cef5876d56212902a (patch)
tree0d9ef0ef9ddfec5fbb186264f4e888332d42db76
parent37ca4172bb9c62ff25b5277ad7066935f538b749 (diff)
downloadsecurity-nougat-mr2.1-release.tar.gz
There are three changes in this CL: 1. Persist all characteristics provided at the time of key creation. We do this to avoid device-specific keymaster implementations stripping keys they are not aware of. 2. Add an onDeviceOffBody API method that will be called whenever a wearable device is detected to have been removed. 3. Check whether a key was created with TAG_ALLOW_WHILE_ON_BODY and the device has gone off-body since the last auth event when deciding whether it can be used. BUG: 30701680 BUG: 28911985 Change-Id: I6be3af3dee8e576fe713dfdd726502d8b333f224
-rw-r--r--keystore/IKeystoreService.cpp26
-rw-r--r--keystore/auth_token_table.cpp11
-rw-r--r--keystore/auth_token_table.h9
-rw-r--r--keystore/blob.h1
-rw-r--r--keystore/include/keystore/IKeystoreService.h2
-rw-r--r--keystore/key_store_service.cpp124
-rw-r--r--keystore/key_store_service.h2
-rw-r--r--keystore/keystore.cpp45
-rw-r--r--keystore/keystore.h8
9 files changed, 197 insertions, 31 deletions
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 384e4238..7df03c7b 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -1352,6 +1352,24 @@ public:
return ret;
}
+ virtual int32_t onDeviceOffBody()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+ status_t status = remote()->transact(BnKeystoreService::ON_DEVICE_OFF_BODY, data, &reply);
+ if (status != NO_ERROR) {
+ ALOGD("onDeviceOffBody() could not contact remote: %d\n", status);
+ return -1;
+ }
+ int32_t err = reply.readExceptionCode();
+ int32_t ret = reply.readInt32();
+ if (err < 0) {
+ ALOGD("onDeviceOffBody() caught exception %d\n", err);
+ return -1;
+ }
+ return ret;
+ }
+
};
IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
@@ -1862,6 +1880,14 @@ status_t BnKeystoreService::onTransact(
return NO_ERROR;
}
+ case ON_DEVICE_OFF_BODY: {
+ CHECK_INTERFACE(IKeystoreService, data, reply);
+ int32_t ret = onDeviceOffBody();
+ reply->writeNoException();
+ reply->writeInt32(ret);
+
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index c6e58434..76e757b3 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -138,6 +138,13 @@ AuthTokenTable::Error AuthTokenTable::FindTimedAuthorization(const std::vector<u
if (static_cast<int64_t>(newest_match->time_received()) + timeout < static_cast<int64_t>(now))
return AUTH_TOKEN_EXPIRED;
+ if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY)) {
+ if (static_cast<int64_t>(newest_match->time_received()) <
+ static_cast<int64_t>(last_off_body_)) {
+ return AUTH_TOKEN_EXPIRED;
+ }
+ }
+
newest_match->UpdateLastUse(now);
*found = newest_match->token();
return OK;
@@ -155,6 +162,10 @@ void AuthTokenTable::RemoveEntriesSupersededBy(const Entry& entry) {
entries_.end());
}
+void AuthTokenTable::onDeviceOffBody() {
+ last_off_body_ = clock_function_();
+}
+
void AuthTokenTable::Clear() {
entries_.clear();
}
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index a2f14460..76cf8169 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -42,7 +42,7 @@ time_t clock_gettime_raw();
class AuthTokenTable {
public:
AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
- : max_entries_(max_entries), clock_function_(clock_function) {}
+ : max_entries_(max_entries), last_off_body_(clock_function()), clock_function_(clock_function) {}
enum Error {
OK,
@@ -95,6 +95,12 @@ class AuthTokenTable {
*/
void MarkCompleted(const keymaster_operation_handle_t op_handle);
+ /**
+ * Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
+ * the device stays on body can be revoked.
+ */
+ void onDeviceOffBody();
+
void Clear();
size_t size() { return entries_.size(); }
@@ -155,6 +161,7 @@ class AuthTokenTable {
std::vector<Entry> entries_;
size_t max_entries_;
+ time_t last_off_body_;
time_t (*clock_function_)();
};
diff --git a/keystore/blob.h b/keystore/blob.h
index 584e312e..e2fc9be9 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -70,6 +70,7 @@ typedef enum {
TYPE_MASTER_KEY = 2,
TYPE_KEY_PAIR = 3,
TYPE_KEYMASTER_10 = 4,
+ TYPE_KEY_CHARACTERISTICS = 5,
} BlobType;
class Entropy;
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index f5d812ac..defd4a99 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -147,6 +147,7 @@ public:
ON_USER_ADDED = IBinder::FIRST_CALL_TRANSACTION + 33,
ON_USER_REMOVED = IBinder::FIRST_CALL_TRANSACTION + 34,
ATTEST_KEY = IBinder::FIRST_CALL_TRANSACTION + 35,
+ ON_DEVICE_OFF_BODY = IBinder::FIRST_CALL_TRANSACTION + 36,
};
DECLARE_META_INTERFACE(KeystoreService);
@@ -248,6 +249,7 @@ public:
virtual int32_t attestKey(const String16& name, const KeymasterArguments& params,
KeymasterCertificateChain* outChain) = 0;
+ virtual int32_t onDeviceOffBody() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index ba0182cd..020bfe4c 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -97,7 +97,7 @@ int32_t KeyStoreService::insert(const String16& name, const uint8_t* item, size_
}
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_GENERIC));
Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -111,8 +111,16 @@ int32_t KeyStoreService::del(const String16& name, int targetUid) {
return ::PERMISSION_DENIED;
}
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
- return mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
+ int32_t result = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+ if (result != ::NO_ERROR) {
+ return result;
+ }
+
+ // Also delete any characteristics files
+ String8 chrFilename(mKeyStore->getKeyNameForUidWithDir(
+ name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
+ return mKeyStore->del(chrFilename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
}
int32_t KeyStoreService::exist(const String16& name, int targetUid) {
@@ -122,7 +130,7 @@ int32_t KeyStoreService::exist(const String16& name, int targetUid) {
}
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
@@ -136,7 +144,7 @@ int32_t KeyStoreService::list(const String16& prefix, int targetUid, Vector<Stri
return ::PERMISSION_DENIED;
}
const String8 prefix8(prefix);
- String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
+ String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) {
return ::SYSTEM_ERROR;
@@ -425,7 +433,7 @@ int32_t KeyStoreService::grant(const String16& name, int32_t granteeUid) {
}
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
@@ -443,7 +451,7 @@ int32_t KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
}
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
@@ -460,7 +468,7 @@ int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
}
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
ALOGW("could not access %s for getmtime", filename.string());
@@ -484,6 +492,7 @@ int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
return static_cast<int64_t>(s.st_mtime);
}
+// TODO(tuckeris): This is dead code, remove it. Don't bother copying over key characteristics here
int32_t KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
int32_t destUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -525,10 +534,10 @@ int32_t KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid, const
}
String8 source8(srcKey);
- String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid));
+ String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid, ::TYPE_ANY));
String8 target8(destKey);
- String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid));
+ String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid, ::TYPE_ANY));
if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
ALOGD("destination already exists: %s", targetFile.string());
@@ -563,8 +572,13 @@ int32_t KeyStoreService::clear_uid(int64_t targetUid64) {
for (uint32_t i = 0; i < aliases.size(); i++) {
String8 name8(aliases[i]);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+
+ // del() will fail silently if no cached characteristics are present for this alias.
+ String8 chr_filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid,
+ ::TYPE_KEY_CHARACTERISTICS));
+ mKeyStore->del(chr_filename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
}
return ::NO_ERROR;
}
@@ -611,6 +625,19 @@ int32_t KeyStoreService::generateKey(const String16& name, const KeymasterArgume
if (device == NULL) {
return ::SYSTEM_ERROR;
}
+
+ // Capture characteristics before they're potentially stripped by the device
+ AuthorizationSet keyCharacteristics(opParams.data(), opParams.size());
+ if (keyCharacteristics.is_valid() != AuthorizationSet::Error::OK) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ UniquePtr<uint8_t[]> kc_buf;
+ kc_buf.reset(new (std::nothrow) uint8_t[keyCharacteristics.SerializedSize()]);
+ if (!kc_buf.get()) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ keyCharacteristics.Serialize(kc_buf.get(), kc_buf.get() + keyCharacteristics.SerializedSize());
+
// TODO: Seed from Linux RNG before this.
if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
device->generate_key != NULL) {
@@ -652,16 +679,30 @@ int32_t KeyStoreService::generateKey(const String16& name, const KeymasterArgume
return rc;
}
+ // Write the key:
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
keyBlob.setFallback(isFallback);
keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
free(const_cast<uint8_t*>(blob.key_material));
+ rc = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
- return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+ if (rc != ::NO_ERROR) {
+ return rc;
+ }
+
+ // Write the characteristics:
+ String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
+
+ Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
+ NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
+ charBlob.setFallback(isFallback);
+ charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+ return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
}
int32_t KeyStoreService::getKeyCharacteristics(const String16& name,
@@ -743,6 +784,19 @@ int32_t KeyStoreService::importKey(const String16& name, const KeymasterArgument
if (device == NULL) {
return ::SYSTEM_ERROR;
}
+
+ // Capture characteristics before they're potentially stripped
+ AuthorizationSet keyCharacteristics(opParams.data(), opParams.size());
+ if (keyCharacteristics.is_valid() != AuthorizationSet::Error::OK) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ UniquePtr<uint8_t[]> kc_buf;
+ kc_buf.reset(new (std::nothrow) uint8_t[keyCharacteristics.SerializedSize()]);
+ if (!kc_buf.get()) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ keyCharacteristics.Serialize(kc_buf.get(), kc_buf.get() + keyCharacteristics.SerializedSize());
+
if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
device->import_key != NULL) {
rc = device->import_key(device, &inParams, format, &input, &blob,
@@ -762,16 +816,30 @@ int32_t KeyStoreService::importKey(const String16& name, const KeymasterArgument
return rc;
}
+ // Write the key:
String8 name8(name);
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
keyBlob.setFallback(isFallback);
keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
free(const_cast<uint8_t*>(blob.key_material));
+ rc = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+
+ if (rc != ::NO_ERROR) {
+ return rc;
+ }
+
+ // Write the characteristics:
+ String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
+
+ Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
+ NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
+ charBlob.setFallback(isFallback);
+ charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
- return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+ return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
}
void KeyStoreService::exportKey(const String16& name, keymaster_key_format_t format,
@@ -864,6 +932,24 @@ void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name,
return;
}
const hw_auth_token_t* authToken = NULL;
+
+ // Merge these characteristics with the ones cached when the key was generated or imported
+ Blob charBlob;
+ AuthorizationSet persistedCharacteristics;
+ responseCode = mKeyStore->getKeyForName(&charBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
+ if (responseCode == ::NO_ERROR) {
+ const uint8_t* serializedCharacteristics = charBlob.getValue();
+ persistedCharacteristics.Deserialize(&serializedCharacteristics,
+ serializedCharacteristics + charBlob.getLength());
+ } else {
+ ALOGD("Unable to read cached characteristics for key");
+ }
+
+ // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
+ persistedCharacteristics.Union(characteristics.get()->sw_enforced);
+ persistedCharacteristics.Difference(characteristics.get()->hw_enforced);
+ persistedCharacteristics.CopyToParamSet(&characteristics.get()->sw_enforced);
+
int32_t authResult = getAuthToken(characteristics.get(), 0, purpose, &authToken,
/*failOnTokenMissing*/ false);
// If per-operation auth is needed we need to begin the operation and
@@ -1161,6 +1247,12 @@ int32_t KeyStoreService::attestKey(const String16& name, const KeymasterArgument
return ::NO_ERROR;
}
+int32_t KeyStoreService::onDeviceOffBody() {
+ // TODO(tuckeris): add permission check. This should be callable from ClockworkHome only.
+ mAuthTokenTable.onDeviceOffBody();
+ return ::NO_ERROR;
+}
+
/**
* Prune the oldest pruneable operation.
*/
@@ -1560,7 +1652,7 @@ int32_t KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
return rc;
}
- String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+ String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
Blob newBlob(upgraded_key.key_material, upgraded_key.key_material_size, nullptr /* info */,
0 /* infoLength */, ::TYPE_KEYMASTER_10);
newBlob.setFallback(blob->isFallback());
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 7d559199..cd433914 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -119,6 +119,8 @@ class KeyStoreService : public BnKeystoreService, public IBinder::DeathRecipient
int32_t attestKey(const String16& name, const KeymasterArguments& params,
KeymasterCertificateChain* outChain) override;
+ int32_t onDeviceOffBody();
+
private:
static const int32_t UID_SELF = -1;
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 90cfdb11..d0a61bf6 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -115,23 +115,39 @@ static int encode_key(char* out, const android::String8& keyName) {
return length;
}
-android::String8 KeyStore::getKeyName(const android::String8& keyName) {
+android::String8 KeyStore::getKeyName(const android::String8& keyName, const BlobType type) {
char encoded[encode_key_length(keyName) + 1]; // add 1 for null char
encode_key(encoded, keyName);
- return android::String8(encoded);
+ if (type == TYPE_KEY_CHARACTERISTICS) {
+ return android::String8::format(".chr_%s", encoded);
+ } else {
+ return android::String8(encoded);
+ }
}
-android::String8 KeyStore::getKeyNameForUid(const android::String8& keyName, uid_t uid) {
+android::String8 KeyStore::getKeyNameForUid(
+ const android::String8& keyName, uid_t uid, const BlobType type) {
char encoded[encode_key_length(keyName) + 1]; // add 1 for null char
encode_key(encoded, keyName);
- return android::String8::format("%u_%s", uid, encoded);
+ if (type == TYPE_KEY_CHARACTERISTICS) {
+ return android::String8::format(".%u_chr_%s", uid, encoded);
+ } else {
+ return android::String8::format("%u_%s", uid, encoded);
+ }
}
-android::String8 KeyStore::getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) {
+android::String8 KeyStore::getKeyNameForUidWithDir(
+ const android::String8& keyName, uid_t uid, const BlobType type) {
char encoded[encode_key_length(keyName) + 1]; // add 1 for null char
encode_key(encoded, keyName);
- return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
- encoded);
+
+ if (type == TYPE_KEY_CHARACTERISTICS) {
+ return android::String8::format("%s/.%u_chr_%s", getUserStateByUid(uid)->getUserDirName(),
+ uid, encoded);
+ } else {
+ return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
+ encoded);
+ }
}
void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
@@ -144,7 +160,7 @@ void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
for (uint32_t i = 0; i < aliases.size(); i++) {
android::String8 filename(aliases[i]);
filename = android::String8::format("%s/%s", userState->getUserDirName(),
- getKeyName(filename).string());
+ getKeyName(filename, TYPE_ANY).string());
bool shouldDelete = true;
if (keepUnenryptedEntries) {
Blob blob;
@@ -160,6 +176,13 @@ void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
}
if (shouldDelete) {
del(filename, ::TYPE_ANY, userId);
+
+ // del() will fail silently if no cached characteristics are present for this alias.
+ android::String8 chr_filename(aliases[i]);
+ chr_filename = android::String8::format("%s/%s", userState->getUserDirName(),
+ getKeyName(chr_filename,
+ TYPE_KEY_CHARACTERISTICS).string());
+ del(chr_filename, ::TYPE_KEY_CHARACTERISTICS, userId);
}
}
if (!userState->deleteMasterKey()) {
@@ -485,7 +508,7 @@ bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
const uid_t uid, const BlobType type) {
- android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid));
+ android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid, type));
uid_t userId = get_user_id(uid);
ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId);
@@ -496,7 +519,7 @@ ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyN
// If this is one of the legacy UID->UID mappings, use it.
uid_t euid = get_keystore_euid(uid);
if (euid != uid) {
- filepath8 = getKeyNameForUidWithDir(keyName, euid);
+ filepath8 = getKeyNameForUidWithDir(keyName, euid, type);
responseCode = get(filepath8.string(), keyBlob, type, userId);
if (responseCode == NO_ERROR) {
return responseCode;
@@ -504,7 +527,7 @@ ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyN
}
// They might be using a granted key.
- android::String8 filename8 = getKeyName(keyName);
+ android::String8 filename8 = getKeyName(keyName, type);
char* end;
strtoul(filename8.string(), &end, 10);
if (end[0] != '_' || end[1] == 0) {
diff --git a/keystore/keystore.h b/keystore/keystore.h
index b15d00f4..278a0a0d 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -53,9 +53,11 @@ class KeyStore {
ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
ResponseCode readMasterKey(const android::String8& pw, uid_t userId);
- android::String8 getKeyName(const android::String8& keyName);
- android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid);
- android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid);
+ android::String8 getKeyName(const android::String8& keyName, const BlobType type);
+ android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid,
+ const BlobType type);
+ android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
+ const BlobType type);
/*
* Delete entries owned by userId. If keepUnencryptedEntries is true