diff options
author | Selene Huang <seleneh@google.com> | 2020-01-08 22:59:02 -0800 |
---|---|---|
committer | Selene Huang <seleneh@google.com> | 2020-02-21 16:02:26 -0800 |
commit | 459cb80866b70b1dbc96fd4a68ddd68425d2503b (patch) | |
tree | fbd7ad48d6c94ca408561b6d2520f9a1539afb23 /identity/aidl/default/WritableIdentityCredential.cpp | |
parent | 6a83338df9e8f4ff696450ea5688c58003753441 (diff) |
Add attestation certificate generation and identity credential tags.
Bug: 149908474
Test: atest android.security.identity.cts.AttestationTest
Test: atest VtsHalIdentityCredentialTargetTest
Test: atest android.hardware.identity-support-lib-test
Change-Id: I18c5d05d806d4157c9dce42a398cc89421e26907
Diffstat (limited to 'identity/aidl/default/WritableIdentityCredential.cpp')
-rw-r--r-- | identity/aidl/default/WritableIdentityCredential.cpp | 119 |
1 files changed, 35 insertions, 84 deletions
diff --git a/identity/aidl/default/WritableIdentityCredential.cpp b/identity/aidl/default/WritableIdentityCredential.cpp index ba2062d7c0..89f7f35696 100644 --- a/identity/aidl/default/WritableIdentityCredential.cpp +++ b/identity/aidl/default/WritableIdentityCredential.cpp @@ -16,6 +16,9 @@ #define LOG_TAG "WritableIdentityCredential" +#include "WritableIdentityCredential.h" +#include "IdentityCredentialStore.h" + #include <android/hardware/identity/support/IdentityCredentialSupport.h> #include <android-base/logging.h> @@ -23,6 +26,8 @@ #include <cppbor/cppbor.h> #include <cppbor/cppbor_parse.h> +#include <utility> + #include "IdentityCredentialStore.h" #include "Util.h" #include "WritableIdentityCredential.h" @@ -33,26 +38,6 @@ using ::std::optional; using namespace ::android::hardware::identity; bool WritableIdentityCredential::initialize() { - optional<vector<uint8_t>> keyPair = support::createEcKeyPair(); - if (!keyPair) { - LOG(ERROR) << "Error creating credentialKey"; - return false; - } - - optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value()); - if (!pubKey) { - LOG(ERROR) << "Error getting public part of credentialKey"; - return false; - } - credentialPubKey_ = pubKey.value(); - - optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value()); - if (!privKey) { - LOG(ERROR) << "Error getting private part of credentialKey"; - return false; - } - credentialPrivKey_ = privKey.value(); - optional<vector<uint8_t>> random = support::getRandom(16); if (!random) { LOG(ERROR) << "Error creating storageKey"; @@ -63,88 +48,54 @@ bool WritableIdentityCredential::initialize() { return true; } -// TODO: use |attestationApplicationId| and |attestationChallenge| and also -// ensure the returned certificate chain satisfy the requirements listed in -// the docs for IWritableIdentityCredential::getAttestationCertificate() -// +// This function generates the attestation certificate using the passed in +// |attestationApplicationId| and |attestationChallenge|. It will generate an +// attestation certificate with current time and expires one year from now. The +// certificate shall contain all values as specified in hal. ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate( - const vector<int8_t>& /*attestationApplicationId*/, - const vector<int8_t>& /*attestationChallenge*/, vector<Certificate>* outCertificateChain) { - // For now, we dynamically generate an attestion key on each and every - // request and use that to sign CredentialKey. In a real implementation this - // would look very differently. - optional<vector<uint8_t>> attestationKeyPair = support::createEcKeyPair(); - if (!attestationKeyPair) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_FAILED, "Error creating attestationKey")); - } - - optional<vector<uint8_t>> attestationPubKey = - support::ecKeyPairGetPublicKey(attestationKeyPair.value()); - if (!attestationPubKey) { + const vector<int8_t>& attestationApplicationId, // + const vector<int8_t>& attestationChallenge, // + vector<Certificate>* outCertificateChain) { + if (!credentialPrivKey_.empty() || !credentialPubKey_.empty() || !certificateChain_.empty()) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, - "Error getting public part of attestationKey")); + "Error attestation certificate previously generated")); } - optional<vector<uint8_t>> attestationPrivKey = - support::ecKeyPairGetPrivateKey(attestationKeyPair.value()); - if (!attestationPrivKey) { + vector<uint8_t> challenge(attestationChallenge.begin(), attestationChallenge.end()); + vector<uint8_t> appId(attestationApplicationId.begin(), attestationApplicationId.end()); + + optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> keyAttestationPair = + support::createEcKeyPairAndAttestation(challenge, appId); + if (!keyAttestationPair) { + LOG(ERROR) << "Error creating credentialKey and attestation"; return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, - "Error getting private part of attestationKey")); + "Error creating credentialKey and attestation")); } - string serialDecimal; - string issuer; - string subject; - time_t validityNotBefore = time(nullptr); - time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600; - - // First create a certificate for |credentialPubKey| which is signed by - // |attestationPrivKey|. - // - serialDecimal = "0"; // TODO: set serial to |attestationChallenge| - issuer = "Android Open Source Project"; - subject = "Android IdentityCredential CredentialKey"; - optional<vector<uint8_t>> credentialPubKeyCertificate = support::ecPublicKeyGenerateCertificate( - credentialPubKey_, attestationPrivKey.value(), serialDecimal, issuer, subject, - validityNotBefore, validityNotAfter); - if (!credentialPubKeyCertificate) { + vector<uint8_t> keyPair = keyAttestationPair.value().first; + certificateChain_ = keyAttestationPair.value().second; + + optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair); + if (!pubKey) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, - "Error creating certificate for credentialPubKey")); + "Error getting public part of credentialKey")); } + credentialPubKey_ = pubKey.value(); - // This is followed by a certificate for |attestationPubKey| self-signed by - // |attestationPrivKey|. - serialDecimal = "0"; // TODO: set serial - issuer = "Android Open Source Project"; - subject = "Android IdentityCredential AttestationKey"; - optional<vector<uint8_t>> attestationKeyCertificate = support::ecPublicKeyGenerateCertificate( - attestationPubKey.value(), attestationPrivKey.value(), serialDecimal, issuer, subject, - validityNotBefore, validityNotAfter); - if (!attestationKeyCertificate) { + optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair); + if (!privKey) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, - "Error creating certificate for attestationPubKey")); + "Error getting private part of credentialKey")); } + credentialPrivKey_ = privKey.value(); - // Concatenate the certificates to form the chain. - vector<uint8_t> certificateChain; - certificateChain.insert(certificateChain.end(), credentialPubKeyCertificate.value().begin(), - credentialPubKeyCertificate.value().end()); - certificateChain.insert(certificateChain.end(), attestationKeyCertificate.value().begin(), - attestationKeyCertificate.value().end()); - - optional<vector<vector<uint8_t>>> splitCertChain = - support::certificateChainSplit(certificateChain); - if (!splitCertChain) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_FAILED, "Error splitting certificate chain")); - } + // convert from vector<vector<uint8_t>>> to vector<Certificate>* *outCertificateChain = vector<Certificate>(); - for (const vector<uint8_t>& cert : splitCertChain.value()) { + for (const vector<uint8_t>& cert : certificateChain_) { Certificate c = Certificate(); c.encodedCertificate = byteStringToSigned(cert); outCertificateChain->push_back(std::move(c)); |