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 <memory>
17#include <gtest/gtest.h>
18
19#include "sign_elf.h"
20#include "code_signing.h"
21
22namespace OHOS {
23namespace SignatureTools {
24class SignElfTest : public testing::Test {
25public:
26    static void SetUpTestCase(void)
27    {
28        (void)rename("./codeSigning/unsigned-file.txt", "./codeSigning/unsigned-file.hap");
29    };
30    static void TearDownTestCase()
31    {
32    };
33    void SetUp()
34    {
35    };
36    void TearDown()
37    {
38    };
39};
40
41void SetElfParamsMap(std::map<std::string, std::string>& params)
42{
43    params["keyPwd"] = "123456";
44    params["mode"] = "localSign";
45    params["keyAlias"] = "oh-app1-key-v1";
46    params["signAlg"] = "SHA256withECDSA";
47    params["appCertFile"] = "./hapSign/app-release1.pem";
48    params["signCode"] = "1";
49    params["compatibleVersion"] = "9";
50    params["outFile"] = "./hapSign/entry-default-signed.elf";
51    params["profileFile"] = "./hapSign/signed-profile.p7b";
52    params["keystorePwd"] = "123456";
53    params["keystoreFile"] = "./hapSign/ohtest.jks";
54    params["inFile"] = "./codeSigning/unsigned-file.hap";
55    params["profileSigned"] = "1";
56    params["inForm"] = "elf";
57    std::string  provision = "{\"app-distribution-type\": \"app_gallery\",\"bundle-info\":{\"app-"
58        "feature\":\"hos_system_app\",\"bundle-name\":\"com.OpenHarmony.app.test\",\"developer-id\":\"O"
59        "penHarmony\",\"distribution-certificate\":\"-----BEGIN CERTIFICATE-----\\n"
60        "MIICMzCCAbegAwIBAgIEaOC/zDAMBggqhkjOPQQDAwUAMGMxCzAJBgNVBAYTAkNO\\n"
61        "MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh\\n"
62        "bTEjMCEGA1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwHhcNMjEwMjAy\\n"
63        "MTIxOTMxWhcNNDkxMjMxMTIxOTMxWjBoMQswCQYDVQQGEwJDTjEUMBIGA1UEChML\\n"
64        "T3Blbkhhcm1vbnkxGTAXBgNVBAsTEE9wZW5IYXJtb255IFRlYW0xKDAmBgNVBAMT\\n"
65        "H09wZW5IYXJtb255IEFwcGxpY2F0aW9uIFJlbGVhc2UwWTATBgcqhkjOPQIBBggq\\n"
66        "hkjOPQMBBwNCAATbYOCQQpW5fdkYHN45v0X3AHax12jPBdEDosFRIZ1eXmxOYzSG\\n"
67        "JwMfsHhUU90E8lI0TXYZnNmgM1sovubeQqATo1IwUDAfBgNVHSMEGDAWgBTbhrci\\n"
68        "FtULoUu33SV7ufEFfaItRzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFPtxruhl\\n"
69        "cRBQsJdwcZqLu9oNUVgaMAwGCCqGSM49BAMDBQADaAAwZQIxAJta0PQ2p4DIu/ps\\n"
70        "LMdLCDgQ5UH1l0B4PGhBlMgdi2zf8nk9spazEQI/0XNwpft8QAIwHSuA2WelVi/o\\n"
71        "zAlF08DnbJrOOtOnQq5wHOPlDYB4OtUzOYJk9scotrEnJxJzGsh/\\n"
72        "-----END CERTIFICATE-----\\n"
73        "\"},\"debug-info\":{\"device-id-type\":\"udid\",\"device-ids\":[\"69C7505BE341BDA5948C3C0CB"
74        "44ABCD530296054159EFE0BD16A16CD0129CC42\",\"7EED06506FCE6325EB2E2FAA019458B856AB10493A6718C76"
75        "79A73F958732865\"]},\"issuer\":\"pki_internal\",\"permissions\":{\"restricted-permissions\":"
76        "[\"\"]},\"type\":\"release\",\"uuid\":\"fe686e1b-3770-4824-a938-961b140a7c98\",\"validity\":"
77        "{\"not-after\":1705127532,\"not-before\":1610519532},\"version-code\":1,\"version-name\":\"1.0.0\"}";
78    params["profileContent"] = provision;
79}
80
81void SetElfOptions(Options* options)
82{
83    std::string mode = "localSign";
84    std::string keyAlias = "oh-app1-key-v1";
85    std::string signAlg = "SHA256withECDSA";
86    std::string signCode = "1";
87    std::string appCertFile = "./hapSign/app-release1.pem";
88    std::string profileFile = "./hapSign/signed-profile.p7b";
89    std::string inFile = "./codeSigning/unsigned-file.hap";
90    std::string keystoreFile = "./hapSign/ohtest.p12";
91    std::string outFile = "./hapSign/entry-default-signed.elf";
92    std::string inForm = "elf";
93    static char keyPwd[] = "123456";
94    static char keystorePwd[] = "123456";
95
96    (*options)["mode"] = "localSign";
97    (*options)["keyAlias"] = keyAlias;
98    (*options)["signAlg"] = signAlg;
99    (*options)["signCode"] = signCode;
100    (*options)["appCertFile"] = appCertFile;
101    (*options)["profileFile"] = profileFile;
102    (*options)["inFile"] = inFile;
103    (*options)["keystoreFile"] = keystoreFile;
104    (*options)["outFile"] = outFile;
105    (*options)["inForm"] = inForm;
106    (*options)["keyPwd"] = keyPwd;
107    (*options)["keystorePwd"] = keystorePwd;
108}
109
110/**
111 * @tc.name: sign001
112 * @tc.desc: Test function of SignElf::sign() interface for SUCCESS.
113 * @tc.size: MEDIUM
114 * @tc.type: FUNC
115 * @tc.level Level 1
116 * @tc.require: SR000H63TL
117 */
118HWTEST_F(SignElfTest, Sign001, testing::ext::TestSize.Level1)
119{
120    // success
121    SignerConfig signerConfig;
122    signerConfig.SetCompatibleVersion(9);
123
124    std::map<std::string, std::string> params;
125    SetElfParamsMap(params);
126    signerConfig.FillParameters(params);
127
128    ContentDigestAlgorithm contentDigestAlgorithm("SHA-256", 32);
129    std::pair<std::string, void*> signatureAlgAndParams("SHA256withECDSA", nullptr);
130    SignatureAlgorithmHelper signatureAlgorithm(SignatureAlgorithmId::ECDSA_WITH_SHA256, "ECDSA_WITH_SHA256",
131                                                contentDigestAlgorithm, signatureAlgAndParams);
132    std::vector<SignatureAlgorithmHelper> signatureAlgorithms;
133    signatureAlgorithms.push_back(signatureAlgorithm);
134    signerConfig.SetSignatureAlgorithms(signatureAlgorithms);
135
136    std::shared_ptr<Options> options = std::make_shared<Options>();
137    SetElfOptions(options.get());
138    signerConfig.SetOptions(options.get());
139
140    signerConfig.GetSigner();
141    SignElf::Sign(signerConfig, params);
142    EXPECT_EQ(signerConfig.GetCompatibleVersion(), 9);
143}
144
145/**
146 * @tc.name: sign002
147 * @tc.desc: The return will be false, because the inFile is not exist.
148 * @tc.size: MEDIUM
149 * @tc.type: FUNC
150 * @tc.level Level 1
151 * @tc.require: SR000H63TL
152 */
153HWTEST_F(SignElfTest, Sign002, testing::ext::TestSize.Level1)
154{
155    SignerConfig signerConfig;
156    signerConfig.SetCompatibleVersion(9);
157
158    std::map<std::string, std::string> params;
159    SetElfParamsMap(params);
160    params["inFile"] = "./hapSign/unsigned-file-no.out";
161    signerConfig.FillParameters(params);
162
163    ContentDigestAlgorithm contentDigestAlgorithm("SHA-256", 32);
164    std::pair<std::string, void*> signatureAlgAndParams("SHA256withECDSA", nullptr);
165    SignatureAlgorithmHelper signatureAlgorithm(SignatureAlgorithmId::ECDSA_WITH_SHA256, "ECDSA_WITH_SHA256",
166                                                contentDigestAlgorithm, signatureAlgAndParams);
167    std::vector<SignatureAlgorithmHelper> signatureAlgorithms;
168    signatureAlgorithms.push_back(signatureAlgorithm);
169    signerConfig.SetSignatureAlgorithms(signatureAlgorithms);
170
171    std::shared_ptr<Options> options = std::make_shared<Options>();
172    SetElfOptions(options.get());
173    (*options)["inFile"] = "./hapSign/unsigned-file-no.out";
174    signerConfig.SetOptions(options.get());
175
176    signerConfig.GetSigner();
177    bool ret = SignElf::Sign(signerConfig, params);
178
179    EXPECT_EQ(ret, false);
180}
181
182/**
183 * @tc.name: sign003
184 * @tc.desc: The return will be false, because the profileFile is not exist.
185 * @tc.size: MEDIUM
186 * @tc.type: FUNC
187 * @tc.level Level 1
188 * @tc.require: SR000H63TL
189 */
190HWTEST_F(SignElfTest, Sign003, testing::ext::TestSize.Level1)
191{
192    // failed:profileFile is null
193    SignerConfig signerConfig;
194    signerConfig.SetCompatibleVersion(9);
195
196    std::map<std::string, std::string> params;
197    SetElfParamsMap(params);
198    params["profileFile"] = "./hapSign/signed-profile-no.p7b";
199    signerConfig.FillParameters(params);
200
201    ContentDigestAlgorithm contentDigestAlgorithm("SHA-256", 32);
202    std::pair<std::string, void*> signatureAlgAndParams("SHA256withECDSA", nullptr);
203    SignatureAlgorithmHelper signatureAlgorithm(SignatureAlgorithmId::ECDSA_WITH_SHA256, "ECDSA_WITH_SHA256",
204                                                contentDigestAlgorithm, signatureAlgAndParams);
205    std::vector<SignatureAlgorithmHelper> signatureAlgorithms;
206    signatureAlgorithms.push_back(signatureAlgorithm);
207    signerConfig.SetSignatureAlgorithms(signatureAlgorithms);
208
209    std::shared_ptr<Options> options = std::make_shared<Options>();
210    SetElfOptions(options.get());
211    (*options)["profileFile"] = "./hapSign/signed-profile-no.p7b";
212    signerConfig.SetOptions(options.get());
213
214    signerConfig.GetSigner();
215    bool ret = SignElf::Sign(signerConfig, params);
216    EXPECT_EQ(ret, false);
217}
218
219/**
220 * @tc.name: sign004
221 * @tc.desc: The return will be false, because the outFile path is not exist.
222 * @tc.size: MEDIUM
223 * @tc.type: FUNC
224 * @tc.level Level 1
225 * @tc.require: SR000H63TL
226 */
227HWTEST_F(SignElfTest, Sign004, testing::ext::TestSize.Level1)
228{
229    // failed:outFile is null
230    SignerConfig signerConfig;
231    signerConfig.SetCompatibleVersion(9);
232
233    std::map<std::string, std::string> params;
234    SetElfParamsMap(params);
235    params["outFile"] = "./hapSign_test/entry-default-signed.elf";
236    signerConfig.FillParameters(params);
237
238    ContentDigestAlgorithm contentDigestAlgorithm("SHA-256", 32);
239    std::pair<std::string, void*> signatureAlgAndParams("SHA256withECDSA", nullptr);
240    SignatureAlgorithmHelper signatureAlgorithm(SignatureAlgorithmId::ECDSA_WITH_SHA256, "ECDSA_WITH_SHA256",
241                                                contentDigestAlgorithm, signatureAlgAndParams);
242    std::vector<SignatureAlgorithmHelper> signatureAlgorithms;
243    signatureAlgorithms.push_back(signatureAlgorithm);
244    signerConfig.SetSignatureAlgorithms(signatureAlgorithms);
245
246    std::shared_ptr<Options> options = std::make_shared<Options>();
247    SetElfOptions(options.get());
248    (*options)["outFile"] = "./hapSign_test/entry-default-signed.elf";
249    signerConfig.SetOptions(options.get());
250
251    signerConfig.GetSigner();
252    bool ret = SignElf::Sign(signerConfig, params);
253    EXPECT_EQ(ret, false);
254}
255
256/**
257 * @tc.name: sign005
258 * @tc.desc: The return will be false, because the signCode is 0, when signelf the signCode must be 1.
259 * @tc.size: MEDIUM
260 * @tc.type: FUNC
261 * @tc.level Level 1
262 * @tc.require: SR000H63TL
263 */
264HWTEST_F(SignElfTest, Sign005, testing::ext::TestSize.Level1)
265{
266    // failed:signCode is 0
267    SignerConfig signerConfig;
268    signerConfig.SetCompatibleVersion(9);
269
270    std::map<std::string, std::string> params;
271    SetElfParamsMap(params);
272    params["signCode"] = "0";
273    signerConfig.FillParameters(params);
274
275    ContentDigestAlgorithm contentDigestAlgorithm("SHA-256", 32);
276    std::pair<std::string, void*> signatureAlgAndParams("SHA256withECDSA", nullptr);
277    SignatureAlgorithmHelper signatureAlgorithm(SignatureAlgorithmId::ECDSA_WITH_SHA256, "ECDSA_WITH_SHA256",
278                                                contentDigestAlgorithm, signatureAlgAndParams);
279    std::vector<SignatureAlgorithmHelper> signatureAlgorithms;
280    signatureAlgorithms.push_back(signatureAlgorithm);
281    signerConfig.SetSignatureAlgorithms(signatureAlgorithms);
282
283    std::shared_ptr<Options> options = std::make_shared<Options>();
284    SetElfOptions(options.get());
285    (*options)["signCode"] = "0";
286    signerConfig.SetOptions(options.get());
287
288    signerConfig.GetSigner();
289    bool ret = SignElf::Sign(signerConfig, params);
290    EXPECT_EQ(ret, false);
291}
292
293/**
294 * @tc.name: GetCodeSignBlock001
295 * @tc.desc: The return will be false, because the input format is not support, it must be hap/hsp/hqf.
296 * @tc.size: MEDIUM
297 * @tc.type: FUNC
298 * @tc.level Level 1
299 * @tc.require: SR000H63TL
300 */
301HWTEST_F(SignElfTest, GetCodeSignBlock001, testing::ext::TestSize.Level1)
302{
303    CodeSigning object;
304    std::string input = "./hapSign_test/entry-default-signed.elf";
305    int64_t offset = 0;
306    std::string inForm = "elf";
307    std::string profileContent = "";
308    ZipSigner zip;
309    std::vector<int8_t> ret;
310    bool flag = object.GetCodeSignBlock(input, offset, inForm, profileContent, zip, ret);
311    EXPECT_EQ(flag, false);
312}
313}
314}
315