diff options
4 files changed, 194 insertions, 66 deletions
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 59cb57b75b..64ef06666f 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -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(); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index da174ce7b1..75a4418694 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -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); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 09cdab1a48..aa008f8a87 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -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); diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h index ae21125213..5b2a6f32e1 100644 --- a/security/keymint/support/include/keymint_support/keymint_tags.h +++ b/security/keymint/support/include/keymint_support/keymint_tags.h @@ -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; |