OSDN Git Service

Remove legacy functions form IKeystoreService.aidl
authorJanis Danisevskis <jdanis@google.com>
Thu, 9 Aug 2018 18:15:44 +0000 (11:15 -0700)
committerJanis Danisevskis <jdanis@google.com>
Wed, 7 Nov 2018 19:10:26 +0000 (11:10 -0800)
In preparation for making the keystore service asynchronous we remove
redundant legacy functionality from the protocol.

This patch removes the functions get_pubkey, sign, verify, generate,
and import_key. Which have long been superseded by exportKey
(get_pubkey), begin/update/finish (sign, verify), generateKey
(generate), and importKey (import_key).

Test: Not yet
Bug: 109769728
Change-Id: Ia59b30377684c013e9b4496ca9e365f8c2710ec1

wifi/keystore/1.0/default/Android.bp
wifi/keystore/1.0/default/keystore.cpp

index cb11fb3..b569113 100644 (file)
@@ -15,6 +15,7 @@ cc_library_shared {
         "libhidltransport",
         "libkeystore_aidl",
         "libkeystore_binder",
+        "libkeystore_parcelables",
         "liblog",
         "libutils",
     ],
index 1245670..23aed30 100644 (file)
@@ -3,9 +3,44 @@
 #include <binder/IServiceManager.h>
 #include <private/android_filesystem_config.h>
 
+#include <keystore/KeyCharacteristics.h>
+#include <keystore/KeymasterArguments.h>
+#include <keystore/KeymasterBlob.h>
+#include <keystore/OperationResult.h>
+#include <keystore/keymaster_types.h>
+#include <keystore/keystore.h>
+#include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_return_types.h>
+
 #include <vector>
 #include "include/wifikeystorehal/keystore.h"
 
