diff options
author | Tucker Sylvestro <tuckeris@google.com> | 2016-08-05 18:02:47 -0400 |
---|---|---|
committer | Tucker Sylvestro <tuckeris@google.com> | 2016-10-05 18:38:42 -0400 |
commit | 0ab28b78bd06a06a0ffa150cef5876d56212902a (patch) | |
tree | 0d9ef0ef9ddfec5fbb186264f4e888332d42db76 | |
parent | 37ca4172bb9c62ff25b5277ad7066935f538b749 (diff) | |
download | security-nougat-mr2.1-release.tar.gz |
Support and use TAG_ALLOW_WHILE_ON_BODYandroid-7.1.2_r9android-7.1.2_r8android-7.1.2_r6android-7.1.2_r5android-7.1.2_r4android-7.1.2_r36android-7.1.2_r33android-7.1.2_r32android-7.1.2_r30android-7.1.2_r3android-7.1.2_r29android-7.1.2_r28android-7.1.2_r27android-7.1.2_r25android-7.1.2_r24android-7.1.2_r23android-7.1.2_r2android-7.1.2_r19android-7.1.2_r18android-7.1.2_r17android-7.1.2_r16android-7.1.2_r15android-7.1.2_r14android-7.1.2_r13android-7.1.2_r12android-7.1.2_r11android-7.1.2_r10android-7.1.2_r1nougat-mr2.3-releasenougat-mr2.2-releasenougat-mr2.1-releasenougat-mr2-releasenougat-mr2-pixel-releasenougat-mr2-dev
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.cpp | 26 | ||||
-rw-r--r-- | keystore/auth_token_table.cpp | 11 | ||||
-rw-r--r-- | keystore/auth_token_table.h | 9 | ||||
-rw-r--r-- | keystore/blob.h | 1 | ||||
-rw-r--r-- | keystore/include/keystore/IKeystoreService.h | 2 | ||||
-rw-r--r-- | keystore/key_store_service.cpp | 124 | ||||
-rw-r--r-- | keystore/key_store_service.h | 2 | ||||
-rw-r--r-- | keystore/keystore.cpp | 45 | ||||
-rw-r--r-- | keystore/keystore.h | 8 |
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 |