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 
28 using namespace OHOS::Security::CodeSign;
29 using namespace std;
30 using namespace testing::ext;
31 
32 namespace OHOS {
33 namespace Security {
34 namespace CodeSign {
35 const 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 
58 const 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 
83 const 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 
108 const 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 
115 static ByteBuffer g_issuerCert;
116 static ByteBuffer g_signingCert;
117 static ByteBuffer g_interCA;
118 static ByteBuffer g_invalidCert;
119 static ByteBuffer g_rootCA;
120 
CastToUint8Ptr(uint32_t * ptr)121 static inline uint8_t *CastToUint8Ptr(uint32_t *ptr)
122 {
123     return reinterpret_cast<uint8_t *>(ptr);
124 }
125 
LoadPemString(const std::string & pemData)126 static 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 
LoadDerFormPemString(const std::string & pemData,ByteBuffer & certBuffer)139 void 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 
FormattedCertChain(const std::vector<ByteBuffer> & certChain,ByteBuffer & buffer)156 static 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 
181 class CertChainVerifierTest : public testing::Test {
182 public:
CertChainVerifierTest()183     CertChainVerifierTest() {};
~CertChainVerifierTest()184     virtual ~CertChainVerifierTest() {};
SetUpTestCase()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     }
TearDownTestCase()195     static void TearDownTestCase() {};
SetUp()196     void SetUp() {};
TearDown()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  */
206 HWTEST_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  */
218 HWTEST_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  */
233 HWTEST_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  */
267 HWTEST_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  */
285 HWTEST_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  */
303 HWTEST_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  */
321 HWTEST_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  */
351 HWTEST_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