Fix RSA and ECDSA key import in softkeymaster.
Bug: 20055613
Change-Id: Ie1998476659cb4c9e1311f0391cc3a6ecb9204ca
diff --git a/soft_keymaster_device.cpp b/soft_keymaster_device.cpp
index 3ddce33..b1e0161 100644
--- a/soft_keymaster_device.cpp
+++ b/soft_keymaster_device.cpp
@@ -27,6 +27,8 @@
#include <type_traits>
+#include <openssl/x509.h>
+
#include <hardware/keymaster1.h>
#define LOG_TAG "SoftKeymasterDevice"
#include <cutils/log.h>
@@ -228,6 +230,11 @@
ImportKeyRequest request;
StoreDefaultNewKeyParams(&request.key_description);
+ keymaster_algorithm_t algorithm;
+ keymaster_error_t err = GetPkcs8KeyAlgorithm(key, key_length, &algorithm);
+ if (err != KM_ERROR_OK)
+ return err;
+ request.key_description.push_back(TAG_ALGORITHM, algorithm);
request.SetKeyMaterial(key, key_length);
request.key_format = KM_KEY_FORMAT_PKCS8;
@@ -250,6 +257,50 @@
return KM_ERROR_OK;
}
+struct EVP_PKEY_Delete {
+ void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
+};
+
+struct PKCS8_PRIV_KEY_INFO_Delete {
+ void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
+};
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::GetPkcs8KeyAlgorithm(const uint8_t* key, size_t key_length,
+ keymaster_algorithm_t* algorithm) {
+ if (key == NULL) {
+ LOG_E("No key specified for import", 0);
+ return KM_ERROR_UNEXPECTED_NULL_POINTER;
+ }
+
+ UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8(
+ d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
+ if (pkcs8.get() == NULL) {
+ LOG_E("Could not parse PKCS8 key blob", 0);
+ return KM_ERROR_INVALID_KEY_BLOB;
+ }
+
+ UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKCS82PKEY(pkcs8.get()));
+ if (pkey.get() == NULL) {
+ LOG_E("Could not extract key from PKCS8 key blob", 0);
+ return KM_ERROR_INVALID_KEY_BLOB;
+ }
+
+ switch (EVP_PKEY_type(pkey->type)) {
+ case EVP_PKEY_RSA:
+ *algorithm = KM_ALGORITHM_RSA;
+ break;
+ case EVP_PKEY_EC:
+ *algorithm = KM_ALGORITHM_ECDSA;
+ break;
+ default:
+ LOG_E("Unsupported algorithm %d", EVP_PKEY_type(pkey->type));
+ return KM_ERROR_UNSUPPORTED_ALGORITHM;
+ }
+
+ return KM_ERROR_OK;
+}
+
/* static */
int SoftKeymasterDevice::get_keypair_public(const struct keymaster1_device* dev,
const uint8_t* key_blob, const size_t key_blob_length,