Merge "Fix use of auth-bound keys after screen lock removal" into oc-mr1-dev am: f08fb3449b
am: b8e9240455
Change-Id: Ifa50f081522c050afa4035482da110c3cdc65004
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index 368590c..779437d 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -48,8 +48,8 @@
#endif
namespace {
-extern const RSA_METHOD keystore_rsa_method;
-extern const ECDSA_METHOD keystore_ecdsa_method;
+KeystoreBackend *g_keystore_backend;
+void ensure_keystore_engine();
/* key_id_dup is called when one of the RSA or EC_KEY objects is duplicated. */
int key_id_dup(CRYPTO_EX_DATA* /* to */,
@@ -76,60 +76,6 @@
free(key_id);
}
-/* KeystoreEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
- * forwarding the requested operations to Keystore. */
-class KeystoreEngine {
- public:
- KeystoreEngine()
- : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
- NULL /* argp */,
- NULL /* new_func */,
- key_id_dup,
- key_id_free)),
- ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
- NULL /* argp */,
- NULL /* new_func */,
- key_id_dup,
- key_id_free)),
- engine_(ENGINE_new()) {
- ENGINE_set_RSA_method(
- engine_, &keystore_rsa_method, sizeof(keystore_rsa_method));
- ENGINE_set_ECDSA_method(
- engine_, &keystore_ecdsa_method, sizeof(keystore_ecdsa_method));
- }
-
- int rsa_ex_index() const { return rsa_index_; }
- int ec_key_ex_index() const { return ec_key_index_; }
-
- const ENGINE* engine() const { return engine_; }
-
- private:
- const int rsa_index_;
- const int ec_key_index_;
- ENGINE* const engine_;
-};
-
-pthread_once_t g_keystore_engine_once = PTHREAD_ONCE_INIT;
-KeystoreEngine *g_keystore_engine;
-KeystoreBackend *g_keystore_backend;
-
-/* init_keystore_engine is called to initialize |g_keystore_engine|. This
- * should only be called by |pthread_once|. */
-void init_keystore_engine() {
- g_keystore_engine = new KeystoreEngine;
-#ifndef BACKEND_WIFI_HIDL
- g_keystore_backend = new KeystoreBackendBinder;
-#else
- g_keystore_backend = new KeystoreBackendHidl;
-#endif
-}
-
-/* ensure_keystore_engine ensures that |g_keystore_engine| is pointing to a
- * valid |KeystoreEngine| object and creates one if not. */
-void ensure_keystore_engine() {
- pthread_once(&g_keystore_engine_once, init_keystore_engine);
-}
-
/* Many OpenSSL APIs take ownership of an argument on success but don't free
* the argument on failure. This means we need to tell our scoped pointers when
* we've transferred ownership, without triggering a warning by not using the
@@ -137,10 +83,7 @@
#define OWNERSHIP_TRANSFERRED(obj) \
typeof ((obj).release()) _dummy __attribute__((unused)) = (obj).release()
-const char* rsa_get_key_id(const RSA* rsa) {
- return reinterpret_cast<char*>(
- RSA_get_ex_data(rsa, g_keystore_engine->rsa_ex_index()));
-}
+const char* rsa_get_key_id(const RSA* rsa);
/* rsa_private_transform takes a big-endian integer from |in|, calculates the
* d'th power of it, modulo the RSA modulus, and writes the result as a
@@ -194,33 +137,7 @@
return 1;
}
-const struct rsa_meth_st keystore_rsa_method = {
- {
- 0 /* references */,
- 1 /* is_static */,
- },
- NULL /* app_data */,
-
- NULL /* init */,
- NULL /* finish */,
-
- NULL /* size */,
-
- NULL /* sign */,
-
- NULL /* encrypt */,
- NULL /* sign_raw */,
- NULL /* decrypt */,
-
- rsa_private_transform,
-
- RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_OPAQUE,
-};
-
-const char* ecdsa_get_key_id(const EC_KEY* ec_key) {
- return reinterpret_cast<char*>(
- EC_KEY_get_ex_data(ec_key, g_keystore_engine->ec_key_ex_index()));
-}
+const char* ecdsa_get_key_id(const EC_KEY* ec_key);
/* ecdsa_sign signs |digest_len| bytes from |digest| with |ec_key| and writes
* the resulting signature (an ASN.1 encoded blob) to |sig|. It returns one on
@@ -263,20 +180,78 @@
return 1;
}
-const ECDSA_METHOD keystore_ecdsa_method = {
- {
- 0 /* references */,
- 1 /* is_static */
- } /* common */,
- NULL /* app_data */,
+/* KeystoreEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
+ * forwarding the requested operations to Keystore. */
+class KeystoreEngine {
+ public:
+ KeystoreEngine()
+ : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
+ NULL /* argp */,
+ NULL /* new_func */,
+ key_id_dup,
+ key_id_free)),
+ ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
+ NULL /* argp */,
+ NULL /* new_func */,
+ key_id_dup,
+ key_id_free)),
+ engine_(ENGINE_new()) {
+ memset(&rsa_method_, 0, sizeof(rsa_method_));
+ rsa_method_.common.is_static = 1;
+ rsa_method_.private_transform = rsa_private_transform;
+ rsa_method_.flags = RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_OPAQUE;
+ ENGINE_set_RSA_method(engine_, &rsa_method_, sizeof(rsa_method_));
- NULL /* init */,
- NULL /* finish */,
- NULL /* group_order_size */,
- ecdsa_sign,
- ECDSA_FLAG_OPAQUE,
+ memset(&ecdsa_method_, 0, sizeof(ecdsa_method_));
+ ecdsa_method_.common.is_static = 1;
+ ecdsa_method_.sign = ecdsa_sign;
+ ecdsa_method_.flags = ECDSA_FLAG_OPAQUE;
+ ENGINE_set_ECDSA_method(engine_, &ecdsa_method_, sizeof(ecdsa_method_));
+ }
+
+ int rsa_ex_index() const { return rsa_index_; }
+ int ec_key_ex_index() const { return ec_key_index_; }
+
+ const ENGINE* engine() const { return engine_; }
+
+ private:
+ const int rsa_index_;
+ const int ec_key_index_;
+ RSA_METHOD rsa_method_;
+ ECDSA_METHOD ecdsa_method_;
+ ENGINE* const engine_;
};
+pthread_once_t g_keystore_engine_once = PTHREAD_ONCE_INIT;
+KeystoreEngine *g_keystore_engine;
+
+/* init_keystore_engine is called to initialize |g_keystore_engine|. This
+ * should only be called by |pthread_once|. */
+void init_keystore_engine() {
+ g_keystore_engine = new KeystoreEngine;
+#ifndef BACKEND_WIFI_HIDL
+ g_keystore_backend = new KeystoreBackendBinder;
+#else
+ g_keystore_backend = new KeystoreBackendHidl;
+#endif
+}
+
+/* ensure_keystore_engine ensures that |g_keystore_engine| is pointing to a
+ * valid |KeystoreEngine| object and creates one if not. */
+void ensure_keystore_engine() {
+ pthread_once(&g_keystore_engine_once, init_keystore_engine);
+}
+
+const char* rsa_get_key_id(const RSA* rsa) {
+ return reinterpret_cast<char*>(
+ RSA_get_ex_data(rsa, g_keystore_engine->rsa_ex_index()));
+}
+
+const char* ecdsa_get_key_id(const EC_KEY* ec_key) {
+ return reinterpret_cast<char*>(
+ EC_KEY_get_ex_data(ec_key, g_keystore_engine->ec_key_ex_index()));
+}
+
struct EVP_PKEY_Delete {
void operator()(EVP_PKEY* p) const {
EVP_PKEY_free(p);
diff --git a/keystore/grant_store.cpp b/keystore/grant_store.cpp
index 9c2e591..2fb09c1 100644
--- a/keystore/grant_store.cpp
+++ b/keystore/grant_store.cpp
@@ -25,8 +25,10 @@
static const char* kKeystoreGrantInfix = "_KEYSTOREGRANT_";
static constexpr size_t kKeystoreGrantInfixLength = 15;
-Grant::Grant(const std::string& alias, const std::string& key_file, const uint64_t grant_no)
- : alias_(alias), key_file_(key_file), grant_no_(grant_no) {}
+Grant::Grant(const std::string& alias, const std::string& owner_dir_name, const uid_t owner_uid,
+ const uint64_t grant_no)
+ : alias_(alias), owner_dir_name_(owner_dir_name), owner_uid_(owner_uid),
+ grant_no_(grant_no) {}
static std::pair<uint64_t, std::string> parseGrantAlias(const std::string& grantAlias) {
auto pos = grantAlias.rfind(kKeystoreGrantInfix);
@@ -39,7 +41,8 @@
return {grant_no, wrapped_alias};
}
-std::string GrantStore::put(const uid_t uid, const std::string& alias, const std::string& key_file) {
+std::string GrantStore::put(const uid_t uid, const std::string& alias,
+ const std::string& owner_dir_name, const uid_t owner_uid) {
std::stringstream s;
s << alias << kKeystoreGrantInfix;
auto& uid_grant_list = grants_[uid];
@@ -47,10 +50,12 @@
bool success = false;
auto iterator = std::find_if(uid_grant_list.begin(), uid_grant_list.end(),
[&](auto& entry) {
- return success = entry.alias_ == alias && entry.key_file_ == key_file;
+ return success = entry.alias_ == alias && entry.owner_dir_name_ == owner_dir_name
+ && entry.owner_uid_ == owner_uid;
});
while (!success) {
- std::tie(iterator, success) = uid_grant_list.emplace(alias, key_file, std::rand());
+ std::tie(iterator, success) = uid_grant_list.emplace(alias, owner_dir_name, owner_uid,
+ std::rand());
}
s << iterator->grant_no_;
return s.str();
@@ -70,10 +75,10 @@
return &(*grant);
}
-bool GrantStore::removeByFileName(const uid_t uid, const std::string& fileName) {
- auto& uid_grant_list = grants_.operator[](uid);
+bool GrantStore::removeByFileAlias(const uid_t uid, const std::string& alias) {
+ auto& uid_grant_list = grants_[uid];
for (auto i = uid_grant_list.begin(); i != uid_grant_list.end(); ++i) {
- if (i->key_file_ == fileName) {
+ if (i->alias_ == alias) {
uid_grant_list.erase(i);
return true;
}
diff --git a/keystore/grant_store.h b/keystore/grant_store.h
index 43e814e..ab03630 100644
--- a/keystore/grant_store.h
+++ b/keystore/grant_store.h
@@ -32,9 +32,11 @@
*/
class Grant {
public:
- Grant(const std::string& alias, const std::string& key_file, const uint64_t grant_no);
+ Grant(const std::string& alias, const std::string& owner_dir_name, const uid_t owner_uid,
+ const uint64_t grant_no);
std::string alias_;
- std::string key_file_;
+ std::string owner_dir_name_;
+ uid_t owner_uid_;
uint64_t grant_no_;
operator const uint64_t&() const { return grant_no_; }
@@ -52,9 +54,10 @@
class GrantStore {
public:
GrantStore() : grants_() {}
- std::string put(const uid_t uid, const std::string& alias, const std::string& key_file);
+ std::string put(const uid_t uid, const std::string& alias, const std::string& owner_dir_name,
+ const uid_t owner_uid);
const Grant* get(const uid_t uid, const std::string& alias) const;
- bool removeByFileName(const uid_t uid, const std::string& filename);
+ bool removeByFileAlias(const uid_t uid, const std::string& alias);
// GrantStore is neither copyable nor movable.
GrantStore(const GrantStore&) = delete;
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 621c505..310d8e2 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -526,7 +526,7 @@
return String16();
}
- return String16(mKeyStore->addGrant(filename.string(), String8(name).string(), granteeUid).c_str());
+ return String16(mKeyStore->addGrant(String8(name).string(), granteeUid, callingUid).c_str());
}
KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
@@ -543,8 +543,8 @@
return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
}
- return mKeyStore->removeGrant(filename.string(), granteeUid) ? ResponseCode::NO_ERROR
- : ResponseCode::KEY_NOT_FOUND;
+ return mKeyStore->removeGrant(name8, granteeUid) ? ResponseCode::NO_ERROR
+ : ResponseCode::KEY_NOT_FOUND;
}
int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 1564a64..8037335 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -24,6 +24,7 @@
#include <openssl/bio.h>
#include <utils/String16.h>
+#include <utils/String8.h>
#include <keystore/IKeystoreService.h>
@@ -39,6 +40,7 @@
const android::String16 KeyStore::sRSAKeyType("RSA");
using namespace keystore;
+using android::String8;
KeyStore::KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback,
bool allowNewFallback)
@@ -414,12 +416,13 @@
return ResponseCode::NO_ERROR;
}
-std::string KeyStore::addGrant(const char* filename, const char* alias, uid_t granteeUid) {
- return mGrants.put(granteeUid, alias, filename);
+std::string KeyStore::addGrant(const char* alias, uid_t granterUid, uid_t granteeUid) {
+ return mGrants.put(granteeUid, alias, getUserStateByUid(granterUid)->getUserDirName(),
+ granterUid);
}
-bool KeyStore::removeGrant(const char* filename, uid_t granteeUid) {
- return mGrants.removeByFileName(granteeUid, filename);
+bool KeyStore::removeGrant(const char* alias, uid_t granteeUid) {
+ return mGrants.removeByFileAlias(granteeUid, alias);
}
ResponseCode KeyStore::importKey(const uint8_t* key, size_t keyLen, const char* filename,
@@ -519,7 +522,8 @@
// They might be using a granted key.
auto grant = mGrants.get(uid, keyName.string());
if (!grant) return ResponseCode::KEY_NOT_FOUND;
- filepath8 = grant->key_file_.c_str();
+ filepath8.format("%s/%s", grant->owner_dir_name_.c_str(),
+ getKeyNameForUid(String8(grant->alias_.c_str()), grant->owner_uid_, type).c_str());
// It is a granted key. Try to load it.
return get(filepath8.string(), keyBlob, type, userId);
diff --git a/keystore/keystore.h b/keystore/keystore.h
index a08508f..39761bb 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -87,8 +87,8 @@
ResponseCode list(const android::String8& prefix, android::Vector<android::String16>* matches,
uid_t userId);
- std::string addGrant(const char* filename, const char* alias, uid_t granteeUid);
- bool removeGrant(const char* filename, uid_t granteeUid);
+ std::string addGrant(const char* alias, uid_t granterUid, uid_t granteeUid);
+ bool removeGrant(const char* alias, uid_t granteeUid);
ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t userId,
int32_t flags);