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