• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 package com.ohos.hapsigntoolcmd;
17 
18 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
19 import static org.junit.jupiter.api.Assertions.assertFalse;
20 import static org.junit.jupiter.api.Assertions.assertTrue;
21 
22 import com.ohos.hapsigntool.HapSignTool;
23 import com.ohos.hapsigntool.utils.KeyPairTools;
24 import com.ohos.hapsigntool.utils.FileUtils;
25 import com.ohos.hapsigntool.zip.Zip;
26 
27 import org.junit.jupiter.api.MethodOrderer;
28 import org.junit.jupiter.api.Order;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.api.TestMethodOrder;
31 import org.junit.platform.commons.logging.Logger;
32 import org.junit.platform.commons.logging.LoggerFactory;
33 
34 import java.io.File;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.math.BigInteger;
39 import java.nio.file.Files;
40 import java.nio.file.Path;
41 import java.nio.file.Paths;
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.Random;
45 import java.util.zip.CRC32;
46 import java.util.zip.ZipEntry;
47 import java.util.zip.ZipOutputStream;
48 
49 /**
50  * CmdUnitTest.
51  *
52  * @since 2021/12/28
53  */
54 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
55 public class CmdUnitTest {
56     /**
57      * Command line parameter appCaCertFile.
58      */
59     public static final String CMD_SUB_CA_CERT_FILE = "-subCaCertFile";
60 
61     /**
62      * Command line parameter outFile.
63      */
64     public static final String CMD_OUT_FILE = "-outFile";
65 
66     /**
67      * Command line parameter basicConstraints.
68      */
69     public static final String CMD_BASIC_CONSTRAINTS = "-basicConstraints";
70 
71     /**
72      * Command line parameter basicConstraintsCa.
73      */
74     public static final String CMD_BASIC_CONSTRAINTS_CA = "-basicConstraintsCa";
75 
76     /**
77      * Command line parameter basicConstraintsCritical.
78      */
79     public static final String CMD_BASIC_CONSTRAINTS_CRITICAL = "-basicConstraintsCritical";
80 
81     /**
82      * Command line parameter basicConstraintsPathLen.
83      */
84     public static final String CMD_BASIC_CONSTRAINTS_PATH_LEN = "-basicConstraintsPathLen";
85 
86     /**
87      * Command line parameter caCertFile.
88      */
89     public static final String CMD_ROOT_CA_CERT_FILE = "-rootCaCertFile";
90 
91     /**
92      * Command line parameter outForm.
93      */
94     public static final String CMD_OUT_FORM = "-outForm";
95 
96     /**
97      * Command line parameter cert.
98      */
99     public static final String CMD_CERT_CHAIN = "certChain";
100 
101     /**
102      * Command line parameter digitalSignature.
103      */
104     public static final String CMD_DIGITAL_SIGNATURE = "digitalSignature";
105 
106     /**
107      * Command line parameter codeSignature and emailProtection.
108      */
109     public static final String CMD_CODE_AND_EMAIL = "codeSignature,emailProtection";
110 
111     /**
112      * Command line parameter mode.
113      */
114     public static final String CMD_MODE = "-mode";
115 
116     /**
117      * Command line parameter keystoreFile.
118      */
119     public static final String CMD_KEY_STORE_FILE = "-keystoreFile";
120 
121     /**
122      * Command line parameter keystorePwd.
123      */
124     public static final String CMD_KEY_STORE_RIGHTS = "-keystorePwd";
125 
126     /**
127      * Command line parameter keyAlg.
128      */
129     public static final String CMD_KEY_ALG = "-keyAlg";
130 
131     /**
132      * Command line parameter keyAlias.
133      */
134     public static final String CMD_KEY_ALIAS = "-keyAlias";
135 
136     /**
137      * Command line parameter keyPwd.
138      */
139     public static final String CMD_KEY_RIGHTS = "-keyPwd";
140 
141     /**
142      * Command line parameter keySize.
143      */
144     public static final String CMD_KEY_SIZE = "-keySize";
145 
146     /**
147      * Command line parameter keyUsage.
148      */
149     public static final String CMD_KEY_USAGE = "-keyUsage";
150 
151     /**
152      * Command line parameter keyUsageCritical.
153      */
154     public static final String CMD_KEY_USAGE_CRITICAL = "-keyUsageCritical";
155 
156     /**
157      * Command line parameter extKeyUsage.
158      */
159     public static final String CMD_EXT_KEY_USAGE = "-extKeyUsage";
160 
161     /**
162      * Command line parameter extKeyUsageCritical.
163      */
164     public static final String CMD_EXT_KEY_USAGE_CRITICAL = "-extKeyUsageCritical";
165 
166     /**
167      * Command line parameter profileCertFile.
168      */
169     public static final String CMD_PROFILE_CERT_FILE = "-profileCertFile";
170 
171     /**
172      * Command line parameter subject.
173      */
174     public static final String CMD_SUBJECT = "-subject";
175 
176     /**
177      * Command line parameter signAlg.
178      */
179     public static final String CMD_SIGN_ALG = "-signAlg";
180 
181     /**
182      * Command line parameter inFile.
183      */
184     public static final String CMD_IN_FILE = "-inFile";
185 
186     /**
187      * Command line parameter issuer.
188      */
189     public static final String CMD_ISSUER = "-issuer";
190 
191     /**
192      * Command line parameter issuerKeyAlias.
193      */
194     public static final String CMD_ISSUER_KEY_ALIAS = "-issuerKeyAlias";
195 
196     /**
197      * Command line parameter issuerKeyPwd.
198      */
199     public static final String CMD_ISSUER_KEY_RIGHTS = "-issuerKeyPwd";
200 
201     /**
202      * Command line parameter validity.
203      */
204     public static final String CMD_VALIDITY = "-validity";
205 
206     /**
207      * Command line parameter appCertFile.
208      */
209     public static final String CMD_APP_CERT_FILE = "-appCertFile";
210 
211     /**
212      * Command line parameter appCertFile.
213      */
214     public static final String CMD_PROFILE_FILE = "-profileFile";
215 
216     /**
217      * Command line parameter appCertFile.
218      */
219     public static final String CMD_OUT_CERT_CHAIN = "-outCertChain";
220 
221     /**
222      * Command line parameter appCertFile.
223      */
224     public static final String CMD_OUT_PROFILE = "-outProfile";
225 
226     /**
227      * Command line parameter false.
228      */
229     public static final String CMD_FALSE = "false";
230 
231     /**
232      * Command line parameter true.
233      */
234     public static final String CMD_TRUE = "true";
235 
236     /**
237      * Command line parameter basicConstraintsPathLen is 0.
238      */
239     public static final String CMD_BC_PATH_LEN_0 = "0";
240 
241     /**
242      * Command line parameter password is 123456.
243      */
244     public static final String CMD_RIGHTS_123456 = "123456";
245 
246     /**
247      * Command line parameter RSA is 2048.
248      */
249     public static final String CMD_RSA_2048 = "2048";
250 
251     /**
252      * Command line parameter ECC is 256.
253      */
254     public static final String CMD_ECC_256 = "NIST-P-256";
255 
256     /**
257      * Command line parameter validity is 365.
258      */
259     public static final String CMD_VALIDITY_365 = "365";
260 
261     /**
262      * Command line parameter json file is UnsgnedDebugProfileTemplate.
263      */
264     public static final String CMD_JSON_FILE = "UnsgnedDebugProfileTemplate.json";
265 
266     /**
267      * Command line parameter localSign.
268      */
269     public static final String CMD_LOCAL_SIGN = "localSign";
270 
271     /**
272      * Command line parameter SHA256withECDSA.
273      */
274     public static final String CMD_SHA_256_WITH_ECDSA = "SHA256withECDSA";
275 
276     /**
277      * Command line parameter cer file is test_app-debug-cert.
278      */
279     public static final String CMD_APP_DEBUG_CERT_PATH = "test_app-debug-cert.pem";
280 
281     /**
282      * Command line parameter cer file is test_app-release-cert.
283      */
284     public static final String CMD_APP_RELEASE_CERT_PATH = "test_app-release-cert.pem";
285 
286     /**
287      * Command line parameter cer file is test_cert.
288      */
289     public static final String CMD_CERT_PATH = "test_cert.cer";
290 
291     /**
292      * Command line parameter csr file is test_csr.
293      */
294     public static final String CMD_CSR_PATH = "test_csr.csr";
295 
296     /**
297      * Command line parameter jks file is test_app_csr.
298      */
299     public static final String CMD_KEY_APP_STORE_PATH = "test_app_keypair.jks";
300 
301     /**
302      * Command line parameter jks file is test_profile_csr.
303      */
304     public static final String CMD_KEY_PROFILE_STORE_PATH = "test_profile_keypair.jks";
305 
306     /**
307      * Command line parameter cer file is test_root_app_ca.
308      */
309     public static final String CMD_ROOT_APP_CA_PATH = "test_root_app_ca.cer";
310 
311     /**
312      * Command line parameter cer file is test_root_profile_ca.
313      */
314     public static final String CMD_ROOT_PROFILE_CA_PATH = "test_root_profile_ca.cer";
315 
316     /**
317      * Command line parameter cer file is test_sub_app_ca.
318      */
319     public static final String CMD_SUB_APP_CA_PATH = "test_sub_app_ca.cer";
320 
321     /**
322      * Command line parameter cer file is test_sub_profile_ca.
323      */
324     public static final String CMD_SUB_PROFILE_CA_PATH = "test_sub_profile_ca.cer";
325 
326     /**
327      * Command line parameter p7b file is test_sign_profile.
328      */
329     public static final String CMD_SIGN_PROFILE_PATH = "test_sign_profile.p7b";
330 
331     /**
332      * Command line parameter cer file is test_profile-debug-cert.
333      */
334     public static final String CMD_PROFILE_DEBUG_CERT_PATH = "test_profile-debug-cert.pem";
335 
336     /**
337      * Command line parameter cer file is test_profile-release-cert.
338      */
339     public static final String CMD_PROFILE_RELEASE_CERT_PATH = "test_profile-release-cert.pem";
340 
341     /**
342      * Command line parameter cer file is test_verify_profile.
343      */
344     public static final String CMD_VERIFY_PROFILE_RESULT_PATH = "test_verify_profile_result.json";
345 
346     /**
347      * Command line parameter oh-profile-key-v1.
348      */
349     public static final String CMD_OH_PROFILE_KEY_V1 = "oh-profile-key-v1";
350 
351     /**
352      * Command line parameter oh-app1-key-v1.
353      */
354     public static final String CMD_OH_APP1_KEY_V1 = "oh-app1-key-v1";
355 
356     /**
357      * Command line parameter oh-root-ca-key-v1.
358      */
359     public static final String CMD_OH_ROOT_CA_KEY_V1 = "oh-root-ca-key-v1";
360 
361     /**
362      * Command line parameter oh-sub-app-ca-key-v1.
363      */
364     public static final String CMD_OH_SUB_APP_CA_KEY_V1 = "oh-sub-app-ca-key-v1";
365 
366     /**
367      * Command line parameter oh-sub-profile-ca-key-v1.
368      */
369     public static final String CMD_OH_SUB_PROFILE_CA_KEY_V1 = "oh-sub-profile-ca-key-v1";
370 
371     /**
372      * Command line parameter CN=ROOT CA.
373      */
374     public static final String CMD_ROOT_CA = "C=CN,O=OpenHarmony,OU=OpenHarmony Community,CN=ROOT CA";
375 
376     /**
377      * Command line parameter CN=App1 Release.
378      */
379     public static final String CMD_APP1_RELEASE = "C=CN,O=OpenHarmony,OU=OpenHarmony Community,CN=App1 Release";
380 
381     /**
382      * Command line parameter CN=Provision Profile Release.
383      */
384     public static final String CMD_PROFILE_RELEASE = "C=CN,O=OpenHarmony,"
385             + "OU=OpenHarmony Community,CN=Provision Profile Release";
386 
387     /**
388      * Command line parameter CN=Provision Profile Signature Service CA.
389      */
390     public static final String CMD_PROFILE_CA = "C=CN,O=OpenHarmony,OU=OpenHarmony Community,"
391             + "CN=Provision Profile Signature Service CA";
392 
393     /**
394      * Command line parameter CN=Application Signature Service CA.
395      */
396     public static final String CMD_APP_CA = "C=CN,"
397             + "O=OpenHarmony,OU=OpenHarmony Community,CN=Application Signature Service CA";
398 
399     /**
400      * Add log info.
401      */
402     private static final Logger logger = LoggerFactory.getLogger(CmdUnitTest.class);
403 
404     /**
405      * test cmdKeypair
406      * @throws IOException io error
407      */
408     @Order(1)
409     @Test
testCmdKeypair()410     public void testCmdKeypair() throws IOException {
411         try {
412             deleteFile(CMD_KEY_APP_STORE_PATH);
413             deleteFile(CMD_KEY_PROFILE_STORE_PATH);
414             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.GENERATE_KEYPAIR});
415             assertFalse(result);
416             assertFalse(FileUtils.isFileExist(CMD_KEY_APP_STORE_PATH));
417             assertFalse(FileUtils.isFileExist(CMD_KEY_PROFILE_STORE_PATH));
418         } catch (Exception exception) {
419             logger.info(exception, () -> exception.getMessage());
420         }
421 
422         deleteFile(CMD_KEY_APP_STORE_PATH);
423         boolean result = HapSignTool.processCmd(new String[]{
424             CmdUtil.Method.GENERATE_KEYPAIR,
425             CMD_KEY_ALIAS, CMD_OH_APP1_KEY_V1,
426             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
427             CMD_KEY_ALG, KeyPairTools.ECC_INPUT,
428             CMD_KEY_SIZE, CMD_ECC_256,
429             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
430             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456});
431         assertTrue(result);
432         assertTrue(FileUtils.isFileExist(CMD_KEY_APP_STORE_PATH));
433         deleteFile(CMD_KEY_PROFILE_STORE_PATH);
434         result = HapSignTool.processCmd(new String[]{
435             CmdUtil.Method.GENERATE_KEYPAIR,
436             CMD_KEY_ALIAS, CMD_OH_PROFILE_KEY_V1,
437             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
438             CMD_KEY_ALG, KeyPairTools.ECC_INPUT,
439             CMD_KEY_SIZE, CMD_ECC_256,
440             CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
441             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456});
442         assertTrue(result);
443         assertTrue(FileUtils.isFileExist(CMD_KEY_PROFILE_STORE_PATH));
444     }
445 
446     /**
447      * Csr test case.
448      *
449      * @throws IOException Error
450      */
451     @Order(2)
452     @Test
testCmdCsr()453     public void testCmdCsr() throws IOException {
454         try {
455             deleteFile(CMD_CSR_PATH);
456             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.GENERATE_CSR});
457             assertFalse(result);
458             assertFalse(FileUtils.isFileExist(CMD_CSR_PATH));
459         } catch (Exception exception) {
460             logger.info(exception, () -> exception.getMessage());
461         }
462 
463         deleteFile(CMD_CSR_PATH);
464         boolean result = HapSignTool.processCmd(new String[]{
465             CmdUtil.Method.GENERATE_CSR,
466             CMD_KEY_ALIAS, CMD_OH_APP1_KEY_V1,
467             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
468             CMD_SUBJECT, CMD_APP1_RELEASE,
469             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
470             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
471             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
472             CMD_OUT_FILE, CMD_CSR_PATH});
473         assertTrue(result);
474         assertTrue(FileUtils.isFileExist(CMD_CSR_PATH));
475     }
476 
477     /**
478      * Cert test case
479      *
480      * @throws IOException Error
481      */
482     @Order(3)
483     @Test
testCmdCert()484     public void testCmdCert() throws IOException {
485         try {
486             deleteFile(CMD_CERT_PATH);
487             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.GENERATE_CERT});
488             assertFalse(result);
489             assertFalse(FileUtils.isFileExist(CMD_CERT_PATH));
490         } catch (Exception exception) {
491             logger.info(exception, () -> exception.getMessage());
492         }
493 
494         deleteFile(CMD_CERT_PATH);
495         boolean result = HapSignTool.processCmd(new String[]{
496             CmdUtil.Method.GENERATE_CERT,
497             CMD_KEY_ALIAS, CMD_OH_APP1_KEY_V1,
498             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
499             CMD_ISSUER, CMD_APP_CA,
500             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
501             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
502             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
503             CMD_OUT_FILE, CMD_CERT_PATH,
504             CMD_ISSUER_KEY_ALIAS, CMD_OH_APP1_KEY_V1,
505             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
506             CMD_SUBJECT, CMD_APP1_RELEASE,
507             CMD_VALIDITY, CMD_VALIDITY_365,
508             CMD_KEY_USAGE, CMD_DIGITAL_SIGNATURE,
509             CMD_KEY_USAGE_CRITICAL, CMD_FALSE,
510             CMD_EXT_KEY_USAGE, CMD_CODE_AND_EMAIL,
511             CMD_EXT_KEY_USAGE_CRITICAL, CMD_TRUE,
512             CMD_BASIC_CONSTRAINTS, CMD_FALSE,
513             CMD_BASIC_CONSTRAINTS_CRITICAL, CMD_TRUE,
514             CMD_BASIC_CONSTRAINTS_CA, CMD_FALSE,
515             CMD_BASIC_CONSTRAINTS_PATH_LEN, CMD_BC_PATH_LEN_0});
516         assertTrue(result);
517         assertTrue(FileUtils.isFileExist(CMD_CERT_PATH));
518     }
519 
520     /**
521      * Ca test case.
522      *
523      * @throws IOException Error
524      */
525     @Order(4)
526     @Test
testCmdCa()527     public void testCmdCa() throws IOException {
528         try {
529             deleteFile(CMD_ROOT_APP_CA_PATH);
530             deleteFile(CMD_ROOT_PROFILE_CA_PATH);
531             deleteFile(CMD_SUB_APP_CA_PATH);
532             deleteFile(CMD_SUB_PROFILE_CA_PATH);
533             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.GENERATE_CA});
534             assertFalse(result);
535             assertFalse(FileUtils.isFileExist(CMD_ROOT_APP_CA_PATH));
536             assertFalse(FileUtils.isFileExist(CMD_ROOT_PROFILE_CA_PATH));
537             assertFalse(FileUtils.isFileExist(CMD_SUB_APP_CA_PATH));
538             assertFalse(FileUtils.isFileExist(CMD_SUB_PROFILE_CA_PATH));
539         } catch (Exception exception) {
540             logger.info(exception, () -> exception.getMessage());
541         }
542         deleteFile(CMD_ROOT_APP_CA_PATH);
543         boolean result = generateAppRootCa();
544         assertTrue(result);
545         assertTrue(FileUtils.isFileExist(CMD_ROOT_APP_CA_PATH));
546         deleteFile(CMD_ROOT_PROFILE_CA_PATH);
547         result = generateProfileRootCa();
548         assertTrue(result);
549         assertTrue(FileUtils.isFileExist(CMD_ROOT_PROFILE_CA_PATH));
550         deleteFile(CMD_SUB_APP_CA_PATH);
551         result = generateAppSubCa();
552         assertTrue(result);
553         assertTrue(FileUtils.isFileExist(CMD_SUB_APP_CA_PATH));
554         deleteFile(CMD_SUB_PROFILE_CA_PATH);
555         result = generateProfileSubCa();
556         assertTrue(result);
557         assertTrue(FileUtils.isFileExist(CMD_SUB_PROFILE_CA_PATH));
558     }
559 
560     /**
561      * App cert test case.
562      *
563      * @throws IOException Error
564      */
565     @Order(5)
566     @Test
testCmdAppCert()567     public void testCmdAppCert() throws IOException {
568         try {
569             deleteFile(CMD_APP_DEBUG_CERT_PATH);
570             deleteFile(CMD_APP_RELEASE_CERT_PATH);
571             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.GENERATE_APP_CERT});
572             assertFalse(result);
573             assertFalse(FileUtils.isFileExist(CMD_APP_DEBUG_CERT_PATH));
574             assertFalse(FileUtils.isFileExist(CMD_APP_RELEASE_CERT_PATH));
575         } catch (Exception exception) {
576             logger.info(exception, () -> exception.getMessage());
577         }
578         deleteFile(CMD_APP_DEBUG_CERT_PATH);
579         boolean result = HapSignTool.processCmd(new String[]{
580             CmdUtil.Method.GENERATE_APP_CERT,
581             CMD_KEY_ALIAS, CMD_OH_APP1_KEY_V1,
582             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
583             CMD_ISSUER, CMD_APP_CA,
584             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
585             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
586             CMD_OUT_FILE, CMD_APP_DEBUG_CERT_PATH,
587             CMD_ISSUER_KEY_ALIAS, CMD_OH_SUB_APP_CA_KEY_V1,
588             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
589             CMD_SUBJECT, CMD_APP1_RELEASE,
590             CMD_VALIDITY, CMD_VALIDITY_365,
591             CMD_OUT_FORM, CMD_CERT_CHAIN,
592             CMD_ROOT_CA_CERT_FILE, CMD_ROOT_APP_CA_PATH,
593             CMD_SUB_CA_CERT_FILE, CMD_SUB_APP_CA_PATH,
594             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA});
595         assertTrue(result);
596         assertTrue(FileUtils.isFileExist(CMD_APP_DEBUG_CERT_PATH));
597         deleteFile(CMD_APP_RELEASE_CERT_PATH);
598         result = HapSignTool.processCmd(new String[]{
599             CmdUtil.Method.GENERATE_APP_CERT,
600             CMD_KEY_ALIAS, CMD_OH_APP1_KEY_V1,
601             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
602             CMD_ISSUER, CMD_APP_CA,
603             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
604             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
605             CMD_OUT_FILE, CMD_APP_RELEASE_CERT_PATH,
606             CMD_ISSUER_KEY_ALIAS, CMD_OH_SUB_APP_CA_KEY_V1,
607             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
608             CMD_SUBJECT, CMD_APP1_RELEASE,
609             CMD_VALIDITY, CMD_VALIDITY_365,
610             CMD_OUT_FORM, CMD_CERT_CHAIN,
611             CMD_ROOT_CA_CERT_FILE, CMD_ROOT_APP_CA_PATH,
612             CMD_SUB_CA_CERT_FILE, CMD_SUB_APP_CA_PATH,
613             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA});
614         assertTrue(result);
615         assertTrue(FileUtils.isFileExist(CMD_APP_RELEASE_CERT_PATH));
616     }
617 
618     /**
619      * Profile cert test case
620      *
621      * @throws IOException Error
622      */
623     @Order(6)
624     @Test
testCmdProfileCert()625     public void testCmdProfileCert() throws IOException {
626         try {
627             deleteFile(CMD_PROFILE_DEBUG_CERT_PATH);
628             deleteFile(CMD_PROFILE_RELEASE_CERT_PATH);
629             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.GENERATE_PROFILE_CERT});
630             assertFalse(result);
631             assertFalse(FileUtils.isFileExist(CMD_PROFILE_DEBUG_CERT_PATH));
632             assertFalse(FileUtils.isFileExist(CMD_PROFILE_RELEASE_CERT_PATH));
633         } catch (Exception exception) {
634             logger.info(exception, () -> exception.getMessage());
635         }
636         deleteFile(CMD_PROFILE_DEBUG_CERT_PATH);
637         boolean result = HapSignTool.processCmd(new String[]{
638             CmdUtil.Method.GENERATE_PROFILE_CERT,
639             CMD_KEY_ALIAS, CMD_OH_PROFILE_KEY_V1,
640             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
641             CMD_ISSUER, CMD_PROFILE_CA,
642             CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
643             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
644             CMD_OUT_FILE, CMD_PROFILE_DEBUG_CERT_PATH,
645             CMD_ISSUER_KEY_ALIAS, CMD_OH_SUB_PROFILE_CA_KEY_V1,
646             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
647             CMD_SUBJECT, CMD_PROFILE_RELEASE,
648             CMD_VALIDITY, CMD_VALIDITY_365,
649             CMD_OUT_FORM, CMD_CERT_CHAIN,
650             CMD_ROOT_CA_CERT_FILE, CMD_ROOT_PROFILE_CA_PATH,
651             CMD_SUB_CA_CERT_FILE, CMD_SUB_PROFILE_CA_PATH,
652             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA});
653         assertTrue(result);
654         assertTrue(FileUtils.isFileExist(CMD_PROFILE_DEBUG_CERT_PATH));
655         deleteFile(CMD_PROFILE_RELEASE_CERT_PATH);
656         result = HapSignTool.processCmd(new String[]{
657             CmdUtil.Method.GENERATE_PROFILE_CERT,
658             CMD_KEY_ALIAS, CMD_OH_PROFILE_KEY_V1,
659             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
660             CMD_ISSUER, CMD_PROFILE_CA,
661             CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
662             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
663             CMD_OUT_FILE, CMD_PROFILE_RELEASE_CERT_PATH,
664             CMD_ISSUER_KEY_ALIAS, CMD_OH_SUB_PROFILE_CA_KEY_V1,
665             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
666             CMD_SUBJECT, CMD_PROFILE_RELEASE,
667             CMD_VALIDITY, CMD_VALIDITY_365,
668             CMD_OUT_FORM, CMD_CERT_CHAIN,
669             CMD_ROOT_CA_CERT_FILE, CMD_ROOT_PROFILE_CA_PATH,
670             CMD_SUB_CA_CERT_FILE, CMD_SUB_PROFILE_CA_PATH,
671             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA});
672         assertTrue(result);
673         assertTrue(FileUtils.isFileExist(CMD_PROFILE_RELEASE_CERT_PATH));
674     }
675 
676     /**
677      * Sign profile test case.
678      *
679      * @throws IOException error
680      */
681     @Order(7)
682     @Test
testCmdSignProfile()683     public void testCmdSignProfile() throws IOException {
684         try {
685             deleteFile(CMD_SIGN_PROFILE_PATH);
686             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.SIGN_PROFILE});
687             assertFalse(result);
688             assertFalse(FileUtils.isFileExist(CMD_SIGN_PROFILE_PATH));
689         } catch (Exception exception) {
690             logger.info(exception, () -> exception.getMessage());
691         }
692 
693         deleteFile(CMD_SIGN_PROFILE_PATH);
694         loadFile(CMD_JSON_FILE);
695         boolean result = HapSignTool.processCmd(new String[]{
696             CmdUtil.Method.SIGN_PROFILE,
697             CMD_MODE, CMD_LOCAL_SIGN,
698             CMD_KEY_ALIAS, CMD_OH_PROFILE_KEY_V1,
699             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
700             CMD_PROFILE_CERT_FILE, CMD_PROFILE_RELEASE_CERT_PATH,
701             CMD_IN_FILE, CMD_JSON_FILE,
702             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
703             CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
704             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
705             CMD_OUT_FILE, CMD_SIGN_PROFILE_PATH});
706         assertTrue(result);
707         assertTrue(FileUtils.isFileExist(CMD_SIGN_PROFILE_PATH));
708     }
709 
710     /**
711      * Verify profile test case.
712      */
713     @Order(8)
714     @Test
testVerifyProfile()715     public void testVerifyProfile() {
716         try {
717             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.VERIFY_PROFILE});
718             assertFalse(result);
719         } catch (Exception exception) {
720             logger.info(exception, () -> exception.getMessage());
721         }
722 
723         boolean result = HapSignTool.processCmd(new String[]{
724             CmdUtil.Method.VERIFY_PROFILE,
725             CMD_IN_FILE, CMD_SIGN_PROFILE_PATH,
726             CMD_OUT_FILE, CMD_VERIFY_PROFILE_RESULT_PATH});
727         assertTrue(result);
728     }
729 
730     /**
731      * Sign hap test case.
732      */
733     @Order(9)
734     @Test
testCmdSignApp()735     public void testCmdSignApp() {
736         try {
737             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.SIGN_APP});
738             assertFalse(result);
739         } catch (Exception exception) {
740             logger.info(exception, () -> exception.getMessage());
741         }
742     }
743 
744     /**
745      * Verify signed app test case.
746      */
747     @Order(10)
748     @Test
testCmdVerifyApp()749     public void testCmdVerifyApp() {
750         try {
751             boolean result = HapSignTool.processCmd(new String[]{CmdUtil.Method.VERIFY_APP});
752             assertFalse(result);
753         } catch (Exception exception) {
754             logger.info(exception, () -> exception.getMessage());
755         }
756     }
757 
758     /**
759      * test sign and verify hap file include multi lib
760      *
761      * @throws IOException error
762      */
763     @Order(11)
764     @Test
testCmdMultiHap()765     public void testCmdMultiHap() throws IOException {
766         File dir = new File("test");
767         dir.mkdir();
768         for (FileType abcFile : FileType.values()) {
769             for (FileType soFile : FileType.values()) {
770                 for (FileType anFile : FileType.values()) {
771                     File unsignedHap = generateHapFile(abcFile, soFile, anFile, FileType.FILE_NOT_EXISTED);
772                     signAndVerifyHap(unsignedHap.getAbsolutePath());
773 
774                     unsignedHap = generateHapFile(abcFile, soFile, anFile, FileType.FILE_UNCOMPRESSED);
775                     signAndVerifyHap(unsignedHap.getAbsolutePath());
776 
777                     unsignedHap = generateHapFile(abcFile, soFile, anFile, FileType.FILE_COMPRESSED);
778                     signAndVerifyHap(unsignedHap.getAbsolutePath());
779                 }
780             }
781         }
782         for (File file : dir.listFiles()) {
783             file.delete();
784         }
785         dir.delete();
786     }
787 
generateHapFile(FileType abc, FileType so, FileType an, FileType otherFile)788     private File generateHapFile(FileType abc, FileType so, FileType an, FileType otherFile) throws IOException {
789         File unsignedHap = new File("test\\unsigned-" + new BigInteger(Long.SIZE, new Random()) + ".hap");
790         try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(unsignedHap))) {
791             if (FileType.FILE_UNCOMPRESSED.equals(abc)) {
792                 fillZipEntryFile(true, ".abc", out);
793             } else if (FileType.FILE_COMPRESSED.equals(abc)) {
794                 fillZipEntryFile(false, ".abc", out);
795             } else {
796                 fillZipEntryFile(true, "", out);
797             }
798             if (FileType.FILE_UNCOMPRESSED.equals(so)) {
799                 fillZipEntryFile(true, ".so", out);
800                 fillZipEntryFile(true, ".so.111", out);
801                 fillZipEntryFile(true, ".so.111.111", out);
802                 fillZipEntryFile(true, ".so.111.111.111", out);
803             } else if (FileType.FILE_COMPRESSED.equals(so)) {
804                 fillZipEntryFile(false, ".so", out);
805                 fillZipEntryFile(false, ".so.111", out);
806                 fillZipEntryFile(false, ".so.111.111", out);
807                 fillZipEntryFile(false, ".so.111.111.111", out);
808             } else {
809                 fillZipEntryFile(true, "", out);
810             }
811             if (FileType.FILE_UNCOMPRESSED.equals(an)) {
812                 fillZipEntryFile(true, ".an", out);
813             } else if (FileType.FILE_COMPRESSED.equals(an)) {
814                 fillZipEntryFile(false, ".an", out);
815             } else {
816                 fillZipEntryFile(true, "", out);
817             }
818             if (FileType.FILE_UNCOMPRESSED.equals(otherFile)) {
819                 fillZipEntryFile(true, ".json", out);
820             } else if (FileType.FILE_COMPRESSED.equals(otherFile)) {
821                 fillZipEntryFile(false, ".json", out);
822             } else {
823                 fillZipEntryFile(true, "", out);
824             }
825         }
826         return unsignedHap;
827     }
828 
fillZipEntryFile(boolean uncompressed, String suffix, ZipOutputStream out)829     private void fillZipEntryFile(boolean uncompressed, String suffix, ZipOutputStream out) throws IOException {
830         String fileName = new BigInteger(Long.SIZE, new Random()).toString() + suffix;
831         if (suffix.startsWith(".so")) {
832             fileName = "libs\\" + fileName;
833         }
834         if (suffix.startsWith(".an")) {
835             fileName = "an\\" + fileName;
836         }
837         ZipEntry zipEntry = new ZipEntry(fileName);
838         byte[] bytes = generateChunkBytes();
839         if (uncompressed) {
840             zipEntry.setMethod(ZipEntry.STORED);
841             zipEntry.setSize(bytes.length);
842             CRC32 crc32 = new CRC32();
843             crc32.reset();
844             crc32.update(bytes, 0, bytes.length);
845             zipEntry.setCrc(crc32.getValue());
846         } else {
847             zipEntry.setMethod(ZipEntry.DEFLATED);
848         }
849         out.putNextEntry(zipEntry);
850         out.write(bytes);
851         out.closeEntry();
852     }
853 
generateChunkBytes()854     private byte[] generateChunkBytes() {
855         Random random = new Random();
856         int size = Math.max(4096, random.nextInt(1024 * 1024 * 2));
857         byte[] bytes = new byte[size];
858         random.nextBytes(bytes);
859         return bytes;
860     }
861 
signAndVerifyHap(String unsignedHap)862     private void signAndVerifyHap(String unsignedHap) throws IOException {
863         String signedHap = File.createTempFile("signed-", ".hap", new File("test")).getAbsolutePath();
864         boolean result = HapSignTool.processCmd(new String[] {
865             CmdUtil.Method.SIGN_APP, CMD_MODE, CMD_LOCAL_SIGN, CMD_KEY_ALIAS, CMD_OH_PROFILE_KEY_V1, CMD_KEY_RIGHTS,
866             CMD_RIGHTS_123456, CMD_APP_CERT_FILE, CMD_PROFILE_RELEASE_CERT_PATH, CMD_PROFILE_FILE,
867             CMD_SIGN_PROFILE_PATH, CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA, CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
868             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456, CMD_IN_FILE, unsignedHap, CMD_OUT_FILE, signedHap
869         });
870         assertTrue(result);
871 
872         result = HapSignTool.processCmd(new String[] {
873             CmdUtil.Method.VERIFY_APP, CMD_IN_FILE, signedHap, CMD_OUT_CERT_CHAIN, "test\\1.cer", CMD_OUT_PROFILE,
874             "test\\1.p7b"
875         });
876         assertTrue(result);
877     }
878 
879     /**
880      * Test Method: isRunnableFile()
881      */
882     @Test
testIsRunnableFile()883     public void testIsRunnableFile() {
884         List<String> correctName = new ArrayList<>();
885         correctName.add("中文.so");
886         correctName.add("srtjdwrtj.an");
887         correctName.add("srtjdwrtj.abc");
888         correctName.add("srtjdwrtj.so");
889         correctName.add("srtjdwrtj.so.1");
890         correctName.add("srtjdwrtj.so.1.1");
891         correctName.add("srtjdwrtj.so.1.1.1");
892         correctName.add("srtjdwrtj.so.111.111.1111");
893         correctName.add("libs\\srtjdwrtj.so.111.111.1111");
894         correctName.add("中文.so.111.111.1111");
895         for (String name : correctName) {
896             assertTrue(FileUtils.isRunnableFile(name));
897         }
898 
899         List<String> incorrectName = new ArrayList<>();
900         incorrectName.add("srtjdwrtj.so.111.111.1111.54645");
901         incorrectName.add("srtjdwrtjso.111.111.11111");
902         incorrectName.add("libs\\srtjdwrtj.so.111.%%%.1111");
903         incorrectName.add("srtjdwrtj.so.abc.111.111.1111");
904         incorrectName.add("srtjdwrtj.so.111.111.json");
905         incorrectName.add("srtjdwrtj.abc.json");
906         incorrectName.add("srtjdwrtj.an.json");
907         incorrectName.add("中文.so.111.111.json");
908         for (String name : incorrectName) {
909             assertFalse(FileUtils.isRunnableFile(name));
910         }
911     }
912 
913 
914     /**
915      * Test Method: testByteToZip()
916      *
917      * @throws IOException read file exception
918      */
919     @Test
testByteToZip()920     public void testByteToZip() throws IOException {
921         File dir = new File("test");
922         dir.mkdir();
923         for (int i = 0; i < 10; i++) {
924             File file = generateHapFile(FileType.FILE_UNCOMPRESSED, FileType.FILE_UNCOMPRESSED,
925                     FileType.FILE_UNCOMPRESSED, FileType.FILE_UNCOMPRESSED);
926             Zip zip = new Zip(file);
927             String outFileName = "test/testOut.hap";
928             zip.toFile(outFileName);
929             File outFile = new File(outFileName);
930             byte[] bytes = FileUtils.readFile(file);
931             byte[] outBytes = FileUtils.readFile(outFile);
932             assertArrayEquals(outBytes, bytes);
933 
934             deleteFile(file.getCanonicalPath());
935             deleteFile(outFileName);
936         }
937     }
938 
generateAppRootCa()939     private boolean generateAppRootCa() {
940         boolean result = HapSignTool.processCmd(new String[]{
941             CmdUtil.Method.GENERATE_CA,
942             CMD_KEY_ALIAS, CMD_OH_ROOT_CA_KEY_V1,
943             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
944             CMD_KEY_ALG, KeyPairTools.ECC_INPUT,
945             CMD_KEY_SIZE, CMD_ECC_256,
946             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
947             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
948             CMD_OUT_FILE, CMD_ROOT_APP_CA_PATH,
949             CMD_SUBJECT, CMD_ROOT_CA,
950             CMD_VALIDITY, CMD_VALIDITY_365,
951             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
952             CMD_BASIC_CONSTRAINTS_PATH_LEN, CMD_BC_PATH_LEN_0});
953         return result;
954     }
955 
generateProfileRootCa()956     private boolean generateProfileRootCa() {
957         boolean result = HapSignTool.processCmd(new String[]{
958             CmdUtil.Method.GENERATE_CA,
959             CMD_KEY_ALIAS, CMD_OH_ROOT_CA_KEY_V1,
960             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
961             CMD_KEY_ALG, KeyPairTools.ECC_INPUT,
962             CMD_KEY_SIZE, CMD_ECC_256,
963             CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
964             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
965             CMD_OUT_FILE, CMD_ROOT_PROFILE_CA_PATH,
966             CMD_SUBJECT, CMD_ROOT_CA,
967             CMD_VALIDITY, CMD_VALIDITY_365,
968             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
969             CMD_BASIC_CONSTRAINTS_PATH_LEN, CMD_BC_PATH_LEN_0});
970         return result;
971     }
972 
generateAppSubCa()973     private boolean generateAppSubCa() {
974         boolean result = HapSignTool.processCmd(new String[]{
975             CmdUtil.Method.GENERATE_CA,
976             CMD_KEY_ALIAS, CMD_OH_SUB_APP_CA_KEY_V1,
977             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
978             CMD_ISSUER, CMD_ROOT_CA,
979             CMD_KEY_ALG, KeyPairTools.ECC_INPUT,
980             CMD_KEY_SIZE, CMD_ECC_256,
981             CMD_KEY_STORE_FILE, CMD_KEY_APP_STORE_PATH,
982             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
983             CMD_OUT_FILE, CMD_SUB_APP_CA_PATH,
984             CMD_ISSUER_KEY_ALIAS, CMD_OH_ROOT_CA_KEY_V1,
985             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
986             CMD_SUBJECT, CMD_APP_CA,
987             CMD_VALIDITY, CMD_VALIDITY_365,
988             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
989             CMD_BASIC_CONSTRAINTS_PATH_LEN, CMD_BC_PATH_LEN_0});
990         return result;
991     }
992 
generateProfileSubCa()993     private boolean generateProfileSubCa() {
994         boolean result = HapSignTool.processCmd(new String[]{
995             CmdUtil.Method.GENERATE_CA,
996             CMD_KEY_ALIAS, CMD_OH_SUB_PROFILE_CA_KEY_V1,
997             CMD_KEY_RIGHTS, CMD_RIGHTS_123456,
998             CMD_ISSUER, CMD_ROOT_CA,
999             CMD_KEY_ALG, KeyPairTools.ECC_INPUT,
1000             CMD_KEY_SIZE, CMD_ECC_256,
1001             CMD_KEY_STORE_FILE, CMD_KEY_PROFILE_STORE_PATH,
1002             CMD_KEY_STORE_RIGHTS, CMD_RIGHTS_123456,
1003             CMD_OUT_FILE, CMD_SUB_PROFILE_CA_PATH,
1004             CMD_ISSUER_KEY_ALIAS, CMD_OH_ROOT_CA_KEY_V1,
1005             CMD_ISSUER_KEY_RIGHTS, CMD_RIGHTS_123456,
1006             CMD_SUBJECT, CMD_PROFILE_CA,
1007             CMD_VALIDITY, CMD_VALIDITY_365,
1008             CMD_SIGN_ALG, CMD_SHA_256_WITH_ECDSA,
1009             CMD_BASIC_CONSTRAINTS_PATH_LEN, CMD_BC_PATH_LEN_0});
1010         return result;
1011     }
1012 
loadFile(String filePath)1013     private void loadFile(String filePath) throws IOException {
1014         ClassLoader classLoader = CmdUnitTest.class.getClassLoader();
1015         InputStream fileInputStream = classLoader.getResourceAsStream(filePath);
1016         byte[] fileData = FileUtils.read(fileInputStream);
1017         FileUtils.write(fileData, new File(filePath));
1018     }
1019 
deleteFile(String filePath)1020     private void deleteFile(String filePath) throws IOException {
1021         if (FileUtils.isFileExist(filePath)) {
1022             Path path = Paths.get(filePath);
1023             Files.delete(path);
1024         }
1025     }
1026 
1027     /**
1028      * Enumerated value of file type in zip.
1029      */
1030     public enum FileType {
1031         FILE_NOT_EXISTED,
1032         FILE_UNCOMPRESSED,
1033         FILE_COMPRESSED;
1034     }
1035 }
1036