mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Added vts tests for certificate subject and serial for various algorithms and self sign or non-self sign certificates."
This commit is contained in:
@@ -845,6 +845,66 @@ ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob)
|
||||
return result;
|
||||
}
|
||||
|
||||
void verify_serial(X509* cert, const uint64_t expected_serial) {
|
||||
BIGNUM_Ptr ser(BN_new());
|
||||
EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
|
||||
|
||||
uint64_t serial;
|
||||
EXPECT_TRUE(BN_get_u64(ser.get(), &serial));
|
||||
EXPECT_EQ(serial, expected_serial);
|
||||
}
|
||||
|
||||
// Please set self_signed to true for fake certificates or self signed
|
||||
// certificates
|
||||
void verify_subject(const X509* cert, //
|
||||
const string& subject, //
|
||||
bool self_signed) {
|
||||
char* cert_issuer = //
|
||||
X509_NAME_oneline(X509_get_issuer_name(cert), nullptr, 0);
|
||||
|
||||
char* cert_subj = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0);
|
||||
|
||||
string expected_subject("/CN=");
|
||||
if (subject.empty()) {
|
||||
expected_subject.append("Android Keystore Key");
|
||||
} else {
|
||||
expected_subject.append(subject);
|
||||
}
|
||||
|
||||
EXPECT_STREQ(expected_subject.c_str(), cert_subj) << "Cert has wrong subject." << cert_subj;
|
||||
|
||||
if (self_signed) {
|
||||
EXPECT_STREQ(cert_issuer, cert_subj)
|
||||
<< "Cert issuer and subject mismatch for self signed certificate.";
|
||||
}
|
||||
|
||||
OPENSSL_free(cert_subj);
|
||||
OPENSSL_free(cert_issuer);
|
||||
}
|
||||
|
||||
vector<uint8_t> build_serial_blob(const uint64_t serial_int) {
|
||||
BIGNUM_Ptr serial(BN_new());
|
||||
EXPECT_TRUE(BN_set_u64(serial.get(), serial_int));
|
||||
|
||||
int len = BN_num_bytes(serial.get());
|
||||
vector<uint8_t> serial_blob(len);
|
||||
if (BN_bn2bin(serial.get(), serial_blob.data()) != len) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return serial_blob;
|
||||
}
|
||||
|
||||
void verify_subject_and_serial(const Certificate& certificate, //
|
||||
const uint64_t expected_serial, //
|
||||
const string& subject, bool self_signed) {
|
||||
X509_Ptr cert(parse_cert_blob(certificate.encodedCertificate));
|
||||
ASSERT_TRUE(!!cert.get());
|
||||
|
||||
verify_serial(cert.get(), expected_serial);
|
||||
verify_subject(cert.get(), subject, self_signed);
|
||||
}
|
||||
|
||||
bool verify_attestation_record(const string& challenge, //
|
||||
const string& app_id, //
|
||||
AuthorizationSet expected_sw_enforced, //
|
||||
@@ -1084,16 +1144,6 @@ AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain) {
|
||||
if (cert_issuer != signer_subj) {
|
||||
return AssertionFailure() << "Cert " << i << " has wrong issuer.\n" << cert_data.str();
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
string cert_sub = x509NameToStr(X509_get_subject_name(key_cert.get()));
|
||||
if ("/CN=Android Keystore Key" != cert_sub) {
|
||||
return AssertionFailure()
|
||||
<< "Leaf cert has wrong subject, should be CN=Android Keystore Key, was "
|
||||
<< cert_sub << '\n'
|
||||
<< cert_data.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (KeyMintAidlTestBase::dump_Attestations) std::cout << cert_data.str();
|
||||
|
||||
@@ -269,12 +269,20 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
|
||||
long challenge_;
|
||||
};
|
||||
|
||||
vector<uint8_t> build_serial_blob(const uint64_t serial_int);
|
||||
void verify_subject(const X509* cert, const string& subject, bool self_signed);
|
||||
void verify_serial(X509* cert, const uint64_t expected_serial);
|
||||
void verify_subject_and_serial(const Certificate& certificate, //
|
||||
const uint64_t expected_serial, //
|
||||
const string& subject, bool self_signed);
|
||||
|
||||
bool verify_attestation_record(const string& challenge, //
|
||||
const string& app_id, //
|
||||
AuthorizationSet expected_sw_enforced, //
|
||||
AuthorizationSet expected_hw_enforced, //
|
||||
SecurityLevel security_level,
|
||||
const vector<uint8_t>& attestation_cert);
|
||||
|
||||
string bin2hex(const vector<uint8_t>& data);
|
||||
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
|
||||
vector<uint8_t> make_name_from_str(const string& name);
|
||||
|
||||
@@ -362,18 +362,27 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestation) {
|
||||
auto challenge = "hello";
|
||||
auto app_id = "foo";
|
||||
|
||||
auto subject = "cert subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 66;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
CheckBaseParams(key_characteristics);
|
||||
@@ -385,6 +394,7 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestation) {
|
||||
<< "Key size " << key_size << "missing";
|
||||
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
|
||||
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
ASSERT_GT(cert_chain_.size(), 0);
|
||||
|
||||
@@ -480,16 +490,25 @@ TEST_P(NewKeyGenerationTest, RsaEncryptionWithAttestation) {
|
||||
auto challenge = "hello";
|
||||
auto app_id = "foo";
|
||||
|
||||
auto subject = "subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 111166;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaEncryptionKey(key_size, 65537)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaEncryptionKey(key_size, 65537)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
AuthorizationSet auths;
|
||||
@@ -521,6 +540,7 @@ TEST_P(NewKeyGenerationTest, RsaEncryptionWithAttestation) {
|
||||
<< "Key size " << key_size << "missing";
|
||||
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
|
||||
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
ASSERT_GT(cert_chain_.size(), 0);
|
||||
|
||||
@@ -541,16 +561,25 @@ TEST_P(NewKeyGenerationTest, RsaEncryptionWithAttestation) {
|
||||
* works as expected.
|
||||
*/
|
||||
TEST_P(NewKeyGenerationTest, RsaWithSelfSign) {
|
||||
auto subject = "cert subj subj subj subj subj subj 22222222222222222222";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 0;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
CheckBaseParams(key_characteristics);
|
||||
@@ -562,6 +591,7 @@ TEST_P(NewKeyGenerationTest, RsaWithSelfSign) {
|
||||
<< "Key size " << key_size << "missing";
|
||||
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
|
||||
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
ASSERT_EQ(cert_chain_.size(), 1);
|
||||
|
||||
@@ -599,16 +629,25 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestationAppIdIgnored) {
|
||||
auto key_size = 2048;
|
||||
auto app_id = "foo";
|
||||
|
||||
auto subject = "cert subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 1;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
CheckBaseParams(key_characteristics);
|
||||
@@ -620,6 +659,7 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestationAppIdIgnored) {
|
||||
<< "Key size " << key_size << "missing";
|
||||
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
|
||||
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
ASSERT_EQ(cert_chain_.size(), 1);
|
||||
|
||||
@@ -676,19 +716,28 @@ TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) {
|
||||
auto challenge = "hello";
|
||||
auto app_id = "foo";
|
||||
|
||||
auto subject = "cert subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 66;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_USAGE_COUNT_LIMIT, 1)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(key_size, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_USAGE_COUNT_LIMIT, 1)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
CheckBaseParams(key_characteristics);
|
||||
@@ -711,6 +760,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) {
|
||||
// Check the usage count limit tag also appears in the attestation.
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
ASSERT_GT(cert_chain_.size(), 0);
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
|
||||
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
|
||||
@@ -794,17 +844,26 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) {
|
||||
auto challenge = "hello";
|
||||
auto app_id = "foo";
|
||||
|
||||
auto subject = "cert subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 0xFFFFFFFFFFFFFFFF;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.EcdsaSigningKey(key_size)
|
||||
.Digest(Digest::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.EcdsaSigningKey(key_size)
|
||||
.Digest(Digest::NONE)
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
CheckBaseParams(key_characteristics);
|
||||
|
||||
@@ -816,6 +875,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) {
|
||||
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
ASSERT_GT(cert_chain_.size(), 0);
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
|
||||
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
|
||||
@@ -834,14 +894,23 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) {
|
||||
* the key will generate a self signed attestation.
|
||||
*/
|
||||
TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) {
|
||||
auto subject = "cert subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 0x123456FFF1234;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
|
||||
vector<uint8_t> key_blob;
|
||||
vector<KeyCharacteristics> key_characteristics;
|
||||
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
|
||||
.EcdsaSigningKey(key_size)
|
||||
.Digest(Digest::NONE)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.EcdsaSigningKey(key_size)
|
||||
.Digest(Digest::NONE)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
&key_blob, &key_characteristics));
|
||||
ASSERT_GT(key_blob.size(), 0U);
|
||||
CheckBaseParams(key_characteristics);
|
||||
|
||||
@@ -852,6 +921,7 @@ TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) {
|
||||
<< "Key size " << key_size << "missing";
|
||||
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
|
||||
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
|
||||
ASSERT_EQ(cert_chain_.size(), 1);
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
|
||||
|
||||
@@ -153,7 +153,7 @@ using all_tags_t = MetaList<
|
||||
TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t,
|
||||
TAG_DIGEST_t, TAG_PADDING_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t,
|
||||
TAG_BOOT_PATCHLEVEL_t, TAG_VENDOR_PATCHLEVEL_t, TAG_TRUSTED_CONFIRMATION_REQUIRED_t,
|
||||
TAG_TRUSTED_USER_PRESENCE_REQUIRED_t>;
|
||||
TAG_TRUSTED_USER_PRESENCE_REQUIRED_t, TAG_CERTIFICATE_SERIAL_t, TAG_CERTIFICATE_SUBJECT_t>;
|
||||
|
||||
template <typename TypedTagType>
|
||||
struct TypedTag2ValueType;
|
||||
|
||||
Reference in New Issue
Block a user