Merge "Keystore 2.0: Legacy support: Tweak to certificate generation."
diff --git a/keystore2/src/crypto/certificate_utils.cpp b/keystore2/src/crypto/certificate_utils.cpp
index 500600f..4b0dca4 100644
--- a/keystore2/src/crypto/certificate_utils.cpp
+++ b/keystore2/src/crypto/certificate_utils.cpp
@@ -544,6 +544,9 @@
bssl::UniquePtr<uint8_t> free_cert_buf(cert_buf);
auto signature = sign(cert_buf, buf_len);
+ if (signature.empty()) {
+ return CertUtilsError::SignatureFailed;
+ }
if (!ASN1_STRING_set(certificate->signature, signature.data(), signature.size())) {
return CertUtilsError::BoringSsl;
diff --git a/keystore2/src/crypto/include/certificate_utils.h b/keystore2/src/crypto/include/certificate_utils.h
index 9d41eb8..1e80d80 100644
--- a/keystore2/src/crypto/include/certificate_utils.h
+++ b/keystore2/src/crypto/include/certificate_utils.h
@@ -52,6 +52,7 @@
MemoryAllocation,
InvalidArgument,
UnexpectedNullPointer,
+ SignatureFailed,
};
private:
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index d965922..a27bfd1 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -19,6 +19,7 @@
#include "km_compat_type_conversion.h"
#include <aidl/android/hardware/security/keymint/Algorithm.h>
#include <aidl/android/hardware/security/keymint/Digest.h>
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
#include <aidl/android/hardware/security/keymint/PaddingMode.h>
#include <aidl/android/system/keystore2/ResponseCode.h>
#include <android-base/logging.h>
@@ -59,6 +60,14 @@
return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
}
+static V4_0_ErrorCode toErrorCode(const ScopedAStatus& status) {
+ if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+ return static_cast<V4_0_ErrorCode>(status.getServiceSpecificError());
+ } else {
+ return V4_0_ErrorCode::UNKNOWN_ERROR;
+ }
+}
+
static std::vector<V4_0::KeyParameter>
convertKeyParametersToLegacy(const std::vector<KeyParameter>& kps) {
std::vector<V4_0::KeyParameter> legacyKps(kps.size());
@@ -660,22 +669,23 @@
BeginResult beginResult;
auto error = begin(KeyPurpose::SIGN, keyBlob, kps, HardwareAuthToken(), &beginResult);
if (!error.isOk()) {
- errorCode = static_cast<V4_0_ErrorCode>(error.getServiceSpecificError());
+ errorCode = toErrorCode(error);
return std::vector<uint8_t>();
}
std::optional<KeyParameterArray> outParams;
std::optional<ByteArray> outByte;
int32_t status;
- beginResult.operation->update(std::nullopt, dataVec, std::nullopt, std::nullopt,
- &outParams, &outByte, &status);
- if (!status) {
+ error = beginResult.operation->update(std::nullopt, dataVec, std::nullopt, std::nullopt,
+ &outParams, &outByte, &status);
+ if (!error.isOk()) {
+ errorCode = toErrorCode(error);
return std::vector<uint8_t>();
}
std::vector<uint8_t> result;
error = beginResult.operation->finish(std::nullopt, std::nullopt, std::nullopt,
std::nullopt, std::nullopt, &outParams, &result);
if (!error.isOk()) {
- errorCode = static_cast<V4_0_ErrorCode>(error.getServiceSpecificError());
+ errorCode = toErrorCode(error);
return std::vector<uint8_t>();
}
return result;
@@ -725,6 +735,7 @@
}
});
if (!result.isOk()) {
+ LOG(ERROR) << __func__ << ": Call to attestKey failed.";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}
if (errorCode != V4_0_ErrorCode::OK) {
@@ -743,6 +754,7 @@
// setIssuer
auto error = keystore::setIssuer(&*cert, &*cert, false);
if (error) {
+ LOG(ERROR) << __func__ << ": Set issuer failed.";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}
@@ -755,26 +767,27 @@
return false;
}) != keyParams.end();
auto noAuthRequired = containsParam(keyParams, KMV1::TAG_NO_AUTH_REQUIRED);
- if (canSelfSign && noAuthRequired) {
- auto errorCode = signCertificate(keyParams, keyBlob, &*cert);
- if (errorCode.has_value()) {
- return errorCode.value();
- }
- } else {
+ // If we cannot sign because of purpose or authorization requirement,
+ if (!(canSelfSign && noAuthRequired)
+ // or if self signing fails for any other reason,
+ || signCertificate(keyParams, keyBlob, &*cert).has_value()) {
+ // we sign with ephemeral key.
keystore::EVP_PKEY_CTX_Ptr pkey_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL));
EVP_PKEY_keygen_init(pkey_ctx.get());
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkey_ctx.get(), NID_X9_62_prime256v1);
EVP_PKEY* pkey_ptr = nullptr;
EVP_PKEY_keygen(pkey_ctx.get(), &pkey_ptr);
error = keystore::signCert(&*cert, pkey_ptr);
- }
- if (error) {
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ if (error) {
+ LOG(ERROR) << __func__ << ": signCert failed.";
+ return V4_0_ErrorCode::UNKNOWN_ERROR;
+ }
}
// encodeCert
auto encodedCertOrError = keystore::encodeCert(&*cert);
if (std::holds_alternative<keystore::CertUtilsError>(encodedCertOrError)) {
+ LOG(ERROR) << __func__ << ": encodeCert failed.";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}