+using android::hardware::keymaster::V4_0::Algorithm;
+using android::hardware::keymaster::V4_0::authorizationValue;
+using android::hardware::keymaster::V4_0::Digest;
+using android::hardware::keymaster::V4_0::KeyFormat;
+using android::hardware::keymaster::V4_0::KeyParameter;
+using android::hardware::keymaster::V4_0::KeyPurpose;
+using android::hardware::keymaster::V4_0::NullOr;
+using android::hardware::keymaster::V4_0::PaddingMode;
+using android::hardware::keymaster::V4_0::TAG_ALGORITHM;
+using android::hardware::keymaster::V4_0::TAG_DIGEST;
+using android::hardware::keymaster::V4_0::TAG_PADDING;
+using android::security::keymaster::ExportResult;
+using android::security::keymaster::KeyCharacteristics;
+using android::security::keymaster::KeymasterArguments;
+using android::security::keymaster::KeymasterBlob;
+using android::security::keymaster::OperationResult;
+
+using KSReturn = keystore::KeyStoreNativeReturnCode;
+
+namespace {
+constexpr const char kKeystoreServiceName[] = "android.security.keystore";
+constexpr int32_t UID_SELF = -1;
+};  // namespace
+
+#define AT __func__ << ":" << __LINE__ << " "
+
 namespace android {
 namespace system {
 namespace wifi {
@@ -17,7 +52,7 @@ using security::IKeystoreService;
 // Methods from ::android::hardware::wifi::keystore::V1_0::IKeystore follow.
 Return<void> Keystore::getBlob(const hidl_string& key, getBlob_cb _hidl_cb) {
     sp<IKeystoreService> service = interface_cast<IKeystoreService>(
-        defaultServiceManager()->getService(String16("android.security.keystore")));
+        defaultServiceManager()->getService(String16(kKeystoreServiceName)));
     if (service == nullptr) {
         _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
         return Void();
@@ -34,38 +69,143 @@ Return<void> Keystore::getBlob(const hidl_string& key, getBlob_cb _hidl_cb) {
 }
 
 Return<void> Keystore::getPublicKey(const hidl_string& keyId, getPublicKey_cb _hidl_cb) {
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(
-        defaultServiceManager()->getService(String16("android.security.keystore")));
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16(kKeystoreServiceName));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
     if (service == nullptr) {
+        LOG(ERROR) << AT << "could not contact keystore";
         _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
         return Void();
     }
-    ::std::vector<uint8_t> pubkey;
-    auto ret = service->get_pubkey(String16(keyId.c_str()), &pubkey);
-    if (!ret.isOk()) {
+
+    ExportResult result;
+    auto binder_result = service->exportKey(
+        String16(keyId.c_str()), static_cast<int32_t>(KeyFormat::X509),
+        KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
         _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
         return Void();
     }
-    _hidl_cb(KeystoreStatusCode::SUCCESS, (hidl_vec<uint8_t>)pubkey);
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "exportKey failed: " << int32_t(result.resultCode);
+        _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+        return Void();
+    }
+
+    _hidl_cb(KeystoreStatusCode::SUCCESS, result.exportData);
     return Void();
 }
 
+static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
+    const ::android::security::keymaster::KeyCharacteristics& characteristics) {
+    for (const auto& param : characteristics.hardwareEnforced.getParameters()) {
+        auto algo = authorizationValue(TAG_ALGORITHM, param);
+        if (algo.isOk()) return algo;
+    }
+    for (const auto& param : characteristics.softwareEnforced.getParameters()) {
+        auto algo = authorizationValue(TAG_ALGORITHM, param);
+        if (algo.isOk()) return algo;
+    }
+    return {};
+}
+
 Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& dataToSign,
                             sign_cb _hidl_cb) {
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(
-        defaultServiceManager()->getService(String16("android.security.keystore")));
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16(kKeystoreServiceName));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
     if (service == nullptr) {
+        LOG(ERROR) << AT << "could not contact keystore";
         _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
         return Void();
     }
-    ::std::vector<uint8_t> signedData;
 
-    auto ret = service->sign(String16(keyId.c_str()), dataToSign, &signedData);
-    if (!ret.isOk()) {
+    KeyCharacteristics keyCharacteristics;
+    String16 key_name16(keyId.c_str());
+    int32_t aidl_result;
+    auto binder_result = service->getKeyCharacteristics(
+        key_name16, KeymasterBlob(), KeymasterBlob(), UID_SELF, &keyCharacteristics, &aidl_result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+        return Void();
+    }
+    if (KSReturn(aidl_result).isOk()) {
+        LOG(ERROR) << AT << "getKeyCharacteristics failed: " << aidl_result;
+    }
+
+    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(keyCharacteristics);
+    if (!algorithm.isOk()) {
+        LOG(ERROR) << AT << "could not get algorithm from key characteristics";
         _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
         return Void();
     }
-    _hidl_cb(KeystoreStatusCode::SUCCESS, (hidl_vec<uint8_t>)signedData);
+
+    hidl_vec<KeyParameter> params(3);
+    params[0] = Authorization(TAG_DIGEST, Digest::NONE);
+    params[1] = Authorization(TAG_PADDING, PaddingMode::NONE);
+    params[2] = Authorization(TAG_ALGORITHM, algorithm.value());
+
+    android::sp<android::IBinder> token(new android::BBinder);
+    OperationResult result;
+    binder_result = service->begin(token, key_name16, (int)KeyPurpose::SIGN, true /*pruneable*/,
+                                   KeymasterArguments(params), std::vector<uint8_t>() /* entropy */,
+                                   UID_SELF, &result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+        return Void();
+    }
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "begin failed: " << int32_t(result.resultCode);
+        _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+        return Void();
+    }
+    auto handle = std::move(result.token);
+
+    const uint8_t* in = dataToSign.data();
+    size_t len = dataToSign.size();
+    do {
+        binder_result = service->update(handle, KeymasterArguments(params),
+                                        std::vector<uint8_t>(in, in + len), &result);
+        if (!binder_result.isOk()) {
+            LOG(ERROR) << AT << "communication error while calling keystore";
+            _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+            return Void();
+        }
+        if (!result.resultCode.isOk()) {
+            LOG(ERROR) << AT << "update failed: " << int32_t(result.resultCode);
+            _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+            return Void();
+        }
+        if ((size_t)result.inputConsumed > len) {
+            LOG(ERROR) << AT << "update consumed more data than provided";
+            service->abort(handle, &aidl_result);
+            _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+            return Void();
+        }
+        len -= result.inputConsumed;
+        in += result.inputConsumed;
+    } while (len > 0);
+
+    binder_result =
+        service->finish(handle, KeymasterArguments(params), std::vector<uint8_t>() /* signature */,
+                        std::vector<uint8_t>() /* entropy */, &result);
+    if (!binder_result.isOk()) {
+        LOG(ERROR) << AT << "communication error while calling keystore";
+        _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+        return Void();
+    }
+    if (!result.resultCode.isOk()) {
+        LOG(ERROR) << AT << "finish failed: " << int32_t(result.resultCode);
+        _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
+        return Void();
+    }
+
+    _hidl_cb(KeystoreStatusCode::SUCCESS, result.data);
     return Void();
 }