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:
Treehugger Robot
2021-04-23 07:53:20 +00:00
committed by Gerrit Code Review
4 changed files with 194 additions and 66 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;