1/* 2 * Copyright (c) 2024-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <cstdlib> 17#include <fcntl.h> 18#include <gtest/gtest.h> 19#include <string> 20#include <openssl/pem.h> 21#include <openssl/x509.h> 22 23#include "access_token_setter.h" 24#include "byte_buffer.h" 25#include "huks_attest_verifier.h" 26#include "log.h" 27 28using namespace OHOS::Security::CodeSign; 29using namespace std; 30using namespace testing::ext; 31 32namespace OHOS { 33namespace Security { 34namespace CodeSign { 35const std::string SIGNING_CERT_CHAIN_PEM = 36"-----BEGIN CERTIFICATE-----\n" \ 37"MIIDgzCCAm2gAwIBAgIBATALBgkqhkiG9w0BAQswfzELMAkGA1UEBhMCQ04xEzAR\n" \ 38"BgNVBAgMCmhlbGxvd29ybGQxEzARBgNVBAoMCmhlbGxvd29ybGQxEzARBgNVBAsM\n" \ 39"CmhlbGxvd29ybGQxFjAUBgNVBAMMDWhlbGxvd29ybGQxMTExGTAXBgkqhkiG9w0B\n" \ 40"CQEWCmhlbGxvd29ybGQwHhcNMjQwODA5MDkzMDEyWhcNMzQwODA5MDkzMDEyWjAa\n" \ 41"MRgwFgYDVQQDEw9BIEtleW1hc3RlciBLZXkwWTATBgcqhkjOPQIBBggqhkjOPQMB\n" \ 42"BwNCAATJqTRIhGKhLmXuJbPI311/5gEljqPbpJpXNp6oe8dOmnyJ9SQQZmMomB5u\n" \ 43"lC5aZIoNrCuKHTAgY1PpNNcFSBBpo4IBPDCCATgwCwYDVR0PBAQDAgeAMAgGA1Ud\n" \ 44"HwQBADCCAR0GDCsGAQQBj1sCgngBAwSCAQswggEHAgEAMDQCAQAGDSsGAQQBj1sC\n" \ 45"gngCAQQEIOIC9EG2Dn3zqle0WWjiHwk2CIP3hJuPjjQwi7z4FaFFMCICAQIGDSsG\n" \ 46"AQQBj1sCgngCAQIEDkxPQ0FMX1NJR05fS0VZMFwCAQIGDSsGAQQBj1sCgngCAQMw\n" \ 47"SAYOKwYBBAGPWwKCeAIBAwEENnsicHJvY2Vzc05hbWUiOiJsb2NhbF9jb2RlX3Np\n" \ 48"Z24iLCJBUEwiOiJzeXN0ZW1fYmFzaWMifTAYAgECBg0rBgEEAY9bAoJ4AgELBAQA\n" \ 49"AAAAMBgCAQIGDSsGAQQBj1sCgngCAQUEBAIAAAAwFgIBAgYOKwYBBAGPWwKCeAIE\n" \ 50"AQUBAf8wCwYJKoZIhvcNAQELA4IBAQB8zqqeaXux3qkQF0GFax7I4YWtTpoeQeJU\n" \ 51"BjyMk/eGmeX+ZD9absOQDzH/wH6MddzPLjoaIuoR+oxDXn2yqQ5xyGQp6uN0E8IB\n" \ 52"OFCjeTbRBR86A+CulTGuitszOpfyKF7SvmzfGx+ij2OtQnZ7QZp+I2YEr1Jc4ESr\n" \ 53"xXXt0zPslidnf7qso+f09C6U9YOnaxISfjxEqFn25+yWX2tXBJ62L6R7+zpKU3ee\n" \ 54"0ljf4jYtlza7s5mYJ2+OHlwdXuF38cpS59cG48UpsL0DAqywqjs5uaGthkrWo2YB\n" \ 55"FlAL4bVfBj2FmcqNhz+j3dgLTNA3VczwkNbj/FIY1T+FDTqnsCED\n" \ 56"-----END CERTIFICATE-----"; 57 58const std::string ISSUER_CERT_CHAIN_PEM = 59"-----BEGIN CERTIFICATE-----\n" \ 60"MIIDyzCCArOgAwIBAgIBAzANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJDTjET\n" \ 61"MBEGA1UECAwKaGVsbG93b3JsZDETMBEGA1UECgwKaGVsbG93b3JsZDETMBEGA1UE\n" \ 62"CwwKaGVsbG93b3JsZDEVMBMGA1UEAwwMaGVsbG93b3JsZDExMRkwFwYJKoZIhvcN\n" \ 63"AQkBFgpoZWxsb3dvcmxkMB4XDTIyMDEyMjA5MjUzM1oXDTMyMDEyMDA5MjUzM1ow\n" \ 64"fzELMAkGA1UEBhMCQ04xEzARBgNVBAgMCmhlbGxvd29ybGQxEzARBgNVBAoMCmhl\n" \ 65"bGxvd29ybGQxEzARBgNVBAsMCmhlbGxvd29ybGQxFjAUBgNVBAMMDWhlbGxvd29y\n" \ 66"bGQxMTExGTAXBgkqhkiG9w0BCQEWCmhlbGxvd29ybGQwggEiMA0GCSqGSIb3DQEB\n" \ 67"AQUAA4IBDwAwggEKAoIBAQC8HHhVEbY3uuriW3wAcAMFwIUd+VImAUKnWAYlsiHL\n" \ 68"Ps3BhpHHb67kjzP3rcQbZ2l1LSMWjoV8jXckVMOFqOlTlrYlGM3G80bVaWcEgw4c\n" \ 69"+nkSk+ApGmNUa69HK3h+5vfz81fVmJL1zX0VaYiA+wCzrFc1w5aGKhsFIcIY8FUo\n" \ 70"i15xrwAURQ+/EylzeF302qGwkCHYy4zQqn3ohku25rPLUOyOp6gJNs/3BVh76b9/\n" \ 71"1iTyP7ldDD7VV4UQCTDppFtrDQY/UrBhe9sPn0+6GWBfkkjz5n1aGE7JP2vmB3qM\n" \ 72"gxIpEkmVLVIxh6dwBOmtr+sT7xJ+UzmTWbbhNGCkzSPxAgMBAAGjUzBRMB0GA1Ud\n" \ 73"DgQWBBSDTqp6QOdxk9zF2H+7IGOckq/A1DAfBgNVHSMEGDAWgBRNYAEJlwxPOj5F\n" \ 74"B7M4mTsMpokRLzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB4\n" \ 75"CkKbJQWuC2pj0cS+zb4v8fRq8OPjRVPylqjHX4IMpmnl2VM0DkNXD0SYPC5IxkK4\n" \ 76"bgtglG0Rkr4blYf+PdNenbebWZvw4Y3JUoQgSasfdIA/rJXZtf3mVUNLmPlcRWZC\n" \ 77"OtGJmvlntp7/qWl7JCIaiD732baJU1DZchy3am2WWGpchBESBOtoSvdywG+T0xQQ\n" \ 78"cXzYQ+mHPsym30JCzChvZCKz+QJlIZUJ3XgoKH7MVviASXGcWLKOBYYUDt3J8/PM\n" \ 79"shbsqb+rm+VqU5ohV8Rr/nQ+QLvEFa8rrz7qY6/2QSbUy7QvFCv7MXFD1kCH92FL\n" \ 80"GwkmWDavM1kdVMXZmV54\n" \ 81"-----END CERTIFICATE-----"; 82 83const std::string INTER_CA_CHAIN_PEM = 84"-----BEGIN CERTIFICATE-----\n" \ 85"MIID3zCCAsegAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBkjELMAkGA1UEBhMCQ04x\n" \ 86"EzARBgNVBAgMCmhlbGxvd29ybGQxEzARBgNVBAcMCmhlbGxvd29ybGQxEzARBgNV\n" \ 87"BAoMCmhlbGxvd29ybGQxEzARBgNVBAsMCmhlbGxvd29ybGQxFDASBgNVBAMMC2hl\n" \ 88"bGxvd29ybGQxMRkwFwYJKoZIhvcNAQkBFgpoZWxsb3dvcmxkMB4XDTIyMDEyMjA5\n" \ 89"MjM0OFoXDTMyMDEyMDA5MjM0OFowfjELMAkGA1UEBhMCQ04xEzARBgNVBAgMCmhl\n" \ 90"bGxvd29ybGQxEzARBgNVBAoMCmhlbGxvd29ybGQxEzARBgNVBAsMCmhlbGxvd29y\n" \ 91"bGQxFTATBgNVBAMMDGhlbGxvd29ybGQxMTEZMBcGCSqGSIb3DQEJARYKaGVsbG93\n" \ 92"b3JsZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTJF+SAh/ccmcxF\n" \ 93"+le0m8Wx7N9kclMYoUVGyJOPDv0L9kE/1hg9HEavCBWal9ZK69r+i1YiH18Y0F5o\n" \ 94"AuqP0teedDByPii8IaDquJKZ1hlMi13vPY1cgUcG77cKzC5TMlmNTLes0ddn9/lY\n" \ 95"4ajl4kgUr3bCEXlp4uhBQPYlntujctcjmEdMtcJQmhHpr2Js9cq2kZney59ae5kk\n" \ 96"LCzpFqpj7cunz5Rs3RZs1+Njw5oABS18qAy1CEBnecLOi6lIPvIckngBHduwczOM\n" \ 97"5YBBXeqOeNk7FWTiIf5MuXlqOSlZ57Wp8SqfDzwS49awwI9dvGpjgyGh3ZQA5TXX\n" \ 98"GGIsn5cCAwEAAaNTMFEwHQYDVR0OBBYEFE1gAQmXDE86PkUHsziZOwymiREvMB8G\n" \ 99"A1UdIwQYMBaAFJp3c+VFpGlC/r/UiPCozoH1UcgMMA8GA1UdEwEB/wQFMAMBAf8w\n" \ 100"DQYJKoZIhvcNAQELBQADggEBAArLbWZWG3cHuCnMBGo28F0KVKctxjLVOCzDhKnH\n" \ 101"IusLVqTnZ7AHeUU56NyoRfSRSIEJ2TNXkHO8MyxNN3lP4RapQavOvENLE99s269I\n" \ 102"suLPCp3k6znJX1ZW7MIrSp7Bz+6rBTuh2H874H/BcvPXaCZB4X3Npjfu4tRcKEtS\n" \ 103"JKdVmIlotjX1qM5eYHY5BDSR0MvRYvSlH7/wA9FEGJ8GHI7vaHxIMxf4+OOz+E4w\n" \ 104"qKIZZfYeVBdEpZvfVGHRbS5dEofqc4NthlObTWlwAIhFgTzLqy8y2Y2jDWcJk91/\n" \ 105"y9u8F1jQAuoemDCY5BalZ+Bn0eZQQHlXujwyZfoIK+oCuUo=\n" \ 106"-----END CERTIFICATE-----"; 107 108const uint8_t CHALLENGE[] = { 109 0xe2, 0x2, 0xf4, 0x41, 0xb6, 0xe, 0x7d, 0xf3, 110 0xaa, 0x57, 0xb4, 0x59, 0x68, 0xe2, 0x1f, 0x9, 111 0x36, 0x8, 0x83, 0xf7, 0x84, 0x9b, 0x8f, 0x8e, 112 0x34, 0x30, 0x8b, 0xbc, 0xf8, 0x15, 0xa1, 0x45 113}; 114 115static ByteBuffer g_issuerCert; 116static ByteBuffer g_signingCert; 117static ByteBuffer g_interCA; 118static ByteBuffer g_invalidCert; 119static ByteBuffer g_rootCA; 120 121static inline uint8_t *CastToUint8Ptr(uint32_t *ptr) 122{ 123 return reinterpret_cast<uint8_t *>(ptr); 124} 125 126static X509 *LoadPemString(const std::string &pemData) 127{ 128 BIO *mem = BIO_new_mem_buf(pemData.c_str(), pemData.length()); 129 if (mem == nullptr) { 130 return nullptr; 131 } 132 133 X509 *x509 = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr); 134 EXPECT_NE(x509, nullptr); 135 BIO_free(mem); 136 return x509; 137} 138 139void LoadDerFormPemString(const std::string &pemData, ByteBuffer &certBuffer) 140{ 141 X509 *x509 = LoadPemString(pemData); 142 uint8_t *derTemp = nullptr; 143 int32_t derTempLen = i2d_X509(x509, &derTemp); 144 EXPECT_NE(derTemp, nullptr); 145 if (derTempLen < 0) { 146 X509_free(x509); 147 return; 148 } 149 150 certBuffer.CopyFrom(derTemp, static_cast<uint32_t>(derTempLen)); 151 152 X509_free(x509); 153 OPENSSL_free(derTemp); 154} 155 156static void FormattedCertChain(const std::vector<ByteBuffer> &certChain, ByteBuffer &buffer) 157{ 158 uint32_t certsCount = certChain.size(); 159 uint32_t totalLen = sizeof(uint32_t); 160 for (uint32_t i = 0; i < certsCount; i++) { 161 totalLen += sizeof(uint32_t) + certChain[i].GetSize(); 162 } 163 buffer.Resize(totalLen); 164 if (!buffer.PutData(0, CastToUint8Ptr(&certsCount), sizeof(uint32_t))) { 165 return; 166 } 167 uint32_t pos = sizeof(uint32_t); 168 for (uint32_t i = 0; i < certsCount; i++) { 169 uint32_t size = certChain[i].GetSize(); 170 if (!buffer.PutData(pos, CastToUint8Ptr(&size), sizeof(uint32_t))) { 171 return; 172 } 173 pos += sizeof(uint32_t); 174 if (!buffer.PutData(pos, certChain[i].GetBuffer(), certChain[i].GetSize())) { 175 return; 176 } 177 pos += certChain[i].GetSize(); 178 } 179} 180 181class CertChainVerifierTest : public testing::Test { 182public: 183 CertChainVerifierTest() {}; 184 virtual ~CertChainVerifierTest() {}; 185 static void SetUpTestCase() 186 { 187 LoadDerFormPemString(SIGNING_CERT_CHAIN_PEM, g_signingCert); 188 LoadDerFormPemString(ISSUER_CERT_CHAIN_PEM, g_issuerCert); 189 LoadDerFormPemString(INTER_CA_CHAIN_PEM, g_interCA); 190 // fake root CA, no use in verifying 191 uint8_t tmp = 0; 192 g_rootCA.CopyFrom(&tmp, sizeof(tmp)); 193 g_invalidCert.CopyFrom(&tmp, sizeof(tmp)); 194 } 195 static void TearDownTestCase() {}; 196 void SetUp() {}; 197 void TearDown() {}; 198}; 199 200/** 201 * @tc.name: CertChainVerifierTest_001 202 * @tc.desc: Get chain from empty buffer 203 * @tc.type: Func 204 * @tc.require: IAJ4QG 205 */ 206HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_001, TestSize.Level0) 207{ 208 ByteBuffer cert, challenge, certBuffer; 209 EXPECT_EQ(GetVerifiedCert(cert, challenge, certBuffer), false); 210} 211 212/** 213 * @tc.name: CertChainVerifierTest_0002 214 * @tc.desc: Get chain from empty cert chain 215 * @tc.type: Func 216 * @tc.require: IAJ4QG 217 */ 218HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_002, TestSize.Level0) 219{ 220 ByteBuffer cert, challenge, certBuffer; 221 uint32_t count = 0; 222 cert.CopyFrom(reinterpret_cast<uint8_t *>(&count), sizeof(count)); 223 EXPECT_EQ(GetVerifiedCert(cert, challenge, certBuffer), false); 224} 225 226 227/** 228 * @tc.name: CertChainVerifierTest_0003 229 * @tc.desc: Get chain from invalid formatted buffer 230 * @tc.type: Func 231 * @tc.require: IAJ4QG 232 */ 233HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_003, TestSize.Level0) 234{ 235 ByteBuffer cert, challenge, certBuffer; 236 std::vector<uint32_t> tmpBuffer = {0}; 237 cert.CopyFrom(reinterpret_cast<uint8_t *>(tmpBuffer.data()), tmpBuffer.size() * sizeof(uint32_t)); 238 EXPECT_EQ(GetVerifiedCert(cert, challenge, certBuffer), false); 239 240 // one cert in cert chain, classify as root CA 241 tmpBuffer[0] = 1; 242 // load issuer failed 243 cert.CopyFrom(reinterpret_cast<uint8_t *>(tmpBuffer.data()), tmpBuffer.size() * sizeof(uint32_t)); 244 EXPECT_EQ(GetVerifiedCert(cert, challenge, certBuffer), false); 245 246 // two certs in cert chain 247 tmpBuffer[0] = 2; 248 // cert size 249 tmpBuffer.push_back(sizeof(uint32_t)); 250 cert.CopyFrom(reinterpret_cast<uint8_t *>(tmpBuffer.data()), tmpBuffer.size() * sizeof(uint32_t)); 251 // no content to load cert, convert from formatted buffer failed 252 EXPECT_EQ(GetVerifiedCert(cert, challenge, certBuffer), false); 253 254 // fill issuer 255 tmpBuffer.push_back(0); 256 cert.CopyFrom(reinterpret_cast<uint8_t *>(tmpBuffer.data()), tmpBuffer.size() * sizeof(uint32_t)); 257 // invalid content, convert content to x509 failed 258 EXPECT_EQ(GetVerifiedCert(cert, challenge, certBuffer), false); 259} 260 261/** 262 * @tc.name: CertChainVerifierTest_0004 263 * @tc.desc: Get verified failed with invalid issuer format 264 * @tc.type: Func 265 * @tc.require: IAJ4QG 266 */ 267HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_004, TestSize.Level0) 268{ 269 ByteBuffer formattedCert, challenge, certBuffer; 270 std::vector<ByteBuffer> certs; 271 certs.push_back(g_signingCert); 272 certs.push_back(g_invalidCert); 273 certs.push_back(g_interCA); 274 certs.push_back(g_rootCA); 275 FormattedCertChain(certs, formattedCert); 276 EXPECT_EQ(GetVerifiedCert(formattedCert, challenge, certBuffer), false); 277} 278 279/** 280 * @tc.name: CertChainVerifierTest_0005 281 * @tc.desc: Get verified failed with invalid interCA format 282 * @tc.type: Func 283 * @tc.require: IAJ4QG 284 */ 285HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_005, TestSize.Level0) 286{ 287 ByteBuffer formattedCert, challenge, certBuffer; 288 std::vector<ByteBuffer> certs; 289 certs.push_back(g_signingCert); 290 certs.push_back(g_issuerCert); 291 certs.push_back(g_invalidCert); 292 certs.push_back(g_rootCA); 293 FormattedCertChain(certs, formattedCert); 294 EXPECT_EQ(GetVerifiedCert(formattedCert, challenge, certBuffer), false); 295} 296 297/** 298 * @tc.name: CertChainVerifierTest_0006 299 * @tc.desc: verifying issuer cert failed 300 * @tc.type: Func 301 * @tc.require: IAJ4QG 302 */ 303HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_006, TestSize.Level0) 304{ 305 ByteBuffer formattedCert, challenge, certBuffer; 306 std::vector<ByteBuffer> certs; 307 certs.push_back(g_signingCert); 308 certs.push_back(g_signingCert); 309 certs.push_back(g_interCA); 310 certs.push_back(g_rootCA); 311 FormattedCertChain(certs, formattedCert); 312 EXPECT_EQ(GetVerifiedCert(formattedCert, challenge, certBuffer), false); 313} 314 315/** 316 * @tc.name: CertChainVerifierTest_0007 317 * @tc.desc: verify signing cert failed 318 * @tc.type: Func 319 * @tc.require: IAJ4QG 320 */ 321HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_007, TestSize.Level0) 322{ 323 ByteBuffer challenge; 324 //parse pub key of failed 325 EXPECT_EQ(VerifyCertAndExtension(nullptr, nullptr, challenge), false); 326 327 X509 *signingCert = LoadPemString(SIGNING_CERT_CHAIN_PEM); 328 X509 *issuerCert = LoadPemString(ISSUER_CERT_CHAIN_PEM); 329 // verify signature failed 330 EXPECT_EQ(VerifyCertAndExtension(issuerCert, signingCert, challenge), false); 331 332 // verify extension failed 333 const char *invalidChallenge = "invalid"; 334 challenge.CopyFrom(reinterpret_cast<const uint8_t *>(invalidChallenge), 335 sizeof(invalidChallenge)); 336 EXPECT_EQ(VerifyCertAndExtension(signingCert, issuerCert, challenge), false); 337 338 // verify extension success 339 challenge.CopyFrom(CHALLENGE, sizeof(CHALLENGE)); 340 EXPECT_EQ(VerifyCertAndExtension(signingCert, issuerCert, challenge), true); 341 X509_free(signingCert); 342 X509_free(issuerCert); 343} 344 345/** 346 * @tc.name: CertChainVerifierTest_0008 347 * @tc.desc: verifying issuer cert success 348 * @tc.type: Func 349 * @tc.require: IAJ4QG 350 */ 351HWTEST_F(CertChainVerifierTest, CertChainVerifierTest_008, TestSize.Level0) 352{ 353 ByteBuffer formattedCert, challenge, certBuffer; 354 std::vector<ByteBuffer> certs; 355 certs.push_back(g_signingCert); 356 certs.push_back(g_issuerCert); 357 certs.push_back(g_interCA); 358 certs.push_back(g_rootCA); 359 FormattedCertChain(certs, formattedCert); 360 // verify extension success 361 challenge.CopyFrom(CHALLENGE, sizeof(CHALLENGE)); 362#ifdef CODE_SIGNATURE_OH_ROOT_CA 363 EXPECT_EQ(GetVerifiedCert(formattedCert, challenge, certBuffer), true); 364#else 365 EXPECT_EQ(GetVerifiedCert(formattedCert, challenge, certBuffer), false); 366#endif 367} 368 369} // namespace CodeSign 370} // namespace Security 371} // namespace OHOS