Revert "Add remote key provisioning to the IC HAL" am: be32113307
am: e8700adfef
am: 77444fe8a2
am: 60422b9749
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1959805 Change-Id: I249c6357955fd5cf9a4add324bd42c15c7bfefe9
This commit is contained in:
commit
963999f2e1
30 changed files with 59 additions and 518 deletions
|
@ -15,7 +15,6 @@ aidl_interface {
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
"android.hardware.keymaster",
|
"android.hardware.keymaster",
|
||||||
"android.hardware.security.keymint",
|
|
||||||
],
|
],
|
||||||
stability: "vintf",
|
stability: "vintf",
|
||||||
backend: {
|
backend: {
|
||||||
|
@ -26,7 +25,6 @@ aidl_interface {
|
||||||
vndk: {
|
vndk: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
apps_enabled: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
versions: [
|
versions: [
|
||||||
|
|
|
@ -39,5 +39,4 @@ parcelable HardwareInformation {
|
||||||
int dataChunkSize;
|
int dataChunkSize;
|
||||||
boolean isDirectAccess;
|
boolean isDirectAccess;
|
||||||
@utf8InCpp String[] supportedDocTypes;
|
@utf8InCpp String[] supportedDocTypes;
|
||||||
boolean isRemoteKeyProvisioningSupported = false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ interface IIdentityCredentialStore {
|
||||||
android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential);
|
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.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData);
|
||||||
android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite);
|
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_OK = 0;
|
||||||
const int STATUS_FAILED = 1;
|
const int STATUS_FAILED = 1;
|
||||||
const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
|
const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
|
||||||
|
|
|
@ -41,5 +41,4 @@ interface IWritableIdentityCredential {
|
||||||
byte[] addEntryValue(in byte[] content);
|
byte[] addEntryValue(in byte[] content);
|
||||||
@SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
|
@SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
|
||||||
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
|
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
|
||||||
void setRemotelyProvisionedAttestationKey(in byte[] attestationKeyBlob, in byte[] attestationCertificate);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,19 +51,4 @@ parcelable HardwareInformation {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@utf8InCpp String[] supportedDocTypes;
|
@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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import android.hardware.identity.HardwareInformation;
|
||||||
import android.hardware.identity.IIdentityCredential;
|
import android.hardware.identity.IIdentityCredential;
|
||||||
import android.hardware.identity.IPresentationSession;
|
import android.hardware.identity.IPresentationSession;
|
||||||
import android.hardware.identity.IWritableIdentityCredential;
|
import android.hardware.identity.IWritableIdentityCredential;
|
||||||
import android.hardware.security.keymint.IRemotelyProvisionedComponent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IIdentityCredentialStore provides an interface to a secure store for user identity documents.
|
* IIdentityCredentialStore provides an interface to a secure store for user identity documents.
|
||||||
|
@ -264,23 +263,4 @@ interface IIdentityCredentialStore {
|
||||||
* @return an IPresentationSession interface.
|
* @return an IPresentationSession interface.
|
||||||
*/
|
*/
|
||||||
IPresentationSession createPresentationSession(in CipherSuite cipherSuite);
|
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();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,36 +335,4 @@ interface IWritableIdentityCredential {
|
||||||
* @param expectedProofOfProvisioningSize the expected size of ProofOfProvisioning.
|
* @param expectedProofOfProvisioningSize the expected size of ProofOfProvisioning.
|
||||||
*/
|
*/
|
||||||
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ cc_library_static {
|
||||||
"android.hardware.identity-support-lib",
|
"android.hardware.identity-support-lib",
|
||||||
"android.hardware.identity-V4-ndk",
|
"android.hardware.identity-V4-ndk",
|
||||||
"android.hardware.keymaster-V4-ndk",
|
"android.hardware.keymaster-V4-ndk",
|
||||||
"android.hardware.security.keymint-V2-ndk",
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,9 +81,6 @@ cc_binary {
|
||||||
init_rc: ["identity-default.rc"],
|
init_rc: ["identity-default.rc"],
|
||||||
vintf_fragments: ["identity-default.xml"],
|
vintf_fragments: ["identity-default.xml"],
|
||||||
vendor: true,
|
vendor: true,
|
||||||
defaults: [
|
|
||||||
"keymint_use_latest_hal_aidl_ndk_static",
|
|
||||||
],
|
|
||||||
cflags: [
|
cflags: [
|
||||||
"-Wall",
|
"-Wall",
|
||||||
"-Wextra",
|
"-Wextra",
|
||||||
|
|
|
@ -267,31 +267,14 @@ bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
|
||||||
|
|
||||||
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
|
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
|
||||||
size_t challengeSize, const uint8_t* applicationId,
|
size_t challengeSize, const uint8_t* applicationId,
|
||||||
size_t applicationIdSize, bool testCredential,
|
size_t applicationIdSize, bool testCredential, uint8_t* cert,
|
||||||
const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
|
size_t* certSize) {
|
||||||
const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
|
vector<uint8_t> challengeVec(challengeSize);
|
||||||
uint8_t* cert, size_t* certSize) {
|
memcpy(challengeVec.data(), challenge, challengeSize);
|
||||||
vector<uint8_t> flatChain;
|
|
||||||
vector<uint8_t> keyPair;
|
vector<uint8_t> applicationIdVec(applicationIdSize);
|
||||||
vector<uint8_t> challengeVec(challenge, challenge + challengeSize);
|
memcpy(applicationIdVec.data(), applicationId, applicationIdSize);
|
||||||
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 =
|
optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
|
||||||
android::hardware::identity::support::createEcKeyPairAndAttestation(
|
android::hardware::identity::support::createEcKeyPairAndAttestation(
|
||||||
challengeVec, applicationIdVec, testCredential);
|
challengeVec, applicationIdVec, testCredential);
|
||||||
|
@ -299,10 +282,10 @@ bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const
|
||||||
eicDebug("Error generating CredentialKey and attestation");
|
eicDebug("Error generating CredentialKey and attestation");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
keyPair = std::move(ret->first);
|
|
||||||
flatChain = android::hardware::identity::support::certificateChainJoin(ret->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Extract certificate chain.
|
||||||
|
vector<uint8_t> flatChain =
|
||||||
|
android::hardware::identity::support::certificateChainJoin(ret.value().second);
|
||||||
if (*certSize < flatChain.size()) {
|
if (*certSize < flatChain.size()) {
|
||||||
eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
|
eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
|
||||||
flatChain.size());
|
flatChain.size());
|
||||||
|
@ -313,7 +296,7 @@ bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const
|
||||||
|
|
||||||
// Extract private key.
|
// Extract private key.
|
||||||
optional<vector<uint8_t>> privKey =
|
optional<vector<uint8_t>> privKey =
|
||||||
android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair);
|
android::hardware::identity::support::ecKeyPairGetPrivateKey(ret.value().first);
|
||||||
if (!privKey) {
|
if (!privKey) {
|
||||||
eicDebug("Error extracting private key");
|
eicDebug("Error extracting private key");
|
||||||
return false;
|
return false;
|
||||||
|
@ -537,12 +520,10 @@ bool eicOpsHkdf(const uint8_t* sharedSecret, size_t sharedSecretSize, const uint
|
||||||
#ifdef EIC_DEBUG
|
#ifdef EIC_DEBUG
|
||||||
|
|
||||||
void eicPrint(const char* format, ...) {
|
void eicPrint(const char* format, ...) {
|
||||||
char buf[1024];
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsnprintf(buf, sizeof(buf), format, args);
|
vfprintf(stderr, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
LOG(INFO) << buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
|
void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
|
||||||
|
|
|
@ -155,11 +155,7 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialK
|
||||||
size_t publicKeyCertSize = sizeof publicKeyCert;
|
size_t publicKeyCertSize = sizeof publicKeyCert;
|
||||||
if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
|
if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
|
||||||
applicationId.data(), applicationId.size(),
|
applicationId.data(), applicationId.size(),
|
||||||
/*attestationKeyBlob=*/nullptr,
|
publicKeyCert, &publicKeyCertSize)) {
|
||||||
/*attestationKeyBlobSize=*/0,
|
|
||||||
/*attestationKeyCert=*/nullptr,
|
|
||||||
/*attestationKeyCertSize=*/0, publicKeyCert,
|
|
||||||
&publicKeyCertSize)) {
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
vector<uint8_t> pubKeyCert(publicKeyCertSize);
|
vector<uint8_t> pubKeyCert(publicKeyCertSize);
|
||||||
|
@ -167,23 +163,6 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialK
|
||||||
return pubKeyCert;
|
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(
|
bool FakeSecureHardwareProvisioningProxy::startPersonalization(
|
||||||
int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
|
int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
|
||||||
size_t expectedProofOfProvisioningSize) {
|
size_t expectedProofOfProvisioningSize) {
|
||||||
|
|
|
@ -43,11 +43,6 @@ class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningPro
|
||||||
optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
|
optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
|
||||||
const vector<uint8_t>& applicationId) override;
|
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,
|
bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
|
||||||
const string& docType,
|
const string& docType,
|
||||||
size_t expectedProofOfProvisioningSize) override;
|
size_t expectedProofOfProvisioningSize) override;
|
||||||
|
|
|
@ -1012,8 +1012,8 @@ ndk::ScopedAStatus IdentityCredential::updateCredential(
|
||||||
IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy"));
|
IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy"));
|
||||||
}
|
}
|
||||||
shared_ptr<WritableIdentityCredential> wc =
|
shared_ptr<WritableIdentityCredential> wc =
|
||||||
ndk::SharedRefBase::make<WritableIdentityCredential>(
|
ndk::SharedRefBase::make<WritableIdentityCredential>(provisioningHwProxy, docType_,
|
||||||
provisioningHwProxy, docType_, testCredential_, hardwareInformation_);
|
testCredential_);
|
||||||
if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
|
if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||||
IIdentityCredentialStore::STATUS_FAILED,
|
IIdentityCredentialStore::STATUS_FAILED,
|
||||||
|
|
|
@ -48,13 +48,11 @@ class IdentityCredential : public BnIdentityCredential {
|
||||||
public:
|
public:
|
||||||
IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
|
IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
|
||||||
const vector<uint8_t>& credentialData,
|
const vector<uint8_t>& credentialData,
|
||||||
std::shared_ptr<PresentationSession> session,
|
std::shared_ptr<PresentationSession> session)
|
||||||
HardwareInformation hardwareInformation)
|
|
||||||
: hwProxyFactory_(hwProxyFactory),
|
: hwProxyFactory_(hwProxyFactory),
|
||||||
credentialData_(credentialData),
|
credentialData_(credentialData),
|
||||||
session_(std::move(session)),
|
session_(std::move(session)),
|
||||||
numStartRetrievalCalls_(0),
|
numStartRetrievalCalls_(0),
|
||||||
hardwareInformation_(std::move(hardwareInformation)),
|
|
||||||
expectedDeviceNameSpacesSize_(0) {}
|
expectedDeviceNameSpacesSize_(0) {}
|
||||||
|
|
||||||
// Parses and decrypts credentialData_, return a status code from
|
// Parses and decrypts credentialData_, return a status code from
|
||||||
|
@ -105,7 +103,6 @@ class IdentityCredential : public BnIdentityCredential {
|
||||||
vector<uint8_t> credentialData_;
|
vector<uint8_t> credentialData_;
|
||||||
shared_ptr<PresentationSession> session_;
|
shared_ptr<PresentationSession> session_;
|
||||||
int numStartRetrievalCalls_;
|
int numStartRetrievalCalls_;
|
||||||
HardwareInformation hardwareInformation_;
|
|
||||||
|
|
||||||
// Set by initialize()
|
// Set by initialize()
|
||||||
string docType_;
|
string docType_;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#define LOG_TAG "IdentityCredentialStore"
|
#define LOG_TAG "IdentityCredentialStore"
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android/binder_manager.h>
|
|
||||||
|
|
||||||
#include "IdentityCredential.h"
|
#include "IdentityCredential.h"
|
||||||
#include "IdentityCredentialStore.h"
|
#include "IdentityCredentialStore.h"
|
||||||
|
@ -26,24 +25,15 @@
|
||||||
|
|
||||||
namespace aidl::android::hardware::identity {
|
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(
|
ndk::ScopedAStatus IdentityCredentialStore::getHardwareInformation(
|
||||||
HardwareInformation* hardwareInformation) {
|
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();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +42,7 @@ ndk::ScopedAStatus IdentityCredentialStore::createCredential(
|
||||||
shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
|
shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
|
||||||
sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
|
sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
|
||||||
shared_ptr<WritableIdentityCredential> wc =
|
shared_ptr<WritableIdentityCredential> wc =
|
||||||
ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential,
|
ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential);
|
||||||
hardwareInformation_);
|
|
||||||
if (!wc->initialize()) {
|
if (!wc->initialize()) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||||
IIdentityCredentialStore::STATUS_FAILED,
|
IIdentityCredentialStore::STATUS_FAILED,
|
||||||
|
@ -74,7 +63,7 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential(
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
|
shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
|
||||||
hwProxyFactory_, credentialData, nullptr /* session */, hardwareInformation_);
|
hwProxyFactory_, credentialData, nullptr /* session */);
|
||||||
auto ret = credential->initialize();
|
auto ret = credential->initialize();
|
||||||
if (ret != IIdentityCredentialStore::STATUS_OK) {
|
if (ret != IIdentityCredentialStore::STATUS_OK) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||||
|
@ -94,8 +83,8 @@ ndk::ScopedAStatus IdentityCredentialStore::createPresentationSession(
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
|
sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
|
||||||
shared_ptr<PresentationSession> session = ndk::SharedRefBase::make<PresentationSession>(
|
shared_ptr<PresentationSession> session =
|
||||||
hwProxyFactory_, hwProxy, hardwareInformation_);
|
ndk::SharedRefBase::make<PresentationSession>(hwProxyFactory_, hwProxy);
|
||||||
auto ret = session->initialize();
|
auto ret = session->initialize();
|
||||||
if (ret != IIdentityCredentialStore::STATUS_OK) {
|
if (ret != IIdentityCredentialStore::STATUS_OK) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||||
|
@ -105,23 +94,4 @@ ndk::ScopedAStatus IdentityCredentialStore::createPresentationSession(
|
||||||
return ndk::ScopedAStatus::ok();
|
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
|
} // namespace aidl::android::hardware::identity
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
|
#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
|
||||||
|
|
||||||
#include <aidl/android/hardware/identity/BnIdentityCredentialStore.h>
|
#include <aidl/android/hardware/identity/BnIdentityCredentialStore.h>
|
||||||
#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
|
|
||||||
|
|
||||||
#include "SecureHardwareProxy.h"
|
#include "SecureHardwareProxy.h"
|
||||||
|
|
||||||
|
@ -26,18 +25,14 @@ namespace aidl::android::hardware::identity {
|
||||||
|
|
||||||
using ::android::sp;
|
using ::android::sp;
|
||||||
using ::android::hardware::identity::SecureHardwareProxyFactory;
|
using ::android::hardware::identity::SecureHardwareProxyFactory;
|
||||||
using ::std::optional;
|
|
||||||
using ::std::shared_ptr;
|
using ::std::shared_ptr;
|
||||||
using ::std::string;
|
using ::std::string;
|
||||||
using ::std::vector;
|
using ::std::vector;
|
||||||
|
|
||||||
class IdentityCredentialStore : public BnIdentityCredentialStore {
|
class IdentityCredentialStore : public BnIdentityCredentialStore {
|
||||||
public:
|
public:
|
||||||
// If remote key provisioning is supported, pass the service name for the correct
|
IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory)
|
||||||
// IRemotelyProvisionedComponent to the remotelyProvisionedComponent parameter. Else
|
: hwProxyFactory_(hwProxyFactory) {}
|
||||||
// pass std::nullopt to indicate remote key provisioning is not supported.
|
|
||||||
IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory,
|
|
||||||
optional<string> remotelyProvisionedComponent);
|
|
||||||
|
|
||||||
// The GCM chunk size used by this implementation is 64 KiB.
|
// The GCM chunk size used by this implementation is 64 KiB.
|
||||||
static constexpr size_t kGcmChunkSize = 64 * 1024;
|
static constexpr size_t kGcmChunkSize = 64 * 1024;
|
||||||
|
@ -55,14 +50,8 @@ class IdentityCredentialStore : public BnIdentityCredentialStore {
|
||||||
ndk::ScopedAStatus createPresentationSession(
|
ndk::ScopedAStatus createPresentationSession(
|
||||||
CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override;
|
CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override;
|
||||||
|
|
||||||
ndk::ScopedAStatus getRemotelyProvisionedComponent(
|
|
||||||
shared_ptr<::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent>*
|
|
||||||
outRemotelyProvisionedComponent) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sp<SecureHardwareProxyFactory> hwProxyFactory_;
|
sp<SecureHardwareProxyFactory> hwProxyFactory_;
|
||||||
optional<string> remotelyProvisionedComponentName_;
|
|
||||||
HardwareInformation hardwareInformation_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aidl::android::hardware::identity
|
} // namespace aidl::android::hardware::identity
|
||||||
|
|
|
@ -122,8 +122,8 @@ ndk::ScopedAStatus PresentationSession::setSessionTranscript(
|
||||||
ndk::ScopedAStatus PresentationSession::getCredential(
|
ndk::ScopedAStatus PresentationSession::getCredential(
|
||||||
const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
|
const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
|
||||||
shared_ptr<PresentationSession> p = ref<PresentationSession>();
|
shared_ptr<PresentationSession> p = ref<PresentationSession>();
|
||||||
shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
|
shared_ptr<IdentityCredential> credential =
|
||||||
hwProxyFactory_, credentialData, p, hardwareInformation_);
|
ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, credentialData, p);
|
||||||
int ret = credential->initialize();
|
int ret = credential->initialize();
|
||||||
if (ret != IIdentityCredentialStore::STATUS_OK) {
|
if (ret != IIdentityCredentialStore::STATUS_OK) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||||
|
|
|
@ -38,11 +38,8 @@ using ::std::vector;
|
||||||
class PresentationSession : public BnPresentationSession {
|
class PresentationSession : public BnPresentationSession {
|
||||||
public:
|
public:
|
||||||
PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory,
|
PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory,
|
||||||
sp<SecureHardwareSessionProxy> hwProxy,
|
sp<SecureHardwareSessionProxy> hwProxy)
|
||||||
HardwareInformation hardwareInformation)
|
: hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {}
|
||||||
: hwProxyFactory_(std::move(hwProxyFactory)),
|
|
||||||
hwProxy_(std::move(hwProxy)),
|
|
||||||
hardwareInformation_(std::move(hardwareInformation)) {}
|
|
||||||
|
|
||||||
virtual ~PresentationSession();
|
virtual ~PresentationSession();
|
||||||
|
|
||||||
|
@ -68,7 +65,6 @@ class PresentationSession : public BnPresentationSession {
|
||||||
// Set by constructor
|
// Set by constructor
|
||||||
sp<SecureHardwareProxyFactory> hwProxyFactory_;
|
sp<SecureHardwareProxyFactory> hwProxyFactory_;
|
||||||
sp<SecureHardwareSessionProxy> hwProxy_;
|
sp<SecureHardwareSessionProxy> hwProxy_;
|
||||||
HardwareInformation hardwareInformation_;
|
|
||||||
|
|
||||||
// Set by initialize()
|
// Set by initialize()
|
||||||
uint64_t id_;
|
uint64_t id_;
|
||||||
|
|
|
@ -82,18 +82,6 @@ class SecureHardwareProvisioningProxy : public RefBase {
|
||||||
virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
|
virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
|
||||||
const vector<uint8_t>& applicationId) = 0;
|
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,
|
virtual bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
|
||||||
const string& docType,
|
const string& docType,
|
||||||
size_t expectedProofOfProvisioningSize) = 0;
|
size_t expectedProofOfProvisioningSize) = 0;
|
||||||
|
|
|
@ -79,15 +79,8 @@ ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate(
|
||||||
IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
|
IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<vector<uint8_t>> certChain;
|
optional<vector<uint8_t>> certChain =
|
||||||
if (attestationKeyBlob_ && attestationCertificateChain_) {
|
hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
|
||||||
certChain = hwProxy_->createCredentialKeyUsingRkp(
|
|
||||||
attestationChallenge, attestationApplicationId, *attestationKeyBlob_,
|
|
||||||
attestationCertificateChain_->at(0));
|
|
||||||
} else {
|
|
||||||
certChain = hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!certChain) {
|
if (!certChain) {
|
||||||
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
|
||||||
IIdentityCredentialStore::STATUS_FAILED,
|
IIdentityCredentialStore::STATUS_FAILED,
|
||||||
|
@ -102,14 +95,8 @@ ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate(
|
||||||
}
|
}
|
||||||
|
|
||||||
*outCertificateChain = vector<Certificate>();
|
*outCertificateChain = vector<Certificate>();
|
||||||
for (vector<uint8_t>& cert : certs.value()) {
|
for (const vector<uint8_t>& cert : certs.value()) {
|
||||||
Certificate c;
|
Certificate c = Certificate();
|
||||||
c.encodedCertificate = std::move(cert);
|
|
||||||
outCertificateChain->push_back(std::move(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const vector<uint8_t>& cert : *attestationCertificateChain_) {
|
|
||||||
Certificate c;
|
|
||||||
c.encodedCertificate = cert;
|
c.encodedCertificate = cert;
|
||||||
outCertificateChain->push_back(std::move(c));
|
outCertificateChain->push_back(std::move(c));
|
||||||
}
|
}
|
||||||
|
@ -415,36 +402,4 @@ ndk::ScopedAStatus WritableIdentityCredential::finishAddingEntries(
|
||||||
return ndk::ScopedAStatus::ok();
|
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
|
} // namespace aidl::android::hardware::identity
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace aidl::android::hardware::identity {
|
||||||
|
|
||||||
using ::android::sp;
|
using ::android::sp;
|
||||||
using ::android::hardware::identity::SecureHardwareProvisioningProxy;
|
using ::android::hardware::identity::SecureHardwareProvisioningProxy;
|
||||||
using ::std::optional;
|
|
||||||
using ::std::set;
|
using ::std::set;
|
||||||
using ::std::string;
|
using ::std::string;
|
||||||
using ::std::vector;
|
using ::std::vector;
|
||||||
|
@ -42,11 +41,8 @@ class WritableIdentityCredential : public BnWritableIdentityCredential {
|
||||||
// For an updated credential, call initializeForUpdate() right after construction.
|
// For an updated credential, call initializeForUpdate() right after construction.
|
||||||
//
|
//
|
||||||
WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
|
WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
|
||||||
bool testCredential, HardwareInformation hardwareInformation)
|
bool testCredential)
|
||||||
: hwProxy_(hwProxy),
|
: hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {}
|
||||||
docType_(docType),
|
|
||||||
testCredential_(testCredential),
|
|
||||||
hardwareInformation_(std::move(hardwareInformation)) {}
|
|
||||||
|
|
||||||
~WritableIdentityCredential();
|
~WritableIdentityCredential();
|
||||||
|
|
||||||
|
@ -82,16 +78,11 @@ class WritableIdentityCredential : public BnWritableIdentityCredential {
|
||||||
vector<uint8_t>* outCredentialData,
|
vector<uint8_t>* outCredentialData,
|
||||||
vector<uint8_t>* outProofOfProvisioningSignature) override;
|
vector<uint8_t>* outProofOfProvisioningSignature) override;
|
||||||
|
|
||||||
ndk::ScopedAStatus setRemotelyProvisionedAttestationKey(
|
|
||||||
const vector<uint8_t>& attestationKeyBlob,
|
|
||||||
const vector<uint8_t>& attestationCertificateChain) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Set by constructor.
|
// Set by constructor.
|
||||||
sp<SecureHardwareProvisioningProxy> hwProxy_;
|
sp<SecureHardwareProvisioningProxy> hwProxy_;
|
||||||
string docType_;
|
string docType_;
|
||||||
bool testCredential_;
|
bool testCredential_;
|
||||||
HardwareInformation hardwareInformation_;
|
|
||||||
|
|
||||||
// This is set in initialize().
|
// This is set in initialize().
|
||||||
bool startPersonalizationCalled_;
|
bool startPersonalizationCalled_;
|
||||||
|
@ -118,10 +109,6 @@ class WritableIdentityCredential : public BnWritableIdentityCredential {
|
||||||
vector<int32_t> entryAccessControlProfileIds_;
|
vector<int32_t> entryAccessControlProfileIds_;
|
||||||
vector<uint8_t> entryBytes_;
|
vector<uint8_t> entryBytes_;
|
||||||
set<string> allNameSpaces_;
|
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
|
} // namespace aidl::android::hardware::identity
|
||||||
|
|
|
@ -196,19 +196,13 @@ bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
|
||||||
|
|
||||||
// Generates CredentialKey plus an attestation certificate.
|
// Generates CredentialKey plus an attestation certificate.
|
||||||
//
|
//
|
||||||
// If |attestationKeyBlob| is non-NULL, the certificate must be signed by the
|
// The attestation certificate will be signed by the attestation keys the secure
|
||||||
// the provided attestation key. Else, the certificate must be signed by the
|
// area has been provisioned with. The given |challenge| and |applicationId|
|
||||||
// attestation key that the secure area has been factory provisioned with. The
|
// will be used as will |testCredential|.
|
||||||
// given |challenge|, |applicationId|, and |testCredential| must be signed
|
|
||||||
// into the attestation.
|
|
||||||
//
|
//
|
||||||
// When |attestationKeyBlob| is non-NULL, then |attestationKeyCert| must
|
// The generated certificate will be in X.509 format and returned in |cert|
|
||||||
// also be passed so that the underlying implementation can properly chain up
|
// and |certSize| must be set to the size of this array and this function will
|
||||||
// the newly-generated certificate to the existing chain.
|
// set it to the size of the certification chain on successfully return.
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
//
|
||||||
// This may return either a single certificate or an entire certificate
|
// This may return either a single certificate or an entire certificate
|
||||||
// chain. If it returns only a single certificate, the implementation of
|
// chain. If it returns only a single certificate, the implementation of
|
||||||
|
@ -217,10 +211,8 @@ bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
|
||||||
//
|
//
|
||||||
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
|
bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
|
||||||
size_t challengeSize, const uint8_t* applicationId,
|
size_t challengeSize, const uint8_t* applicationId,
|
||||||
size_t applicationIdSize, bool testCredential,
|
size_t applicationIdSize, bool testCredential, uint8_t* cert,
|
||||||
const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
|
size_t* certSize); // inout
|
||||||
const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
|
|
||||||
uint8_t* /*out*/ cert, size_t* /*inout*/ certSize);
|
|
||||||
|
|
||||||
// Generate an X.509 certificate for the key identified by |publicKey| which
|
// Generate an X.509 certificate for the key identified by |publicKey| which
|
||||||
// must be of the form returned by eicOpsCreateEcKey().
|
// must be of the form returned by eicOpsCreateEcKey().
|
||||||
|
|
|
@ -133,10 +133,7 @@ bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId) {
|
||||||
|
|
||||||
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
|
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
|
||||||
size_t challengeSize, const uint8_t* applicationId,
|
size_t challengeSize, const uint8_t* applicationId,
|
||||||
size_t applicationIdSize, const uint8_t* attestationKeyBlob,
|
size_t applicationIdSize, uint8_t* publicKeyCert,
|
||||||
size_t attestationKeyBlobSize,
|
|
||||||
const uint8_t* attestationKeyCert,
|
|
||||||
size_t attestationKeyCertSize, uint8_t* publicKeyCert,
|
|
||||||
size_t* publicKeyCertSize) {
|
size_t* publicKeyCertSize) {
|
||||||
if (ctx->isUpdate) {
|
if (ctx->isUpdate) {
|
||||||
eicDebug("Cannot create CredentialKey on update");
|
eicDebug("Cannot create CredentialKey on update");
|
||||||
|
@ -145,9 +142,7 @@ bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* cha
|
||||||
|
|
||||||
if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize,
|
if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize,
|
||||||
applicationId, applicationIdSize, ctx->testCredential,
|
applicationId, applicationIdSize, ctx->testCredential,
|
||||||
attestationKeyBlob, attestationKeyBlobSize, attestationKeyCert,
|
publicKeyCert, publicKeyCertSize)) {
|
||||||
attestationKeyCertSize, publicKeyCert, publicKeyCertSize)) {
|
|
||||||
eicDebug("Error creating credential key");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -77,10 +77,7 @@ bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId);
|
||||||
|
|
||||||
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
|
bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
|
||||||
size_t challengeSize, const uint8_t* applicationId,
|
size_t challengeSize, const uint8_t* applicationId,
|
||||||
size_t applicationIdSize, const uint8_t* attestationKeyBlob,
|
size_t applicationIdSize, uint8_t* publicKeyCert,
|
||||||
size_t attestationKeyBlobSize,
|
|
||||||
const uint8_t* attestationKeyCert,
|
|
||||||
size_t attestationKeyCertSize, uint8_t* publicKeyCert,
|
|
||||||
size_t* publicKeyCertSize);
|
size_t* publicKeyCertSize);
|
||||||
|
|
||||||
bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount,
|
bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount,
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#define LOG_TAG "android.hardware.identity-service"
|
#define LOG_TAG "android.hardware.identity-service"
|
||||||
|
|
||||||
#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android/binder_manager.h>
|
#include <android/binder_manager.h>
|
||||||
#include <android/binder_process.h>
|
#include <android/binder_process.h>
|
||||||
|
@ -33,7 +32,6 @@ using ::android::base::LogSeverity;
|
||||||
using ::android::base::StderrLogger;
|
using ::android::base::StderrLogger;
|
||||||
|
|
||||||
using ::aidl::android::hardware::identity::IdentityCredentialStore;
|
using ::aidl::android::hardware::identity::IdentityCredentialStore;
|
||||||
using ::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
|
|
||||||
using ::android::hardware::identity::FakeSecureHardwareProxyFactory;
|
using ::android::hardware::identity::FakeSecureHardwareProxyFactory;
|
||||||
using ::android::hardware::identity::SecureHardwareProxyFactory;
|
using ::android::hardware::identity::SecureHardwareProxyFactory;
|
||||||
|
|
||||||
|
@ -49,13 +47,10 @@ int main(int /*argc*/, char* argv[]) {
|
||||||
InitLogging(argv, ComboLogger);
|
InitLogging(argv, ComboLogger);
|
||||||
|
|
||||||
sp<SecureHardwareProxyFactory> hwProxyFactory = new FakeSecureHardwareProxyFactory();
|
sp<SecureHardwareProxyFactory> hwProxyFactory = new FakeSecureHardwareProxyFactory();
|
||||||
const std::string remotelyProvisionedComponentName =
|
|
||||||
std::string(IRemotelyProvisionedComponent::descriptor) + "/default";
|
|
||||||
|
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||||
std::shared_ptr<IdentityCredentialStore> store =
|
std::shared_ptr<IdentityCredentialStore> store =
|
||||||
ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory,
|
ndk::SharedRefBase::make<IdentityCredentialStore>(hwProxyFactory);
|
||||||
remotelyProvisionedComponentName);
|
|
||||||
|
|
||||||
const std::string instance = std::string() + IdentityCredentialStore::descriptor + "/default";
|
const std::string instance = std::string() + IdentityCredentialStore::descriptor + "/default";
|
||||||
binder_status_t status = AServiceManager_addService(store->asBinder().get(), instance.c_str());
|
binder_status_t status = AServiceManager_addService(store->asBinder().get(), instance.c_str());
|
||||||
|
|
|
@ -11,8 +11,6 @@ cc_test {
|
||||||
name: "VtsHalIdentityTargetTest",
|
name: "VtsHalIdentityTargetTest",
|
||||||
defaults: [
|
defaults: [
|
||||||
"VtsHalTargetTestDefaults",
|
"VtsHalTargetTestDefaults",
|
||||||
"keymint_use_latest_hal_aidl_cpp_static",
|
|
||||||
"keymint_use_latest_hal_aidl_ndk_static",
|
|
||||||
"use_libaidlvintf_gtest_helper_static",
|
"use_libaidlvintf_gtest_helper_static",
|
||||||
],
|
],
|
||||||
cflags: [
|
cflags: [
|
||||||
|
@ -34,15 +32,12 @@ cc_test {
|
||||||
],
|
],
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libbinder",
|
"libbinder",
|
||||||
"libbinder_ndk",
|
|
||||||
"libcrypto",
|
"libcrypto",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"android.hardware.security.secureclock-V1-ndk",
|
|
||||||
"libcppbor_external",
|
"libcppbor_external",
|
||||||
"libcppcose_rkp",
|
"libcppcose_rkp",
|
||||||
"libkeymaster_portable",
|
"libkeymaster_portable",
|
||||||
"libkeymint_vts_test_utils",
|
|
||||||
"libpuresoftkeymasterdevice",
|
"libpuresoftkeymasterdevice",
|
||||||
"android.hardware.keymaster@4.0",
|
"android.hardware.keymaster@4.0",
|
||||||
"android.hardware.identity-support-lib",
|
"android.hardware.identity-support-lib",
|
||||||
|
@ -51,7 +46,6 @@ cc_test {
|
||||||
"android.hardware.keymaster-V4-ndk",
|
"android.hardware.keymaster-V4-ndk",
|
||||||
"libkeymaster4support",
|
"libkeymaster4support",
|
||||||
"libkeymaster4_1support",
|
"libkeymaster4_1support",
|
||||||
"libkeymint_remote_prov_support",
|
|
||||||
],
|
],
|
||||||
test_suites: [
|
test_suites: [
|
||||||
"general-tests",
|
"general-tests",
|
||||||
|
|
|
@ -20,16 +20,12 @@
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
|
|
||||||
#include <KeyMintAidlTestBase.h>
|
|
||||||
#include <aidl/Gtest.h>
|
#include <aidl/Gtest.h>
|
||||||
#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
|
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <keymaster/km_openssl/openssl_utils.h>
|
#include <keymaster/km_openssl/openssl_utils.h>
|
||||||
#include <keymasterV4_1/attestation_record.h>
|
#include <keymasterV4_1/attestation_record.h>
|
||||||
#include <keymint_support/openssl_utils.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace android::hardware::identity::test_utils {
|
namespace android::hardware::identity::test_utils {
|
||||||
|
@ -40,13 +36,10 @@ using std::optional;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
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::sp;
|
||||||
using ::android::String16;
|
using ::android::String16;
|
||||||
using ::android::base::StringPrintf;
|
using ::android::base::StringPrintf;
|
||||||
using ::android::binder::Status;
|
using ::android::binder::Status;
|
||||||
using ::android::hardware::security::keymint::MacedPublicKey;
|
|
||||||
using ::keymaster::X509_Ptr;
|
using ::keymaster::X509_Ptr;
|
||||||
|
|
||||||
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
|
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
|
||||||
|
@ -65,77 +58,6 @@ bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal) {
|
||||||
vector<uint8_t> privKey;
|
vector<uint8_t> privKey;
|
||||||
return generateReaderCertificate(serialDecimal, &privKey);
|
return generateReaderCertificate(serialDecimal, &privKey);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||||
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
|
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
|
||||||
#include <android/hardware/security/keymint/MacedPublicKey.h>
|
|
||||||
#include <cppbor.h>
|
#include <cppbor.h>
|
||||||
#include <cppbor_parse.h>
|
#include <cppbor_parse.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
@ -98,9 +97,6 @@ struct TestProfile {
|
||||||
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
|
bool setupWritableCredential(sp<IWritableIdentityCredential>& writableCredential,
|
||||||
sp<IIdentityCredentialStore>& credentialStore, bool testCredential);
|
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);
|
||||||
|
|
||||||
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
|
optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal,
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
#include <aidl/Gtest.h>
|
#include <aidl/Gtest.h>
|
||||||
#include <aidl/Vintf.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-base/logging.h>
|
||||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||||
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
|
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
|
||||||
|
@ -44,8 +42,6 @@ using std::vector;
|
||||||
using ::android::sp;
|
using ::android::sp;
|
||||||
using ::android::String16;
|
using ::android::String16;
|
||||||
using ::android::binder::Status;
|
using ::android::binder::Status;
|
||||||
using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
|
|
||||||
using ::android::hardware::security::keymint::MacedPublicKey;
|
|
||||||
|
|
||||||
class IdentityCredentialTests : public testing::TestWithParam<string> {
|
class IdentityCredentialTests : public testing::TestWithParam<string> {
|
||||||
public:
|
public:
|
||||||
|
@ -105,103 +101,6 @@ TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithChallenge) {
|
||||||
attestationApplicationId, false);
|
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) {
|
TEST_P(IdentityCredentialTests, verifyAttestationDoubleCallFails) {
|
||||||
Status result;
|
Status result;
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,6 @@ cc_defaults {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// A rust_defaults that includes the latest KeyMint AIDL library.
|
||||||
// Modules that depend on KeyMint directly can include this cc_defaults to avoid
|
// Modules that depend on KeyMint directly can include this cc_defaults to avoid
|
||||||
// managing dependency versions explicitly.
|
// managing dependency versions explicitly.
|
||||||
|
|
|
@ -75,9 +75,6 @@ cc_test_library {
|
||||||
export_include_dirs: [
|
export_include_dirs: [
|
||||||
".",
|
".",
|
||||||
],
|
],
|
||||||
export_static_lib_headers: [
|
|
||||||
"libkeymint_support",
|
|
||||||
],
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"libgmock_ndk",
|
"libgmock_ndk",
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue