Merge changes from topic "revert-1956689-add rkp to identity-default-ENFHZTRTBV"
* changes:
Revert "Fix formatting of identity credential aidl"
Revert "Log to logd in the default identity service"
Revert "Refactor IC support for RKP"
Revert "Add remote key provisioning to the IC HAL"
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index e3b8191..dad3b8d 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -15,7 +15,6 @@
],
imports: [
"android.hardware.keymaster",
- "android.hardware.security.keymint",
],
stability: "vintf",
backend: {
@@ -26,7 +25,6 @@
vndk: {
enabled: true,
},
- apps_enabled: false,
},
},
versions: [
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
index 9b96ea8..cd8d56b 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
@@ -39,5 +39,4 @@
int dataChunkSize;
boolean isDirectAccess;
@utf8InCpp String[] supportedDocTypes;
- boolean isRemoteKeyProvisioningSupported = false;
}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
index 31ca8b1..c912c52 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -38,7 +38,6 @@
android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential);
android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData);
android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite);
- android.hardware.security.keymint.IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
const int STATUS_OK = 0;
const int STATUS_FAILED = 1;
const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
index 5377349..9a0fa9e 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -41,5 +41,4 @@
byte[] addEntryValue(in byte[] content);
@SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
- void setRemotelyProvisionedAttestationKey(in byte[] attestationKeyBlob, in byte[] attestationCertificate);
}
diff --git a/identity/aidl/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/android/hardware/identity/HardwareInformation.aidl
index acd13b6..d67739d 100644
--- a/identity/aidl/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/android/hardware/identity/HardwareInformation.aidl
@@ -51,19 +51,4 @@
*
*/
@utf8InCpp String[] supportedDocTypes;
-
- /**
- * isRemoteKeyProvisioningSupported indicates whether or not the underlying implementation
- * supports a remotely provisioned key for attestation or not. If this field is false, then
- * the implementation only uses a factory-installed, fixed attestation key. If this field is
- * true, then an IRemotelyProvisionedComponent is associated with the IIdentityCredentialStore,
- * and a remotely provisioned key blob may be provided for credential key attestation.
- *
- * Note that remote provisioning is not required, even when it is supported. Implementations
- * MUST use a factory-installed attestation key as a fallback for when there are no
- * remotely provisioned keys available. This behavior mirrors keystore key attestation.
- *
- * This field was added in API version 4.
- */
- boolean isRemoteKeyProvisioningSupported = false;
}
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index d3e4da0..86be7f5 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -21,7 +21,6 @@
import android.hardware.identity.IIdentityCredential;
import android.hardware.identity.IPresentationSession;
import android.hardware.identity.IWritableIdentityCredential;
-import android.hardware.security.keymint.IRemotelyProvisionedComponent;
/**
* IIdentityCredentialStore provides an interface to a secure store for user identity documents.
@@ -216,16 +215,16 @@
* @return an IWritableIdentityCredential interface that provides operations to
* provision a credential.
*/
- IWritableIdentityCredential createCredential(
- in @utf8InCpp String docType, in boolean testCredential);
+ IWritableIdentityCredential createCredential(in @utf8InCpp String docType,
+ in boolean testCredential);
/**
* getCredential retrieves an IIdentityCredential interface which allows use of a stored
* Credential.
*
- * The cipher suite used to communicate with the remote verifier must also be specified.
- * Currently only a single cipher-suite is supported. Support for other cipher suites may be
- * added in a future version of this HAL.
+ * The cipher suite used to communicate with the remote verifier must also be specified. Currently
+ * only a single cipher-suite is supported. Support for other cipher suites may be added in a
+ * future version of this HAL.
*
* This method fails with STATUS_INVALID_DATA if the passed in credentialData cannot be
* decoded or decrypted.
@@ -264,23 +263,4 @@
* @return an IPresentationSession interface.
*/
IPresentationSession createPresentationSession(in CipherSuite cipherSuite);
-
- /**
- * Fetch the IRemotelyProvisionedComponent that is used to generate attestation keys for
- * remote provisionining. Keys generated by this component are to be certified by a remote
- * provisionined authority, then used to attest to credential keys via
- * IWritableIdentityCredential.setRemotelyProvisionedAttestationKey.
- *
- * Support for this method is indicated by HardwareInformation. If the
- * |isRemoteKeyProvisioningSupported| field is false, this method will fail with
- * EX_UNSUPPORTED_OPERATION.
- *
- * This method was added in API version 4.
- *
- * @see
- * android.hardware.identity.IWritableIdentityCredential#setRemotelyProvisionedAttestationKey
- *
- * @return an IRemotelyProvisionedComponent that is used to generate attestation keys.
- */
- IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
}
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index 756b008..22bcf61 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -131,8 +131,7 @@
*
* @return the X.509 certificate chain for the credentialKey
*/
- Certificate[] getAttestationCertificate(
- in byte[] attestationApplicationId, in byte[] attestationChallenge);
+ Certificate[] getAttestationCertificate(in byte[] attestationApplicationId, in byte[] attestationChallenge);
/**
* Start the personalization process.
@@ -184,11 +183,11 @@
* in the secure environment. If this requirement is not met the call fails with
* STATUS_INVALID_DATA.
*
- * @return a structure with the passed-in data and MAC created with storageKey for
- * authenticating the data at a later point in time.
+ * @return a structure with the passed-in data and MAC created with storageKey for authenticating
+ * the data at a later point in time.
*/
SecureAccessControlProfile addAccessControlProfile(in int id, in Certificate readerCertificate,
- in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
+ in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
/**
* Begins the process of adding an entry to the credential. All access control profiles must be
@@ -210,7 +209,7 @@
* is not met this method fails with STATUS_INVALID_DATA.
*/
void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace,
- in @utf8InCpp String name, in int entrySize);
+ in @utf8InCpp String name, in int entrySize);
/**
* Continues the process of adding an entry, providing a value or part of a value.
@@ -222,8 +221,8 @@
* chunk sizes must equal the value of the beginAddEntry() entrySize argument. If this
* requirement is not met the call fails with STATUS_INVALID_DATA.
*
- * @param content is the entry value, encoded as CBOR. In the case the content exceeds
- * gcmChunkSize, this may be partial content up to gcmChunkSize bytes long.
+ * @param content is the entry value, encoded as CBOR. In the case the content exceeds gcmChunkSize,
+ * this may be partial content up to gcmChunkSize bytes long.
*
* @return the encrypted and MACed content. For directly-available credentials the contents are
* implementation-defined. For other credentials, the result contains
@@ -322,7 +321,8 @@
* }
*/
@SuppressWarnings(value={"out-array"})
- void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
+ void finishAddingEntries(out byte[] credentialData,
+ out byte[] proofOfProvisioningSignature);
/**
* Sets the expected size of the ProofOfProvisioning returned by finishAddingEntries(). This
@@ -336,35 +336,4 @@
*/
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
- /**
- * Sets the attestation key used to sign the credentialKey certificate. This method is used to
- * support remotely provisioned attestation keys, removing the credential's dependency on any
- * factory-provisioned attestation key.
- *
- * This method must be called before getAttestationCertificate. After this method is called,
- * the certificate chain returned by getAttestationCertificate will contain a leaf certificate
- * signed by attestationKeyBlob and the chain in attestationCertificate will make up the rest
- * of the returned chain.
- *
- * Returns EX_UNSUPPORTED_FUNCTION if remote provisioning is not supported
- * (see IIdentityCredentialStore.getHardwareInformation()).
- *
- * This method was added in API version 4.
- *
- * @param attestationKeyBlob is a key blob generated by the IRemotelyProvisionedComponent that
- * is returned by ICredentialStore.getRemotelyProvisionedComponent. The format is vendor-
- * specified, and matches the key blob returned by IKeyMintDevice.generateKey.
- *
- * @param attestationCertificate contains the X.509 certificate chain that certifies the
- * attestationKeyBlob. This certificate is expected to have been remotely provisioned
- * by a trusted authority. This parameter must contain a concatenated chain of DER-encoded
- * X.509 certificates. The certificates must be ordered such that the attestation key
- * certificate is first (starting at byte 0). The issuer certificate for the attestation
- * certificate immediately follows, continuing this chain to the final, root certificate.
- *
- * @see getAttestationCertificate
- * @see android.hardware.identity.ICredentialStore#getRemotelyProvisionedComponent
- */
- void setRemotelyProvisionedAttestationKey(
- in byte[] attestationKeyBlob, in byte[] attestationCertificate);
}
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index 32b3543..ca24afa 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -42,7 +42,6 @@
"android.hardware.identity-support-lib",
"android.hardware.identity-V4-ndk",
"android.hardware.keymaster-V4-ndk",
- "android.hardware.security.keymint-V2-ndk",
],
}
@@ -82,9 +81,6 @@
init_rc: ["identity-default.rc"],
vintf_fragments: ["identity-default.xml"],
vendor: true,
- defaults: [
- "keymint_use_latest_hal_aidl_ndk_static",
- ],
cflags: [
"-Wall",
"-Wextra",
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index 3fd9f1d..c98a91e 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -267,42 +267,25 @@
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, bool testCredential,
- const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
- const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
- uint8_t* cert, size_t* certSize) {
- vector<uint8_t> flatChain;
- vector<uint8_t> keyPair;
- vector<uint8_t> challengeVec(challenge, challenge + challengeSize);
- vector<uint8_t> applicationIdVec(applicationId, applicationId + applicationIdSize);
- if (attestationKeyBlob && attestationKeyBlobSize > 0 && attestationKeyCert &&
- attestationKeyCertSize > 0) {
- vector<uint8_t> attestationKeyBlobVec(attestationKeyBlob,
- attestationKeyBlob + attestationKeyBlobSize);
- vector<uint8_t> attestationKeyCertVec(attestationKeyCert,
- attestationKeyCert + attestationKeyCertSize);
- optional<std::pair<vector<uint8_t>, vector<uint8_t>>> keyAndCert =
- android::hardware::identity::support::createEcKeyPairWithAttestationKey(
- challengeVec, applicationIdVec, attestationKeyBlobVec,
- attestationKeyCertVec, testCredential);
- if (!keyAndCert) {
- eicDebug("Error generating CredentialKey and attestation");
- return false;
- }
- keyPair = std::move(keyAndCert->first);
- flatChain = std::move(keyAndCert->second);
- } else {
- optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
- android::hardware::identity::support::createEcKeyPairAndAttestation(
- challengeVec, applicationIdVec, testCredential);
- if (!ret) {
- eicDebug("Error generating CredentialKey and attestation");
- return false;
- }
- keyPair = std::move(ret->first);
- flatChain = android::hardware::identity::support::certificateChainJoin(ret->second);
+ size_t applicationIdSize, bool testCredential, uint8_t* cert,
+ size_t* certSize) {
+ vector<uint8_t> challengeVec(challengeSize);
+ memcpy(challengeVec.data(), challenge, challengeSize);
+
+ vector<uint8_t> applicationIdVec(applicationIdSize);
+ memcpy(applicationIdVec.data(), applicationId, applicationIdSize);
+
+ optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
+ android::hardware::identity::support::createEcKeyPairAndAttestation(
+ challengeVec, applicationIdVec, testCredential);
+ if (!ret) {
+ eicDebug("Error generating CredentialKey and attestation");
+ return false;
}
+ // Extract certificate chain.
+ vector<uint8_t> flatChain =
+ android::hardware::identity::support::certificateChainJoin(ret.value().second);
if (*certSize < flatChain.size()) {
eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
flatChain.size());
@@ -313,7 +296,7 @@
// Extract private key.
optional<vector<uint8_t>> privKey =
- android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair);
+ android::hardware::identity::support::ecKeyPairGetPrivateKey(ret.value().first);
if (!privKey) {
eicDebug("Error extracting private key");
return false;
@@ -537,12 +520,10 @@
#ifdef EIC_DEBUG
void eicPrint(const char* format, ...) {
- char buf[1024];
va_list args;
va_start(args, format);
- vsnprintf(buf, sizeof(buf), format, args);
+ vfprintf(stderr, format, args);
va_end(args);
- LOG(INFO) << buf;
}
void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index 9b9a749..91e634c 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -155,11 +155,7 @@
size_t publicKeyCertSize = sizeof publicKeyCert;
if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
applicationId.data(), applicationId.size(),
- /*attestationKeyBlob=*/nullptr,
- /*attestationKeyBlobSize=*/0,
- /*attestationKeyCert=*/nullptr,
- /*attestationKeyCertSize=*/0, publicKeyCert,
- &publicKeyCertSize)) {
+ publicKeyCert, &publicKeyCertSize)) {
return std::nullopt;
}
vector<uint8_t> pubKeyCert(publicKeyCertSize);
@@ -167,23 +163,6 @@
return pubKeyCert;
}
-optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKeyUsingRkp(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attstationKeyCert) {
- size_t publicKeyCertSize = 4096;
- vector<uint8_t> publicKeyCert(publicKeyCertSize);
- if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
- applicationId.data(), applicationId.size(),
- attestationKeyBlob.data(), attestationKeyBlob.size(),
- attstationKeyCert.data(), attstationKeyCert.size(),
- publicKeyCert.data(), &publicKeyCertSize)) {
- LOG(ERROR) << "error creating credential key";
- return std::nullopt;
- }
- publicKeyCert.resize(publicKeyCertSize);
- return publicKeyCert;
-}
-
bool FakeSecureHardwareProvisioningProxy::startPersonalization(
int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
size_t expectedProofOfProvisioningSize) {
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index 2512074..df98c7a 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -43,11 +43,6 @@
optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
const vector<uint8_t>& applicationId) override;
- optional<vector<uint8_t>> createCredentialKeyUsingRkp(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- const vector<uint8_t>& attestationKeyBlob,
- const vector<uint8_t>& attestationKeyCert) override;
-
bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
const string& docType,
size_t expectedProofOfProvisioningSize) override;
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index ff80752..7678ecb 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -1012,8 +1012,8 @@
IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy"));
}
shared_ptr<WritableIdentityCredential> wc =
- ndk::SharedRefBase::make<WritableIdentityCredential>(
- provisioningHwProxy, docType_, testCredential_, hardwareInformation_);
+ ndk::SharedRefBase::make<WritableIdentityCredential>(provisioningHwProxy, docType_,
+ testCredential_);
if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index 5929829..2935fb8 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -48,13 +48,11 @@
public:
IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
const vector<uint8_t>& credentialData,
- std::shared_ptr<PresentationSession> session,
- HardwareInformation hardwareInformation)
+ std::shared_ptr<PresentationSession> session)
: hwProxyFactory_(hwProxyFactory),
credentialData_(credentialData),
session_(std::move(session)),
numStartRetrievalCalls_(0),
- hardwareInformation_(std::move(hardwareInformation)),
expectedDeviceNameSpacesSize_(0) {}
// Parses and decrypts credentialData_, return a status code from
@@ -105,7 +103,6 @@
vector<uint8_t> credentialData_;
shared_ptr<PresentationSession> session_;
int numStartRetrievalCalls_;
- HardwareInformation hardwareInformation_;
// Set by initialize()
string docType_;
diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp
index bbc2cef..4703ffe 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.cpp
+++ b/identity/aidl/default/common/IdentityCredentialStore.cpp
@@ -17,7 +17,6 @@
#define LOG_TAG "IdentityCredentialStore"
#include <android-base/logging.h>
-#include <android/binder_manager.h>
#include "IdentityCredential.h"
#include "IdentityCredentialStore.h"
@@ -26,24 +25,15 @@
namespace aidl::android::hardware::identity {
-using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
-
-IdentityCredentialStore::IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
- optional<string> remotelyProvisionedComponent)
- : hwProxyFactory_(hwProxyFactory),
- remotelyProvisionedComponentName_(remotelyProvisionedComponent) {
- hardwareInformation_.credentialStoreName = "Identity Credential Reference Implementation";
- hardwareInformation_.credentialStoreAuthorName = "Google";
- hardwareInformation_.dataChunkSize = kGcmChunkSize;
- hardwareInformation_.isDirectAccess = false;
- hardwareInformation_.supportedDocTypes = {};
- hardwareInformation_.isRemoteKeyProvisioningSupported =
- remotelyProvisionedComponentName_.has_value();
-}
-
ndk::ScopedAStatus IdentityCredentialStore::getHardwareInformation(
HardwareInformation* hardwareInformation) {
- *hardwareInformation = hardwareInformation_;
+ HardwareInformation hw;
+ hw.credentialStoreName = "Identity Credential Reference Implementation";
+ hw.credentialStoreAuthorName = "Google";
+ hw.dataChunkSize = kGcmChunkSize;
+ hw.isDirectAccess = false;
+ hw.supportedDocTypes = {};
+ *hardwareInformation = hw;
return ndk::ScopedAStatus::ok();
}
@@ -52,8 +42,7 @@
shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
shared_ptr<WritableIdentityCredential> wc =
- ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential,
- hardwareInformation_);
+ ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential);
if (!wc->initialize()) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
@@ -74,7 +63,7 @@
}
shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
- hwProxyFactory_, credentialData, nullptr /* session */, hardwareInformation_);
+ hwProxyFactory_, credentialData, nullptr /* session */);
auto ret = credential->initialize();
if (ret != IIdentityCredentialStore::STATUS_OK) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -94,8 +83,8 @@
}
sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
- shared_ptr<PresentationSession> session = ndk::SharedRefBase::make<PresentationSession>(
- hwProxyFactory_, hwProxy, hardwareInformation_);
+ shared_ptr<PresentationSession> session =
+ ndk::SharedRefBase::make<PresentationSession>(hwProxyFactory_, hwProxy);
auto ret = session->initialize();
if (ret != IIdentityCredentialStore::STATUS_OK) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -105,23 +94,4 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus IdentityCredentialStore::getRemotelyProvisionedComponent(
- shared_ptr<IRemotelyProvisionedComponent>* outRemotelyProvisionedComponent) {
- if (!remotelyProvisionedComponentName_) {
- return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
- EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
- }
-
- ndk::SpAIBinder binder(
- AServiceManager_waitForService(remotelyProvisionedComponentName_->c_str()));
- if (binder.get() == nullptr) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_FAILED,
- "Unable to get remotely provisioned component"));
- }
-
- *outRemotelyProvisionedComponent = IRemotelyProvisionedComponent::fromBinder(binder);
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h
index dd1261b..77b894d 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.h
+++ b/identity/aidl/default/common/IdentityCredentialStore.h
@@ -18,7 +18,6 @@
#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
#include <aidl/android/hardware/identity/BnIdentityCredentialStore.h>
-#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
#include "SecureHardwareProxy.h"
@@ -26,18 +25,14 @@
using ::android::sp;
using ::android::hardware::identity::SecureHardwareProxyFactory;
-using ::std::optional;
using ::std::shared_ptr;
using ::std::string;
using ::std::vector;
class IdentityCredentialStore : public BnIdentityCredentialStore {
public:
- // If remote key provisioning is supported, pass the service name for the correct
- // IRemotelyProvisionedComponent to the remotelyProvisionedComponent parameter. Else
- // pass std::nullopt to indicate remote key provisioning is not supported.
- IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
- optional<string> remotelyProvisionedComponent);
+ IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory)
+ : hwProxyFactory_(hwProxyFactory) {}
// The GCM chunk size used by this implementation is 64 KiB.
static constexpr size_t kGcmChunkSize = 64 * 1024;
@@ -55,14 +50,8 @@
ndk::ScopedAStatus createPresentationSession(
CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override;
- ndk::ScopedAStatus getRemotelyProvisionedComponent(
- shared_ptr<::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent>*
- outRemotelyProvisionedComponent) override;
-
private:
sp<SecureHardwareProxyFactory> hwProxyFactory_;
- optional<string> remotelyProvisionedComponentName_;
- HardwareInformation hardwareInformation_;
};
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp
index 2eb7f2e..fbd8972 100644
--- a/identity/aidl/default/common/PresentationSession.cpp
+++ b/identity/aidl/default/common/PresentationSession.cpp
@@ -122,8 +122,8 @@
ndk::ScopedAStatus PresentationSession::getCredential(
const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
shared_ptr<PresentationSession> p = ref<PresentationSession>();
- shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
- hwProxyFactory_, credentialData, p, hardwareInformation_);
+ shared_ptr<IdentityCredential> credential =
+ ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, credentialData, p);
int ret = credential->initialize();
if (ret != IIdentityCredentialStore::STATUS_OK) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h
index 4cb174a..76ca67b 100644
--- a/identity/aidl/default/common/PresentationSession.h
+++ b/identity/aidl/default/common/PresentationSession.h
@@ -38,11 +38,8 @@
class PresentationSession : public BnPresentationSession {
public:
PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory,
- sp<SecureHardwareSessionProxy> hwProxy,
- HardwareInformation hardwareInformation)
- : hwProxyFactory_(std::move(hwProxyFactory)),
- hwProxy_(std::move(hwProxy)),
- hardwareInformation_(std::move(hardwareInformation)) {}
+ sp<SecureHardwareSessionProxy> hwProxy)
+ : hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {}
virtual ~PresentationSession();
@@ -68,7 +65,6 @@
// Set by constructor
sp<SecureHardwareProxyFactory> hwProxyFactory_;
sp<SecureHardwareSessionProxy> hwProxy_;
- HardwareInformation hardwareInformation_;
// Set by initialize()
uint64_t id_;
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index 9f63ad8..a580444 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -82,18 +82,6 @@
virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
const vector<uint8_t>& applicationId) = 0;
- // Returns public key certificate with a remotely provisioned attestation key.
- //
- // This returns a single certificate that is signed by the given |attestationKeyBlob|.
- // The implementation of eicOpsCreateCredentialKey() on the TA side must coordinate
- // with its corresponding keymint implementation to sign using the attestation key. The
- // |attestationKeyCert| parameter is the certificates for |attestationKeyBlob|,
- // formatted as concatenated, DER-encoded, X.509 certificates.
- virtual optional<vector<uint8_t>> createCredentialKeyUsingRkp(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- const vector<uint8_t>& attestationKeyBlob,
- const vector<uint8_t>& attestationKeyCert) = 0;
-
virtual bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
const string& docType,
size_t expectedProofOfProvisioningSize) = 0;
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
index e420a7b..200ee61 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -79,15 +79,8 @@
IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
}
- optional<vector<uint8_t>> certChain;
- if (attestationKeyBlob_ && attestationCertificateChain_) {
- certChain = hwProxy_->createCredentialKeyUsingRkp(
- attestationChallenge, attestationApplicationId, *attestationKeyBlob_,
- attestationCertificateChain_->at(0));
- } else {
- certChain = hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
- }
-
+ optional<vector<uint8_t>> certChain =
+ hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
if (!certChain) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
@@ -102,14 +95,8 @@
}
*outCertificateChain = vector<Certificate>();
- for (vector<uint8_t>& cert : certs.value()) {
- Certificate c;
- c.encodedCertificate = std::move(cert);
- outCertificateChain->push_back(std::move(c));
- }
-
- for (const vector<uint8_t>& cert : *attestationCertificateChain_) {
- Certificate c;
+ for (const vector<uint8_t>& cert : certs.value()) {
+ Certificate c = Certificate();
c.encodedCertificate = cert;
outCertificateChain->push_back(std::move(c));
}
@@ -415,36 +402,4 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus WritableIdentityCredential::setRemotelyProvisionedAttestationKey(
- const vector<uint8_t>& attestationKeyBlob,
- const vector<uint8_t>& attestationCertificateChain) {
- if (!hardwareInformation_.isRemoteKeyProvisioningSupported) {
- return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
- EX_UNSUPPORTED_OPERATION, "Remote key provisioning is not supported"));
- }
-
- if (attestationKeyBlob.empty() || attestationCertificateChain.empty()) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_FAILED,
- "Empty data passed to setRemotlyProvisionedAttestationKey"));
- }
-
- if (attestationKeyBlob_.has_value()) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_FAILED, "Attestation key already set"));
- }
-
- optional<vector<vector<uint8_t>>> certs =
- support::certificateChainSplit(attestationCertificateChain);
- if (!certs) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_FAILED,
- "Error splitting chain into separate certificates"));
- }
-
- attestationKeyBlob_ = attestationKeyBlob;
- attestationCertificateChain_ = *certs;
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/WritableIdentityCredential.h b/identity/aidl/default/common/WritableIdentityCredential.h
index 39d32c9..36ad430 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.h
+++ b/identity/aidl/default/common/WritableIdentityCredential.h
@@ -30,7 +30,6 @@
using ::android::sp;
using ::android::hardware::identity::SecureHardwareProvisioningProxy;
-using ::std::optional;
using ::std::set;
using ::std::string;
using ::std::vector;
@@ -42,11 +41,8 @@
// For an updated credential, call initializeForUpdate() right after construction.
//
WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
- bool testCredential, HardwareInformation hardwareInformation)
- : hwProxy_(hwProxy),
- docType_(docType),
- testCredential_(testCredential),
- hardwareInformation_(std::move(hardwareInformation)) {}
+ bool testCredential)
+ : hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {}
~WritableIdentityCredential();
@@ -82,16 +78,11 @@
vector<uint8_t>* outCredentialData,
vector<uint8_t>* outProofOfProvisioningSignature) override;
- ndk::ScopedAStatus setRemotelyProvisionedAttestationKey(
- const vector<uint8_t>& attestationKeyBlob,
- const vector<uint8_t>& attestationCertificateChain) override;
-
private:
// Set by constructor.
sp<SecureHardwareProvisioningProxy> hwProxy_;
string docType_;
bool testCredential_;
- HardwareInformation hardwareInformation_;
// This is set in initialize().
bool startPersonalizationCalled_;
@@ -118,10 +109,6 @@
vector<int32_t> entryAccessControlProfileIds_;
vector<uint8_t> entryBytes_;
set<string> allNameSpaces_;
-
- // Remotely provisioned attestation data, set via setRemotelyProvisionedAttestationKey
- optional<vector<uint8_t>> attestationKeyBlob_;
- optional<vector<vector<uint8_t>>> attestationCertificateChain_;
};
} // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h
index df96c7d..aa26e62 100644
--- a/identity/aidl/default/libeic/EicOps.h
+++ b/identity/aidl/default/libeic/EicOps.h
@@ -196,19 +196,13 @@
// Generates CredentialKey plus an attestation certificate.
//
-// If |attestationKeyBlob| is non-NULL, the certificate must be signed by the
-// the provided attestation key. Else, the certificate must be signed by the
-// attestation key that the secure area has been factory provisioned with. The
-// given |challenge|, |applicationId|, and |testCredential| must be signed
-// into the attestation.
+// The attestation certificate will be signed by the attestation keys the secure
+// area has been provisioned with. The given |challenge| and |applicationId|
+// will be used as will |testCredential|.
//
-// When |attestationKeyBlob| is non-NULL, then |attestationKeyCert| must
-// also be passed so that the underlying implementation can properly chain up
-// the newly-generated certificate to the existing chain.
-//
-// The generated certificate must be in X.509 format and returned in |cert|
-// and |certSize| must be set to the size of this array. This function must
-// set |certSize| to the size of the certification chain on successfully return.
+// The generated certificate will be in X.509 format and returned in |cert|
+// and |certSize| must be set to the size of this array and this function will
+// set it to the size of the certification chain on successfully return.
//
// This may return either a single certificate or an entire certificate
// chain. If it returns only a single certificate, the implementation of
@@ -217,10 +211,8 @@
//
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, bool testCredential,
- const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
- const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
- uint8_t* /*out*/ cert, size_t* /*inout*/ certSize);
+ size_t applicationIdSize, bool testCredential, uint8_t* cert,
+ size_t* certSize); // inout
// Generate an X.509 certificate for the key identified by |publicKey| which
// must be of the form returned by eicOpsCreateEcKey().
diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c
index ff009dd..a241b71 100644
--- a/identity/aidl/default/libeic/EicProvisioning.c
+++ b/identity/aidl/default/libeic/EicProvisioning.c
@@ -133,10 +133,7 @@
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, const uint8_t* attestationKeyBlob,
- size_t attestationKeyBlobSize,
- const uint8_t* attestationKeyCert,
- size_t attestationKeyCertSize, uint8_t* publicKeyCert,
+ size_t applicationIdSize, uint8_t* publicKeyCert,
size_t* publicKeyCertSize) {
if (ctx->isUpdate) {
eicDebug("Cannot create CredentialKey on update");
@@ -145,9 +142,7 @@
if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize,
applicationId, applicationIdSize, ctx->testCredential,
- attestationKeyBlob, attestationKeyBlobSize, attestationKeyCert,
- attestationKeyCertSize, publicKeyCert, publicKeyCertSize)) {
- eicDebug("Error creating credential key");
+ publicKeyCert, publicKeyCertSize)) {
return false;
}
return true;
diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h
index 2619bfc..d94f8f1 100644
--- a/identity/aidl/default/libeic/EicProvisioning.h
+++ b/identity/aidl/default/libeic/EicProvisioning.h
@@ -77,10 +77,7 @@
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
size_t challengeSize, const uint8_t* applicationId,
- size_t applicationIdSize, const uint8_t* attestationKeyBlob,
- size_t attestationKeyBlobSize,
- const uint8_t* attestationKeyCert,
- size_t attestationKeyCertSize, uint8_t* publicKeyCert,
+ size_t applicationIdSize, uint8_t* publicKeyCert,
size_t* publicKeyCertSize);
bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount,
diff --git a/identity/aidl/default/service.cpp b/identity/aidl/default/service.cpp
index ed3c4cb..78f4fbc 100644
--- a/identity/aidl/default/service.cpp
+++ b/identity/aidl/default/service.cpp
@@ -16,7 +16,6 @@
#define LOG_TAG "android.hardware.identity-service"
-#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
@@ -27,35 +26,20 @@
using ::android::sp;
using ::android::base::InitLogging;
-using ::android::base::LogdLogger;
-using ::android::base::LogId;
-using ::android::base::LogSeverity;
using ::android::base::StderrLogger;
using ::aidl::android::hardware::identity::IdentityCredentialStore;
-using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
using ::android::hardware::identity::FakeSecureHardwareProxyFactory;
using ::android::hardware::identity::SecureHardwareProxyFactory;
-void ComboLogger(LogId id, LogSeverity severity, const char* tag, const char* file,
- unsigned int line, const char* message) {
- StderrLogger(id, severity, tag, file, line, message);
-
- static LogdLogger logdLogger;
- logdLogger(id, severity, tag, file, line, message);
-}
-
int main(int /*argc*/, char* argv[]) {
- InitLogging(argv, ComboLogger);
+ InitLogging(argv, StderrLogger);
sp<SecureHardwareProxyFactory> hwProxyFactory = new FakeSecureHardwareProxyFactory();
- const std::string remotelyProvisionedComponentName =
- std::string(IRemotelyProvisionedComponent::descriptor) + "/default";
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<IdentityCredentialStore> store =
- ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory,
- remotelyProvisionedComponentName);
+ ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory);
const std::string instance = std::string() + IdentityCredentialStore::descriptor + "/default";
binder_status_t status = AServiceManager_addService(store->asBinder().get(), instance.c_str());
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index c5b84a1..7b6f2c8 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -11,8 +11,6 @@
name: "VtsHalIdentityTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
- "keymint_use_latest_hal_aidl_cpp_static",
- "keymint_use_latest_hal_aidl_ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
cflags: [
@@ -34,15 +32,12 @@
],
shared_libs: [
"libbinder",
- "libbinder_ndk",
"libcrypto",
],
static_libs: [
- "android.hardware.security.secureclock-V1-ndk",
"libcppbor_external",
"libcppcose_rkp",
"libkeymaster_portable",
- "libkeymint_vts_test_utils",
"libpuresoftkeymasterdevice",
"android.hardware.keymaster@4.0",
"android.hardware.identity-support-lib",
@@ -51,7 +46,6 @@
"android.hardware.keymaster-V4-ndk",
"libkeymaster4support",
"libkeymaster4_1support",
- "libkeymint_remote_prov_support",
],
test_suites: [
"general-tests",
diff --git a/identity/aidl/vts/Util.cpp b/identity/aidl/vts/Util.cpp
index f3d7c30..1148cb0 100644
--- a/identity/aidl/vts/Util.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -20,16 +20,12 @@
#include <android-base/logging.h>
-#include <KeyMintAidlTestBase.h>
#include <aidl/Gtest.h>
-#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
#include <android-base/stringprintf.h>
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymasterV4_1/attestation_record.h>
-#include <keymint_support/openssl_utils.h>
-#include <openssl/evp.h>
-
#include <charconv>
+
#include <map>
namespace android::hardware::identity::test_utils {
@@ -40,13 +36,10 @@
using std::string;
using std::vector;
-using ::aidl::android::hardware::security::keymint::test::check_maced_pubkey;
-using ::aidl::android::hardware::security::keymint::test::p256_pub_key;
using ::android::sp;
using ::android::String16;
using ::android::base::StringPrintf;
using ::android::binder::Status;
-using ::android::hardware::security::keymint::MacedPublicKey;
using ::keymaster::X509_Ptr;
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
@@ -65,77 +58,6 @@
}
}
-optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
- const MacedPublicKey& macedPublicKey) {
- // The helper library uses the NDK symbols, so play a little trickery here to convert
- // the data into the proper type so we can reuse the helper function to get the pubkey.
- ::aidl::android::hardware::security::keymint::MacedPublicKey ndkMacedPublicKey;
- ndkMacedPublicKey.macedKey = macedPublicKey.macedKey;
-
- vector<uint8_t> publicKeyBits;
- check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/true, &publicKeyBits);
-
- ::aidl::android::hardware::security::keymint::EVP_PKEY_Ptr publicKey;
- p256_pub_key(publicKeyBits, &publicKey);
-
- // Generate an arbitrary root key for our chain
- bssl::UniquePtr<EC_KEY> ecRootKey(EC_KEY_new());
- bssl::UniquePtr<EVP_PKEY> rootKey(EVP_PKEY_new());
- if (ecRootKey.get() == nullptr || rootKey.get() == nullptr) {
- LOG(ERROR) << "Memory allocation failed";
- return {};
- }
-
- bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
- if (group.get() == nullptr) {
- LOG(ERROR) << "Error creating EC group by curve name";
- return {};
- }
-
- if (EC_KEY_set_group(ecRootKey.get(), group.get()) != 1 ||
- EC_KEY_generate_key(ecRootKey.get()) != 1 || EC_KEY_check_key(ecRootKey.get()) < 0) {
- LOG(ERROR) << "Error generating key";
- return {};
- }
-
- if (EVP_PKEY_set1_EC_KEY(rootKey.get(), ecRootKey.get()) != 1) {
- LOG(ERROR) << "Error getting private key";
- return {};
- }
-
- // The VTS test does not fully validate the chain, so we're ok without the proper CA extensions.
- map<string, vector<uint8_t>> extensions;
-
- // Now make a self-signed cert
- optional<vector<uint8_t>> root = support::ecPublicKeyGenerateCertificate(
- rootKey.get(), rootKey.get(),
- /*serialDecimal=*/"31415",
- /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
- /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
- /*validityNotBefore=*/time(nullptr),
- /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
- if (!root) {
- LOG(ERROR) << "Error generating root cert";
- return std::nullopt;
- }
-
- // Now sign a CA cert so that we have a chain that's good enough to satisfy
- // the VTS tests.
- optional<vector<uint8_t>> intermediate = support::ecPublicKeyGenerateCertificate(
- publicKey.get(), rootKey.get(),
- /*serialDecimal=*/"42",
- /*subject=*/"Android IdentityCredential VTS Test Root Certificate",
- /*subject=*/"Android IdentityCredential VTS Test Attestation Certificate",
- /*validityNotBefore=*/time(nullptr),
- /*validityNotAfter=*/time(nullptr) + 365 * 24 * 3600, extensions);
- if (!intermediate) {
- LOG(ERROR) << "Error generating intermediate cert";
- return std::nullopt;
- }
-
- return vector<vector<uint8_t>>{std::move(*intermediate), std::move(*root)};
-}
-
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal) {
vector<uint8_t> privKey;
return generateReaderCertificate(serialDecimal, &privKey);
diff --git a/identity/aidl/vts/Util.h b/identity/aidl/vts/Util.h
index b120dc9..80e52a2 100644
--- a/identity/aidl/vts/Util.h
+++ b/identity/aidl/vts/Util.h
@@ -19,7 +19,6 @@
#include <android/hardware/identity/IIdentityCredentialStore.h>
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
-#include <android/hardware/security/keymint/MacedPublicKey.h>
#include <cppbor.h>
#include <cppbor_parse.h>
#include <gtest/gtest.h>
@@ -98,9 +97,6 @@
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
sp<IIdentityCredentialStore>& credentialStore, bool testCredential);
-optional<vector<vector<uint8_t>>> createFakeRemotelyProvisionedCertificateChain(
- const ::android::hardware::security::keymint::MacedPublicKey& macedPublicKey);
-
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal);
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
index 94d4c88..bc37020 100644
--- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
+++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
@@ -18,8 +18,6 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
-#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
-#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
#include <android-base/logging.h>
#include <android/hardware/identity/IIdentityCredentialStore.h>
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
@@ -44,8 +42,6 @@
using ::android::sp;
using ::android::String16;
using ::android::binder::Status;
-using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
-using ::android::hardware::security::keymint::MacedPublicKey;
class IdentityCredentialTests : public testing::TestWithParam<string> {
public:
@@ -105,103 +101,6 @@
attestationApplicationId, false);
}
-TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithRemoteProvisioning) {
- HardwareInformation hwInfo;
- ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
-
- if (!hwInfo.isRemoteKeyProvisioningSupported) {
- GTEST_SKIP() << "Remote provisioning is not supported";
- }
-
- Status result;
-
- sp<IWritableIdentityCredential> writableCredential;
- ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
- false /* testCredential */));
-
- sp<IRemotelyProvisionedComponent> rpc;
- result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- MacedPublicKey macedPublicKey;
- std::vector<uint8_t> attestationKey;
- result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
- test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
- ASSERT_TRUE(remotelyProvisionedCertChain);
-
- vector<uint8_t> concatenatedCerts;
- for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
- concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
- }
- result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
- concatenatedCerts);
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
- vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
- vector<Certificate> attestationCertificate;
- vector<uint8_t> attestationApplicationId = {1};
-
- result = writableCredential->getAttestationCertificate(
- attestationApplicationId, attestationChallenge, &attestationCertificate);
-
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
- attestationApplicationId, false);
-
- ASSERT_EQ(remotelyProvisionedCertChain->size() + 1, attestationCertificate.size());
- for (size_t i = 0; i < remotelyProvisionedCertChain->size(); ++i) {
- ASSERT_EQ(remotelyProvisionedCertChain->at(i),
- attestationCertificate[i + 1].encodedCertificate)
- << "Certificate mismatch (cert index " << i + 1 << " out of "
- << attestationCertificate.size() << " total certs)";
- }
-}
-
-TEST_P(IdentityCredentialTests, verifyRemotelyProvisionedKeyMayOnlyBeSetOnce) {
- HardwareInformation hwInfo;
- ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
-
- if (!hwInfo.isRemoteKeyProvisioningSupported) {
- GTEST_SKIP() << "Remote provisioning is not supported";
- }
-
- sp<IRemotelyProvisionedComponent> rpc;
- Status result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- MacedPublicKey macedPublicKey;
- std::vector<uint8_t> attestationKey;
- result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
- test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
- ASSERT_TRUE(remotelyProvisionedCertChain);
-
- vector<uint8_t> concatenatedCerts;
- for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
- concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
- }
-
- sp<IWritableIdentityCredential> writableCredential;
- ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
- /*testCredential=*/false));
-
- result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
- concatenatedCerts);
- ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
-
- // Now try again, and verify that the implementation rejects it.
- result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
- concatenatedCerts);
- EXPECT_FALSE(result.isOk());
-}
-
TEST_P(IdentityCredentialTests, verifyAttestationDoubleCallFails) {
Status result;
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 82746d6..3b91de6 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -17,8 +17,6 @@
#ifndef IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
#define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
-#include <openssl/evp.h>
-
#include <cstdint>
#include <map>
#include <optional>
@@ -130,15 +128,6 @@
const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
bool isTestCredential);
-// Alternate version of createEcKeyPairAndAttestation that accepts an attestation key
-// blob to sign the generated key. Only a single certificate is returned, rather than
-// a full chain.
-//
-optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
- bool isTestCredential);
-
// (TODO: remove when no longer used by 3rd party.)
optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
@@ -251,13 +240,6 @@
time_t validityNotBefore, time_t validityNotAfter,
const map<string, vector<uint8_t>>& extensions);
-// Identical behavior to the above version of ecPublicKeyGenerateCertificate, except this
-// overload takes OpenSSL key parameters instead of key bitstrings as inputs.
-optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
- EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
- const string& issuer, const string& subject, time_t validityNotBefore,
- time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions);
-
// Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
// format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
// in the format returned by ecKeyPairGetPrivateKey()).
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 36ecdb0..7f4674d 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -54,7 +54,6 @@
#include <keymaster/contexts/pure_soft_keymaster_context.h>
#include <keymaster/contexts/soft_attestation_cert.h>
#include <keymaster/keymaster_tags.h>
-#include <keymaster/km_openssl/asymmetric_key.h>
#include <keymaster/km_openssl/attestation_utils.h>
#include <keymaster/km_openssl/certificate_utils.h>
@@ -169,286 +168,6 @@
using X509_NAME_Ptr = bssl::UniquePtr<X509_NAME>;
using X509_EXTENSION_Ptr = bssl::UniquePtr<X509_EXTENSION>;
-namespace {
-
-EVP_PKEY_Ptr generateP256Key() {
- EC_KEY_Ptr ec_key(EC_KEY_new());
- EVP_PKEY_Ptr pkey(EVP_PKEY_new());
- EC_GROUP_Ptr group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
-
- if (ec_key.get() == nullptr || pkey.get() == nullptr) {
- LOG(ERROR) << "Memory allocation failed";
- return {};
- }
-
- if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
- EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
- LOG(ERROR) << "Error generating key";
- return {};
- }
-
- if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
- LOG(ERROR) << "Error getting private key";
- return {};
- }
-
- return pkey;
-}
-
-optional<vector<uint8_t>> derEncodeKeyPair(const EVP_PKEY& pkey) {
- int size = i2d_PrivateKey(&pkey, nullptr);
- if (size == 0) {
- LOG(ERROR) << "Error generating public key encoding";
- return std::nullopt;
- }
-
- vector<uint8_t> keyPair(size);
- unsigned char* p = keyPair.data();
- i2d_PrivateKey(&pkey, &p);
-
- return keyPair;
-}
-
-// Extract the issuer subject name from the leaf cert in the given chain,
-// returning it as DER-encoded bytes.
-optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate) {
- const uint8_t* input = certificate.data();
- X509_Ptr cert(d2i_X509(/*cert=*/nullptr, &input, certificate.size()));
- if (!cert) {
- LOG(ERROR) << "Failed to parse certificate";
- return std::nullopt;
- }
-
- X509_NAME* subject = X509_get_subject_name(cert.get());
- if (!subject) {
- LOG(ERROR) << "Failed to retrieve subject name";
- return std::nullopt;
- }
-
- int encodedSubjectLength = i2d_X509_NAME(subject, /*out=*/nullptr);
- if (encodedSubjectLength < 0) {
- LOG(ERROR) << "Error obtaining encoded subject name length";
- return std::nullopt;
- }
-
- vector<uint8_t> encodedSubject(encodedSubjectLength);
- uint8_t* out = encodedSubject.data();
- if (encodedSubjectLength != i2d_X509_NAME(subject, &out)) {
- LOG(ERROR) << "Error encoding subject name";
- return std::nullopt;
- }
-
- return encodedSubject;
-}
-
-// Generates the attestation certificate with the parameters passed in. Note
-// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
-// milli seconds since epoch. We are setting them to milliseconds due to
-// requirement in AuthorizationSet KM_DATE fields. The certificate created is
-// actually in seconds.
-//
-optional<vector<vector<uint8_t>>> signAttestationCertificate(
- const ::keymaster::PureSoftKeymasterContext& context, const EVP_PKEY* key,
- const vector<uint8_t>& applicationId, const vector<uint8_t>& challenge,
- const vector<uint8_t>& attestationKeyBlob,
- const vector<uint8_t>& derAttestationCertSubjectName, uint64_t activeTimeMilliSeconds,
- uint64_t expireTimeMilliSeconds, bool isTestCredential) {
- ::keymaster::X509_NAME_Ptr subjectName;
- if (KM_ERROR_OK !=
- ::keymaster::make_name_from_str("Android Identity Credential Key", &subjectName)) {
- LOG(ERROR) << "Cannot create attestation subject";
- return {};
- }
-
- vector<uint8_t> subject(i2d_X509_NAME(subjectName.get(), NULL));
- unsigned char* subjectPtr = subject.data();
-
- i2d_X509_NAME(subjectName.get(), &subjectPtr);
-
- ::keymaster::AuthorizationSet auth_set(
- ::keymaster::AuthorizationSetBuilder()
- .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
- .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
- .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
- challenge.size())
- .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
- // Even though identity attestation hal said the application
- // id should be in software enforced authentication set,
- // keymaster portable lib expect the input in this
- // parameter because the software enforced in input to keymaster
- // refers to the key software enforced properties. And this
- // parameter refers to properties of the attestation which
- // includes app id.
- .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
- applicationId.data(), applicationId.size())
- .Authorization(::keymaster::TAG_CERTIFICATE_SUBJECT, subject.data(),
- subject.size())
- .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
-
- // Unique id and device id is not applicable for identity credential attestation,
- // so we don't need to set those or application id.
- ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
- ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
-
- ::keymaster::AuthorizationSetBuilder hwEnforcedBuilder =
- ::keymaster::AuthorizationSetBuilder()
- .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
- .Authorization(::keymaster::TAG_KEY_SIZE, 256)
- .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
- .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
- .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
- .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
- .Authorization(::keymaster::TAG_OS_VERSION, 42)
- .Authorization(::keymaster::TAG_OS_PATCHLEVEL, 43);
-
- // Only include TAG_IDENTITY_CREDENTIAL_KEY if it's not a test credential
- if (!isTestCredential) {
- hwEnforcedBuilder.Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY);
- }
- ::keymaster::AuthorizationSet hwEnforced(hwEnforcedBuilder);
-
- keymaster_error_t error;
- ::keymaster::AttestKeyInfo attestKeyInfo;
- ::keymaster::KeymasterBlob issuerSubjectNameBlob;
- if (!attestationKeyBlob.empty()) {
- ::keymaster::KeymasterKeyBlob blob(attestationKeyBlob.data(), attestationKeyBlob.size());
- ::keymaster::UniquePtr<::keymaster::Key> parsedKey;
- error = context.ParseKeyBlob(blob, /*additional_params=*/{}, &parsedKey);
- if (error != KM_ERROR_OK) {
- LOG(ERROR) << "Error loading attestation key: " << error;
- return std::nullopt;
- }
-
- attestKeyInfo.signing_key =
- static_cast<::keymaster::AsymmetricKey&>(*parsedKey).InternalToEvp();
- issuerSubjectNameBlob = ::keymaster::KeymasterBlob(derAttestationCertSubjectName.data(),
- derAttestationCertSubjectName.size());
- attestKeyInfo.issuer_subject = &issuerSubjectNameBlob;
- }
-
- ::keymaster::CertificateChain certChain = generate_attestation(
- key, swEnforced, hwEnforced, auth_set, std::move(attestKeyInfo), context, &error);
-
- if (KM_ERROR_OK != error) {
- LOG(ERROR) << "Error generating attestation from EVP key: " << error;
- return std::nullopt;
- }
-
- vector<vector<uint8_t>> vectors(certChain.entry_count);
- for (std::size_t i = 0; i < certChain.entry_count; i++) {
- vectors[i] = {certChain.entries[i].data,
- certChain.entries[i].data + certChain.entries[i].data_length};
- }
- return vectors;
-}
-
-int parseDigits(const char** s, int numDigits) {
- int result;
- auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
- if (ec != std::errc()) {
- LOG(ERROR) << "Error parsing " << numDigits << " digits "
- << " from " << s;
- return 0;
- }
- *s += numDigits;
- return result;
-}
-
-bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
- struct tm tm;
-
- memset(&tm, '\0', sizeof(tm));
- const char* timeStr = (const char*)asn1Time->data;
- const char* s = timeStr;
- if (asn1Time->type == V_ASN1_UTCTIME) {
- tm.tm_year = parseDigits(&s, 2);
- if (tm.tm_year < 70) {
- tm.tm_year += 100;
- }
- } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
- tm.tm_year = parseDigits(&s, 4) - 1900;
- tm.tm_year -= 1900;
- } else {
- LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
- return false;
- }
- tm.tm_mon = parseDigits(&s, 2) - 1;
- tm.tm_mday = parseDigits(&s, 2);
- tm.tm_hour = parseDigits(&s, 2);
- tm.tm_min = parseDigits(&s, 2);
- tm.tm_sec = parseDigits(&s, 2);
- // This may need to be updated if someone create certificates using +/- instead of Z.
- //
- if (*s != 'Z') {
- LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
- return false;
- }
-
- time_t t = timegm(&tm);
- if (t == -1) {
- LOG(ERROR) << "Error converting broken-down time to time_t";
- return false;
- }
- *outTime = t;
- return true;
-}
-
-optional<uint64_t> getCertificateExpiryAsMillis(const uint8_t* derCert, size_t derCertSize) {
- X509_Ptr x509Cert(d2i_X509(nullptr, &derCert, derCertSize));
- if (!x509Cert) {
- LOG(ERROR) << "Error parsing certificate";
- return std::nullopt;
- }
-
- time_t notAfter;
- if (!parseAsn1Time(X509_get0_notAfter(x509Cert.get()), ¬After)) {
- LOG(ERROR) << "Error getting notAfter from batch certificate";
- return std::nullopt;
- }
-
- return notAfter * 1000;
-}
-
-optional<vector<vector<uint8_t>>> createAttestation(EVP_PKEY* pkey,
- const vector<uint8_t>& challenge,
- const vector<uint8_t>& applicationId,
- bool isTestCredential) {
- // Pretend to be implemented in a trusted environment just so we can pass
- // the VTS tests. Of course, this is a pretend-only game since hopefully no
- // relying party is ever going to trust our batch key and those keys above
- // it.
- ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
- KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
-
- keymaster_error_t error;
- ::keymaster::CertificateChain attestation_chain =
- context.GetAttestationChain(KM_ALGORITHM_EC, &error);
- if (KM_ERROR_OK != error) {
- LOG(ERROR) << "Error getting attestation chain " << error;
- return std::nullopt;
- }
-
- if (attestation_chain.entry_count < 1) {
- LOG(ERROR) << "Expected at least one entry in attestation chain";
- return std::nullopt;
- }
-
- uint64_t activeTimeMs = time(nullptr) * 1000;
- optional<uint64_t> expireTimeMs = getCertificateExpiryAsMillis(
- attestation_chain.entries[0].data, attestation_chain.entries[0].data_length);
- if (!expireTimeMs) {
- LOG(ERROR) << "Error getting expiration time for batch cert";
- return std::nullopt;
- }
-
- return signAttestationCertificate(context, pkey, applicationId, challenge,
- /*attestationKeyBlob=*/{},
- /*derAttestationCertSubjectName=*/{}, activeTimeMs,
- *expireTimeMs, isTestCredential);
-}
-
-} // namespace
-
// bool getRandom(size_t numBytes, vector<uint8_t>& output) {
optional<vector<uint8_t>> getRandom(size_t numBytes) {
vector<uint8_t> output;
@@ -858,30 +577,69 @@
return hmac;
}
-optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- bool isTestCredential) {
- EVP_PKEY_Ptr pkey = generateP256Key();
-
- optional<vector<vector<uint8_t>>> attestationCertChain =
- createAttestation(pkey.get(), challenge, applicationId, isTestCredential);
- if (!attestationCertChain) {
- LOG(ERROR) << "Error create attestation from key and challenge";
- return {};
+int parseDigits(const char** s, int numDigits) {
+ int result;
+ auto [_, ec] = std::from_chars(*s, *s + numDigits, result);
+ if (ec != std::errc()) {
+ LOG(ERROR) << "Error parsing " << numDigits << " digits "
+ << " from " << s;
+ return 0;
}
-
- optional<vector<uint8_t>> keyPair = derEncodeKeyPair(*pkey);
- if (!keyPair) {
- return std::nullopt;
- }
-
- return make_pair(*keyPair, *attestationCertChain);
+ *s += numDigits;
+ return result;
}
-optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
- const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
- const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
- bool isTestCredential) {
+bool parseAsn1Time(const ASN1_TIME* asn1Time, time_t* outTime) {
+ struct tm tm;
+
+ memset(&tm, '\0', sizeof(tm));
+ const char* timeStr = (const char*)asn1Time->data;
+ const char* s = timeStr;
+ if (asn1Time->type == V_ASN1_UTCTIME) {
+ tm.tm_year = parseDigits(&s, 2);
+ if (tm.tm_year < 70) {
+ tm.tm_year += 100;
+ }
+ } else if (asn1Time->type == V_ASN1_GENERALIZEDTIME) {
+ tm.tm_year = parseDigits(&s, 4) - 1900;
+ tm.tm_year -= 1900;
+ } else {
+ LOG(ERROR) << "Unsupported ASN1_TIME type " << asn1Time->type;
+ return false;
+ }
+ tm.tm_mon = parseDigits(&s, 2) - 1;
+ tm.tm_mday = parseDigits(&s, 2);
+ tm.tm_hour = parseDigits(&s, 2);
+ tm.tm_min = parseDigits(&s, 2);
+ tm.tm_sec = parseDigits(&s, 2);
+ // This may need to be updated if someone create certificates using +/- instead of Z.
+ //
+ if (*s != 'Z') {
+ LOG(ERROR) << "Expected Z in string '" << timeStr << "' at offset " << (s - timeStr);
+ return false;
+ }
+
+ time_t t = timegm(&tm);
+ if (t == -1) {
+ LOG(ERROR) << "Error converting broken-down time to time_t";
+ return false;
+ }
+ *outTime = t;
+ return true;
+}
+
+// Generates the attestation certificate with the parameters passed in. Note
+// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
+// milli seconds since epoch. We are setting them to milliseconds due to
+// requirement in AuthorizationSet KM_DATE fields. The certificate created is
+// actually in seconds.
+//
+// If 0 is passed for expiration time, the expiration time from batch
+// certificate will be used.
+//
+optional<vector<vector<uint8_t>>> createAttestation(
+ const EVP_PKEY* key, const vector<uint8_t>& applicationId, const vector<uint8_t>& challenge,
+ uint64_t activeTimeMilliSeconds, uint64_t expireTimeMilliSeconds, bool isTestCredential) {
// Pretend to be implemented in a trusted environment just so we can pass
// the VTS tests. Of course, this is a pretend-only game since hopefully no
// relying party is ever going to trust our batch key and those keys above
@@ -889,45 +647,148 @@
::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
- EVP_PKEY_Ptr pkey = generateP256Key();
-
- uint64_t validFromMs = time(nullptr) * 1000;
- optional<uint64_t> notAfterMs =
- getCertificateExpiryAsMillis(attestationKeyCert.data(), attestationKeyCert.size());
- if (!notAfterMs) {
- LOG(ERROR) << "Error getting expiration time for attestation cert";
- return std::nullopt;
+ keymaster_error_t error;
+ ::keymaster::CertificateChain attestation_chain =
+ context.GetAttestationChain(KM_ALGORITHM_EC, &error);
+ if (KM_ERROR_OK != error) {
+ LOG(ERROR) << "Error getting attestation chain " << error;
+ return {};
+ }
+ if (expireTimeMilliSeconds == 0) {
+ if (attestation_chain.entry_count < 1) {
+ LOG(ERROR) << "Expected at least one entry in attestation chain";
+ return {};
+ }
+ keymaster_blob_t* bcBlob = &(attestation_chain.entries[0]);
+ const uint8_t* bcData = bcBlob->data;
+ auto bc = X509_Ptr(d2i_X509(nullptr, &bcData, bcBlob->data_length));
+ time_t bcNotAfter;
+ if (!parseAsn1Time(X509_get0_notAfter(bc.get()), &bcNotAfter)) {
+ LOG(ERROR) << "Error getting notAfter from batch certificate";
+ return {};
+ }
+ expireTimeMilliSeconds = bcNotAfter * 1000;
}
- optional<vector<uint8_t>> derIssuerSubject =
- extractDerSubjectFromCertificate(attestationKeyCert);
- if (!derIssuerSubject) {
- LOG(ERROR) << "Error error extracting issuer name from the given certificate chain";
- return std::nullopt;
+ ::keymaster::X509_NAME_Ptr subjectName;
+ if (KM_ERROR_OK !=
+ ::keymaster::make_name_from_str("Android Identity Credential Key", &subjectName)) {
+ LOG(ERROR) << "Cannot create attestation subject";
+ return {};
}
- optional<vector<vector<uint8_t>>> attestationCertChain = signAttestationCertificate(
- context, pkey.get(), applicationId, challenge, attestationKeyBlob, *derIssuerSubject,
- validFromMs, *notAfterMs, isTestCredential);
- if (!attestationCertChain) {
- LOG(ERROR) << "Error signing attestation certificate";
- return std::nullopt;
+ vector<uint8_t> subject(i2d_X509_NAME(subjectName.get(), NULL));
+ unsigned char* subjectPtr = subject.data();
+
+ i2d_X509_NAME(subjectName.get(), &subjectPtr);
+
+ ::keymaster::AuthorizationSet auth_set(
+ ::keymaster::AuthorizationSetBuilder()
+ .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
+ .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
+ .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
+ challenge.size())
+ .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
+ // Even though identity attestation hal said the application
+ // id should be in software enforced authentication set,
+ // keymaster portable lib expect the input in this
+ // parameter because the software enforced in input to keymaster
+ // refers to the key software enforced properties. And this
+ // parameter refers to properties of the attestation which
+ // includes app id.
+ .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
+ applicationId.data(), applicationId.size())
+ .Authorization(::keymaster::TAG_CERTIFICATE_SUBJECT, subject.data(),
+ subject.size())
+ .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
+
+ // Unique id and device id is not applicable for identity credential attestation,
+ // so we don't need to set those or application id.
+ ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
+ ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
+
+ ::keymaster::AuthorizationSetBuilder hwEnforcedBuilder =
+ ::keymaster::AuthorizationSetBuilder()
+ .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
+ .Authorization(::keymaster::TAG_KEY_SIZE, 256)
+ .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
+ .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
+ .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
+ .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
+ .Authorization(::keymaster::TAG_OS_VERSION, 42)
+ .Authorization(::keymaster::TAG_OS_PATCHLEVEL, 43);
+
+ // Only include TAG_IDENTITY_CREDENTIAL_KEY if it's not a test credential
+ if (!isTestCredential) {
+ hwEnforcedBuilder.Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY);
}
- if (!attestationCertChain) {
+ ::keymaster::AuthorizationSet hwEnforced(hwEnforcedBuilder);
+
+ ::keymaster::CertificateChain cert_chain_out = generate_attestation(
+ key, swEnforced, hwEnforced, auth_set, {} /* attest_key */, context, &error);
+
+ if (KM_ERROR_OK != error) {
+ LOG(ERROR) << "Error generating attestation from EVP key: " << error;
+ return {};
+ }
+
+ // translate certificate format from keymaster_cert_chain_t to vector<vector<uint8_t>>.
+ vector<vector<uint8_t>> attestationCertificate;
+ for (std::size_t i = 0; i < cert_chain_out.entry_count; i++) {
+ attestationCertificate.insert(
+ attestationCertificate.end(),
+ vector<uint8_t>(
+ cert_chain_out.entries[i].data,
+ cert_chain_out.entries[i].data + cert_chain_out.entries[i].data_length));
+ }
+
+ return attestationCertificate;
+}
+
+optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
+ const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
+ bool isTestCredential) {
+ auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
+ auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
+ auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+
+ if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+ LOG(ERROR) << "Memory allocation failed";
+ return {};
+ }
+
+ if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+ EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+ LOG(ERROR) << "Error generating key";
+ return {};
+ }
+
+ if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+ LOG(ERROR) << "Error getting private key";
+ return {};
+ }
+
+ uint64_t nowMs = time(nullptr) * 1000;
+ uint64_t expireTimeMs = 0; // Set to same as batch certificate
+
+ optional<vector<vector<uint8_t>>> attestationCert = createAttestation(
+ pkey.get(), applicationId, challenge, nowMs, expireTimeMs, isTestCredential);
+ if (!attestationCert) {
LOG(ERROR) << "Error create attestation from key and challenge";
- return std::nullopt;
- }
- if (attestationCertChain->size() != 1) {
- LOG(ERROR) << "Expected exactly one attestation cert, got " << attestationCertChain->size();
- return std::nullopt;
+ return {};
}
- optional<vector<uint8_t>> keyPair = derEncodeKeyPair(*pkey);
- if (!keyPair) {
- return std::nullopt;
+ int size = i2d_PrivateKey(pkey.get(), nullptr);
+ if (size == 0) {
+ LOG(ERROR) << "Error generating public key encoding";
+ return {};
}
- return make_pair(*keyPair, attestationCertChain->at(0));
+ vector<uint8_t> keyPair(size);
+ unsigned char* p = keyPair.data();
+ i2d_PrivateKey(pkey.get(), &p);
+
+ return make_pair(keyPair, attestationCert.value());
}
optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
@@ -959,8 +820,12 @@
return {};
}
+ uint64_t nowMs = time(nullptr) * 1000;
+ uint64_t expireTimeMs = 0; // Set to same as batch certificate
+
optional<vector<vector<uint8_t>>> attestationCert =
- createAttestation(pkey.get(), applicationId, challenge, false /* isTestCredential */);
+ createAttestation(pkey.get(), applicationId, challenge, nowMs, expireTimeMs,
+ false /* isTestCredential */);
if (!attestationCert) {
LOG(ERROR) << "Error create attestation from key and challenge";
return {};
@@ -1269,14 +1134,6 @@
return {};
}
- return ecPublicKeyGenerateCertificate(pkey.get(), privPkey.get(), serialDecimal, issuer,
- subject, validityNotBefore, validityNotAfter, extensions);
-}
-
-optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
- EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
- const string& issuer, const string& subject, time_t validityNotBefore,
- time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions) {
auto x509 = X509_Ptr(X509_new());
if (!x509.get()) {
LOG(ERROR) << "Error creating X509 certificate";
@@ -1288,7 +1145,7 @@
return {};
}
- if (X509_set_pubkey(x509.get(), publicKey) != 1) {
+ if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
LOG(ERROR) << "Error setting public key";
return {};
}
@@ -1363,7 +1220,7 @@
}
}
- if (X509_sign(x509.get(), signingKey, EVP_sha256()) == 0) {
+ if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
LOG(ERROR) << "Error signing X509 certificate";
return {};
}
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index bba9f6e..dcbe9c1 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -56,13 +56,6 @@
],
}
-cc_defaults {
- name: "keymint_use_latest_hal_aidl_cpp_static",
- static_libs: [
- "android.hardware.security.keymint-V2-cpp",
- ],
-}
-
// A rust_defaults that includes the latest KeyMint AIDL library.
// Modules that depend on KeyMint directly can include this cc_defaults to avoid
// managing dependency versions explicitly.
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 91db3c8..2d2d701 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -75,9 +75,6 @@
export_include_dirs: [
".",
],
- export_static_lib_headers: [
- "libkeymint_support",
- ],
static_libs: [
"libgmock_ndk",
],