getSegmentHeaderList() {
- return segmentHeaderList;
- }
-
- /**
- * set segment header list
- */
- public void setSegmentHeaders() {
- // fs-verity info segment
- segmentHeaderList.add(new SegmentHeader(SegmentHeader.CSB_FSVERITY_INFO_SEG, this.fsVerityInfoSegment.size()));
- // hap info segment
- segmentHeaderList.add(new SegmentHeader(SegmentHeader.CSB_HAP_META_SEG, this.hapInfoSegment.size()));
- // native lib info segment
- segmentHeaderList.add(
- new SegmentHeader(SegmentHeader.CSB_NATIVE_LIB_INFO_SEG, this.nativeLibInfoSegment.size()));
- }
-
- public CodeSignBlockHeader getCodeSignBlockHeader() {
- return codeSignBlockHeader;
- }
-
- public void setCodeSignBlockHeader(CodeSignBlockHeader csbHeader) {
- this.codeSignBlockHeader = csbHeader;
- }
-
- public void setFsVerityInfoSegment(FsVerityInfoSegment fsVeritySeg) {
- this.fsVerityInfoSegment = fsVeritySeg;
- }
-
- public FsVerityInfoSegment getFsVerityInfoSegment() {
- return fsVerityInfoSegment;
- }
-
- public HapInfoSegment getHapInfoSegment() {
- return hapInfoSegment;
- }
-
- public void setHapInfoSegment(HapInfoSegment hapSeg) {
- this.hapInfoSegment = hapSeg;
- }
-
- public NativeLibInfoSegment getSoInfoSegment() {
- return nativeLibInfoSegment;
- }
-
- public void setSoInfoSegment(NativeLibInfoSegment soSeg) {
- this.nativeLibInfoSegment = soSeg;
- }
-
- /**
- * Convert code sign block object to a newly created byte array
- *
- * @return Byte array representation of a CodeSignBlock object
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(this.codeSignBlockHeader.getBlockSize()).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(this.codeSignBlockHeader.toByteArray());
- for (SegmentHeader sh : this.segmentHeaderList) {
- bf.put(sh.toByteArray());
- }
- bf.put(this.zeroPadding);
- // Hap merkle tree
- if (this.hapInfoSegment.getSignInfo().getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED) != null) {
- bf.put(merkleTreeMap.get("Hap"));
- }
- bf.put(this.fsVerityInfoSegment.toByteArray());
- bf.put(this.hapInfoSegment.toByteArray());
- bf.put(this.nativeLibInfoSegment.toByteArray());
- return bf.array();
- }
-
- /**
- * SegmentOffset is the position of each segment defined in segmentHeaderList,
- * based on the start position of code sign block
- */
- public void computeSegmentOffset() {
- // 1) the first segment is placed after merkle tree
- int segmentOffset = CodeSignBlockHeader.size()
- + this.segmentHeaderList.size() * SegmentHeader.SEGMENT_HEADER_LENGTH + this.zeroPadding.length
- + this.getOneMerkleTreeByFileName(CodeSigning.HAP_SIGNATURE_ENTRY_NAME).length;
- for (SegmentHeader sh : segmentHeaderList) {
- sh.setSegmentOffset(segmentOffset);
- segmentOffset += sh.getSegmentSize();
- }
- }
-
- /**
- * Compute the offset to store merkle tree raw bytes based on file start
- *
- * @param codeSignBlockOffset offset to store code sign block based on file start
- * @return offset to store merkle tree based on the file start, it includes the codeSignBlockOffset
- */
- public long computeMerkleTreeOffset(long codeSignBlockOffset) {
- long sizeWithoutMerkleTree = CodeSignBlockHeader.size()
- + SEGMENT_HEADER_COUNT * SegmentHeader.SEGMENT_HEADER_LENGTH;
- // add code sign block offset while computing align position for merkle tree
- long residual = (codeSignBlockOffset + sizeWithoutMerkleTree) % PAGE_SIZE_4K;
- if (residual == 0) {
- this.zeroPadding = new byte[0];
- } else {
- this.zeroPadding = new byte[(int) (PAGE_SIZE_4K - residual)];
- }
- return codeSignBlockOffset + sizeWithoutMerkleTree + zeroPadding.length;
- }
-
- /**
- * Convert CodeSignBlock to bytes
- *
- * @param fsvTreeOffset merkle tree offset
- * @return byte array representing the code sign block
- */
- public byte[] generateCodeSignBlockByte(long fsvTreeOffset) {
- // 1) compute overall block size without merkle tree
- long csbSize = CodeSignBlockHeader.size()
- + (long) this.segmentHeaderList.size() * SegmentHeader.SEGMENT_HEADER_LENGTH + this.zeroPadding.length
- + this.getOneMerkleTreeByFileName(CodeSigning.HAP_SIGNATURE_ENTRY_NAME).length
- + this.fsVerityInfoSegment.size() + this.hapInfoSegment.size() + this.nativeLibInfoSegment.size();
- Extension ext = this.hapInfoSegment.getSignInfo().getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED);
- if (ext instanceof MerkleTreeExtension) {
- MerkleTreeExtension merkleTreeExtension = (MerkleTreeExtension) ext;
- merkleTreeExtension.setMerkleTreeOffset(fsvTreeOffset);
- }
- this.codeSignBlockHeader.setBlockSize(csbSize);
- // 2) generate byte array of complete code sign block
- return toByteArray();
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT,
- "CodeSignBlockHeader[%s], SegmentHeaders[%s], FsVeritySeg[%s], HapInfoSeg[%s], SoInfoSeg[%s]",
- this.codeSignBlockHeader, Arrays.toString(this.segmentHeaderList.toArray()), this.fsVerityInfoSegment,
- this.hapInfoSegment, this.nativeLibInfoSegment);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/CodeSignBlockHeader.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/CodeSignBlockHeader.java
deleted file mode 100644
index 8a1572fa42747aa2bb2c68e92ca570a3e6ec5fb7..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/CodeSignBlockHeader.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Locale;
-
-/**
- * Code sign block header
- *
- * Structure:
- * 1) u64 magic: magic number
- * 2) u32 version: sign tool version
- * 3) u32 blockSize: size of code sign block
- * 4) u32 segmentNum: number of segments, i.e. FsVerityInfoSegment, HapInfoSegment, SoInfoSegment
- * 5) u32 flags
- * 6) u8[8] reserved: for reservation
- *
- * The Size of Code sign Block header if fixed, getBlockLength() method returns the size.
- *
- * @since 2023/09/08
- */
-public class CodeSignBlockHeader {
- /**
- * Flag indicating that merkle tree is included in code sign block
- */
- public static final int FLAG_MERKLE_TREE_INLINED = 0x1;
-
- /**
- * Flag indicating that native lib is included in code sign block
- */
- public static final int FLAG_NATIVE_LIB_INCLUDED = 0x2;
-
- // code signing version
- private static final int CODE_SIGNING_VERSION = 1;
-
- // byte size of magic number
- private static final byte MAGIC_BYTE_ARRAY_LENGTH = Long.BYTES;
-
- // lower 8 bytes of MD5 result of string "hap code sign block" (E046 C8C6 5389 FCCD)
- private static final long MAGIC_NUM = ((0xE046C8C6L << 32) + 0x5389FCCDL);
-
- // size of byte[8] reserved
- private static final byte RESERVED_BYTE_ARRAY_LENGTH = 8;
-
- // At all times three segment are always included in code sign block, update this if new segments are created.
- private static final int SEGMENT_NUM = 3;
-
- private long magic;
-
- private int version;
-
- private int blockSize;
-
- private int segmentNum;
-
- private int flags;
-
- private byte[] reserved;
-
- /**
- * Construct of CodeSignBlockHeader
- *
- * @param builder builder
- */
- private CodeSignBlockHeader(Builder builder) {
- this.magic = builder.magic;
- this.version = builder.version;
- this.blockSize = builder.blockSize;
- this.segmentNum = builder.segmentNum;
- this.flags = builder.flags;
- this.reserved = builder.reserved;
- }
-
- public void setSegmentNum(int num) {
- this.segmentNum = num;
- }
-
- public int getSegmentNum() {
- return segmentNum;
- }
-
- public void setBlockSize(long size) {
- this.blockSize = (int) size;
- }
-
- public int getBlockSize() {
- return blockSize;
- }
-
- public void setFlags(int flags) {
- this.flags = flags;
- }
-
- /**
- * Converts code sign block headers to a newly created byte array
- *
- * @return Byte array representation of a code sign block header
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(size()).order(ByteOrder.LITTLE_ENDIAN);
- bf.putLong(magic);
- bf.putInt(version);
- bf.putInt(blockSize);
- bf.putInt(segmentNum);
- bf.putInt(flags);
- bf.put(reserved);
- return bf.array();
- }
-
- /**
- * Init the CodeSignBlockHeader by a byte array
- *
- * @param bytes Byte array representation of a CodeSignBlockHeader object
- * @return a newly created CodeSignBlockHeader object
- * @throws VerifyCodeSignException parse result invalid
- */
- public static CodeSignBlockHeader fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- if (bytes.length != size()) {
- throw new VerifyCodeSignException("Invalid size of CodeSignBlockHeader");
- }
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- // after put, rewind is mandatory before get
- bf.rewind();
- long inMagic = bf.getLong();
- if (inMagic != MAGIC_NUM) {
- throw new VerifyCodeSignException("Invalid magic num of CodeSignBlockHeader");
- }
- int inVersion = bf.getInt();
- if (inVersion != CODE_SIGNING_VERSION) {
- throw new VerifyCodeSignException("Invalid version of CodeSignBlockHeader");
- }
- int inBlockSize = bf.getInt();
- int inSegmentNum = bf.getInt();
- if (inSegmentNum != SEGMENT_NUM) {
- throw new VerifyCodeSignException("Invalid segmentNum of CodeSignBlockHeader");
- }
- int inFlags = bf.getInt();
- if (inFlags < 0 || inFlags > (FLAG_MERKLE_TREE_INLINED + FLAG_NATIVE_LIB_INCLUDED)) {
- throw new VerifyCodeSignException("Invalid flags of CodeSignBlockHeader");
- }
- byte[] inReserved = new byte[RESERVED_BYTE_ARRAY_LENGTH];
- bf.get(inReserved);
- return new Builder().setMagic(inMagic).setVersion(inVersion).setBlockSize(inBlockSize)
- .setSegmentNum(inSegmentNum).setFlags(inFlags).setReserved(inReserved).build();
- }
-
- /**
- * Return the byte size of code sign block header
- *
- * @return byte size of code sign block header
- */
- public static int size() {
- return MAGIC_BYTE_ARRAY_LENGTH + Integer.BYTES * 4 + RESERVED_BYTE_ARRAY_LENGTH;
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT,
- "CodeSignBlockHeader{magic: %d, version: %d, blockSize: %d, segmentNum: %d, flags: %d}", this.magic,
- this.version, this.blockSize, this.segmentNum, this.flags);
- }
-
- /**
- * Builder of CodeSignBlockHeader class
- */
- public static class Builder {
- private long magic = MAGIC_NUM;
-
- private int version = CODE_SIGNING_VERSION;
-
- private int blockSize;
-
- private int segmentNum;
-
- private int flags;
-
- private byte[] reserved = new byte[RESERVED_BYTE_ARRAY_LENGTH];
-
- public Builder setMagic(long magic) {
- this.magic = magic;
- return this;
- }
-
- public Builder setVersion(int version) {
- this.version = version;
- return this;
- }
-
- public Builder setBlockSize(int blockSize) {
- this.blockSize = blockSize;
- return this;
- }
-
- public Builder setSegmentNum(int segmentNum) {
- this.segmentNum = segmentNum;
- return this;
- }
-
- public Builder setFlags(int flags) {
- this.flags = flags;
- return this;
- }
-
- public Builder setReserved(byte[] reserved) {
- this.reserved = reserved;
- return this;
- }
-
- /**
- * Create a CodeSignBlockHeader object
- *
- * @return a CodeSignBlockHeader object
- */
- public CodeSignBlockHeader build() {
- return new CodeSignBlockHeader(this);
- }
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/ElfSignBlock.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/ElfSignBlock.java
deleted file mode 100644
index 959f9ed87a911beca73a3e3caf6c108590f68535..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/ElfSignBlock.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityDescriptor;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityDescriptorWithSign;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * elf sign block is a chunk of bytes attached to elf file.
- * 1) u32 type: 0x2 merkle tree
- * 2) u32 length: merkle tree with padding size
- * 3) u8[] merkle tree data
- * 4) u32 type: 0x1 fsverity descriptor
- * 5) u32 length: fsverity descriptor size
- * 6) u8 version: fs-verity version
- * 7) u8 hashAlgorithm: hash algorithm to use for the Merkle tree
- * 8) u8 log2BlockSize: log2 of size of data and tree blocks
- * 9) u8 saltSize: byte size of salt
- * 10) u32 signSize: byte size of signature
- * 11) u64 dataSize: byte size of data being signed
- * 12) u8[64] rootHash: merkle tree root hash
- * 13) u8[32] salt: salt used in signing
- * 14) u32 flags
- * 15) u32 reserved
- * 16) u64 treeOffset: merkle tree offset
- * 17) u8[127] reserved
- * 18) u8 csVersion: code sign version
- * 19) u8[] signature: signature after signing the data in byte array representation
- *
- * @since 2023/09/08
- */
-public class ElfSignBlock {
- /**
- * page size in bytes
- */
- public static final int PAGE_SIZE_4K = 4096;
-
- /**
- * Type of MerkleTree
- */
- public static final int MERKLE_TREE_INLINED = 0x2;
-
- private int type = MERKLE_TREE_INLINED;
-
- private int treeLength;
-
- private byte[] merkleTreeWithPadding;
-
- private FsVerityDescriptorWithSign descriptorWithSign;
-
- /**
- * Constructor of ElfSignBlock
- *
- * @param paddingSize padding size before merkle tree
- * @param merkleTreeData merkle tree data
- * @param descriptorWithSign FsVerityDescriptorWithSign object
- */
- public ElfSignBlock(int paddingSize, byte[] merkleTreeData, FsVerityDescriptorWithSign descriptorWithSign) {
- byte[] inMerkleTreeData = new byte[0];
- if (merkleTreeData != null) {
- inMerkleTreeData = merkleTreeData;
- }
- this.treeLength = paddingSize + inMerkleTreeData.length;
- this.merkleTreeWithPadding = new byte[this.treeLength];
- System.arraycopy(inMerkleTreeData, 0, merkleTreeWithPadding, paddingSize, inMerkleTreeData.length);
- this.descriptorWithSign = descriptorWithSign;
- }
-
- private ElfSignBlock(int type, int treeLength, byte[] merkleTreeWithPadding,
- FsVerityDescriptorWithSign descriptorWithSign) {
- this.type = type;
- this.treeLength = treeLength;
- this.merkleTreeWithPadding = merkleTreeWithPadding;
- this.descriptorWithSign = descriptorWithSign;
- }
-
- /**
- * Return the byte size of code sign block
- *
- * @return byte size of code sign block
- */
- public int size() {
- return Integer.BYTES * 2 + merkleTreeWithPadding.length + descriptorWithSign.size();
- }
-
- /**
- * return padding length by the sign block offset
- *
- * @param signBlockOffset sign block offset based on the start of file
- * @return merkle tree raw bytes offset based on the start of file
- */
- public static int computeMerkleTreePaddingLength(long signBlockOffset) {
- return (int) (PAGE_SIZE_4K - (signBlockOffset + Integer.BYTES * 2) % PAGE_SIZE_4K) % PAGE_SIZE_4K;
- }
-
- public byte[] getMerkleTreeWithPadding() {
- return merkleTreeWithPadding;
- }
-
- /**
- * get DataSize
- *
- * @return DataSize
- */
- public long getDataSize() {
- return descriptorWithSign.getFsVerityDescriptor().getFileSize();
- }
-
- /**
- * get TreeOffset
- *
- * @return TreeOffset
- */
- public long getTreeOffset() {
- return descriptorWithSign.getFsVerityDescriptor().getMerkleTreeOffset();
- }
-
- /**
- * get Signature
- *
- * @return Signature
- */
- public byte[] getSignature() {
- return descriptorWithSign.getSignature();
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- * @throws FsVerityDigestException if error
- */
- public byte[] toByteArray() throws FsVerityDigestException {
- ByteBuffer bf = ByteBuffer.allocate(size()).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(type);
- bf.putInt(merkleTreeWithPadding.length);
- bf.put(merkleTreeWithPadding);
- bf.put(descriptorWithSign.toByteArray());
- return bf.array();
- }
-
- /**
- * Init the ElfSignBlock by a byte array
- *
- * @param bytes Byte array representation of a ElfSignBlock object
- * @return a newly created ElfSignBlock object
- * @throws VerifyCodeSignException parse result invalid
- */
- public static ElfSignBlock fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- // after put, rewind is mandatory before get
- bf.rewind();
- int inTreeType = bf.getInt();
- if (MERKLE_TREE_INLINED != inTreeType) {
- throw new VerifyCodeSignException("Invalid merkle tree type of ElfSignBlock");
- }
- int inTreeLength = bf.getInt();
- byte[] treeWithPadding = new byte[inTreeLength];
- bf.get(treeWithPadding);
- int inFsdType = bf.getInt();
- if (FsVerityDescriptor.FS_VERITY_DESCRIPTOR_TYPE != inFsdType) {
- throw new VerifyCodeSignException("Invalid fs-verify descriptor type of ElfSignBlock");
- }
- int inFsdLength = bf.getInt();
- if (bytes.length != Integer.BYTES * 2 + inTreeLength + Integer.BYTES * 2 + inFsdLength) {
- throw new VerifyCodeSignException("Invalid fs-verify descriptor with signature length of ElfSignBlock");
- }
- byte[] fsdArray = new byte[FsVerityDescriptor.DESCRIPTOR_SIZE];
- bf.get(fsdArray);
- FsVerityDescriptor fsd = FsVerityDescriptor.fromByteArray(fsdArray);
- if (inFsdLength != fsd.getSignSize() + FsVerityDescriptor.DESCRIPTOR_SIZE) {
- throw new VerifyCodeSignException("Invalid sign size of ElfSignBlock");
- }
- byte[] inSignature = new byte[inFsdLength - FsVerityDescriptor.DESCRIPTOR_SIZE];
- bf.get(inSignature);
- FsVerityDescriptorWithSign fsVerityDescriptorWithSign = new FsVerityDescriptorWithSign(inFsdType, inFsdLength,
- fsd, inSignature);
- return new ElfSignBlock(inTreeType, inTreeLength, treeWithPadding, fsVerityDescriptorWithSign);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/Extension.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/Extension.java
deleted file mode 100644
index 2d23c548812465c6419fea07d40299268c9121cb..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/Extension.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Locale;
-
-/**
- * Extension is an optional field in relative to SignInfo.
- * It is the base class for all types of extensions, i.e. MerkleTreeExtension.
- *
- * Structure:
- * u32 type: Indicates the type of extension
- *
- * u32 size: byte size of extension data
- *
- * @since 2023/09/08
- */
-public class Extension {
- /**
- * Byte size of Extension base class.
- */
- public static final int EXTENSION_HEADER_SIZE = 8;
-
- private final int type;
-
- private final int size;
-
- public Extension(int type, int size) {
- this.type = type;
- this.size = size;
- }
-
- public int size() {
- return EXTENSION_HEADER_SIZE;
- }
-
- public boolean isType(int type) {
- return this.type == type;
- }
-
- /**
- * Converts Extension to a newly created byte array
- *
- * @return Byte array representation of Extension
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(EXTENSION_HEADER_SIZE).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(this.type);
- bf.putInt(this.size);
- return bf.array();
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT, "Extension: type[%d], size[%d]", this.type, this.size);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/FsVerityInfoSegment.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/FsVerityInfoSegment.java
deleted file mode 100644
index 117431cf1dbb769c4f3757d3f0c955824e574cfd..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/FsVerityInfoSegment.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityDescriptor;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityGenerator;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Locale;
-
-/**
- * Fs-verity info segment contains information of fs-verity protection
- * More information of fs-verity can be found here
- *
- * Structure
- *
- * 1) u32 magic: magic number
- *
- * 2) u8 version: fs-verity version
- *
- * 3) u8 hashAlgorithm: hash algorithm to use for the Merkle tree
- *
- * 4) u8 log2BlockSize: log2 of size of data and tree blocks
- *
- * 5) u8[] reserved: for reservation
- *
- * @since 2023/09/08
- */
-public class FsVerityInfoSegment {
- /**
- * fs-verity info segment size in bytes
- */
- public static final int FS_VERITY_INFO_SEGMENT_SIZE = 64;
-
- // lower 4 bytes of the MD5 result of string "fs-verity info segment" (1E38 31AB)
- private static final int MAGIC = (0x1E38 << 16) + (0x31AB);
-
- private static final int RESERVED_BYTE_ARRAY_LENGTH = 57;
-
- private int magic = MAGIC;
-
- private byte hashAlgorithm;
-
- private byte version;
-
- private byte log2BlockSize;
-
- private byte[] reserved = new byte[RESERVED_BYTE_ARRAY_LENGTH];
-
- /**
- * Default constructor
- */
- public FsVerityInfoSegment() {
- }
-
- public FsVerityInfoSegment(byte version, byte hashAlgorithm, byte log2BlockSize) {
- this(MAGIC, version, hashAlgorithm, log2BlockSize, new byte[RESERVED_BYTE_ARRAY_LENGTH]);
- }
-
- /**
- * Constructor of FsVerityInfoSegment
- *
- * @param magic magic num
- * @param version version of fs-verity
- * @param hashAlgorithm hash algorithm to use for the Merkle tree
- * @param log2BlockSize log2 of size of data and tree blocks
- * @param reserved for reservation
- */
- public FsVerityInfoSegment(int magic, byte version, byte hashAlgorithm, byte log2BlockSize, byte[] reserved) {
- this.magic = magic;
- this.version = version;
- this.hashAlgorithm = hashAlgorithm;
- this.log2BlockSize = log2BlockSize;
- this.reserved = reserved;
- }
-
- public int size() {
- return FS_VERITY_INFO_SEGMENT_SIZE;
- }
-
- /**
- * Converts FsVerityInfoSegment to a newly created byte array
- *
- * @return Byte array representation of FsVerityInfoSegment
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(FS_VERITY_INFO_SEGMENT_SIZE).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(this.magic);
- bf.put(version);
- bf.put(hashAlgorithm);
- bf.put(log2BlockSize);
- bf.put(reserved);
- return bf.array();
- }
-
- /**
- * Init the FsVerityInfoSegment by a byte array
- *
- * @param bytes Byte array representation of a FsVerityInfoSegment object
- * @return a newly created FsVerityInfoSegment object
- * @throws VerifyCodeSignException parsing result invalid
- */
- public static FsVerityInfoSegment fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- if (bytes.length != FS_VERITY_INFO_SEGMENT_SIZE) {
- throw new VerifyCodeSignException("Invalid size of FsVerityInfoSegment");
- }
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- int inMagic = bf.getInt();
- if (inMagic != MAGIC) {
- throw new VerifyCodeSignException("Invalid magic number of FsVerityInfoSegment");
- }
- byte inVersion = bf.get();
- if (inVersion != FsVerityDescriptor.VERSION) {
- throw new VerifyCodeSignException("Invalid version of FsVerityInfoSegment");
- }
- byte inHashAlgorithm = bf.get();
- if (inHashAlgorithm != FsVerityGenerator.getFsVerityHashAlgorithm()) {
- throw new VerifyCodeSignException("Invalid hashAlgorithm of FsVerityInfoSegment");
- }
- byte inLog2BlockSize = bf.get();
- if (inLog2BlockSize != FsVerityGenerator.getLog2BlockSize()) {
- throw new VerifyCodeSignException("Invalid log2BlockSize of FsVerityInfoSegment");
- }
- byte[] inReservedBytes = new byte[RESERVED_BYTE_ARRAY_LENGTH];
- bf.get(inReservedBytes);
- return new FsVerityInfoSegment(inMagic, inVersion, inHashAlgorithm, inLog2BlockSize, inReservedBytes);
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT, "FsVerityInfoSeg: magic[%d], version[%d], hashAlg[%d], log2BlockSize[%d]",
- this.magic, this.version, this.hashAlgorithm, this.log2BlockSize);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/HapInfoSegment.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/HapInfoSegment.java
deleted file mode 100644
index 2697ea7af826915595ec20b941f6dec06f82f964..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/HapInfoSegment.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Locale;
-
-/**
- * Hap info segment
- *
- * Structure
- *
- * 1) u32 magic: magic number
- *
- * 2) SignInfo hapSignInfo: data struct of sign info, refer to SignInfo.java
- *
- * @since 2023/09/08
- */
-public class HapInfoSegment {
- private static final int MAGIC_NUM_BYTES = 4;
-
- /**
- * lower 4 bytes of the MD5 result of string "hap info segment" (C1B5 CC66)
- */
- private static final int MAGIC_NUM = (0xC1B5 << 16) + 0xCC66;
-
- private int magic = MAGIC_NUM;
-
- private SignInfo hapSignInfo;
-
- /**
- * Default constructor of HapInfoSegment
- */
- public HapInfoSegment() {
- this(MAGIC_NUM, new SignInfo(0, 0, 0, null, null));
- }
-
- /**
- * Default constructor of HapInfoSegment
- *
- * @param magic magic number
- * @param hapSignInfo hap sign info
- */
- public HapInfoSegment(int magic, SignInfo hapSignInfo) {
- this.magic = magic;
- this.hapSignInfo = hapSignInfo;
- }
-
- public void setSignInfo(SignInfo signInfo) {
- this.hapSignInfo = signInfo;
- }
-
- public SignInfo getSignInfo() {
- return hapSignInfo;
- }
-
- /**
- * Returns byte size of HapInfoSegment
- *
- * @return byte size of HapInfoSegment
- */
- public int size() {
- return MAGIC_NUM_BYTES + hapSignInfo.size();
- }
-
- /**
- * Converts HapInfoSegment to a newly created byte array
- *
- * @return Byte array representation of HapInfoSegment
- */
- public byte[] toByteArray() {
- byte[] hapSignInfoByteArray = this.hapSignInfo.toByteArray();
- // For now, only hap info segment has a merkle tree extension. So info segment
- // has none extension.
- ByteBuffer bf = ByteBuffer.allocate(MAGIC_NUM_BYTES + hapSignInfoByteArray.length)
- .order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(magic);
- bf.put(hapSignInfoByteArray);
- return bf.array();
- }
-
- /**
- * Init the HapInfoSegment by a byte array
- *
- * @param bytes Byte array representation of a HapInfoSegment object
- * @return a newly created HapInfoSegment object
- * @throws VerifyCodeSignException parsing result invalid
- */
- public static HapInfoSegment fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- int inMagic = bf.getInt();
- if (inMagic != MAGIC_NUM) {
- throw new VerifyCodeSignException("Invalid magic number of HapInfoSegment");
- }
- if (bytes.length <= MAGIC_NUM_BYTES) {
- throw new VerifyCodeSignException("Invalid bytes size of HapInfoSegment");
- }
- byte[] hapSignInfoByteArray = new byte[bytes.length - MAGIC_NUM_BYTES];
- bf.get(hapSignInfoByteArray);
- SignInfo inHapSignInfo = SignInfo.fromByteArray(hapSignInfoByteArray);
- if (inHapSignInfo.getDataSize() % CodeSignBlock.PAGE_SIZE_4K != 0) {
- throw new VerifyCodeSignException(
- String.format(Locale.ROOT, "Invalid dataSize number of HapInfoSegment, not a multiple of 4096: %d",
- inHapSignInfo.getDataSize()));
- }
- if (inHapSignInfo.getExtensionNum() != SignInfo.MAX_EXTENSION_NUM) {
- throw new VerifyCodeSignException("Invalid extensionNum of HapInfoSegment");
- }
- if (inHapSignInfo.getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED) == null) {
- throw new VerifyCodeSignException("No merkle tree extension is found in HapInfoSegment");
- }
- return new HapInfoSegment(inMagic, inHapSignInfo);
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT, "HapInfoSegment: magic[%d], signInfo[%s]", this.magic,
- this.hapSignInfo.toString());
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/MerkleTreeExtension.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/MerkleTreeExtension.java
deleted file mode 100644
index 303d92edf13effedc56dec7605e4b2c3bd5aa908..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/MerkleTreeExtension.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.Locale;
-
-/**
- * Merkle tree extension is a type of Extension to store a merkle tree's information, i.e. size and root hash, ect.
- *
- * structure
- *
- * 1) u32 type
- *
- * 2) u64 merkleTreeSize: the size of merkle tree
- *
- * 3) u64 merkleTreeOffset: offset of the merkle tree by the start of the file.
- *
- * 4) u8[64] rootHash: merkle tree root hash
- *
- * @since 2023/09/08
- */
-public class MerkleTreeExtension extends Extension {
- /**
- * Type of MerkleTreeExtension
- */
- public static final int MERKLE_TREE_INLINED = 0x1;
-
- /**
- * Byte size of MerkleTreeExtension including merkleTreeSize, offset and root hash.
- */
- public static final int MERKLE_TREE_EXTENSION_DATA_SIZE = 80;
-
- private static final int ROOT_HASH_SIZE = 64;
-
- private final long merkleTreeSize;
-
- private long merkleTreeOffset;
-
- private byte[] rootHash;
-
- /**
- * Constructor for MerkleTreeExtension
- *
- * @param merkleTreeSize Byte array representation of merkle tree
- * @param merkleTreeOffset merkle tree offset based on file start
- * @param rootHash Root hash of the merkle tree
- */
- public MerkleTreeExtension(long merkleTreeSize, long merkleTreeOffset, byte[] rootHash) {
- super(MERKLE_TREE_INLINED, MERKLE_TREE_EXTENSION_DATA_SIZE);
- this.merkleTreeSize = merkleTreeSize;
- this.merkleTreeOffset = merkleTreeOffset;
- if (rootHash == null) {
- this.rootHash = new byte[ROOT_HASH_SIZE];
- } else {
- this.rootHash = Arrays.copyOf(rootHash, ROOT_HASH_SIZE);
- }
- }
-
- @Override
- public int size() {
- return Extension.EXTENSION_HEADER_SIZE + MERKLE_TREE_EXTENSION_DATA_SIZE;
- }
-
- public long getMerkleTreeSize() {
- return merkleTreeSize;
- }
-
- public long getMerkleTreeOffset() {
- return merkleTreeOffset;
- }
-
- public void setMerkleTreeOffset(long offset) {
- this.merkleTreeOffset = offset;
- }
-
- /**
- * Converts MerkleTreeExtension to a newly created byte array
- *
- * @return Byte array representation of MerkleTreeExtension
- */
- @Override
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(Extension.EXTENSION_HEADER_SIZE + MERKLE_TREE_EXTENSION_DATA_SIZE)
- .order(ByteOrder.LITTLE_ENDIAN);
- bf.put(super.toByteArray());
- bf.putLong(this.merkleTreeSize);
- bf.putLong(this.merkleTreeOffset);
- bf.put(this.rootHash);
- return bf.array();
- }
-
- /**
- * Init the MerkleTreeExtension by a byte array
- *
- * @param bytes Byte array representation of a MerkleTreeExtension object
- * @return a newly created MerkleTreeExtension object
- * @throws VerifyCodeSignException parsing result invalid
- */
- public static MerkleTreeExtension fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- long inMerkleTreeSize = bf.getLong();
- if (inMerkleTreeSize % CodeSignBlock.PAGE_SIZE_4K != 0) {
- throw new VerifyCodeSignException("merkleTreeSize is not a multiple of 4096");
- }
- long inMerkleTreeOffset = bf.getLong();
- if (inMerkleTreeOffset % CodeSignBlock.PAGE_SIZE_4K != 0) {
- throw new VerifyCodeSignException("merkleTreeOffset is not a aligned to 4096");
- }
- byte[] inRootHash = new byte[ROOT_HASH_SIZE];
- bf.get(inRootHash);
- return new MerkleTreeExtension(inMerkleTreeSize, inMerkleTreeOffset, inRootHash);
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- @Override
- public String toString() {
- return String.format(Locale.ROOT, "MerkleTreeExtension: merkleTreeSize[%d], merkleTreeOffset[%d],"
- + " rootHash[%s]", this.merkleTreeSize, this.merkleTreeOffset, Arrays.toString(this.rootHash));
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/NativeLibInfoSegment.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/NativeLibInfoSegment.java
deleted file mode 100644
index e7bcfc49d5db540dc34409db85df2d714e71584a..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/NativeLibInfoSegment.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-import com.ohos.hapsigntool.hap.entity.Pair;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * SoInfoSegment consists of a header part:
- *
- * u32 magic: magic number
- *
- * u32 length: byte size of SoInfoSegment
- *
- * u32 section num: the amount of file being signed
- *
- * Followed by an area containing the offset and size of each file being signed with its signed info:
- *
- * u32 file name offset: position of file name based on the start of SoInfoSegment
- *
- * u32 file name size : byte size of file name string
- *
- * u32 sign info offset : position of signed info based on the start of SoInfoSegment
- *
- * u32 sign size: byte size of signed info
- *
- * Ends with the file name and signed info content:
- *
- * file name List : file name of each signed file
- *
- * sign info List : signed info of each file
- *
- *
- * @since 2023/09/08
- */
-public class NativeLibInfoSegment {
- private static final int MAGIC_LENGTH_SECNUM_BYTES = 12;
-
- private static final int SIGNED_FILE_POS_SIZE = 16;
-
- // lower 4 bytes of the MD5 result of string "native lib info segment" (0ED2 E720)
- private static final int MAGIC_NUM = (0x0ED2 << 16) + 0xE720;
-
- private static final int ALIGNMENT_FOR_SIGNINFO = 4;
-
- private int magic;
-
- private int segmentSize;
-
- private int sectionNum;
-
- private List> soInfoList = new ArrayList<>();
-
- private List signedFilePosList;
-
- private List fileNameList;
-
- private List signInfoList;
-
- private byte[] zeroPadding;
-
- private int fileNameListBlockSize;
-
- private int signInfoListBlockSize;
-
- /**
- * Constructor for SoInfoSegment
- *
- * @param builder Builder
- */
- private NativeLibInfoSegment(Builder builder) {
- this.magic = builder.magic;
- this.segmentSize = builder.segmentSize;
- this.sectionNum = builder.sectionNum;
- this.signedFilePosList = builder.signedFilePosList;
- this.fileNameList = builder.fileNameList;
- this.signInfoList = builder.signInfoList;
- this.zeroPadding = builder.zeroPadding;
- }
-
- /**
- * set soInfoList, generate fileNameList and soInfoList
- *
- * @param soInfoList list of file and its signed info
- */
- public void setSoInfoList(List> soInfoList) {
- this.soInfoList = soInfoList;
- // Once map is set, update length, sectionNum as well
- this.sectionNum = soInfoList.size();
- // generate file name list and sign info list
- generateList();
- }
-
- public int getSectionNum() {
- return sectionNum;
- }
-
- public List getFileNameList() {
- return fileNameList;
- }
-
- public List getSignInfoList() {
- return signInfoList;
- }
-
- // generate List based on current so
- private void generateList() {
- // empty all before generate list
- this.fileNameList.clear();
- this.signInfoList.clear();
- this.signedFilePosList.clear();
- int fileNameOffset = 0;
- int signInfoOffset = 0;
- for (Pair soInfo : soInfoList) {
- String fileName = soInfo.getFirst();
- SignInfo signInfo = soInfo.getSecond();
- int fileNameSizeInBytes = fileName.getBytes(StandardCharsets.UTF_8).length;
- int signInfoSizeInBytes = signInfo.toByteArray().length;
- this.fileNameList.add(fileName);
- this.signInfoList.add(signInfo);
- this.signedFilePosList.add(
- new SignedFilePos(fileNameOffset, fileNameSizeInBytes, signInfoOffset, signInfoSizeInBytes));
- // increase fileNameOffset and signInfoOffset
- fileNameOffset += fileNameSizeInBytes;
- signInfoOffset += signInfoSizeInBytes;
- }
- this.fileNameListBlockSize = fileNameOffset;
- this.signInfoListBlockSize = signInfoOffset;
- // alignment for signInfo
- this.zeroPadding = new byte[(ALIGNMENT_FOR_SIGNINFO - this.fileNameListBlockSize % ALIGNMENT_FOR_SIGNINFO)
- % ALIGNMENT_FOR_SIGNINFO];
- // after fileNameList and signInfoList is generated, update segment size
- this.segmentSize = this.size();
- // adjust file name and sign info offset base on segment start
- int fileNameOffsetBase = MAGIC_LENGTH_SECNUM_BYTES + signedFilePosList.size() * SIGNED_FILE_POS_SIZE;
- int signInfoOffsetBase = fileNameOffsetBase + this.fileNameListBlockSize;
- for (SignedFilePos pos : this.signedFilePosList) {
- pos.increaseFileNameOffset(fileNameOffsetBase);
- pos.increaseSignInfoOffset(signInfoOffsetBase + this.zeroPadding.length);
- }
- }
-
- /**
- * Returns byte size of SoInfoSegment
- *
- * @return byte size of SoInfoSegment
- */
- public int size() {
- int blockSize = MAGIC_LENGTH_SECNUM_BYTES;
- blockSize += signedFilePosList.size() * SIGNED_FILE_POS_SIZE;
- blockSize += this.fileNameListBlockSize + this.zeroPadding.length + this.signInfoListBlockSize;
- return blockSize;
- }
-
- /**
- * Converts SoInfoSegment to a newly created byte array
- *
- * @return Byte array representation of SoInfoSegment
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(this.size()).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(magic);
- bf.putInt(segmentSize);
- bf.putInt(sectionNum);
- for (SignedFilePos offsetAndSize : this.signedFilePosList) {
- bf.putInt(offsetAndSize.getFileNameOffset());
- bf.putInt(offsetAndSize.getFileNameSize());
- bf.putInt(offsetAndSize.getSignInfoOffset());
- bf.putInt(offsetAndSize.getSignInfoSize());
- }
- for (String fileName : fileNameList) {
- bf.put(fileName.getBytes(StandardCharsets.UTF_8));
- }
- bf.put(this.zeroPadding);
- for (SignInfo signInfo : signInfoList) {
- bf.put(signInfo.toByteArray());
- }
- return bf.array();
- }
-
- /**
- * Init the SoInfoSegment by a byte array
- *
- * @param bytes Byte array representation of a SoInfoSegment object
- * @return a newly created NativeLibInfoSegment object
- * @throws VerifyCodeSignException parsing result invalid
- */
- public static NativeLibInfoSegment fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- int inMagic = bf.getInt();
- if (inMagic != MAGIC_NUM) {
- throw new VerifyCodeSignException("Invalid magic number of NativeLibInfoSegment");
- }
- int inSegmentSize = bf.getInt();
- if (inSegmentSize < 0) {
- throw new VerifyCodeSignException("Invalid segmentSize of NativeLibInfoSegment");
- }
- int inSectionNum = bf.getInt();
- if (inSectionNum < 0) {
- throw new VerifyCodeSignException("Invalid sectionNum of NativeLibInfoSegment");
- }
- List inSignedFilePosList = new ArrayList<>();
- for (int i = 0; i < inSectionNum; i++) {
- byte[] entry = new byte[SIGNED_FILE_POS_SIZE];
- bf.get(entry);
- inSignedFilePosList.add(SignedFilePos.fromByteArray(entry));
- }
- // parse file name list
- List inFileNameList = new ArrayList<>();
- int fileNameListSize = 0;
- for (SignedFilePos pos : inSignedFilePosList) {
- byte[] fileNameBuffer = new byte[pos.getFileNameSize()];
- fileNameListSize += pos.getFileNameSize();
- bf.get(fileNameBuffer);
- inFileNameList.add(new String(fileNameBuffer, StandardCharsets.UTF_8));
- }
- // parse zeroPadding
- byte[] inZeroPadding = new byte[(ALIGNMENT_FOR_SIGNINFO - fileNameListSize % ALIGNMENT_FOR_SIGNINFO)
- % ALIGNMENT_FOR_SIGNINFO];
- bf.get(inZeroPadding);
- // parse sign info list
- List inSignInfoList = new ArrayList<>();
- for (SignedFilePos pos : inSignedFilePosList) {
- if (pos.getSignInfoOffset() % ALIGNMENT_FOR_SIGNINFO != 0) {
- throw new VerifyCodeSignException("SignInfo not aligned in NativeLibInfoSegment");
- }
- byte[] signInfoBuffer = new byte[pos.getSignInfoSize()];
- bf.get(signInfoBuffer);
- inSignInfoList.add(SignInfo.fromByteArray(signInfoBuffer));
- }
- return new Builder().setMagic(inMagic).setSegmentSize(inSegmentSize).setSectionNum(inSectionNum)
- .setSignedFilePosList(inSignedFilePosList).setFileNameList(inFileNameList)
- .setSignInfoList(inSignInfoList).setZeroPadding(inZeroPadding).build();
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT,
- "SoInfoSegment: magic[%d], length[%d], secNum[%d], signedFileEntryList[%s], fileNameList[%s], "
- + "zeroPadding[%s], signInfoList[%s]", this.magic, this.segmentSize, this.sectionNum,
- Arrays.toString(this.signedFilePosList.toArray()), Arrays.toString(this.fileNameList.toArray()),
- Arrays.toString(this.zeroPadding), Arrays.toString(this.signInfoList.toArray()));
- }
-
- /**
- * Builder of NativeLibInfoSegment class
- */
- public static class Builder {
- private int magic = MAGIC_NUM;
-
- private int segmentSize;
-
- private int sectionNum;
-
- private List signedFilePosList = new ArrayList<>();
-
- private List fileNameList = new ArrayList<>();
-
- private List signInfoList = new ArrayList<>();
-
- private byte[] zeroPadding = new byte[0];
-
- public Builder setMagic(int magic) {
- this.magic = magic;
- return this;
- }
-
- public Builder setSegmentSize(int segmentSize) {
- this.segmentSize = segmentSize;
- return this;
- }
-
- public Builder setSectionNum(int sectionNum) {
- this.sectionNum = sectionNum;
- return this;
- }
-
- public Builder setSignedFilePosList(List signedFilePosList) {
- this.signedFilePosList = signedFilePosList;
- return this;
- }
-
- public Builder setFileNameList(List fileNameList) {
- this.fileNameList = fileNameList;
- return this;
- }
-
- public Builder setSignInfoList(List signInfoList) {
- this.signInfoList = signInfoList;
- return this;
- }
-
- public Builder setZeroPadding(byte[] zeroPadding) {
- this.zeroPadding = zeroPadding;
- return this;
- }
-
- /**
- * Create a NativeLibInfoSegment object
- *
- * @return a NativeLibInfoSegment object
- */
- public NativeLibInfoSegment build() {
- return new NativeLibInfoSegment(this);
- }
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SegmentHeader.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SegmentHeader.java
deleted file mode 100644
index 975dda21553f8f8687784640839fc365852615de..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SegmentHeader.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Locale;
-
-/**
- * segment header has three field:
- *
- * u32 type: indicates the type of segment: fs-verity/so/hap info segment
- *
- * u32 segment offset: the segment position based on the start of code sign block
- *
- * u32 segment size: byte size of the segment
- *
- * @since 2023/09/08
- */
-public class SegmentHeader {
- /**
- * Byte size of SegmentHeader
- */
- public static final int SEGMENT_HEADER_LENGTH = 12;
-
- /**
- * Fs-verity segment type
- */
- public static final int CSB_FSVERITY_INFO_SEG = 0x1;
-
- /**
- * Hap info segment type
- */
- public static final int CSB_HAP_META_SEG = 0x2;
-
- /**
- * So info segment type
- */
- public static final int CSB_NATIVE_LIB_INFO_SEG = 0x3;
-
- private final int type;
-
- private int segmentOffset;
-
- private final int segmentSize;
-
- /**
- * Constructor for SegmentHeader
- *
- * @param type segment type
- * @param segmentSize byte size of the segment
- */
- public SegmentHeader(int type, int segmentSize) {
- this(type, 0, segmentSize);
- }
-
- /**
- * Constructor for SegmentHeader
- *
- * @param type segment type
- * @param segmentOffset segment offset based on the start of code sign block
- * @param segmentSize byte size of segment
- */
- public SegmentHeader(int type, int segmentOffset, int segmentSize) {
- this.type = type;
- this.segmentOffset = segmentOffset;
- this.segmentSize = segmentSize;
- }
-
- public int getType() {
- return type;
- }
-
- public void setSegmentOffset(int offset) {
- this.segmentOffset = offset;
- }
-
- public int getSegmentOffset() {
- return segmentOffset;
- }
-
- public int getSegmentSize() {
- return segmentSize;
- }
-
- /**
- * Converts SegmentHeader to a newly created byte array
- *
- * @return Byte array representation of SegmentHeader
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(SEGMENT_HEADER_LENGTH).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(type);
- bf.putInt(segmentOffset);
- bf.putInt(segmentSize);
- return bf.array();
- }
-
- /**
- * Init the SegmentHeader by a byte array
- *
- * @param bytes Byte array representation of a SegmentHeader object
- * @return a newly created SegmentHeader object
- * @throws VerifyCodeSignException parsing result invalid
- */
- public static SegmentHeader fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- if (bytes.length != SEGMENT_HEADER_LENGTH) {
- throw new VerifyCodeSignException("Invalid size of SegmentHeader");
- }
- ByteBuffer bf = ByteBuffer.allocate(SEGMENT_HEADER_LENGTH).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- int inType = bf.getInt();
- if ((inType != CSB_FSVERITY_INFO_SEG) && (inType != CSB_HAP_META_SEG) && (inType != CSB_NATIVE_LIB_INFO_SEG)) {
- throw new VerifyCodeSignException("Invalid type of SegmentHeader");
- }
- int inSegmentOffset = bf.getInt();
- // segment offset is always larger than the size of CodeSignBlockHeader
- if (inSegmentOffset < CodeSignBlockHeader.size()) {
- throw new VerifyCodeSignException("Invalid segmentOffset of SegmentHeader");
- }
- int inSegmentSize = bf.getInt();
- if (inSegmentSize < 0) {
- throw new VerifyCodeSignException("Invalid segmentSize of SegmentHeader");
- }
- if ((inType == CSB_FSVERITY_INFO_SEG) && (inSegmentSize != FsVerityInfoSegment.FS_VERITY_INFO_SEGMENT_SIZE)) {
- throw new VerifyCodeSignException("Invalid segmentSize of fs-verity SegmentHeader");
- }
- return new SegmentHeader(inType, inSegmentOffset, inSegmentSize);
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT, "Segment Header: type=%d, seg_offset = %d, seg_size = %d", this.type,
- this.segmentOffset, this.segmentSize);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SignInfo.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SignInfo.java
deleted file mode 100644
index e2d538c4f3dc2cd6d05518caf9240c7be54b9d50..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SignInfo.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Sign info represents information after signing a file, including signature, merkle tree.
- * Structure:
- *
- * 1) u32 saltSize: byte size of salt
- *
- * 2) u32 sigSize: byte size of signature
- *
- * 3) u32 flags: reserved flags
- *
- * 4) u64 dataSize: byte size of data being signed
- *
- * 5) u8[32] salt: salt used in signing
- *
- * 6) u32 extensionNum: number of extension
- *
- * 7) u32 extensionOffset
- *
- * 8) u8[] signature: signature of the data
- *
- * MerkleTree is represented as an extension of the sign info.
- * Its structure is defined in MerkleTreeExtension.java
- *
- * @since 2023/09/08
- */
-public class SignInfo {
- /**
- * merkle tree extension is included in sign info
- */
- public static final int FLAG_MERKLE_TREE_INCLUDED = 0x1;
-
- /**
- * maximum of extension number
- */
- public static final int MAX_EXTENSION_NUM = 1;
-
- /**
- * sign info structure without signature in bytes, refer to toByteArray() method
- */
- private static final int SIGN_INFO_SIZE_WITHOUT_SIGNATURE = 60;
-
- private static final int SALT_BUFFER_LENGTH = 32;
-
- private static final int SIGNATURE_ALIGNMENT = 4;
-
- private int saltSize;
-
- private int sigSize;
-
- private int flags;
-
- private long dataSize;
-
- private byte[] salt;
-
- private int extensionNum;
-
- private int extensionOffset;
-
- private byte[] signature;
-
- private byte[] zeroPadding;
-
- // temporary, use list instead
- private List extensionList = new ArrayList<>();
-
- /**
- * Constructor for SignInfo
- *
- * @param saltSize byte size of salt
- * @param flags reserved flags
- * @param dataSize byte size of data being signed
- * @param salt salt in byte array representation
- * @param sig signature after signing the data in byte array representation
- */
- public SignInfo(int saltSize, int flags, long dataSize, byte[] salt, byte[] sig) {
- this.saltSize = saltSize;
- this.flags = flags;
- this.dataSize = dataSize;
- if (salt == null) {
- this.salt = new byte[SALT_BUFFER_LENGTH];
- } else {
- this.salt = salt;
- }
- this.signature = sig;
- this.sigSize = sig == null ? 0 : sig.length;
- // align for extension after signature
- this.zeroPadding = new byte[(SIGNATURE_ALIGNMENT - (this.sigSize % SIGNATURE_ALIGNMENT)) % SIGNATURE_ALIGNMENT];
- }
-
- /**
- * Constructor by a SignInfoBuilder
- *
- * @param builder SignInfoBuilder
- */
- private SignInfo(SignInfoBuilder builder) {
- this.saltSize = builder.saltSize;
- this.sigSize = builder.sigSize;
- this.flags = builder.flags;
- this.dataSize = builder.dataSize;
- this.salt = builder.salt;
- this.extensionNum = builder.extensionNum;
- this.extensionOffset = builder.extensionOffset;
- this.signature = builder.signature;
- this.zeroPadding = builder.zeroPadding;
- this.extensionList = builder.extensionList;
- }
-
- /**
- * Add one Extension into SignInfo Object
- *
- * @param extension Extension object
- */
- public void addExtension(Extension extension) {
- this.extensionOffset = this.size();
- this.extensionList.add(extension);
- this.extensionNum = this.extensionList.size();
- }
-
- /**
- * Get Extension from SignInfo based on extension type
- *
- * @param type extension type
- * @return Extension object
- */
- public Extension getExtensionByType(int type) {
- for (Extension ext : this.extensionList) {
- if (ext.isType(type)) {
- return ext;
- }
- }
- return null;
- }
-
- /**
- * Returns extensionNum
- *
- * @return extensionNum
- */
- public int getExtensionNum() {
- return extensionNum;
- }
-
- public byte[] getSignature() {
- return signature;
- }
-
- public long getDataSize() {
- return dataSize;
- }
-
- /**
- * Returns byte size of SignInfo object
- *
- * @return byte size of SignInfo object
- */
- public int size() {
- int blockSize = SIGN_INFO_SIZE_WITHOUT_SIGNATURE + this.signature.length + this.zeroPadding.length;
- for (Extension ext : this.extensionList) {
- blockSize += ext.size();
- }
- return blockSize;
- }
-
- /**
- * Converts SignInfo to a newly created byte array
- *
- * @return Byte array representation of SignInfo
- */
- public byte[] toByteArray() {
- ByteBuffer bf = ByteBuffer.allocate(this.size()).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(this.saltSize);
- bf.putInt(this.sigSize);
- bf.putInt(this.flags);
- bf.putLong(this.dataSize);
- bf.put(this.salt);
- bf.putInt(this.extensionNum);
- bf.putInt(this.extensionOffset);
- bf.put(this.signature);
- bf.put(this.zeroPadding);
- // put extension
- for (Extension ext : this.extensionList) {
- bf.put(ext.toByteArray());
- }
- return bf.array();
- }
-
- /**
- * Init the SignInfo by a byte array
- *
- * @param bytes Byte array representation of a SignInfo object
- * @return a newly created SignInfo object
- * @throws VerifyCodeSignException parsing result invalid
- */
- public static SignInfo fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- int inSaltSize = bf.getInt();
- if (inSaltSize < 0) {
- throw new VerifyCodeSignException("Invalid saltSize of SignInfo");
- }
- int inSigSize = bf.getInt();
- if (inSigSize < 0) {
- throw new VerifyCodeSignException("Invalid sigSize of SignInfo");
- }
- int inFlags = bf.getInt();
- if (inFlags != 0 && inFlags != FLAG_MERKLE_TREE_INCLUDED) {
- throw new VerifyCodeSignException("Invalid flags of SignInfo");
- }
- long inDataSize = bf.getLong();
- if (inDataSize < 0) {
- throw new VerifyCodeSignException("Invalid dataSize of SignInfo");
- }
- byte[] inSalt = new byte[SALT_BUFFER_LENGTH];
- bf.get(inSalt);
- int inExtensionNum = bf.getInt();
- if (inExtensionNum < 0 || inExtensionNum > MAX_EXTENSION_NUM) {
- throw new VerifyCodeSignException("Invalid extensionNum of SignInfo");
- }
- int inExtensionOffset = bf.getInt();
- if (inExtensionOffset < 0 || inExtensionOffset % 4 != 0) {
- throw new VerifyCodeSignException("Invalid extensionOffset of SignInfo");
- }
- byte[] inSignature = new byte[inSigSize];
- bf.get(inSignature);
- byte[] inZeroPadding = new byte[(SIGNATURE_ALIGNMENT - (inSigSize % SIGNATURE_ALIGNMENT))
- % SIGNATURE_ALIGNMENT];
- bf.get(inZeroPadding);
- // parse merkle tree extension
- List inExtensionList = parseMerkleTreeExtension(bf, inExtensionNum);
- return new SignInfoBuilder().setSaltSize(inSaltSize)
- .setSigSize(inSigSize)
- .setFlags(inFlags)
- .setDataSize(inDataSize)
- .setSalt(inSalt)
- .setExtensionNum(inExtensionNum)
- .setExtensionOffset(inExtensionOffset)
- .setSignature(inSignature)
- .setZeroPadding(inZeroPadding)
- .setExtensionList(inExtensionList)
- .build();
- }
-
- private static List parseMerkleTreeExtension(ByteBuffer bf, int inExtensionNum)
- throws VerifyCodeSignException {
- List inExtensionList = new ArrayList<>();
- if (inExtensionNum == 1) {
- // parse merkle tree extension
- int extensionType = bf.getInt();
- if (extensionType != MerkleTreeExtension.MERKLE_TREE_INLINED) {
- throw new VerifyCodeSignException("Invalid extensionType of SignInfo");
- }
- int extensionSize = bf.getInt();
- if (extensionSize != MerkleTreeExtension.MERKLE_TREE_EXTENSION_DATA_SIZE) {
- throw new VerifyCodeSignException("Invalid extensionSize of SignInfo");
- }
- byte[] merkleTreeExtension = new byte[MerkleTreeExtension.MERKLE_TREE_EXTENSION_DATA_SIZE];
- bf.get(merkleTreeExtension);
- inExtensionList.add(MerkleTreeExtension.fromByteArray(merkleTreeExtension));
- }
- return inExtensionList;
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- String str = String.format(Locale.ROOT, "SignInfo: saltSize[%d], sigSize[%d],"
- + "flags[%d], dataSize[%d], salt[%s], zeroPad[%s], extNum[%d], extOffset[%d]",
- this.saltSize, this.sigSize, this.flags, this.dataSize, Arrays.toString(this.salt),
- Arrays.toString(this.zeroPadding), this.extensionNum, this.extensionOffset);
- if (this.getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED) != null) {
- str += String.format(Locale.ROOT, "SignInfo.merkleTreeExtension[%s]",
- this.getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED).toString());
- }
- return str;
- }
-
- /**
- * Builder of SignInfo object
- */
- public static class SignInfoBuilder {
- private int saltSize;
-
- private int sigSize;
-
- private int flags;
-
- private long dataSize;
-
- private byte[] salt;
-
- private int extensionNum;
-
- private int extensionOffset;
-
- private byte[] signature;
-
- private byte[] zeroPadding;
-
- // temporary, use list instead
- private List extensionList = new ArrayList<>();
-
- /**
- * set saltSize
- *
- * @param saltSize saltSize
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setSaltSize(int saltSize) {
- this.saltSize = saltSize;
- return this;
- }
-
- /**
- * set sigSize
- *
- * @param sigSize sigSize
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setSigSize(int sigSize) {
- this.sigSize = sigSize;
- return this;
- }
-
- /**
- * set flags
- *
- * @param flags flags
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setFlags(int flags) {
- this.flags = flags;
- return this;
- }
-
- /**
- * set dataSize
- *
- * @param dataSize dataSize
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setDataSize(long dataSize) {
- this.dataSize = dataSize;
- return this;
- }
-
- /**
- * set salt
- *
- * @param salt salt
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setSalt(byte[] salt) {
- this.salt = salt;
- return this;
- }
-
- /**
- * set extensionNum
- *
- * @param extensionNum extensionNum
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setExtensionNum(int extensionNum) {
- this.extensionNum = extensionNum;
- return this;
- }
-
- /**
- * set extensionOffset
- *
- * @param extensionOffset extensionOffset
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setExtensionOffset(int extensionOffset) {
- this.extensionOffset = extensionOffset;
- return this;
- }
-
- /**
- * set signature
- *
- * @param signature signature
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setSignature(byte[] signature) {
- this.signature = signature;
- return this;
- }
-
- /**
- * set zeroPadding
- *
- * @param zeroPadding zeroPadding
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setZeroPadding(byte[] zeroPadding) {
- this.zeroPadding = zeroPadding;
- return this;
- }
-
- /**
- * set extensionList
- *
- * @param extensionList extensionList
- * @return SignInfoBuilder
- */
- public SignInfoBuilder setExtensionList(List extensionList) {
- this.extensionList = extensionList;
- return this;
- }
-
- /**
- * return a SignInfo object
- *
- * @return SignInfo object
- */
- public SignInfo build() {
- return new SignInfo(this);
- }
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SignedFilePos.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SignedFilePos.java
deleted file mode 100644
index 6b2eb33593798e0390b476cbf13ea72e6a12ad39..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/datastructure/SignedFilePos.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.datastructure;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Locale;
-
-/**
- * Sign info of file
- *
- * @since 2023/09/08
- */
-public class SignedFilePos {
- /**
- * file name offset based on start of so info segment
- */
- private int fileNameOffset;
-
- /**
- * byte size of file
- */
- private final int fileNameSize;
-
- /**
- * sign info offset based on start of so info segment
- */
- private int signInfoOffset;
-
- /**
- * byte size of sign info
- */
- private final int signInfoSize;
-
- /**
- * Constructor for SignedFilePos
- *
- * @param fileNameOffset file name offset based on segment start
- * @param fileNameSize byte size of file name string
- * @param signInfoOffset sign info offset based on segment start
- * @param signInfoSize byte size of sign info
- */
- public SignedFilePos(int fileNameOffset, int fileNameSize, int signInfoOffset, int signInfoSize) {
- this.fileNameOffset = fileNameOffset;
- this.fileNameSize = fileNameSize;
- this.signInfoOffset = signInfoOffset;
- this.signInfoSize = signInfoSize;
- }
-
- public int getFileNameOffset() {
- return fileNameOffset;
- }
-
- public int getFileNameSize() {
- return fileNameSize;
- }
-
- public int getSignInfoOffset() {
- return signInfoOffset;
- }
-
- public int getSignInfoSize() {
- return signInfoSize;
- }
-
- /**
- * increase file name offset
- *
- * @param incOffset increase value
- */
- public void increaseFileNameOffset(int incOffset) {
- this.fileNameOffset += incOffset;
- }
-
- /**
- * increase sign info offset
- *
- * @param incOffset increase value
- */
- public void increaseSignInfoOffset(int incOffset) {
- this.signInfoOffset += incOffset;
- }
-
- /**
- * Constructor for SignedFilePos by byte array
- *
- * @param bytes Byte array representation of SignedFilePos
- * @return a newly created SignedFilePos object
- */
- public static SignedFilePos fromByteArray(byte[] bytes) {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- bf.rewind();
- int inFileNameOffset = bf.getInt();
- int inFileNameSize = bf.getInt();
- int inSignInfoOffset = bf.getInt();
- int inSignInfoSize = bf.getInt();
- return new SignedFilePos(inFileNameOffset, inFileNameSize, inSignInfoOffset, inSignInfoSize);
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT, "SignedFilePos: fileNameOffset, Size[%d, %d], signInfoOffset, Size[%d, %d]",
- this.fileNameOffset, this.fileNameSize, this.signInfoOffset, this.signInfoSize);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/CodeSignException.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/CodeSignException.java
deleted file mode 100644
index 8263bf508fa60ecf16d5b408adf3c2482000e6db..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/CodeSignException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.exception;
-
-/**
- * CodeSign exception
- *
- * @since 2023/06/05
- */
-public class CodeSignException extends Exception {
- private static final long serialVersionUID = -281871003709431259L;
-
- /**
- * CodeSignException
- *
- * @param message msg
- */
- public CodeSignException(String message) {
- super(message);
- }
-
- /**
- * CodeSignException
- *
- * @param message msg
- * @param cause cause
- */
- public CodeSignException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/FsVerityDigestException.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/FsVerityDigestException.java
deleted file mode 100644
index 5ac1210bce1aaf1ef0a3cf8273dca12f0afa236a..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/FsVerityDigestException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.exception;
-
-/**
- * Fail to compute FsVerity digest of a file
- *
- * @since 2023/06/05
- */
-public class FsVerityDigestException extends Exception {
- private static final long serialVersionUID = 5788641970791287892L;
-
- public FsVerityDigestException(String message) {
- super(message);
- }
-
- public FsVerityDigestException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/VerifyCodeSignException.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/VerifyCodeSignException.java
deleted file mode 100644
index 36d28623a55e49399ec3ab83ea2f78f1e0ca59dd..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/exception/VerifyCodeSignException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.exception;
-
-/**
- * Exception occurs when the required parameters are missed
- *
- * @since 2023/06/05
- */
-public class VerifyCodeSignException extends Exception {
- private static final long serialVersionUID = -8922730964374794468L;
-
- /**
- * Exception occurs when the required parameters are not entered
- *
- * @param message msg
- */
- public VerifyCodeSignException(String message) {
- super(message);
- }
-
- /**
- * Exception occurs when the required parameters are not entered
- *
- * @param message msg
- * @param cause cause
- */
- public VerifyCodeSignException(String message, Throwable cause) {
- super(message, cause);
- }
-}
-
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java
deleted file mode 100644
index 5531b7f837b0b55054bc7a1db9291d2e94f38916..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptor.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Format of FsVerity descriptor
- * uint8 version
- * uint8 hashAlgorithm
- * uint8 log2BlockSize
- * uint8 saltSize
- * uint32 signSize
- * le64 dataSize
- * uint8[64] rootHash
- * uint8[32] salt
- * uint32 flags
- * uint8[4] 0
- * uint64 treeOffset
- * uint8[127] 0
- * uint8 csVersion
- *
- * @since 2023/06/05
- */
-public class FsVerityDescriptor {
- /**
- * fs-verity version, must be 1
- */
- public static final byte VERSION = 1;
-
- /**
- * page size in bytes
- */
- public static final int PAGE_SIZE_4K = 4096;
-
- /**
- * Indicating merkle tree offset is set in fs-verity descriptor
- */
- public static final int FLAG_STORE_MERKLE_TREE_OFFSET = 0x1;
-
- /**
- * Indicating fs-verity descriptor type
- */
- public static final int FS_VERITY_DESCRIPTOR_TYPE = 0x1;
-
- /**
- * code sign version
- */
- public static final byte CODE_SIGN_VERSION = 0x1;
-
- /**
- * FsVerity descriptor size
- */
- public static final int DESCRIPTOR_SIZE = 256;
-
- /**
- * root hash size
- */
- public static final int ROOT_HASH_FILED_SIZE = 64;
-
- /**
- * salt size
- */
- public static final int SALT_SIZE = 32;
-
- /**
- * reserved size
- */
- public static final int RESERVED_SIZE_AFTER_FLAGS = 4;
-
- /**
- * reserved size
- */
- public static final int RESERVED_SIZE_AFTER_TREE_OFFSET = 127;
-
- private byte version;
-
- private long fileSize;
-
- private byte hashAlgorithm;
-
- private byte log2BlockSize;
-
- private byte saltSize;
-
- private int signSize;
-
- private byte[] salt;
-
- private byte[] rawRootHash;
-
- private int flags;
-
- private long merkleTreeOffset;
-
- private byte csVersion;
-
- private FsVerityDescriptor(Builder builder) {
- this.version = builder.version;
- this.fileSize = builder.fileSize;
- this.hashAlgorithm = builder.hashAlgorithm;
- this.log2BlockSize = builder.log2BlockSize;
- this.saltSize = builder.saltSize;
- this.signSize = builder.signSize;
- this.salt = builder.salt;
- this.rawRootHash = builder.rawRootHash;
- this.flags = builder.flags;
- this.merkleTreeOffset = builder.merkleTreeOffset;
- this.csVersion = builder.csVersion;
- }
-
- public long getFileSize() {
- return fileSize;
- }
-
- public long getMerkleTreeOffset() {
- return merkleTreeOffset;
- }
-
- public int getSignSize() {
- return signSize;
- }
-
- /**
- * Init the FsVerityDescriptor by a byte array
- *
- * @param bytes Byte array representation of a FsVerityDescriptor object
- * @return a newly created FsVerityDescriptor object
- * @throws VerifyCodeSignException parse result invalid
- */
- public static FsVerityDescriptor fromByteArray(byte[] bytes) throws VerifyCodeSignException {
- ByteBuffer bf = ByteBuffer.allocate(bytes.length).order(ByteOrder.LITTLE_ENDIAN);
- bf.put(bytes);
- // after put, rewind is mandatory before get
- bf.rewind();
- FsVerityDescriptor.Builder builder = new FsVerityDescriptor.Builder();
- byte inFsVersion = bf.get();
- if (FsVerityDescriptor.VERSION != inFsVersion) {
- throw new VerifyCodeSignException("Invalid fs-verify descriptor version of ElfSignBlock");
- }
- byte inFsHashAlgorithm = bf.get();
- byte inLog2BlockSize = bf.get();
- builder.setVersion(inFsVersion).setHashAlgorithm(inFsHashAlgorithm).setLog2BlockSize(inLog2BlockSize);
- byte inSaltSize = bf.get();
- int inSignSize = bf.getInt();
- long inDataSize = bf.getLong();
- byte[] inRootHash = new byte[FsVerityDescriptor.ROOT_HASH_FILED_SIZE];
- bf.get(inRootHash);
- builder.setSaltSize(inSaltSize).setSignSize(inSignSize).setFileSize(inDataSize).setRawRootHash(inRootHash);
- byte[] inSalt = new byte[FsVerityDescriptor.SALT_SIZE];
- bf.get(inSalt);
- int inFlags = bf.getInt();
- bf.getInt();
- long inTreeOffset = bf.getLong();
- if (inTreeOffset % PAGE_SIZE_4K != 0) {
- throw new VerifyCodeSignException("Invalid merkle tree offset of ElfSignBlock");
- }
- bf.get(new byte[FsVerityDescriptor.RESERVED_SIZE_AFTER_TREE_OFFSET]);
- byte inCsVersion = bf.get();
- builder.setSalt(inSalt).setFlags(inFlags).setMerkleTreeOffset(inTreeOffset).setCsVersion(inCsVersion);
- return builder.build();
- }
-
- /**
- * Get FsVerity descriptor bytes
- *
- * @return bytes of descriptor
- * @throws FsVerityDigestException if error
- */
- public byte[] toByteArray() throws FsVerityDigestException {
- ByteBuffer buffer = ByteBuffer.allocate(DESCRIPTOR_SIZE).order(ByteOrder.LITTLE_ENDIAN);
- buffer.put(VERSION);
- buffer.put(hashAlgorithm);
- buffer.put(log2BlockSize);
- if (this.saltSize > SALT_SIZE) {
- throw new FsVerityDigestException("Salt is too long");
- }
- buffer.put(this.saltSize);
- buffer.putInt(signSize);
- buffer.putLong(fileSize);
- writeBytesWithSize(buffer, rawRootHash, ROOT_HASH_FILED_SIZE);
- writeBytesWithSize(buffer, salt, SALT_SIZE);
- buffer.putInt(flags);
- writeBytesWithSize(buffer, null, RESERVED_SIZE_AFTER_FLAGS);
- buffer.putLong(merkleTreeOffset);
- writeBytesWithSize(buffer, null, RESERVED_SIZE_AFTER_TREE_OFFSET);
- buffer.put(csVersion);
- return buffer.array();
- }
-
- /**
- * Get bytes for generate digest, first byte is CODE_SIGN_VERSION, sign size is 0, last 128 bytes is 0
- *
- * @return bytes of descriptor
- * @throws FsVerityDigestException if error
- */
- public byte[] getByteForGenerateDigest() throws FsVerityDigestException {
- ByteBuffer buffer = ByteBuffer.allocate(DESCRIPTOR_SIZE).order(ByteOrder.LITTLE_ENDIAN);
- buffer.put(CODE_SIGN_VERSION);
- buffer.put(hashAlgorithm);
- buffer.put(log2BlockSize);
- if (this.saltSize > SALT_SIZE) {
- throw new FsVerityDigestException("Salt is too long");
- }
- buffer.put(this.saltSize);
- buffer.putInt(0);
- buffer.putLong(fileSize);
- writeBytesWithSize(buffer, rawRootHash, ROOT_HASH_FILED_SIZE);
- writeBytesWithSize(buffer, salt, SALT_SIZE);
- buffer.putInt(flags);
- writeBytesWithSize(buffer, null, RESERVED_SIZE_AFTER_FLAGS);
- buffer.putLong(merkleTreeOffset);
- return buffer.array();
- }
-
- /**
- * Write bytes to ByteBuffer with specific size
- *
- * @param buffer target buffer
- * @param src bytes to write
- * @param size size of written bytes, fill 0 if src bytes is long enough
- */
- private void writeBytesWithSize(ByteBuffer buffer, byte[] src, int size) {
- int pos = buffer.position();
- if (src != null) {
- if (src.length > size) {
- buffer.put(src, 0, size);
- } else {
- buffer.put(src);
- }
- }
- buffer.position(pos + size);
- }
-
- /**
- * Builder of FsVerityDescriptor class
- */
- public static class Builder {
- private byte version = VERSION;
-
- private long fileSize;
-
- private byte hashAlgorithm;
-
- private byte log2BlockSize;
-
- private byte saltSize;
-
- private int signSize;
-
- private byte[] salt;
-
- private byte[] rawRootHash;
-
- private int flags;
-
- private long merkleTreeOffset;
-
- private byte csVersion;
-
- public Builder setVersion(byte version) {
- this.version = version;
- return this;
- }
-
- public Builder setFileSize(long fileSize) {
- this.fileSize = fileSize;
- return this;
- }
-
- public Builder setHashAlgorithm(byte hashAlgorithm) {
- this.hashAlgorithm = hashAlgorithm;
- return this;
- }
-
- public Builder setLog2BlockSize(byte log2BlockSize) {
- this.log2BlockSize = log2BlockSize;
- return this;
- }
-
- public Builder setSignSize(int signSize) {
- this.signSize = signSize;
- return this;
- }
-
- public Builder setSaltSize(byte saltSize) {
- this.saltSize = saltSize;
- return this;
- }
-
- public Builder setSalt(byte[] salt) {
- this.salt = salt;
- return this;
- }
-
- public Builder setRawRootHash(byte[] rawRootHash) {
- this.rawRootHash = rawRootHash;
- return this;
- }
-
- public Builder setFlags(int flags) {
- this.flags = flags;
- return this;
- }
-
- public Builder setMerkleTreeOffset(long merkleTreeOffset) {
- this.merkleTreeOffset = merkleTreeOffset;
- return this;
- }
-
- public Builder setCsVersion(byte csVersion) {
- this.csVersion = csVersion;
- return this;
- }
-
- /**
- * Create a FsVerityDescriptor object
- *
- * @return a FsVerityDescriptor object
- */
- public FsVerityDescriptor build() {
- return new FsVerityDescriptor(this);
- }
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptorWithSign.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptorWithSign.java
deleted file mode 100644
index 6e3084b55d5b2c09f9ab451f0b540767def7dd15..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDescriptorWithSign.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * fsverity descriptor and signature
- * 1) u32 type: 0x1 fsverity descriptor
- * 2) u32 length: fsverity descriptor size
- * 3) FsVerityDescriptor: fsVerityDescriptor
- * 4) u8[] signature: signature after signing the data in byte array representation
- *
- * @since 2023/09/08
- */
-public class FsVerityDescriptorWithSign {
- private int type = FsVerityDescriptor.FS_VERITY_DESCRIPTOR_TYPE;
-
- private int length;
-
- private FsVerityDescriptor fsVerityDescriptor;
-
- private byte[] signature = new byte[0];
-
- /**
- * Constructor of FsVerityDescriptorWithSign
- *
- * @param fsVerityDescriptor fs-verity descriptor
- * @param signature signature
- */
- public FsVerityDescriptorWithSign(FsVerityDescriptor fsVerityDescriptor, byte[] signature) {
- this.fsVerityDescriptor = fsVerityDescriptor;
- if (signature != null) {
- this.signature = signature;
- }
- length = FsVerityDescriptor.DESCRIPTOR_SIZE + this.signature.length;
- }
-
- /**
- * Constructor of FsVerityDescriptorWithSign
- *
- * @param type fs-verity descriptor type
- * @param length fs-verity descriptor with signature size
- * @param fsVerityDescriptor fs-verity descriptor
- * @param signature signature
- */
- public FsVerityDescriptorWithSign(int type, int length, FsVerityDescriptor fsVerityDescriptor, byte[] signature) {
- this.type = type;
- this.length = length;
- this.fsVerityDescriptor = fsVerityDescriptor;
- this.signature = signature;
- }
-
- /**
- * Returns byte size of FsVerityDescriptorWithSign
- *
- * @return byte size of FsVerityDescriptorWithSign
- */
- public int size() {
- return Integer.BYTES * 2 + FsVerityDescriptor.DESCRIPTOR_SIZE + signature.length;
- }
-
- /**
- * Converts FsVerityDescriptorWithSign to a newly created byte array
- *
- * @return Byte array representation of FsVerityDescriptorWithSign
- * @throws FsVerityDigestException if error
- */
- public byte[] toByteArray() throws FsVerityDigestException {
- ByteBuffer buffer = ByteBuffer.allocate(size()).order(ByteOrder.LITTLE_ENDIAN);
- buffer.putInt(type);
- buffer.putInt(length);
- buffer.put(fsVerityDescriptor.toByteArray());
- buffer.put(signature);
- return buffer.array();
- }
-
- public FsVerityDescriptor getFsVerityDescriptor() {
- return fsVerityDescriptor;
- }
-
- public byte[] getSignature() {
- return signature;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDigest.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDigest.java
deleted file mode 100644
index cff3617c9f01f933191cca4c09fd2fd5c66cafbf..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityDigest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Format of FsVerity digest
- * int8[8] magic "FSVerity"
- * le16 digestAlgorithm sha256 = 1, sha512 = 2
- * le16 digestSize
- * uint8[] digest
- *
- * @since 2023/06/05
- */
-public class FsVerityDigest {
- private static final String FSVERITY_DIGEST_MAGIC = "FSVerity";
-
- private static final int DIGEST_HEADER_SIZE = 12;
-
- /**
- * Get formatted FsVerity digest
- *
- * @param algoID hash algorithm id
- * @param digest raw digest computed from input
- * @return formatted FsVerity digest bytes
- */
- public static byte[] getFsVerityDigest(byte algoID, byte[] digest) {
- int size = DIGEST_HEADER_SIZE + digest.length;
- ByteBuffer buffer = ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN);
- buffer.put(FSVERITY_DIGEST_MAGIC.getBytes(StandardCharsets.UTF_8));
- buffer.putShort(algoID);
- buffer.putShort((short) digest.length);
- buffer.put(digest);
- return buffer.array();
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java
deleted file mode 100644
index 57501d09d6ab5e056e991a4fcd669340b362fa94..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityGenerator.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.utils.DigestUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * FsVerity data generator supper class
- *
- * @since 2023/06/05
- */
-public class FsVerityGenerator {
- /**
- * FsVerity hash algorithm
- */
- private static final FsVerityHashAlgorithm FS_VERITY_HASH_ALGORITHM = FsVerityHashAlgorithm.SHA256;
-
- private static final byte LOG_2_OF_FSVERITY_HASH_PAGE_SIZE = 12;
-
- /**
- * salt for hashing one page
- */
- protected byte[] salt = null;
-
- private byte[] fsVerityDigest = null;
-
- private byte[] treeBytes = null;
-
- private byte[] rootHash = null;
-
- /**
- * generate merkle tree of given input
- *
- * @param inputStream input stream for generate merkle tree
- * @param size total size of input stream
- * @param fsVerityHashAlgorithm hash algorithm for FsVerity
- * @return merkle tree
- * @throws FsVerityDigestException if error
- */
- public MerkleTree generateMerkleTree(InputStream inputStream, long size,
- FsVerityHashAlgorithm fsVerityHashAlgorithm) throws FsVerityDigestException {
- MerkleTree merkleTree;
- try (MerkleTreeBuilder builder = new MerkleTreeBuilder()) {
- merkleTree = builder.generateMerkleTree(inputStream, size, fsVerityHashAlgorithm);
- } catch (IOException e) {
- throw new FsVerityDigestException("IOException: " + e.getMessage());
- } catch (NoSuchAlgorithmException e) {
- throw new FsVerityDigestException("Invalid algorithm:" + e.getMessage());
- }
- return merkleTree;
- }
-
- /**
- * generate FsVerity digest of given input
- *
- * @param inputStream input stream for generate FsVerity digest
- * @param size total size of input stream
- * @param fsvTreeOffset merkle tree raw bytes offset based on the start of file
- * @throws FsVerityDigestException if error
- */
- public void generateFsVerityDigest(InputStream inputStream, long size, long fsvTreeOffset)
- throws FsVerityDigestException {
- MerkleTree merkleTree;
- if (size == 0) {
- merkleTree = new MerkleTree(null, null, FS_VERITY_HASH_ALGORITHM);
- } else {
- merkleTree = generateMerkleTree(inputStream, size, FS_VERITY_HASH_ALGORITHM);
- }
- int flags = fsvTreeOffset == 0 ? 0 : FsVerityDescriptor.FLAG_STORE_MERKLE_TREE_OFFSET;
- // sign size is 0, cs version is 0
- FsVerityDescriptor.Builder builder = new FsVerityDescriptor.Builder().setFileSize(size)
- .setHashAlgorithm(FS_VERITY_HASH_ALGORITHM.getId())
- .setLog2BlockSize(LOG_2_OF_FSVERITY_HASH_PAGE_SIZE)
- .setSaltSize((byte) getSaltSize())
- .setSalt(salt)
- .setRawRootHash(merkleTree.rootHash)
- .setFlags(flags)
- .setMerkleTreeOffset(fsvTreeOffset);
- byte[] fsVerityDescriptor = builder.build().getByteForGenerateDigest();
- byte[] digest;
- try {
- digest = DigestUtils.computeDigest(fsVerityDescriptor, FS_VERITY_HASH_ALGORITHM.getHashAlgorithm());
- } catch (NoSuchAlgorithmException e) {
- throw new FsVerityDigestException("Invalid algorithm" + e.getMessage(), e);
- }
- fsVerityDigest = FsVerityDigest.getFsVerityDigest(FS_VERITY_HASH_ALGORITHM.getId(), digest);
- treeBytes = merkleTree.tree;
- rootHash = merkleTree.rootHash;
- }
-
- /**
- * Get FsVerity digest
- *
- * @return bytes of FsVerity digest
- */
- public byte[] getFsVerityDigest() {
- return fsVerityDigest;
- }
-
- /**
- * Get merkle tree in bytes
- *
- * @return bytes of merkle tree
- */
- public byte[] getTreeBytes() {
- return treeBytes;
- }
-
- /**
- * Get merkle tree rootHash in bytes
- *
- * @return bytes of merkle tree rootHash
- */
- public byte[] getRootHash() {
- return rootHash;
- }
-
- public byte[] getSalt() {
- return salt;
- }
-
- /**
- * Returns byte size of salt
- *
- * @return byte size of salt
- */
- public int getSaltSize() {
- return this.salt == null ? 0 : this.salt.length;
- }
-
- /**
- * Returns the id of fs-verity hash algorithm
- *
- * @return fs-verity hash algorithm id
- */
- public static byte getFsVerityHashAlgorithm() {
- return FS_VERITY_HASH_ALGORITHM.getId();
- }
-
- /**
- * Returns the log2 of size of data and tree blocks
- *
- * @return log2 of size of data and tree blocks
- */
- public static byte getLog2BlockSize() {
- return LOG_2_OF_FSVERITY_HASH_PAGE_SIZE;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityHashAlgorithm.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityHashAlgorithm.java
deleted file mode 100644
index 7d188413c321fe89efa35b064dfc8fd8597f7d47..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/FsVerityHashAlgorithm.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-/**
- * FsVerity hash algorithm
- *
- * @since 2023/06/05
- */
-public enum FsVerityHashAlgorithm {
- SHA256((byte) 1, "SHA-256", 256 / 8),
- SHA512((byte) 2, "SHA-512", 512 / 8);
-
- private final byte id;
-
- private final String hashAlgorithm;
-
- private final int outputByteSize;
-
- FsVerityHashAlgorithm(byte id, String hashAlgorithm, int outputByteSize) {
- this.id = id;
- this.hashAlgorithm = hashAlgorithm;
- this.outputByteSize = outputByteSize;
- }
-
- public byte getId() {
- return id;
- }
-
- public String getHashAlgorithm() {
- return hashAlgorithm;
- }
-
- public int getOutputByteSize() {
- return outputByteSize;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTree.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTree.java
deleted file mode 100644
index eebfdd2813cb6a445240be1f3cf4315c9bfc1e00..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTree.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-/**
- * Merkle tree data
- *
- * @since 2023/06/05
- */
-public class MerkleTree {
- /**
- * root hash of merkle tree
- */
- public final byte[] rootHash;
-
- /**
- * content data of merkle tree
- */
- public final byte[] tree;
-
- /**
- * hash algorithm used for merkle tree
- */
- public final FsVerityHashAlgorithm fsVerityHashAlgorithm;
-
- MerkleTree(byte[] rootHash, byte[] tree, FsVerityHashAlgorithm fsVerityHashAlgorithm) {
- this.rootHash = rootHash;
- this.tree = tree;
- this.fsVerityHashAlgorithm = fsVerityHashAlgorithm;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java
deleted file mode 100644
index cbc198e9aa532b9a8cf62d9433040a47c16ff4ea..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/fsverity/MerkleTreeBuilder.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.fsverity;
-
-import com.ohos.hapsigntool.codesigning.utils.DigestUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Phaser;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Merkle tree builder
- *
- * @since 2023/06/05
- */
-public class MerkleTreeBuilder implements AutoCloseable {
- private static final int FSVERITY_HASH_PAGE_SIZE = 4096;
-
- private static final long INPUTSTREAM_MAX_SIZE = 4503599627370496L;
-
- private static final int CHUNK_SIZE = 4096;
-
- private static final long MAX_READ_SIZE = 4194304L;
-
- private static final int MAX_PROCESSORS = 32;
-
- private static final int BLOCKINGQUEUE = 4;
-
- private static final int POOL_SIZE = Math.min(MAX_PROCESSORS, Runtime.getRuntime().availableProcessors());
-
- private String mAlgorithm = "SHA-256";
-
- private final ExecutorService mPools = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 0L, TimeUnit.MILLISECONDS,
- new ArrayBlockingQueue<>(BLOCKINGQUEUE), new ThreadPoolExecutor.CallerRunsPolicy());
-
- /**
- * Turn off multitasking
- */
- public void close() {
- this.mPools.shutdownNow();
- }
-
- /**
- * set algorithm
- *
- * @param algorithm hash algorithm
- */
- private void setAlgorithm(String algorithm) {
- this.mAlgorithm = algorithm;
- }
-
- /**
- * translation inputStream to hash data
- *
- * @param inputStream input stream for generating merkle tree
- * @param size total size of input stream
- * @param outputBuffer hash data
- * @throws IOException if error
- */
- private void transInputStreamToHashData(InputStream inputStream, long size, ByteBuffer outputBuffer)
- throws IOException {
- if (size == 0) {
- throw new IOException("Input size is empty");
- } else if (size > INPUTSTREAM_MAX_SIZE) {
- throw new IOException("Input size is too long");
- }
- int count = (int) getChunkCount(size, MAX_READ_SIZE);
- int chunks = (int) getChunkCount(size, CHUNK_SIZE);
- byte[][] hashes = new byte[chunks][];
- long readOffset = 0L;
- Phaser tasks = new Phaser(1);
- for (int i = 0; i < count; i++) {
- long readLimit = Math.min(readOffset + MAX_READ_SIZE, size);
- int readSize = (int) (readLimit - readOffset);
- int fullChunkSize = (int) getFullChunkSize(readSize, CHUNK_SIZE, CHUNK_SIZE);
-
- ByteBuffer byteBuffer = ByteBuffer.allocate(fullChunkSize);
- byte[] buffer = new byte[CHUNK_SIZE];
- int num;
- int offset = 0;
- int len = CHUNK_SIZE;
- while ((num = inputStream.read(buffer, 0, len)) > 0) {
- byteBuffer.put(buffer, 0, num);
- offset += num;
- len = Math.min(CHUNK_SIZE, readSize - offset);
- if (len <= 0 || offset == readSize) {
- break;
- }
- }
- if (offset != readSize) {
- throw new IOException("IOException read buffer from input errorLHJ.");
- }
- byteBuffer.flip();
- int readChunkIndex = (int) getFullChunkSize(MAX_READ_SIZE, CHUNK_SIZE, i);
- runHashTask(hashes, tasks, byteBuffer, readChunkIndex);
- readOffset += readSize;
- }
- tasks.arriveAndAwaitAdvance();
- for (byte[] hash : hashes) {
- outputBuffer.put(hash, 0, hash.length);
- }
- }
-
- /**
- * split buffer by begin and end information
- *
- * @param buffer original buffer
- * @param begin begin position
- * @param end end position
- * @return slice buffer
- */
- private static ByteBuffer slice(ByteBuffer buffer, int begin, int end) {
- ByteBuffer tempBuffer = buffer.duplicate();
- tempBuffer.position(0);
- tempBuffer.limit(end);
- tempBuffer.position(begin);
- return tempBuffer.slice();
- }
-
- /**
- * calculate merkle tree level and size by data size and digest size
- *
- * @param dataSize original data size
- * @param digestSize algorithm data size
- * @return level offset list, contains the offset of
- * each level from the root node to the leaf node
- */
- private static int[] getOffsetArrays(long dataSize, int digestSize) {
- ArrayList levelSize = getLevelSize(dataSize, digestSize);
- int[] levelOffset = new int[levelSize.size() + 1];
- levelOffset[0] = 0;
- for (int i = 0; i < levelSize.size(); i++) {
- levelOffset[i + 1] = levelOffset[i] + Math.toIntExact(levelSize.get(levelSize.size() - i - 1));
- }
- return levelOffset;
- }
-
- /**
- * calculate data size list by data size and digest size
- *
- * @param dataSize original data size
- * @param digestSize algorithm data size
- * @return data size list, contains the offset of
- * each level from the root node to the leaf node
- */
- private static ArrayList getLevelSize(long dataSize, int digestSize) {
- ArrayList levelSize = new ArrayList<>();
- long fullChunkSize = 0L;
- long originalDataSize = dataSize;
- do {
- fullChunkSize = getFullChunkSize(originalDataSize, CHUNK_SIZE, digestSize);
- long size = getFullChunkSize(fullChunkSize, CHUNK_SIZE, CHUNK_SIZE);
- levelSize.add(size);
- originalDataSize = fullChunkSize;
- } while (fullChunkSize > CHUNK_SIZE);
- return levelSize;
- }
-
- private void runHashTask(byte[][] hashes, Phaser tasks, ByteBuffer buffer, int readChunkIndex) {
- Runnable task = () -> {
- int offset = 0;
- int bufferSize = buffer.capacity();
- int index = readChunkIndex;
- while (offset < bufferSize) {
- ByteBuffer chunk = slice(buffer, offset, offset + CHUNK_SIZE);
- byte[] tempByte = new byte[CHUNK_SIZE];
- chunk.get(tempByte);
- try {
- hashes[index++] = DigestUtils.computeDigest(tempByte, this.mAlgorithm);
- } catch (NoSuchAlgorithmException e) {
- throw new IllegalStateException(e);
- }
- offset += CHUNK_SIZE;
- }
- tasks.arriveAndDeregister();
- };
- tasks.register();
- this.mPools.execute(task);
- }
-
- /**
- * hash data of buffer
- *
- * @param inputBuffer original data
- * @param outputBuffer hash data
- */
- private void transInputDataToHashData(ByteBuffer inputBuffer, ByteBuffer outputBuffer) {
- long size = inputBuffer.capacity();
- int chunks = (int) getChunkCount(size, CHUNK_SIZE);
- byte[][] hashes = new byte[chunks][];
- Phaser tasks = new Phaser(1);
- long readOffset = 0L;
- int startChunkIndex = 0;
- while (readOffset < size) {
- long readLimit = Math.min(readOffset + MAX_READ_SIZE, size);
- ByteBuffer buffer = slice(inputBuffer, (int) readOffset, (int) readLimit);
- buffer.rewind();
- int readChunkIndex = startChunkIndex;
- runHashTask(hashes, tasks, buffer, readChunkIndex);
- int readSize = (int) (readLimit - readOffset);
- startChunkIndex += (int) getChunkCount(readSize, CHUNK_SIZE);
- readOffset += readSize;
- }
- tasks.arriveAndAwaitAdvance();
- for (byte[] hash : hashes) {
- outputBuffer.put(hash, 0, hash.length);
- }
- }
-
- /**
- * generate merkle tree of given input
- *
- * @param inputStream input stream for generate merkle tree
- * @param size total size of input stream
- * @param fsVerityHashAlgorithm hash algorithm for FsVerity
- * @return merkle tree
- * @throws IOException if error
- * @throws NoSuchAlgorithmException if error
- */
- public MerkleTree generateMerkleTree(InputStream inputStream, long size,
- FsVerityHashAlgorithm fsVerityHashAlgorithm) throws IOException, NoSuchAlgorithmException {
- setAlgorithm(fsVerityHashAlgorithm.getHashAlgorithm());
- int digestSize = fsVerityHashAlgorithm.getOutputByteSize();
- int[] offsetArrays = getOffsetArrays(size, digestSize);
- ByteBuffer allHashBuffer = ByteBuffer.allocate(offsetArrays[offsetArrays.length - 1]);
- generateHashDataByInputData(inputStream, size, allHashBuffer, offsetArrays, digestSize);
- generateHashDataByHashData(allHashBuffer, offsetArrays, digestSize);
- return getMerkleTree(allHashBuffer, size, fsVerityHashAlgorithm);
- }
-
- /**
- * translation inputBuffer arrays to hash ByteBuffer
- *
- * @param inputStream input stream for generate merkle tree
- * @param size total size of input stream
- * @param outputBuffer hash data
- * @param offsetArrays level offset
- * @param digestSize algorithm output byte size
- * @throws IOException if error
- */
- private void generateHashDataByInputData(InputStream inputStream, long size, ByteBuffer outputBuffer,
- int[] offsetArrays, int digestSize) throws IOException {
- int inputDataOffsetBegin = offsetArrays[offsetArrays.length - 2];
- int inputDataOffsetEnd = offsetArrays[offsetArrays.length - 1];
- ByteBuffer hashBuffer = slice(outputBuffer, inputDataOffsetBegin, inputDataOffsetEnd);
- transInputStreamToHashData(inputStream, size, hashBuffer);
- dataRoundupChunkSize(hashBuffer, size, digestSize);
- }
-
- /**
- * get buffer data by level offset, transforms digest data, save in another
- * memory
- *
- * @param buffer hash data
- * @param offsetArrays level offset
- * @param digestSize algorithm output byte size
- */
- private void generateHashDataByHashData(ByteBuffer buffer, int[] offsetArrays, int digestSize) {
- for (int i = offsetArrays.length - 3; i >= 0; i--) {
- ByteBuffer generateHashBuffer = slice(buffer, offsetArrays[i], offsetArrays[i + 1]);
- ByteBuffer originalHashBuffer = slice(buffer.asReadOnlyBuffer(), offsetArrays[i + 1], offsetArrays[i + 2]);
- transInputDataToHashData(originalHashBuffer, generateHashBuffer);
- dataRoundupChunkSize(generateHashBuffer, originalHashBuffer.capacity(), digestSize);
- }
- }
-
- /**
- * generate merkle tree of given input
- *
- * @param dataBuffer tree data memory block
- * @param inputDataSize total size of input stream
- * @param fsVerityHashAlgorithm hash algorithm for FsVerity
- * @return merkle tree
- * @throws NoSuchAlgorithmException if error
- */
- private MerkleTree getMerkleTree(ByteBuffer dataBuffer, long inputDataSize,
- FsVerityHashAlgorithm fsVerityHashAlgorithm) throws NoSuchAlgorithmException {
- int digestSize = fsVerityHashAlgorithm.getOutputByteSize();
- dataBuffer.flip();
- byte[] rootHash = null;
- byte[] tree = null;
- if (inputDataSize < FSVERITY_HASH_PAGE_SIZE) {
- ByteBuffer fsVerityHashPageBuffer = slice(dataBuffer, 0, digestSize);
- rootHash = new byte[digestSize];
- fsVerityHashPageBuffer.get(rootHash);
- } else {
- tree = dataBuffer.array();
- ByteBuffer fsVerityHashPageBuffer = slice(dataBuffer.asReadOnlyBuffer(), 0, FSVERITY_HASH_PAGE_SIZE);
- byte[] fsVerityHashPage = new byte[FSVERITY_HASH_PAGE_SIZE];
- fsVerityHashPageBuffer.get(fsVerityHashPage);
- rootHash = DigestUtils.computeDigest(fsVerityHashPage, this.mAlgorithm);
- }
- return new MerkleTree(rootHash, tree, fsVerityHashAlgorithm);
- }
-
- /**
- * generate merkle tree of given input
- *
- * @param data original data
- * @param originalDataSize data size
- * @param digestSize algorithm output byte size
- */
- private void dataRoundupChunkSize(ByteBuffer data, long originalDataSize, int digestSize) {
- long fullChunkSize = getFullChunkSize(originalDataSize, CHUNK_SIZE, digestSize);
- int diffValue = (int) (fullChunkSize % CHUNK_SIZE);
- if (diffValue > 0) {
- byte[] padding = new byte[CHUNK_SIZE - diffValue];
- data.put(padding, 0, padding.length);
- }
- }
-
- /**
- * get mount of chunks to store data
- *
- * @param dataSize data size
- * @param divisor split chunk size
- * @return chunk count
- */
- private static long getChunkCount(long dataSize, long divisor) {
- return (long) Math.ceil((double) dataSize / (double) divisor);
- }
-
- /**
- * get total size of chunk to store data
- *
- * @param dataSize data size
- * @param divisor split chunk size
- * @param multiplier chunk multiplier
- * @return chunk size
- */
- private static long getFullChunkSize(long dataSize, long divisor, long multiplier) {
- return getChunkCount(dataSize, divisor) * multiplier;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java
deleted file mode 100644
index 238f5cb8a16315ee07327a825061ce02c6df730f..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/BcSignedDataGenerator.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.sign;
-
-import com.ohos.hapsigntool.codesigning.exception.CodeSignException;
-import com.ohos.hapsigntool.codesigning.utils.CmsUtils;
-import com.ohos.hapsigntool.codesigning.utils.DigestUtils;
-import com.ohos.hapsigntool.hap.config.SignerConfig;
-import com.ohos.hapsigntool.hap.entity.Pair;
-import com.ohos.hapsigntool.hap.sign.ContentDigestAlgorithm;
-import com.ohos.hapsigntool.hap.sign.SignatureAlgorithm;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1Set;
-import org.bouncycastle.asn1.BERSet;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.DERSet;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.DERUTF8String;
-import org.bouncycastle.asn1.cms.Time;
-import org.bouncycastle.asn1.pkcs.Attribute;
-import org.bouncycastle.asn1.pkcs.ContentInfo;
-import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.SignedData;
-import org.bouncycastle.asn1.pkcs.SignerInfo;
-import org.bouncycastle.cert.jcajce.JcaX509CRLHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
-import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
-import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CRLException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509CRL;
-import java.security.cert.X509Certificate;
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.Date;
-import java.util.List;
-
-/**
- * BC implementation
- *
- * @since 2023/06/05
- */
-public class BcSignedDataGenerator implements SignedDataGenerator {
- /**
- * OID of the signer identity
- */
- public static final String SIGNER_OID = "1.3.6.1.4.1.2011.2.376.1.4.1";
-
- private static final Logger LOGGER = LogManager.getLogger(BcSignedDataGenerator.class);
-
- private static final SignatureAlgorithmIdentifierFinder SIGN_ALG_ID_FINDER
- = new DefaultSignatureAlgorithmIdentifierFinder();
-
- private static final DigestAlgorithmIdentifierFinder DIGEST_ALG_ID_FINDER
- = new DefaultDigestAlgorithmIdentifierFinder();
-
- private String ownerID;
-
- public void setOwnerID(String ownerID) {
- this.ownerID = ownerID;
- }
- @Override
- public byte[] generateSignedData(byte[] content, SignerConfig signConfig) throws CodeSignException {
- if (content == null) {
- throw new CodeSignException("Verity digest is null");
- }
- Pair pairDigestAndSignInfo = getSignInfo(content, signConfig);
- // Unsupported certificate revocation, SignedData's _crls is null
- SignedData signedData = new SignedData(new ASN1Integer(1), pairDigestAndSignInfo.getFirst(),
- new ContentInfo(PKCSObjectIdentifiers.data, null), createBerSetFromLst(signConfig.getCertificates()),
- createBerSetFromLst(null), pairDigestAndSignInfo.getSecond());
- return encodingUnsignedData(content, signedData);
- }
-
- private Pair getSignInfo(byte[] content, SignerConfig signConfig) throws CodeSignException {
- ASN1EncodableVector signInfoVector = new ASN1EncodableVector();
- ASN1EncodableVector digestVector = new ASN1EncodableVector();
- for (SignatureAlgorithm signAlgorithm : signConfig.getSignatureAlgorithms()) {
- SignerInfo signInfo = createSignInfo(signAlgorithm, content, signConfig);
- signInfoVector.add(signInfo);
- digestVector.add(signInfo.getDigestAlgorithm());
- LOGGER.info("Create a sign info successfully.");
- }
- return Pair.create(new DERSet(digestVector), new DERSet(signInfoVector));
- }
-
- private SignerInfo createSignInfo(SignatureAlgorithm signAlgorithm, byte[] unsignedDataDigest,
- SignerConfig signConfig) throws CodeSignException {
- ContentDigestAlgorithm hashAlgorithm = signAlgorithm.getContentDigestAlgorithm();
- byte[] digest = computeDigest(unsignedDataDigest, hashAlgorithm.name());
- ASN1Set authed = getPKCS9Attributes(digest);
- byte[] codeAuthed = getEncoded(authed);
- Pair signPair = signAlgorithm.getSignatureAlgAndParams();
- byte[] signBytes = signConfig.getSigner().getSignature(codeAuthed, signPair.getFirst(), signPair.getSecond());
- if (signBytes == null) {
- throw new CodeSignException("get signature failed");
- }
- if (signConfig.getCertificates().isEmpty()) {
- throw new CodeSignException("No certificates configured for sign");
- }
- X509Certificate cert = signConfig.getCertificates().get(0);
- if (!verifySignFromServer(cert.getPublicKey(), signBytes, signPair, codeAuthed)) {
- throw new CodeSignException("verifySignatureFromServer failed");
- }
- JcaX509CertificateHolder certificateHolder = getJcaX509CertificateHolder(cert);
- return new SignerInfo(new ASN1Integer(1),
- new IssuerAndSerialNumber(certificateHolder.getIssuer(), certificateHolder.getSerialNumber()),
- DIGEST_ALG_ID_FINDER.find(hashAlgorithm.getDigestAlgorithm()), authed,
- SIGN_ALG_ID_FINDER.find(signPair.getFirst()), new DEROctetString(signBytes), null);
- }
-
- private byte[] computeDigest(byte[] unsignedDataDigest, String algorithm) throws CodeSignException {
- byte[] digest;
- try {
- digest = DigestUtils.computeDigest(unsignedDataDigest, algorithm);
- } catch (NoSuchAlgorithmException e) {
- throw new CodeSignException("Invalid algorithm" + e.getMessage(), e);
- }
- return digest;
- }
-
- private byte[] getEncoded(ASN1Set authed) throws CodeSignException {
- byte[] codeAuthed;
- try {
- codeAuthed = authed.getEncoded();
- } catch (IOException e) {
- throw new CodeSignException("cannot encode authed", e);
- }
- return codeAuthed;
- }
-
- private JcaX509CRLHolder getJcaX509CRLHolder(X509CRL crl) throws CodeSignException {
- JcaX509CRLHolder crlHolder;
- try {
- crlHolder = new JcaX509CRLHolder(crl);
- } catch (CRLException e) {
- throw new CodeSignException("Create crl failed", e);
- }
- return crlHolder;
- }
-
- private JcaX509CertificateHolder getJcaX509CertificateHolder(X509Certificate cert) throws CodeSignException {
- JcaX509CertificateHolder certificateHolder;
- try {
- certificateHolder = new JcaX509CertificateHolder(cert);
- } catch (CertificateEncodingException e) {
- throw new CodeSignException("Create sign info failed", e);
- }
- return certificateHolder;
- }
-
- private ASN1Set getPKCS9Attributes(byte[] digest) {
- ASN1EncodableVector table = new ASN1EncodableVector();
- Attribute signingTimeAttr = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_signingTime,
- new DERSet(new Time(new Date())));
- Attribute contentTypeAttr = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_contentType,
- new DERSet(PKCSObjectIdentifiers.data));
- Attribute messageDigestAttr = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_messageDigest,
- new DERSet(new DEROctetString(digest)));
- table.add(signingTimeAttr);
- table.add(contentTypeAttr);
- table.add(messageDigestAttr);
- if (ownerID != null) {
- Attribute ownerIDAttr = new Attribute(new ASN1ObjectIdentifier(SIGNER_OID),
- new DERSet(new DERUTF8String(ownerID)));
- table.add(ownerIDAttr);
- }
- return new DERSet(table);
- }
-
- private boolean verifySignFromServer(PublicKey publicKey, byte[] signBytes,
- Pair signPair, byte[] authed) throws CodeSignException {
- try {
- Signature signature = Signature.getInstance(signPair.getFirst());
- signature.initVerify(publicKey);
- if (signPair.getSecond() != null) {
- signature.setParameter(signPair.getSecond());
- }
- signature.update(authed);
- if (!signature.verify(signBytes)) {
- throw new CodeSignException("Signature verify failed");
- }
- return true;
- } catch (InvalidKeyException | SignatureException e) {
- LOGGER.error("The generated signature could not be verified " + " using the public key in the certificate",
- e);
- } catch (NoSuchAlgorithmException e) {
- LOGGER.error("The generated signature " + signPair.getFirst()
- + " could not be verified using the public key in the certificate", e);
- } catch (InvalidAlgorithmParameterException e) {
- LOGGER.error("The generated signature " + signPair.getSecond()
- + " could not be verified using the public key in the certificate", e);
- }
- return false;
- }
-
- private ASN1Set createBerSetFromLst(List> lists) throws CodeSignException {
- if (lists == null || lists.size() == 0) {
- return null;
- }
- ASN1EncodableVector vector = new ASN1EncodableVector();
- for (Object obj : lists) {
- if (obj instanceof X509CRL) {
- vector.add(getJcaX509CRLHolder((X509CRL) obj).toASN1Structure());
- } else if (obj instanceof X509Certificate) {
- vector.add(getJcaX509CertificateHolder((X509Certificate) obj).toASN1Structure());
- }
- }
- return new BERSet(vector);
- }
-
- private byte[] encodingUnsignedData(byte[] unsignedDataDigest, SignedData signedData) throws CodeSignException {
- byte[] signResult;
- try {
- ContentInfo contentInfo = new ContentInfo(PKCSObjectIdentifiers.signedData, signedData);
- signResult = contentInfo.getEncoded(ASN1Encoding.DER);
- } catch (IOException e) {
- throw new CodeSignException("failed to encode unsigned data!", e);
- }
- verifySignResult(unsignedDataDigest, signResult);
- return signResult;
- }
-
- private void verifySignResult(byte[] unsignedDataDigest, byte[] signResult) throws CodeSignException {
- boolean result = false;
- try {
- result = CmsUtils.verifySignDataWithUnsignedDataDigest(unsignedDataDigest, signResult);
- } catch (CMSException e) {
- throw new CodeSignException("failed to verify signed data and unsigned data digest", e);
- }
- if (!result) {
- throw new CodeSignException("PKCS cms data did not verify");
- }
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CentralDirectory.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CentralDirectory.java
deleted file mode 100644
index e664912a75a6ad8abd5bbd0297205dd5db297405..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CentralDirectory.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.sign;
-
-import com.ohos.hapsigntool.utils.FileUtils;
-
-import org.bouncycastle.util.Strings;
-
-import java.util.Locale;
-import java.util.zip.ZipEntry;
-
-/**
- * Central directory structure
- * further reference to Zip Format
- *
- * @since 2023/09/14
- */
-public class CentralDirectory {
- /**
- * Byte size of all fields before "compression method" in central directory structure
- */
- public static final int BYTE_SIZE_BEFORE_COMPRESSION_METHOD = 10;
-
- /**
- * Byte size of all fields between "compression method" and "file comment length" in central directory structure
- */
- public static final int BYTE_SIZE_BETWEEN_COMPRESSION_MODE_AND_FILE_SIZE = 16;
-
- /**
- * Byte size of all fields between "file comment length" and
- * "relative offset of local header" in central directory structure
- */
- public static final int BYTE_SIZE_BETWEEN_FILE_COMMENT_LENGTH_AND_LOCHDR_RELATIVE_OFFSET = 8;
-
- private final char compressionMethod;
-
- private final char fileNameLength;
-
- private final char extraFieldLength;
-
- private final char fileCommentLength;
-
- private final long relativeOffsetOfLocalHeader;
-
- private final byte[] fileName;
-
- public CentralDirectory(Builder builder) {
- this.compressionMethod = builder.compressionMethod;
- this.fileNameLength = builder.fileNameLength;
- this.extraFieldLength = builder.extraFieldLength;
- this.fileCommentLength = builder.fileCommentLength;
- this.relativeOffsetOfLocalHeader = builder.relativeOffsetOfLocalHeader;
- this.fileName = builder.fileName;
- }
-
- /**
- * Return true if entry is an executable file, i.e. abc or so
- *
- * @return true if entry is an executable file
- */
- public boolean isCodeFile() {
- return FileUtils.isRunnableFile(this.getFileName());
- }
-
- /**
- * Return true if zip entry is uncompressed
- *
- * @return true if zip entry is uncompressed
- */
- public boolean isUncompressed() {
- return this.compressionMethod == ZipEntry.STORED;
- }
-
- public String getFileName() {
- return Strings.fromByteArray(this.fileName);
- }
-
- public long getRelativeOffsetOfLocalHeader() {
- return relativeOffsetOfLocalHeader;
- }
-
- /**
- * Sum byte size of three variable fields: file name, extra field, file comment
- *
- * @return Sum byte size of three variable fields
- */
- public char getFileNameLength() {
- return fileNameLength;
- }
-
- public char getExtraFieldLength() {
- return extraFieldLength;
- }
-
- /**
- * Return a string representation of the object
- *
- * @return string representation of the object
- */
- public String toString() {
- return String.format(Locale.ROOT,
- "CentralDirectory:compressionMode(%d), fileName(%s), relativeOffsetOfLocalHeader(%d), "
- + "fileNameLength(%d), extraFieldLength(%d), fileCommentLength(%d)", (int) this.compressionMethod,
- this.getFileName(), this.relativeOffsetOfLocalHeader, (int) this.fileNameLength,
- (int) this.extraFieldLength, (int) this.fileCommentLength);
- }
-
- /**
- * Builder of CentralDirectory class
- */
- public static class Builder {
- private char compressionMethod;
-
- private char fileNameLength;
-
- private char extraFieldLength;
-
- private char fileCommentLength;
-
- private long relativeOffsetOfLocalHeader;
-
- private byte[] fileName;
-
- public Builder setCompressionMethod(char compressionMethod) {
- this.compressionMethod = compressionMethod;
- return this;
- }
-
- public Builder setFileNameLength(char fileNameLength) {
- this.fileNameLength = fileNameLength;
- return this;
- }
-
- public Builder setExtraFieldLength(char extraFieldLength) {
- this.extraFieldLength = extraFieldLength;
- return this;
- }
-
- public Builder setFileCommentLength(char fileCommentLength) {
- this.fileCommentLength = fileCommentLength;
- return this;
- }
-
- public Builder setRelativeOffsetOfLocalHeader(long relativeOffsetOfLocalHeader) {
- this.relativeOffsetOfLocalHeader = relativeOffsetOfLocalHeader;
- return this;
- }
-
- public Builder setFileName(byte[] fileName) {
- this.fileName = fileName;
- return this;
- }
-
- /**
- * Create a CentralDirectory object
- *
- * @return a CentralDirectory object
- */
- public CentralDirectory build() {
- return new CentralDirectory(this);
- }
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java
deleted file mode 100644
index cb9f3e10013763b8f89dc47e95e24121c2b766dd..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/CodeSigning.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.sign;
-
-import com.ohos.hapsigntool.codesigning.datastructure.CodeSignBlock;
-import com.ohos.hapsigntool.codesigning.datastructure.ElfSignBlock;
-import com.ohos.hapsigntool.codesigning.datastructure.Extension;
-import com.ohos.hapsigntool.codesigning.datastructure.FsVerityInfoSegment;
-import com.ohos.hapsigntool.codesigning.datastructure.MerkleTreeExtension;
-import com.ohos.hapsigntool.codesigning.datastructure.SignInfo;
-import com.ohos.hapsigntool.codesigning.exception.CodeSignException;
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityDescriptor;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityDescriptorWithSign;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityGenerator;
-import com.ohos.hapsigntool.codesigning.utils.HapUtils;
-import com.ohos.hapsigntool.hap.config.SignerConfig;
-import com.ohos.hapsigntool.hap.entity.Pair;
-import com.ohos.hapsigntool.hap.exception.HapFormatException;
-import com.ohos.hapsigntool.hap.exception.ProfileException;
-import com.ohos.hapsigntool.signer.LocalSigner;
-import com.ohos.hapsigntool.utils.FileUtils;
-import com.ohos.hapsigntool.utils.StringUtils;
-import com.ohos.hapsigntool.zip.UnsignedDecimalUtil;
-import com.ohos.hapsigntool.zip.Zip;
-import com.ohos.hapsigntool.zip.ZipEntryHeader;
-import com.ohos.hapsigntool.zip.ZipEntry;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Locale;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * core functions of code signing
- *
- * @since 2023/06/05
- */
-public class CodeSigning {
- /**
- * Only hap and hsp bundle supports code signing, concatenate then with '/' for verification usage
- */
- public static final String SUPPORT_FILE_FORM = "hap/hsp";
-
- /**
- * Only elf file supports bin code signing, concatenate then with '/' for verification usage
- */
- public static final String SUPPORT_BIN_FILE_FORM = "elf";
-
- /**
- * Defined entry name of hap file
- */
- public static final String HAP_SIGNATURE_ENTRY_NAME = "Hap";
-
- private static final Logger LOGGER = LogManager.getLogger(CodeSigning.class);
-
- private static final String NATIVE_LIB_AN_SUFFIX = ".an";
-
- private static final String NATIVE_LIB_SO_SUFFIX = ".so";
-
- private final List extractedNativeLibSuffixs = new ArrayList<>();
-
- private final SignerConfig signConfig;
-
- private CodeSignBlock codeSignBlock;
-
- private long timestamp = 0L;
-
- /**
- * provide code sign functions to sign a hap
- *
- * @param signConfig configuration of sign
- */
- public CodeSigning(SignerConfig signConfig) {
- this.signConfig = signConfig;
- }
-
- /**
- * Sign the given elf file, and pack all signature into output file
- *
- * @param input file to sign
- * @param offset position of codesign block based on start of the file
- * @param inForm file's format
- * @param profileContent profile of the elf
- * @return byte array of code sign block
- * @throws CodeSignException code signing exception
- * @throws IOException io error
- * @throws FsVerityDigestException computing FsVerity digest error
- * @throws ProfileException profile of elf is invalid
- */
- public byte[] getElfCodeSignBlock(File input, long offset, String inForm, String profileContent)
- throws CodeSignException, FsVerityDigestException, IOException, ProfileException {
- if (!SUPPORT_BIN_FILE_FORM.contains(inForm)) {
- throw new CodeSignException("file's format is unsupported");
- }
- long fileSize = input.length();
- int paddingSize = ElfSignBlock.computeMerkleTreePaddingLength(offset);
- long fsvTreeOffset = offset + Integer.BYTES * 2 + paddingSize;
- try (FileInputStream inputStream = new FileInputStream(input)) {
- FsVerityGenerator fsVerityGenerator = new FsVerityGenerator();
- fsVerityGenerator.generateFsVerityDigest(inputStream, fileSize, fsvTreeOffset);
- byte[] fsVerityDigest = fsVerityGenerator.getFsVerityDigest();
- // ownerID should be DEBUG_LIB_ID while signing ELF
- String ownerID = (profileContent == null) ? "DEBUG_LIB_ID" : HapUtils.getAppIdentifier(profileContent);
- byte[] signature = generateSignature(fsVerityDigest, ownerID);
- // add fs-verify info
- FsVerityDescriptor.Builder fsdbuilder = new FsVerityDescriptor.Builder().setFileSize(fileSize)
- .setHashAlgorithm(FsVerityGenerator.getFsVerityHashAlgorithm())
- .setLog2BlockSize(FsVerityGenerator.getLog2BlockSize())
- .setSaltSize((byte) fsVerityGenerator.getSaltSize())
- .setSignSize(signature.length)
- .setFileSize(fileSize)
- .setSalt(fsVerityGenerator.getSalt())
- .setRawRootHash(fsVerityGenerator.getRootHash())
- .setFlags(FsVerityDescriptor.FLAG_STORE_MERKLE_TREE_OFFSET)
- .setMerkleTreeOffset(fsvTreeOffset)
- .setCsVersion(FsVerityDescriptor.CODE_SIGN_VERSION);
- FsVerityDescriptorWithSign fsVerityDescriptorWithSign = new FsVerityDescriptorWithSign(fsdbuilder.build(),
- signature);
- byte[] treeBytes = fsVerityGenerator.getTreeBytes();
- ElfSignBlock signBlock = new ElfSignBlock(paddingSize, treeBytes, fsVerityDescriptorWithSign);
- LOGGER.info("Sign elf successfully.");
- return signBlock.toByteArray();
- }
- }
-
- /**
- * Sign the given hap file, and pack all signature into output file
- *
- * @param input file to sign
- * @param offset position of codesign block based on start of the file
- * @param inForm file's format
- * @param profileContent profile of the hap
- * @param zip zip
- * @return byte array of code sign block
- * @throws CodeSignException code signing exception
- * @throws IOException io error
- * @throws HapFormatException hap format invalid
- * @throws FsVerityDigestException computing FsVerity digest error
- * @throws ProfileException profile of the hap error
- */
- public byte[] getCodeSignBlock(File input, long offset, String inForm, String profileContent, Zip zip)
- throws CodeSignException, IOException, HapFormatException, FsVerityDigestException, ProfileException {
- LOGGER.info("Start to sign code.");
- if (!SUPPORT_FILE_FORM.contains(inForm)) {
- throw new CodeSignException("file's format is unsupported");
- }
- long dataSize = computeDataSize(zip);
- timestamp = System.currentTimeMillis();
- // generate CodeSignBlock
- this.codeSignBlock = new CodeSignBlock();
- // compute merkle tree offset, replace with computeMerkleTreeOffset if fs-verity descriptor supports
- long fsvTreeOffset = this.codeSignBlock.computeMerkleTreeOffset(offset);
- // update fs-verity segment
- FsVerityInfoSegment fsVerityInfoSegment = new FsVerityInfoSegment(FsVerityDescriptor.VERSION,
- FsVerityGenerator.getFsVerityHashAlgorithm(), FsVerityGenerator.getLog2BlockSize());
- this.codeSignBlock.setFsVerityInfoSegment(fsVerityInfoSegment);
-
- LOGGER.debug("Sign hap.");
- String ownerID = HapUtils.getAppIdentifier(profileContent);
-
- try (FileInputStream inputStream = new FileInputStream(input)) {
- Pair hapSignInfoAndMerkleTreeBytesPair = signFile(inputStream, dataSize, true,
- fsvTreeOffset, ownerID);
- // update hap segment in CodeSignBlock
- this.codeSignBlock.getHapInfoSegment().setSignInfo(hapSignInfoAndMerkleTreeBytesPair.getFirst());
- // Insert merkle tree bytes into code sign block
- this.codeSignBlock.addOneMerkleTree(HAP_SIGNATURE_ENTRY_NAME,
- hapSignInfoAndMerkleTreeBytesPair.getSecond());
- }
- // update native lib info segment in CodeSignBlock
- signNativeLibs(input, ownerID);
-
- // last update codeSignBlock before generating its byte array representation
- updateCodeSignBlock(this.codeSignBlock);
-
- // complete code sign block byte array here
- byte[] generated = this.codeSignBlock.generateCodeSignBlockByte(fsvTreeOffset);
- LOGGER.info("Sign successfully.");
- return generated;
- }
-
- private long computeDataSize(Zip zip) throws HapFormatException {
- long dataSize = 0L;
- for (ZipEntry entry : zip.getZipEntries()) {
- ZipEntryHeader zipEntryHeader = entry.getZipEntryData().getZipEntryHeader();
- if (FileUtils.isRunnableFile(zipEntryHeader.getFileName())
- && zipEntryHeader.getMethod() == Zip.FILE_UNCOMPRESS_METHOD_FLAG) {
- continue;
- }
- // if the first file is not uncompressed abc or so, set dataSize to zero
- if (entry.getCentralDirectory().getOffset() == 0) {
- break;
- }
- // the first entry which is not abc/so/an is found, return its data offset
- dataSize = entry.getCentralDirectory().getOffset() + ZipEntryHeader.HEADER_LENGTH
- + zipEntryHeader.getFileNameLength() + zipEntryHeader.getExtraLength();
- break;
- }
- if ((dataSize % CodeSignBlock.PAGE_SIZE_4K) != 0) {
- throw new HapFormatException(
- String.format(Locale.ROOT, "Invalid dataSize(%d), not a multiple of 4096", dataSize));
- }
- return dataSize;
- }
-
- private void signNativeLibs(File input, String ownerID) throws IOException, FsVerityDigestException,
- CodeSignException {
- // 'an' libs are always signed
- extractedNativeLibSuffixs.add(NATIVE_LIB_AN_SUFFIX);
- // 'so' libs are always signed
- extractedNativeLibSuffixs.add(NATIVE_LIB_SO_SUFFIX);
-
- // sign native files
- try (JarFile inputJar = new JarFile(input, false)) {
- List entryNames = getNativeEntriesFromHap(inputJar);
- if (entryNames.isEmpty()) {
- LOGGER.info("No native libs.");
- return;
- }
- List> nativeLibInfoList = signFilesFromJar(entryNames, inputJar, ownerID);
- // update SoInfoSegment in CodeSignBlock
- this.codeSignBlock.getSoInfoSegment().setSoInfoList(nativeLibInfoList);
- }
- }
-
- /**
- * Get entry name of all native files in hap
- *
- * @param hap the given hap
- * @return list of entry name
- */
- private List getNativeEntriesFromHap(JarFile hap) {
- List result = new ArrayList<>();
- for (Enumeration e = hap.entries(); e.hasMoreElements();) {
- JarEntry entry = e.nextElement();
- if (!entry.isDirectory()) {
- if (!isNativeFile(entry.getName())) {
- continue;
- }
- result.add(entry.getName());
- }
- }
- return result;
- }
-
- /**
- * Check whether the entry is a native file
- *
- * @param entryName the name of entry
- * @return true if it is a native file, and false otherwise
- */
- private boolean isNativeFile(String entryName) {
- if (StringUtils.isEmpty(entryName)) {
- return false;
- }
- if (entryName.endsWith(NATIVE_LIB_AN_SUFFIX)) {
- return true;
- }
- if (extractedNativeLibSuffixs.contains(NATIVE_LIB_SO_SUFFIX)) {
- Pattern pattern = FileUtils.SUFFIX_REGEX_MAP.get("so");
- Matcher matcher = pattern.matcher(entryName);
- if (matcher.find()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Sign specific entries in a hap
- *
- * @param entryNames list of entries which need to be signed
- * @param hap input hap
- * @param ownerID app-id in signature to identify
- * @return sign info and merkle tree of each file
- * @throws IOException io error
- * @throws FsVerityDigestException computing FsVerity digest error
- * @throws CodeSignException sign error
- */
- private List> signFilesFromJar(List entryNames, JarFile hap, String ownerID)
- throws IOException, FsVerityDigestException, CodeSignException {
- List> nativeLibInfoList = new ArrayList<>();
- for (String name : entryNames) {
- LOGGER.debug("Sign entry name = " + name);
- JarEntry inEntry = hap.getJarEntry(name);
- try (InputStream inputStream = hap.getInputStream(inEntry)) {
- long fileSize = inEntry.getSize();
- // We don't store merkle tree in code signing of native libs
- // Therefore, the second value of pair returned is ignored
- Pair pairSignInfoAndMerkleTreeBytes = signFile(inputStream, fileSize,
- false, 0, ownerID);
- nativeLibInfoList.add(Pair.create(name, pairSignInfoAndMerkleTreeBytes.getFirst()));
- }
- }
- return nativeLibInfoList;
- }
-
- /**
- * Sign a file from input stream
- *
- * @param inputStream input stream of a file
- * @param fileSize size of the file
- * @param storeTree whether to store merkle tree in signed info
- * @param fsvTreeOffset merkle tree raw bytes offset based on the start of file
- * @param ownerID app-id in signature to identify
- * @return pair of signature and tree
- * @throws FsVerityDigestException computing FsVerity Digest error
- * @throws CodeSignException signing error
- */
- public Pair signFile(InputStream inputStream, long fileSize, boolean storeTree,
- long fsvTreeOffset, String ownerID) throws FsVerityDigestException, CodeSignException {
- FsVerityGenerator fsVerityGenerator = new FsVerityGenerator();
- fsVerityGenerator.generateFsVerityDigest(inputStream, fileSize, fsvTreeOffset);
- byte[] fsVerityDigest = fsVerityGenerator.getFsVerityDigest();
- byte[] signature = generateSignature(fsVerityDigest, ownerID);
- int flags = 0;
- if (storeTree) {
- flags = SignInfo.FLAG_MERKLE_TREE_INCLUDED;
- }
- SignInfo signInfo = new SignInfo(fsVerityGenerator.getSaltSize(), flags, fileSize, fsVerityGenerator.getSalt(),
- signature);
- // if store merkle tree in sign info
- if (storeTree) {
- int merkleTreeSize = fsVerityGenerator.getTreeBytes() == null ? 0 : fsVerityGenerator.getTreeBytes().length;
- Extension merkleTreeExtension = new MerkleTreeExtension(merkleTreeSize, fsvTreeOffset,
- fsVerityGenerator.getRootHash());
- signInfo.addExtension(merkleTreeExtension);
- }
- return Pair.create(signInfo, fsVerityGenerator.getTreeBytes());
- }
-
- private byte[] generateSignature(byte[] signedData, String ownerID) throws CodeSignException {
- // signConfig is created by SignerFactory
- if ((signConfig.getSigner() instanceof LocalSigner)) {
- if (signConfig.getCertificates().isEmpty()) {
- throw new CodeSignException("No certificates configured for sign");
- }
- }
-
- BcSignedDataGenerator bcSignedDataGenerator = new BcSignedDataGenerator();
- bcSignedDataGenerator.setOwnerID(ownerID);
- return bcSignedDataGenerator.generateSignedData(signedData, signConfig);
- }
-
- /**
- * At here, segment header, fsverity info/hap/so info segment, merkle tree
- * segment should all be generated.
- * code sign block size, segment number, offset is not updated.
- * Try to update whatever could be updated here.
- *
- * @param codeSignBlock CodeSignBlock
- */
- private void updateCodeSignBlock(CodeSignBlock codeSignBlock) {
- // construct segment header list
- codeSignBlock.setSegmentHeaders();
- // Compute and set segment number
- codeSignBlock.setSegmentNum();
- // update code sign block header flag
- codeSignBlock.setCodeSignBlockFlag();
- // compute segment offset
- codeSignBlock.computeSegmentOffset();
- }
-
- private List parseCentralDirectory(byte[] buffer, int count) {
- List cdList = new ArrayList<>();
- ByteBuffer cdBuffer = ByteBuffer.allocate(buffer.length).order(ByteOrder.LITTLE_ENDIAN);
- cdBuffer.put(buffer);
- cdBuffer.rewind();
- for (int i = 0; i < count; i++) {
- byte[] bytesBeforeCompressionMethod = new byte[CentralDirectory.BYTE_SIZE_BEFORE_COMPRESSION_METHOD];
- cdBuffer.get(bytesBeforeCompressionMethod);
- char compressionMode = cdBuffer.getChar();
- CentralDirectory.Builder builder = new CentralDirectory.Builder().setCompressionMethod(compressionMode);
- byte[] bytesBetweenCmprMethodAndFileNameLength =
- new byte[CentralDirectory.BYTE_SIZE_BETWEEN_COMPRESSION_MODE_AND_FILE_SIZE];
- cdBuffer.get(bytesBetweenCmprMethodAndFileNameLength);
- char fileNameLength = cdBuffer.getChar();
- char extraFieldLength = cdBuffer.getChar();
- char fileCommentLength = cdBuffer.getChar();
- byte[] attributes =
- new byte[CentralDirectory.BYTE_SIZE_BETWEEN_FILE_COMMENT_LENGTH_AND_LOCHDR_RELATIVE_OFFSET];
- cdBuffer.get(attributes);
- long locHdrOffset = UnsignedDecimalUtil.getUnsignedInt(cdBuffer);
- builder.setFileNameLength(fileNameLength).setExtraFieldLength(extraFieldLength)
- .setFileCommentLength(fileCommentLength).setRelativeOffsetOfLocalHeader(locHdrOffset);
- byte[] fileNameBuffer = new byte[fileNameLength];
- cdBuffer.get(fileNameBuffer);
- if (extraFieldLength != 0) {
- cdBuffer.get(new byte[extraFieldLength]);
- }
- if (fileCommentLength != 0) {
- cdBuffer.get(new byte[fileCommentLength]);
- }
- CentralDirectory cd = builder.setFileName(fileNameBuffer).build();
- cdList.add(cd);
- }
-
- return cdList;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/SignedDataGenerator.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/SignedDataGenerator.java
deleted file mode 100644
index 03d1b2bb4b52d5ccb24ef31c2369e5aa37cd0368..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/SignedDataGenerator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.sign;
-
-import com.ohos.hapsigntool.codesigning.exception.CodeSignException;
-import com.ohos.hapsigntool.hap.config.SignerConfig;
-
-/**
- * Signed data generator interface
- *
- * @since 2023/06/05
- */
-@FunctionalInterface
-public interface SignedDataGenerator {
- /**
- * Create a BcSignedDataGenerator instance
- */
- SignedDataGenerator BC = new BcSignedDataGenerator();
-
- /**
- * Generate signature data with specific content and sign configuration.
- *
- * @param content unsigned file digest content.
- * @param signerConfig sign configurations.
- * @return signed data.
- * @throws CodeSignException if error.
- */
- byte[] generateSignedData(byte[] content, SignerConfig signerConfig) throws CodeSignException;
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/VerifyCodeSignature.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/VerifyCodeSignature.java
deleted file mode 100644
index 3afd589518fd1478439a37f90fc67eacbd28eef5..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/sign/VerifyCodeSignature.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.sign;
-
-import com.ohos.hapsigntool.codesigning.datastructure.CodeSignBlock;
-import com.ohos.hapsigntool.codesigning.datastructure.CodeSignBlockHeader;
-import com.ohos.hapsigntool.codesigning.datastructure.ElfSignBlock;
-import com.ohos.hapsigntool.codesigning.datastructure.Extension;
-import com.ohos.hapsigntool.codesigning.datastructure.FsVerityInfoSegment;
-import com.ohos.hapsigntool.codesigning.datastructure.HapInfoSegment;
-import com.ohos.hapsigntool.codesigning.datastructure.MerkleTreeExtension;
-import com.ohos.hapsigntool.codesigning.datastructure.NativeLibInfoSegment;
-import com.ohos.hapsigntool.codesigning.datastructure.SegmentHeader;
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-import com.ohos.hapsigntool.codesigning.fsverity.FsVerityGenerator;
-import com.ohos.hapsigntool.codesigning.utils.CmsUtils;
-import com.ohos.hapsigntool.codesigning.utils.HapUtils;
-import com.ohos.hapsigntool.hap.entity.Pair;
-import com.ohos.hapsigntool.hap.exception.ProfileException;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.cms.Attribute;
-import org.bouncycastle.asn1.cms.AttributeTable;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.CMSSignedData;
-import org.bouncycastle.cms.SignerInformation;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Locale;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * Verify code signature given a file with code sign block
- *
- * @since 2023/09/08
- */
-public class VerifyCodeSignature {
- private static final Logger LOGGER = LogManager.getLogger(VerifyCodeSignature.class);
-
- private static void checkOwnerID(byte[] signature, String profileOwnerID, String profileType)
- throws CMSException, VerifyCodeSignException {
- String ownerID = profileOwnerID;
- // if profileType is debug, check the app-id in signature, should be null or DEBUG_LIB_ID
- if ("debug".equals(profileType)) {
- ownerID = "DEBUG_LIB_ID";
- }
-
- CMSSignedData cmsSignedData = new CMSSignedData(signature);
- Collection signers = cmsSignedData.getSignerInfos().getSigners();
- Collection results = null;
- for (SignerInformation signer : signers) {
- AttributeTable attrTable = signer.getSignedAttributes();
- Attribute attr = attrTable.get(new ASN1ObjectIdentifier(BcSignedDataGenerator.SIGNER_OID));
- // if app-id is null, if profileType is debug, it's ok.
- if (attr == null) {
- if ("debug".equals(profileType)) {
- continue;
- }
- if (ownerID == null) {
- continue;
- } else {
- throw new VerifyCodeSignException("app-identifier is not in the signature");
- }
- }
- if (ownerID == null) {
- throw new VerifyCodeSignException("app-identifier in profile is null, but is not null in signature");
- }
- // if app-id in signature exists, it should be equal to the app-id in profile.
- String resultOwnerID = attr.getAttrValues().getObjectAt(0).toString();
- if (!ownerID.equals(resultOwnerID)) {
- throw new VerifyCodeSignException("app-identifier in signature is invalid");
- }
- }
- }
-
- /**
- * Verify a signed elf's signature
- *
- * @param file signed elf file
- * @param offset start position of code sign block based on the start of the elf file
- * @param length byte size of code sign block
- * @param fileFormat elf or hqf or hsp, etc.
- * @param profileContent profile json string
- * @return true if signature verify succeed and false otherwise
- * @throws IOException If an input or output exception occurred
- * @throws VerifyCodeSignException parsing result invalid
- * @throws FsVerityDigestException if fs-verity digest generation failed
- * @throws CMSException if signature verify failed
- * @throws ProfileException if verify profile failed
- */
- public static boolean verifyElf(File file, long offset, long length, String fileFormat, String profileContent)
- throws IOException, VerifyCodeSignException, FsVerityDigestException, CMSException, ProfileException {
- if (!CodeSigning.SUPPORT_BIN_FILE_FORM.contains(fileFormat)) {
- LOGGER.info("Not elf file, skip code signing verify");
- return true;
- }
- // 1) parse sign block to ElfCodeSignBlock object
- ElfSignBlock elfSignBlock;
- try (FileInputStream signedElf = new FileInputStream(file)) {
- byte[] codeSignBlockBytes = new byte[(int) length];
- signedElf.skip(offset);
- signedElf.read(codeSignBlockBytes);
- elfSignBlock = ElfSignBlock.fromByteArray(codeSignBlockBytes);
- }
- // 2) verify file data
- try (FileInputStream signedElf = new FileInputStream(file)) {
- int paddingSize = ElfSignBlock.computeMerkleTreePaddingLength(offset);
- byte[] merkleTreeWithPadding = elfSignBlock.getMerkleTreeWithPadding();
- byte[] merkleTree = Arrays.copyOfRange(merkleTreeWithPadding, paddingSize, merkleTreeWithPadding.length);
- verifySingleFile(signedElf, elfSignBlock.getDataSize(), elfSignBlock.getSignature(),
- elfSignBlock.getTreeOffset(), merkleTree);
- }
- if (profileContent != null) {
- Pair pairResult = HapUtils.parseAppIdentifier(profileContent);
- checkOwnerID(elfSignBlock.getSignature(), pairResult.getFirst(), pairResult.getSecond());
- }
- return true;
- }
-
- /**
- * Verify a signed hap's signature
- *
- * @param file signed hap file
- * @param offset start position of code sign block based on the start of the hap file
- * @param length byte size of code sign block
- * @param fileFormat hap or hqf or hsp, etc.
- * @param profileContent profile of the hap
- * @return true if signature verify succeed and false otherwise
- * @throws IOException If an input or output exception occurred
- * @throws VerifyCodeSignException parsing result invalid
- * @throws FsVerityDigestException if fs-verity digest generation failed
- * @throws CMSException if signature verify failed
- * @throws ProfileException profile of the hap failed
- */
- public static boolean verifyHap(File file, long offset, long length, String fileFormat, String profileContent)
- throws IOException, VerifyCodeSignException, FsVerityDigestException, CMSException, ProfileException {
- if (!CodeSigning.SUPPORT_FILE_FORM.contains(fileFormat)) {
- LOGGER.info("Not hap or hsp file, skip code signing verify");
- return true;
- }
- Pair pairResult = HapUtils.parseAppIdentifier(profileContent);
-
- CodeSignBlock csb = generateCodeSignBlock(file, offset, length);
- // 2) verify hap
- try (FileInputStream hap = new FileInputStream(file)) {
- long dataSize = csb.getHapInfoSegment().getSignInfo().getDataSize();
- byte[] signature = csb.getHapInfoSegment().getSignInfo().getSignature();
- Extension extension = csb.getHapInfoSegment()
- .getSignInfo()
- .getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED);
- MerkleTreeExtension mte = new MerkleTreeExtension(0, 0, null);
- if (extension instanceof MerkleTreeExtension) {
- mte = (MerkleTreeExtension) extension;
- }
- // temporary: merkle tree offset set to zero, change to merkleTreeOffset
- verifySingleFile(hap, dataSize, signature, mte.getMerkleTreeOffset(),
- csb.getOneMerkleTreeByFileName(CodeSigning.HAP_SIGNATURE_ENTRY_NAME));
- checkOwnerID(signature, pairResult.getFirst(), pairResult.getSecond());
- }
- // 3) verify native libs
- try (JarFile inputJar = new JarFile(file, false)) {
- for (int i = 0; i < csb.getSoInfoSegment().getSectionNum(); i++) {
- String entryName = csb.getSoInfoSegment().getFileNameList().get(i);
- byte[] entrySig = csb.getSoInfoSegment().getSignInfoList().get(i).getSignature();
- JarEntry entry = inputJar.getJarEntry(entryName);
- if (entry.getSize() != csb.getSoInfoSegment().getSignInfoList().get(i).getDataSize()) {
- throw new VerifyCodeSignException(
- String.format(Locale.ROOT, "Invalid dataSize of native lib %s", entryName));
- }
- InputStream entryInputStream = inputJar.getInputStream(entry);
- // temporary merkleTreeOffset 0
- verifySingleFile(entryInputStream, entry.getSize(), entrySig, 0, null);
- checkOwnerID(entrySig, pairResult.getFirst(), pairResult.getSecond());
- }
- }
- return true;
- }
-
- private static CodeSignBlock generateCodeSignBlock(File file, long offset, long length)
- throws IOException, VerifyCodeSignException {
- CodeSignBlock csb = new CodeSignBlock();
- // 1) parse sign block to CodeSignBlock object
- try (FileInputStream signedHap = new FileInputStream(file)) {
- int fileReadOffset = 0;
- // 0) skip data part, but fileReadOffset remains at start(0)
- signedHap.skip(offset);
- // 1) parse codeSignBlockHeader
- byte[] codeSignBlockHeaderByteArray = new byte[CodeSignBlockHeader.size()];
- fileReadOffset += signedHap.read(codeSignBlockHeaderByteArray);
- csb.setCodeSignBlockHeader(CodeSignBlockHeader.fromByteArray(codeSignBlockHeaderByteArray));
- if (csb.getCodeSignBlockHeader().getBlockSize() != length) {
- throw new VerifyCodeSignException("Invalid code Sign block size of setCodeSignBlockHeader");
- }
- // 2) parse segment headers
- for (int i = 0; i < csb.getCodeSignBlockHeader().getSegmentNum(); i++) {
- byte[] segmentHeaderByteArray = new byte[SegmentHeader.SEGMENT_HEADER_LENGTH];
- fileReadOffset += signedHap.read(segmentHeaderByteArray);
- csb.addToSegmentList(SegmentHeader.fromByteArray(segmentHeaderByteArray));
- }
- // compute merkle tree offset by alignment, based on file start
- long computedTreeOffset = getAlignmentAddr(CodeSignBlock.PAGE_SIZE_4K, fileReadOffset + offset);
- // skip zero padding before merkle tree, adds zero padding length to fileReadOffset
- fileReadOffset += signedHap.skip(computedTreeOffset - offset - fileReadOffset);
- parseMerkleTree(csb, fileReadOffset, signedHap, computedTreeOffset);
- }
- return csb;
- }
-
- private static void parseMerkleTree(CodeSignBlock csb, int readOffset, FileInputStream signedHap,
- long computedTreeOffset) throws VerifyCodeSignException, IOException {
- // check segment offset and segment size
- byte[] merkleTreeBytes = new byte[0];
- int fileReadOffset = readOffset;
- for (SegmentHeader segmentHeader : csb.getSegmentHeaderList()) {
- if (fileReadOffset > segmentHeader.getSegmentOffset()) {
- throw new VerifyCodeSignException("Invaild offset of merkle tree and segment header");
- }
- // get merkle tree bytes
- if (fileReadOffset < segmentHeader.getSegmentOffset()) {
- merkleTreeBytes = new byte[segmentHeader.getSegmentOffset() - fileReadOffset];
- fileReadOffset += signedHap.read(merkleTreeBytes);
- }
- byte[] sh = new byte[segmentHeader.getSegmentSize()];
- fileReadOffset += signedHap.read(sh);
- if (segmentHeader.getType() == SegmentHeader.CSB_FSVERITY_INFO_SEG) {
- // 3) parse fs-verity info segment
- csb.setFsVerityInfoSegment(FsVerityInfoSegment.fromByteArray(sh));
- } else if (segmentHeader.getType() == SegmentHeader.CSB_HAP_META_SEG) {
- // 4) parse hap info segment
- csb.setHapInfoSegment(HapInfoSegment.fromByteArray(sh));
- } else if (segmentHeader.getType() == SegmentHeader.CSB_NATIVE_LIB_INFO_SEG) {
- // 5) parse so info segment
- csb.setSoInfoSegment(NativeLibInfoSegment.fromByteArray(sh));
- }
- }
- if (fileReadOffset != csb.getCodeSignBlockHeader().getBlockSize()) {
- throw new VerifyCodeSignException("Invalid blockSize of getCodeSignBlockHeader");
- }
- // parse merkle tree
- Extension extension = csb.getHapInfoSegment()
- .getSignInfo()
- .getExtensionByType(MerkleTreeExtension.MERKLE_TREE_INLINED);
- if (extension == null) {
- throw new VerifyCodeSignException("Missing merkleTreeExtension in verifycation");
- }
- if (extension instanceof MerkleTreeExtension) {
- MerkleTreeExtension mte = (MerkleTreeExtension) extension;
- if (computedTreeOffset != mte.getMerkleTreeOffset()) {
- throw new VerifyCodeSignException("Invalid merkle tree offset");
- }
- if (merkleTreeBytes.length != mte.getMerkleTreeSize()) {
- throw new VerifyCodeSignException("Invalid merkle tree size");
- }
- csb.addOneMerkleTree(CodeSigning.HAP_SIGNATURE_ENTRY_NAME, merkleTreeBytes);
- }
- }
-
- private static long getAlignmentAddr(long alignment, long input) {
- long residual = input % alignment;
- if (residual == 0) {
- return input;
- } else {
- return input + (alignment - residual);
- }
- }
-
- /**
- * Verifies the signature of a given file with its signature in pkcs#7 format
- *
- * @param input file being verified in InputStream representation
- * @param length size of signed data in the file
- * @param signature byte array of signature in pkcs#7 format
- * @param merkleTreeOffset merkle tree offset based on file start
- * @param inMerkleTreeBytes merkle tree raw bytes
- * @throws FsVerityDigestException if fs-verity digest generation failed
- * @throws CMSException if signature verify failed
- * @throws VerifyCodeSignException parsing code sign block error
- */
- public static void verifySingleFile(InputStream input, long length, byte[] signature, long merkleTreeOffset,
- byte[] inMerkleTreeBytes) throws FsVerityDigestException, CMSException, VerifyCodeSignException {
- Pair pairResult = generateFsVerityDigest(input, length, merkleTreeOffset);
- byte[] generatedMerkleTreeBytes = pairResult.getSecond();
- if (generatedMerkleTreeBytes == null) {
- generatedMerkleTreeBytes = new byte[0];
- }
- // For native libs, inMerkleTreeBytes is null, skip check here
- if ((inMerkleTreeBytes != null) && !Arrays.equals(inMerkleTreeBytes, generatedMerkleTreeBytes)) {
- throw new VerifyCodeSignException("verify merkle tree bytes failed");
- }
- CmsUtils.verifySignDataWithUnsignedDataDigest(pairResult.getFirst(), signature);
- }
-
- private static Pair generateFsVerityDigest(InputStream inputStream, long size,
- long merkleTreeOffset) throws FsVerityDigestException {
- FsVerityGenerator fsVerityGenerator = new FsVerityGenerator();
- fsVerityGenerator.generateFsVerityDigest(inputStream, size, merkleTreeOffset);
- return Pair.create(fsVerityGenerator.getFsVerityDigest(), fsVerityGenerator.getTreeBytes());
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java
deleted file mode 100644
index df4b11a7d18f1de22400abd3c26d36f17946ec53..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/CmsUtils.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.utils;
-
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.CMSProcessableByteArray;
-import org.bouncycastle.cms.CMSSignedData;
-import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-
-import java.security.Security;
-import java.security.cert.CertificateException;
-import java.util.Collection;
-
-/**
- * CMS utils class
- *
- * @since 2023/06/05
- */
-public class CmsUtils {
- static {
- if (Security.getProvider("BC") == null) {
- Security.addProvider(new BouncyCastleProvider());
- }
- }
-
- /**
- * Private constructor
- */
- private CmsUtils() {
- }
-
- private static void isCollectionValid(Collection collection)
- throws OperatorCreationException {
- if (collection == null) {
- throw new OperatorCreationException("No matched cert: " + collection);
- }
- if (collection.size() != 1) {
- throw new OperatorCreationException(
- "More than one matched certs, matched certs size: " + collection.size());
- }
- }
-
- @SuppressWarnings("unchecked")
- private static boolean verifyCmsSignedData(CMSSignedData cmsSignedData) throws CMSException {
- return cmsSignedData.verifySignatures(signId -> {
- Collection collection = cmsSignedData.getCertificates().getMatches(signId);
- isCollectionValid(collection);
- X509CertificateHolder cert = collection.iterator().next();
- try {
- return new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert);
- } catch (CertificateException e) {
- throw new OperatorCreationException("Verify BC signatures failed: " + e.getMessage(), e);
- }
- });
- }
-
- /**
- * Verify signed data using an unsigned data digest
- *
- * @param unsignedDataDigest unsigned data digest
- * @param signedData signed data
- * @return true if verify success
- * @throws CMSException if error
- */
- public static boolean verifySignDataWithUnsignedDataDigest(byte[] unsignedDataDigest, byte[] signedData)
- throws CMSException {
- CMSSignedData cmsSignedData = new CMSSignedData(new CMSProcessableByteArray(unsignedDataDigest), signedData);
- return verifyCmsSignedData(cmsSignedData);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/DigestUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/DigestUtils.java
deleted file mode 100644
index aafbaf577149d08d65b1f4052d54ed1e5836bd0b..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/DigestUtils.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.utils;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Digest util class
- *
- * @since 2023/06/05
- */
-public class DigestUtils {
- /**
- * digest the inputContent with specific algorithm
- *
- * @param inputContentArray input Content Array
- * @param algorithm hash algorithm
- * @return the result of digest, is a byte array
- * @throws NoSuchAlgorithmException if error
- */
- public static byte[] computeDigest(byte[] inputContentArray, String algorithm) throws NoSuchAlgorithmException {
- MessageDigest md = MessageDigest.getInstance(algorithm);
- md.update(inputContentArray);
- return md.digest();
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java
deleted file mode 100644
index 6d92964a6acc31f27f53044e463949cd98b616b5..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/HapUtils.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.utils;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
-import com.ohos.hapsigntool.hap.entity.Pair;
-import com.ohos.hapsigntool.hap.exception.ProfileException;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * utility for check hap configs
- *
- * @since 2023/06/05
- */
-public class HapUtils {
- private static final Logger LOGGER = LogManager.getLogger(HapUtils.class);
-
- private static final String COMPRESS_NATIVE_LIBS_OPTION = "compressNativeLibs";
-
- private static final List HAP_CONFIG_FILES = new ArrayList<>();
-
- private static final String HAP_FA_CONFIG_JSON_FILE = "config.json";
-
- private static final String HAP_STAGE_MODULE_JSON_FILE = "module.json";
-
- private static final String HAP_DEBUG_OWNER_ID = "DEBUG_LIB_ID";
-
- private static final int MAX_APP_ID_LEN = 32; // max app-identifier in profile
-
- static {
- HAP_CONFIG_FILES.add(HAP_FA_CONFIG_JSON_FILE);
- HAP_CONFIG_FILES.add(HAP_STAGE_MODULE_JSON_FILE);
- }
-
- private HapUtils() {
- }
-
- /**
- * Check configuration in hap to find out whether the native libs are compressed
- *
- * @param hapFile the given hap
- * @return boolean value of parsing result
- * @throws IOException io error
- */
- public static boolean checkCompressNativeLibs(File hapFile) throws IOException {
- try (JarFile inputJar = new JarFile(hapFile, false)) {
- for (String configFile : HAP_CONFIG_FILES) {
- JarEntry entry = inputJar.getJarEntry(configFile);
- if (entry == null) {
- continue;
- }
- try (InputStream data = inputJar.getInputStream(entry)) {
- String jsonString = new String(InputStreamUtils.toByteArray(data, (int) entry.getSize()),
- StandardCharsets.UTF_8);
- return checkCompressNativeLibs(jsonString);
- }
- }
- }
- return true;
- }
-
- /**
- * Check whether the native libs are compressed by parsing config json
- *
- * @param jsonString the config json string
- * @return boolean value of parsing result
- */
- public static boolean checkCompressNativeLibs(String jsonString) {
- JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
- Queue queue = new LinkedList<>();
- queue.offer(jsonObject);
- while (queue.size() > 0) {
- JsonObject curJsonObject = queue.poll();
- JsonElement jsonElement = curJsonObject.get(COMPRESS_NATIVE_LIBS_OPTION);
- if (jsonElement != null) {
- return jsonElement.getAsBoolean();
- }
- for (Map.Entry entry : curJsonObject.entrySet()) {
- if (entry.getValue().isJsonObject()) {
- queue.offer(entry.getValue().getAsJsonObject());
- }
- }
- }
- // default to compress native libs
- return true;
- }
-
- /**
- * get app-id from profile
- *
- * @param profileContent the content of profile
- * @return string value of app-id
- * @throws ProfileException profile is invalid
- */
- public static String getAppIdentifier(String profileContent) throws ProfileException {
- Pair resultPair = parseAppIdentifier(profileContent);
- String ownerID = resultPair.getFirst();
- String profileType = resultPair.getSecond();
- if ("debug".equals(profileType)) {
- return HAP_DEBUG_OWNER_ID;
- } else if ("release".equals(profileType)) {
- return ownerID;
- } else {
- throw new ProfileException("unsupported profile type");
- }
- }
-
- /**
- * parse app-id and profileType from profile
- *
- * @param profileContent the content of profile
- * @return Pair value of app-id and profileType
- * @throws ProfileException profile is invalid
- */
- public static Pair parseAppIdentifier(String profileContent) throws ProfileException {
- String ownerID = null;
- String profileType = null;
- try {
- JsonElement parser = JsonParser.parseString(profileContent);
- JsonObject profileJson = parser.getAsJsonObject();
- String profileTypeKey = "type";
- if (!profileJson.has(profileTypeKey)) {
- throw new ProfileException("profile has no type key");
- }
-
- profileType = profileJson.get(profileTypeKey).getAsString();
- if (profileType == null || profileType.length() == 0) {
- throw new ProfileException("Get profile type error");
- }
-
- String appIdentifier = "app-identifier";
- String buildInfoMember = "bundle-info";
- JsonObject buildInfoObject = profileJson.getAsJsonObject(buildInfoMember);
- if (buildInfoObject == null) {
- throw new ProfileException("can not find bundle-info");
- }
- if (buildInfoObject.has(appIdentifier)) {
- JsonElement ownerIDElement = buildInfoObject.get(appIdentifier);
- if (!ownerIDElement.getAsJsonPrimitive().isString()) {
- throw new ProfileException("value of app-identifier is not string");
- }
- ownerID = ownerIDElement.getAsString();
- if (ownerID.isEmpty() || ownerID.length() > MAX_APP_ID_LEN) {
- throw new ProfileException("app-id length in profile is invalid");
- }
-
- }
- } catch (JsonSyntaxException | UnsupportedOperationException e) {
- LOGGER.error(e.getMessage());
- throw new ProfileException("profile json is invalid");
- }
- return Pair.create(ownerID, profileType);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/InputStreamUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/InputStreamUtils.java
deleted file mode 100644
index 816ea38c1138737404e0bdadab2e196c5b8d3cfd..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/codesigning/utils/InputStreamUtils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.codesigning.utils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * InputStream util class
- *
- * @since 2023/08/10
- */
-public class InputStreamUtils {
- private static final int BUFFER_SIZE = 4096;
-
- /**
- * get byte array by inputStream and size
- *
- * @param inputStream inputStream data
- * @param inputStreamSize inputStream size
- * @return byte array value
- * @throws IOException io error
- */
- public static byte[] toByteArray(InputStream inputStream, int inputStreamSize) throws IOException {
- if (inputStreamSize == 0) {
- return new byte[0];
- }
- if (inputStreamSize < 0) {
- throw new IllegalArgumentException("inputStreamSize: " + inputStreamSize + "is less than zero: ");
- }
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- copy(inputStream, inputStreamSize, output);
- return output.toByteArray();
- }
-
- private static int copy(InputStream inputStream, int inputStreamSize, OutputStream output) throws IOException {
- byte[] buffer = new byte[BUFFER_SIZE];
- int readSize = 0;
- int count = 0;
- while (readSize < inputStreamSize && (readSize = inputStream.read(buffer)) != -1) {
- output.write(buffer, 0, readSize);
- count += readSize;
- }
- if (count != inputStreamSize) {
- throw new IOException("read size err. readSizeCount: " + count + ", inputStreamSize: " + inputStreamSize);
- }
- return count;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ERROR.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ERROR.java
index 2f2627faa8bcc285f2e648dde255108359461151..286031eef28f9834822ad4c033407b001f43f3fd 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ERROR.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ERROR.java
@@ -88,12 +88,7 @@ public enum ERROR {
/**
* Enum constant IO_CSR_ERROR.
*/
- IO_CSR_ERROR(118),
-
- /**
- * Enum constant ZIP_ERROR.
- */
- ZIP_ERROR(119);
+ IO_CSR_ERROR(118);
/**
* Field errorCode.
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/VerifyException.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/VerifyException.java
deleted file mode 100644
index fb204b53f01dafcae06eaa3887ba8040a4638b79..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/VerifyException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.error;
-
-/**
- * verify exception.
- *
- * @since 2023/08/26
- */
-public class VerifyException extends Exception {
- /**
- * Create VerifyException with params.
- *
- * @param message Error msg to throw
- */
- public VerifyException(String message) {
- super(message);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ZipException.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ZipException.java
deleted file mode 100644
index 6ad0dfb29d8ae3c5ce6463094d3064dcebfc02ed..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/error/ZipException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.error;
-
-import java.io.IOException;
-
-/**
- * Zip exception for programs.
- *
- * @since 2023/12/07
- */
-public class ZipException extends IOException {
- /**
- * new ZipException
- *
- * @param message exception message
- */
- public ZipException(String message) {
- super(message);
- }
-
- /**
- * new ZipException
- *
- * @param message exception message
- * @param e exception
- */
- public ZipException(String message, Exception e) {
- super(message, e);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/ElfBlockData.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/ElfBlockData.java
deleted file mode 100644
index b8cdd1ad6ed0b53ae902d9485f8235f7533ac6dc..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/ElfBlockData.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.hap.entity;
-
-/**
- * Elf block info
- *
- * @since 2023/11/20
- */
-public class ElfBlockData {
- int blockNum;
- int blockStart;
-
- public ElfBlockData(int blockNum, int blockStart) {
- this.blockNum = blockNum;
- this.blockStart = blockStart;
- }
-
- public int getBlockNum() {
- return blockNum;
- }
-
- public void setBlockNum(int blockNum) {
- this.blockNum = blockNum;
- }
-
- public int getBlockStart() {
- return blockStart;
- }
-
- public void setBlockStart(int blockStart) {
- this.blockStart = blockStart;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwBlockHead.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwBlockHead.java
index c790e885625a4e9d09e75bd74bd77a96849f5899..ba283115a5b10dda774221383ee316b0730d446b 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwBlockHead.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwBlockHead.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -15,24 +15,11 @@
package com.ohos.hapsigntool.hap.entity;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
/**
* define class of hap signature sub-block head
- *
- * @since 2023/11/07
*/
public class HwBlockHead {
- /**
- * bin file sign block length is 8 byte
- */
- public static final int BLOCK_LEN = 8;
-
- /**
- * elf file sign block length is 12 byte
- */
- public static final int ELF_BLOCK_LEN = 12;
+ private static final int BLOCK_LEN = 8; // current block length
private static final int BIT_SIZE = 8;
@@ -40,26 +27,15 @@ public class HwBlockHead {
private static final int TRIPLE_BIT_SIZE = 24;
- /**
- * get bin block length
- *
- * @return return bin block length
- */
public static int getBlockLen() {
return BLOCK_LEN;
}
- /**
- * get elf block length
- *
- * @return return elf block length
- */
- public static int getElfBlockLen() {
- return ELF_BLOCK_LEN;
+ private HwBlockHead() {
}
/**
- * get serialization of file type bin BlockHead
+ * get serialization of HwBlockHead
*
* @param type type of signature block
* @param tag tags of signature block
@@ -79,22 +55,4 @@ public class HwBlockHead {
(byte) (offset & 0xff)
};
}
-
- /**
- * get serialization of file type elf BlockHead
- *
- * @param type type of signature block
- * @param tag tags of signature block
- * @param length the length of block data
- * @param offset Byte offset of the data block relative to the start position of the signature block
- * @return Byte array after serialization of HwBlockHead
- */
- public static byte[] getBlockHeadLittleEndian(char type, char tag, int length, int offset) {
- ByteBuffer bf = ByteBuffer.allocate(HwBlockHead.ELF_BLOCK_LEN).order(ByteOrder.LITTLE_ENDIAN);
- bf.putChar(type);
- bf.putChar(tag);
- bf.putInt(length);
- bf.putInt(offset);
- return bf.array();
- }
}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwSignHead.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwSignHead.java
index 46ce01fe83e56c0f74f4367349864afdf3f538c9..6584253be06e08e60d4453b73e2680644787b073 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwSignHead.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/HwSignHead.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -18,8 +18,6 @@ package com.ohos.hapsigntool.hap.entity;
import com.ohos.hapsigntool.utils.ByteArrayUtils;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
/**
* define class of hap signature block head
@@ -32,29 +30,14 @@ public class HwSignHead {
*/
public static final int SIGN_HEAD_LEN = 32;
- /**
- * sign hap magic string 16Bytes-Magic
- */
- public static final char[] MAGIC = "hw signed app ".toCharArray();
-
- /**
- * sign elf magic string 16Bytes-Magic
- */
- public static final char[] ELF_MAGIC = "elf sign block ".toCharArray();
-
- /**
- * sign block version 4-Bytes, version is 1.0.0.0
- */
- public static final char[] VERSION = "1000".toCharArray();
-
+ private static final char[] MAGIC = "hw signed app ".toCharArray(); // 16Bytes-Magic
+ private static final char[] VERSION = "1000".toCharArray(); // 4-Bytes, version is 1.0.0.0
private static final int NUM_OF_BLOCK = 2; // number of sub-block
-
private static final int RESERVE_LENGTH = 4;
-
private char[] reserve = new char[RESERVE_LENGTH];
/**
- * get serialization of HwSignHead file type of bin
+ * get serialization of HwSignHead
*
* @param subBlockSize the total size of all sub-blocks
* @return Byte array after serialization of HwSignHead
@@ -89,27 +72,4 @@ public class HwSignHead {
}
return signHead;
}
-
- /**
- * get serialization of HwSignHead file type of elf
- *
- * @param subBlockSize the total size of all sub-blocks
- * @param subBlockNum the sign block num
- * @return Byte array after serialization of HwSignHead
- */
- public byte[] getSignHeadLittleEndian(int subBlockSize, int subBlockNum) {
- ByteBuffer bf = ByteBuffer.allocate(SIGN_HEAD_LEN).order(ByteOrder.LITTLE_ENDIAN);
- for (char c : ELF_MAGIC) {
- bf.put((byte) c);
- }
- for (char c : VERSION) {
- bf.put((byte) c);
- }
- bf.putInt(subBlockSize);
- bf.putInt(subBlockNum);
- for (char c : reserve) {
- bf.put((byte) c);
- }
- return bf.array();
- }
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SignBlockData.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SignBlockData.java
deleted file mode 100644
index 2ad9874f082283de6f42c1ab2bee9bd95cf96c27..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SignBlockData.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.hap.entity;
-
-import com.ohos.hapsigntool.utils.FileUtils;
-
-/**
- * sign block data
- *
- * @since 2023-11-07
- */
-public class SignBlockData {
- private char type;
- private byte[] blockHead;
- private byte[] signData;
- private String signFile;
- private long len;
- private boolean isByte;
-
- public SignBlockData(byte[] signData, char type) {
- this.signData = signData;
- this.type = type;
- this.len = signData == null ? 0 : signData.length;
- this.isByte = true;
- }
-
- public SignBlockData(String signFile, char type) {
- this.signFile = signFile;
- this.type = type;
- this.len = FileUtils.getFileLen(signFile);
- this.isByte = false;
- }
-
- public char getType() {
- return type;
- }
-
- public void setType(char type) {
- this.type = type;
- }
-
- public byte[] getBlockHead() {
- return blockHead;
- }
-
- public void setBlockHead(byte[] blockHead) {
- this.blockHead = blockHead;
- }
-
- public byte[] getSignData() {
- return signData;
- }
-
- public void setSignData(byte[] signData) {
- this.signData = signData;
- }
-
- public String getSignFile() {
- return signFile;
- }
-
- public void setSignFile(String signFile) {
- this.signFile = signFile;
- }
-
- public long getLen() {
- return len;
- }
-
- public void setLen(long len) {
- this.len = len;
- }
-
- public boolean isByte() {
- return isByte;
- }
-
- public void setByte(boolean isByte) {
- this.isByte = isByte;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SigningBlock.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SigningBlock.java
index 663dd56ee4a81f39bc2fa96a21ee394c43de0cea..0794f0d781f781bdeafbf385b88bb149c2f34728 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SigningBlock.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/entity/SigningBlock.java
@@ -25,14 +25,6 @@ public class SigningBlock {
private int length;
private byte[] value;
- private int offset;
-
- /**
- * Init Signing Block type and value
- *
- * @param type signing type
- * @param value signing value
- */
public SigningBlock(int type, byte[] value) {
super();
this.type = type;
@@ -40,21 +32,6 @@ public class SigningBlock {
this.value = value;
}
- /**
- * Init Signing Block type and value
- *
- * @param type signing type
- * @param value signing value
- * @param offset signing block offset
- */
- public SigningBlock(int type, byte[] value, int offset) {
- super();
- this.type = type;
- this.length = value.length;
- this.value = value;
- this.offset = offset;
- }
-
public int getType() {
return type;
}
@@ -66,8 +43,4 @@ public class SigningBlock {
public byte[] getValue() {
return value;
}
-
- public int getOffset() {
- return offset;
- }
}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java
index b0e1fa3fb6a0851dddaf2ce08fabb213a01b8cbf..731abb15719b00e6f84d2dc039efbc807455c522 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/LocalJKSSignProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -21,7 +21,6 @@ import com.ohos.hapsigntool.hap.exception.MissingParamsException;
import com.ohos.hapsigntool.utils.FileUtils;
import com.ohos.hapsigntool.utils.ParamConstants;
import com.ohos.hapsigntool.utils.ParamProcessUtil;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -88,9 +87,9 @@ public class LocalJKSSignProvider extends SignProvider {
public void checkParams(Options options) throws InvalidParamsException, MissingParamsException {
super.checkParams(options);
String[] paramFileds = {
- ParamConstants.PARAM_LOCAL_JKS_KEYSTORE,
- ParamConstants.PARAM_LOCAL_JKS_KEYSTORE_CODE,
- ParamConstants.PARAM_LOCAL_JKS_KEYALIAS_CODE
+ ParamConstants.PARAM_LOCAL_JKS_KEYSTORE,
+ ParamConstants.PARAM_LOCAL_JKS_KEYSTORE_CODE,
+ ParamConstants.PARAM_LOCAL_JKS_KEYALIAS_CODE
};
Set paramSet = ParamProcessUtil.initParamField(paramFileds);
@@ -104,7 +103,7 @@ public class LocalJKSSignProvider extends SignProvider {
}
}
}
- checkSignCode();
+
checkPublicKeyPath();
}
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java
index 3d0a6d494dded3cc29ee61699b6a364f122efb62..e5da2793d25edba4ad9865b44d7f2785c1a6523c 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/provider/SignProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -15,28 +15,21 @@
package com.ohos.hapsigntool.hap.provider;
-import static com.ohos.hapsigntool.codesigning.sign.CodeSigning.SUPPORT_BIN_FILE_FORM;
-import static com.ohos.hapsigntool.codesigning.sign.CodeSigning.SUPPORT_FILE_FORM;
-
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.ohos.hapsigntool.api.model.Options;
-import com.ohos.hapsigntool.codesigning.exception.CodeSignException;
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.sign.CodeSigning;
import com.ohos.hapsigntool.error.CustomException;
import com.ohos.hapsigntool.hap.config.SignerConfig;
import com.ohos.hapsigntool.hap.entity.SigningBlock;
-import com.ohos.hapsigntool.hap.exception.HapFormatException;
import com.ohos.hapsigntool.hap.exception.InvalidParamsException;
import com.ohos.hapsigntool.hap.exception.MissingParamsException;
import com.ohos.hapsigntool.hap.exception.ProfileException;
import com.ohos.hapsigntool.hap.exception.SignatureException;
import com.ohos.hapsigntool.hap.exception.VerifyCertificateChainException;
+import com.ohos.hapsigntool.hap.exception.HapFormatException;
import com.ohos.hapsigntool.hap.sign.SignBin;
-import com.ohos.hapsigntool.hap.sign.SignElf;
import com.ohos.hapsigntool.hap.sign.SignHap;
import com.ohos.hapsigntool.hap.sign.SignatureAlgorithm;
import com.ohos.hapsigntool.hap.verify.VerifyUtils;
@@ -51,7 +44,6 @@ import com.ohos.hapsigntool.utils.StringUtils;
import com.ohos.hapsigntool.zip.ByteBufferZipDataInput;
import com.ohos.hapsigntool.zip.RandomAccessFileZipDataInput;
import com.ohos.hapsigntool.zip.RandomAccessFileZipDataOutput;
-import com.ohos.hapsigntool.zip.Zip;
import com.ohos.hapsigntool.zip.ZipDataInput;
import com.ohos.hapsigntool.zip.ZipDataOutput;
import com.ohos.hapsigntool.zip.ZipFileInfo;
@@ -64,10 +56,10 @@ import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
@@ -81,8 +73,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
+import java.util.TimeZone;
+import java.util.Optional;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
/**
* Sign provider super class
@@ -106,7 +101,6 @@ public abstract class SignProvider {
VALID_SIGN_ALG_NAME.add(ParamConstants.HAP_SIG_ALGORITHM_SHA256_RSA_MGF1);
VALID_SIGN_ALG_NAME.add(ParamConstants.HAP_SIG_ALGORITHM_SHA384_RSA_MGF1);
VALID_SIGN_ALG_NAME.add(ParamConstants.HAP_SIG_ALGORITHM_SHA512_RSA_MGF1);
- Security.addProvider(new BouncyCastleProvider());
}
static {
@@ -125,8 +119,6 @@ public abstract class SignProvider {
*/
protected Map signParams = new HashMap();
- private String profileContent;
-
/**
* Read data of optional blocks from file user inputted.
*
@@ -227,7 +219,7 @@ public abstract class SignProvider {
List signatureAlgorithms = new ArrayList();
signatureAlgorithms.add(
- ParamProcessUtil.getSignatureAlgorithm(this.signParams.get(ParamConstants.PARAM_BASIC_SIGANTURE_ALG)));
+ ParamProcessUtil.getSignatureAlgorithm(this.signParams.get(ParamConstants.PARAM_BASIC_SIGANTURE_ALG)));
signerConfig.setSignatureAlgorithms(signatureAlgorithms);
if (!crl.equals(Optional.empty())) {
@@ -243,6 +235,7 @@ public abstract class SignProvider {
* @return true, if sign successfully.
*/
public boolean signBin(Options options) {
+ Security.addProvider(new BouncyCastleProvider());
List publicCert = null;
SignerConfig signerConfig;
try {
@@ -268,47 +261,6 @@ public abstract class SignProvider {
return true;
}
- /**
- * sign elf file
- *
- * @param options parameters used to sign elf file
- * @return true, if sign successfully.
- */
- public boolean signElf(Options options) {
- List publicCert = null;
- SignerConfig signerConfig = null;
- try {
- publicCert = getX509Certificates(options);
-
- // Get x509 CRL
- Optional crl = getCrl();
-
- // Create signer configs, which contains public cert and crl info.
- signerConfig = createSignerConfigs(publicCert, crl, options);
- } catch (InvalidKeyException | InvalidParamsException | MissingParamsException | ProfileException e) {
- LOGGER.error("create signer configs failed.", e);
- printErrorLogWithoutStack(e);
- return false;
- }
-
- if (ParamConstants.ProfileSignFlag.DISABLE_SIGN_CODE.getSignFlag().equals(
- signParams.get(ParamConstants.PARAM_BASIC_PROFILE_SIGNED))) {
- LOGGER.error("hap-sign-tool: error: Sign elf can not use unsigned profile.");
- return false;
- }
-
- if (profileContent != null) {
- signParams.put(ParamConstants.PARAM_PROFILE_JSON_CONTENT, profileContent);
- }
- /* 6. make signed file into output file. */
- if (!SignElf.sign(signerConfig, signParams)) {
- LOGGER.error("hap-sign-tool: error: Sign elf internal failed.");
- return false;
- }
- LOGGER.info("Sign success");
- return true;
- }
-
/**
* sign hap file
*
@@ -316,6 +268,7 @@ public abstract class SignProvider {
* @return true, if sign successfully
*/
public boolean sign(Options options) {
+ Security.addProvider(new BouncyCastleProvider());
List publicCerts = null;
File output = null;
File tmpOutput = null;
@@ -326,16 +279,15 @@ public abstract class SignProvider {
checkCompatibleVersion();
File input = new File(signParams.get(ParamConstants.PARAM_BASIC_INPUT_FILE));
output = new File(signParams.get(ParamConstants.PARAM_BASIC_OUTPUT_FILE));
- String suffix = getFileSuffix(input);
if (input.getCanonicalPath().equals(output.getCanonicalPath())) {
- tmpOutput = File.createTempFile("signedHap", "." + suffix);
+ tmpOutput = File.createTempFile("signedHap", ".hap");
isPathOverlap = true;
} else {
tmpOutput = output;
}
// copy file and Alignment
int alignment = Integer.parseInt(signParams.get(ParamConstants.PARAM_BASIC_ALIGNMENT));
- Zip zip = copyFileAndAlignment(input, tmpOutput, alignment);
+ copyFileAndAlignment(input, tmpOutput, alignment);
// generate sign block and output signedHap
try (RandomAccessFile outputHap = new RandomAccessFile(tmpOutput, "rw")) {
ZipDataInput outputHapIn = new RandomAccessFileZipDataInput(outputHap);
@@ -343,8 +295,9 @@ public abstract class SignProvider {
long centralDirectoryOffset = zipInfo.getCentralDirectoryOffset();
ZipDataInput beforeCentralDir = outputHapIn.slice(0, centralDirectoryOffset);
ByteBuffer centralDirBuffer =
- outputHapIn.createByteBuffer(centralDirectoryOffset, zipInfo.getCentralDirectorySize());
+ outputHapIn.createByteBuffer(centralDirectoryOffset, zipInfo.getCentralDirectorySize());
ZipDataInput centralDirectory = new ByteBufferZipDataInput(centralDirBuffer);
+
ByteBuffer eocdBuffer = zipInfo.getEocd();
ZipDataInput eocd = new ByteBufferZipDataInput(eocdBuffer);
@@ -353,7 +306,6 @@ public abstract class SignProvider {
signerConfig.setCompatibleVersion(Integer.parseInt(
signParams.get(ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION)));
ZipDataInput[] contents = {beforeCentralDir, centralDirectory, eocd};
- appendCodeSignBlock(signerConfig, tmpOutput, suffix, centralDirectoryOffset, zip);
byte[] signingBlock = SignHap.sign(contents, signerConfig, optionalBlocks);
long newCentralDirectoryOffset = centralDirectoryOffset + signingBlock.length;
ZipUtils.setCentralDirectoryOffset(eocdBuffer, newCentralDirectoryOffset);
@@ -362,8 +314,8 @@ public abstract class SignProvider {
outputSignedFile(outputHap, centralDirectoryOffset, signingBlock, centralDirectory, eocdBuffer);
isRet = true;
}
- } catch (FsVerityDigestException | InvalidKeyException | HapFormatException | MissingParamsException
-|InvalidParamsException |ProfileException |NumberFormatException |CustomException |IOException |CodeSignException e) {
+ } catch (IOException | InvalidKeyException | HapFormatException | MissingParamsException
+ | InvalidParamsException | ProfileException | NumberFormatException | CustomException e) {
printErrorLogWithoutStack(e);
} catch (SignatureException e) {
printErrorLog(e);
@@ -371,60 +323,6 @@ public abstract class SignProvider {
return doAfterSign(isRet, isPathOverlap, tmpOutput, output);
}
- /**
- * append code signBlock
- *
- * @param signerConfig signerConfig
- * @param tmpOutput temp output file
- * @param suffix suffix
- * @param centralDirectoryOffset central directory offset
- * @param zip zip
- * @throws FsVerityDigestException FsVerity digest on error
- * @throws CodeSignException code sign on error
- * @throws IOException IO error
- * @throws HapFormatException hap format on error
- * @throws ProfileException profile of app is invalid
- */
- private void appendCodeSignBlock(SignerConfig signerConfig, File tmpOutput, String suffix,
- long centralDirectoryOffset, Zip zip)
- throws FsVerityDigestException, CodeSignException, IOException, HapFormatException, ProfileException {
- if (!SUPPORT_BIN_FILE_FORM.contains(suffix) && !SUPPORT_FILE_FORM.contains(suffix)) {
- LOGGER.warn("no need to sign code for :" + suffix);
- return;
- }
- if (signParams.get(ParamConstants.PARAM_SIGN_CODE)
- .equals(ParamConstants.SignCodeFlag.ENABLE_SIGN_CODE.getSignCodeFlag())) {
- // 4 means hap format occupy 4 byte storage location,2 means optional blocks reserve 2 storage location
- long codeSignOffset = centralDirectoryOffset + ((4 + 4 + 4) * (optionalBlocks.size() + 2) + (4 + 4 + 4));
- // create CodeSigning Object
- CodeSigning codeSigning = new CodeSigning(signerConfig);
- byte[] codeSignArray = codeSigning.getCodeSignBlock(tmpOutput, codeSignOffset, suffix, profileContent, zip);
- ByteBuffer result = ByteBuffer.allocate(codeSignArray.length + (4 + 4 + 4));
- result.order(ByteOrder.LITTLE_ENDIAN);
- result.putInt(HapUtils.HAP_CODE_SIGN_BLOCK_ID); // type
- result.putInt(codeSignArray.length); // length
- result.putInt((int) codeSignOffset); // offset
- result.put(codeSignArray);
- SigningBlock propertyBlock = new SigningBlock(HapUtils.HAP_PROPERTY_BLOCK_ID, result.array());
- optionalBlocks.add(0, propertyBlock);
- }
- }
-
- /**
- * obtain file name suffix
- *
- * @param output output file
- * @return suffix
- * @throws HapFormatException hap format error
- */
- private String getFileSuffix(File output) throws HapFormatException {
- String[] fileNameArray = output.getName().split("\\.");
- if (fileNameArray.length < ParamConstants.FILE_NAME_MIN_LENGTH) {
- throw new HapFormatException("hap format error :" + output);
- }
- return fileNameArray[fileNameArray.length - 1];
- }
-
/**
* Load certificate chain from input parameters
*
@@ -443,10 +341,6 @@ public abstract class SignProvider {
publicCerts = getPublicCerts();
// 3. load optionalBlocks
loadOptionalBlocks();
- if ("elf".equals(options.getString(ParamConstants.PARAM_IN_FORM))
- && StringUtils.isEmpty(options.getString(ParamConstants.PARAM_BASIC_PROFILE))) {
- return publicCerts;
- }
checkProfileValid(publicCerts);
return publicCerts;
}
@@ -459,9 +353,9 @@ public abstract class SignProvider {
outputHapOut.write(eocdBuffer);
}
- private boolean doAfterSign(boolean isSuccess, boolean isPathOverlap, File tmpOutput, File output) {
+ private boolean doAfterSign(boolean isSuccess, boolean pathOverlap, File tmpOutput, File output) {
boolean isRet = isSuccess;
- if (isRet && isPathOverlap) {
+ if (isRet && pathOverlap) {
try {
Files.move(tmpOutput.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
@@ -496,20 +390,18 @@ public abstract class SignProvider {
* @param input file input
* @param tmpOutput file tmpOutput
* @param alignment alignment
- * @return zip zip
- * @throws IOException io error
- * @throws HapFormatException hap format error
+ * @throws IOException io error
*/
- private Zip copyFileAndAlignment(File input, File tmpOutput, int alignment)
- throws IOException, HapFormatException {
- Zip zip = new Zip(input);
- zip.alignment(alignment);
- zip.removeSignBlock();
- long start = System.currentTimeMillis();
- zip.toFile(tmpOutput.getCanonicalPath());
- long end = System.currentTimeMillis();
- LOGGER.debug("zip to file use {} ms", end - start);
- return zip;
+ private void copyFileAndAlignment(File input, File tmpOutput, int alignment) throws IOException {
+ try (JarFile inputJar = new JarFile(input, false);
+ FileOutputStream outputFile = new FileOutputStream(tmpOutput);
+ JarOutputStream outputJar = new JarOutputStream(outputFile)) {
+ long timestamp = TIMESTAMP;
+ timestamp -= TimeZone.getDefault().getOffset(timestamp);
+ outputJar.setLevel(COMPRESSION_MODE);
+ List entryNames = SignHap.getEntryNamesFromHap(inputJar);
+ SignHap.copyFiles(entryNames, inputJar, outputJar, timestamp, alignment);
+ }
}
/**
@@ -600,8 +492,9 @@ public abstract class SignProvider {
private void checkProfileValid(List inputCerts) throws ProfileException {
try {
byte[] profile = findProfileFromOptionalBlocks();
- boolean isProfileWithoutSign = ParamConstants.ProfileSignFlag.DISABLE_SIGN_CODE.getSignFlag().equals(
+ boolean isProfileWithoutSign = ParamConstants.ProfileSignFlag.UNSIGNED_PROFILE.getSignFlag().equals(
signParams.get(ParamConstants.PARAM_BASIC_PROFILE_SIGNED));
+ String content;
if (!isProfileWithoutSign) {
CMSSignedData cmsSignedData = new CMSSignedData(profile);
boolean isVerify = VerifyUtils.verifyCmsSignedData(cmsSignedData);
@@ -612,11 +505,11 @@ public abstract class SignProvider {
if (!(contentObj instanceof byte[])) {
throw new ProfileException("Check profile failed, signed profile content is not byte array!");
}
- profileContent = new String((byte[]) contentObj, StandardCharsets.UTF_8);
+ content = new String((byte[]) contentObj, StandardCharsets.UTF_8);
} else {
- profileContent = new String(profile, StandardCharsets.UTF_8);
+ content = new String(profile, StandardCharsets.UTF_8);
}
- JsonElement parser = JsonParser.parseString(profileContent);
+ JsonElement parser = JsonParser.parseString(content);
JsonObject profileJson = parser.getAsJsonObject();
checkProfileInfo(profileJson, inputCerts);
} catch (CMSException e) {
@@ -643,7 +536,7 @@ public abstract class SignProvider {
throw new ProfileException("Unsupported profile type!");
}
if (!inputCerts.isEmpty() && !checkInputCertMatchWithProfile(inputCerts.get(0), certInProfile)) {
- throw new ProfileException("input certificates do not match with profile!");
+ throw new ProfileException("input certificates do not match with profile!");
}
String cn = getCertificateCN(certInProfile);
LOGGER.info("certificate in profile: {}", cn);
@@ -672,20 +565,18 @@ public abstract class SignProvider {
*/
public void checkParams(Options options) throws MissingParamsException, InvalidParamsException {
String[] paramFileds = {
- ParamConstants.PARAM_BASIC_ALIGNMENT,
- ParamConstants.PARAM_BASIC_SIGANTURE_ALG,
- ParamConstants.PARAM_BASIC_INPUT_FILE,
- ParamConstants.PARAM_BASIC_OUTPUT_FILE,
- ParamConstants.PARAM_BASIC_PRIVATE_KEY,
- ParamConstants.PARAM_BASIC_PROFILE,
- ParamConstants.PARAM_BASIC_PROOF,
- ParamConstants.PARAM_BASIC_PROPERTY,
- ParamConstants.PARAM_REMOTE_SERVER,
- ParamConstants.PARAM_BASIC_PROFILE_SIGNED,
- ParamConstants.PARAM_LOCAL_PUBLIC_CERT,
- ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION,
- ParamConstants.PARAM_SIGN_CODE,
- ParamConstants.PARAM_IN_FORM
+ ParamConstants.PARAM_BASIC_ALIGNMENT,
+ ParamConstants.PARAM_BASIC_SIGANTURE_ALG,
+ ParamConstants.PARAM_BASIC_INPUT_FILE,
+ ParamConstants.PARAM_BASIC_OUTPUT_FILE,
+ ParamConstants.PARAM_BASIC_PRIVATE_KEY,
+ ParamConstants.PARAM_BASIC_PROFILE,
+ ParamConstants.PARAM_BASIC_PROOF,
+ ParamConstants.PARAM_BASIC_PROPERTY,
+ ParamConstants.PARAM_REMOTE_SERVER,
+ ParamConstants.PARAM_BASIC_PROFILE_SIGNED,
+ ParamConstants.PARAM_LOCAL_PUBLIC_CERT,
+ ParamConstants.PARAM_BASIC_COMPATIBLE_VERSION
};
Set paramSet = ParamProcessUtil.initParamField(paramFileds);
@@ -697,29 +588,10 @@ public abstract class SignProvider {
if (!signParams.containsKey(ParamConstants.PARAM_BASIC_PROFILE_SIGNED)) {
signParams.put(ParamConstants.PARAM_BASIC_PROFILE_SIGNED, "1");
}
- checkSignCode();
checkSignatureAlg();
checkSignAlignment();
}
- /**
- * Check code sign, if param do not have code sign default "1".
- *
- * @throws InvalidParamsException invalid param
- */
- protected void checkSignCode() throws InvalidParamsException {
- if (!signParams.containsKey(ParamConstants.PARAM_SIGN_CODE)) {
- signParams.put(ParamConstants.PARAM_SIGN_CODE,
- ParamConstants.SignCodeFlag.ENABLE_SIGN_CODE.getSignCodeFlag());
- return;
- }
- String codeSign = signParams.get(ParamConstants.PARAM_SIGN_CODE);
- if (!codeSign.equals(ParamConstants.SignCodeFlag.ENABLE_SIGN_CODE.getSignCodeFlag())
- && !codeSign.equals(ParamConstants.SignCodeFlag.DISABLE_SIGN_CODE.getSignCodeFlag())) {
- throw new InvalidParamsException("Invalid parameter: " + ParamConstants.PARAM_SIGN_CODE);
- }
- }
-
/**
* Check compatible version, if param do not have compatible version default 9.
*
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignBin.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignBin.java
index 670eea6c335fa89964638c1aced1a3217cebd910..bc94668de46bccd15069f025448f3fe36159d1da 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignBin.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignBin.java
@@ -60,10 +60,6 @@ public class SignBin {
public static boolean sign(SignerConfig signerConfig, Map signParams) {
boolean result = false;
/* 1. Make block head, write to output file. */
- String codesign = signParams.get(ParamConstants.PARAM_SIGN_CODE);
- if (ParamConstants.ProfileSignFlag.ENABLE_SIGN_CODE.getSignFlag().equals(codesign)) {
- LOGGER.warn("can not sign bin with codesign");
- }
String inputFile = signParams.get(ParamConstants.PARAM_BASIC_INPUT_FILE);
String outputFile = signParams.get(ParamConstants.PARAM_BASIC_OUTPUT_FILE);
String profileFile = signParams.get(ParamConstants.PARAM_BASIC_PROFILE);
@@ -176,7 +172,7 @@ public class SignBin {
}
HwSignHead signHeadData = new HwSignHead();
byte[] signHeadByte = signHeadData.getSignHead((int) size);
- if (signHeadByte == null || signHeadByte.length == 0) {
+ if (signHeadByte == null) {
LOGGER.error("Failed to get sign head data.");
return false;
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignElf.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignElf.java
deleted file mode 100644
index 8f990e1d55fa5cda222671cd6adc3e37dd9b3fcd..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignElf.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.hap.sign;
-
-import com.ohos.hapsigntool.codesigning.exception.CodeSignException;
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.sign.CodeSigning;
-import com.ohos.hapsigntool.hap.config.SignerConfig;
-import com.ohos.hapsigntool.hap.entity.HwBlockHead;
-import com.ohos.hapsigntool.hap.entity.HwSignHead;
-import com.ohos.hapsigntool.hap.entity.SignBlockData;
-import com.ohos.hapsigntool.hap.entity.SignatureBlockTags;
-import com.ohos.hapsigntool.hap.entity.SignatureBlockTypes;
-import com.ohos.hapsigntool.hap.exception.HapFormatException;
-import com.ohos.hapsigntool.hap.exception.ProfileException;
-import com.ohos.hapsigntool.utils.FileUtils;
-import com.ohos.hapsigntool.utils.ParamConstants;
-import com.ohos.hapsigntool.utils.ParamProcessUtil;
-import com.ohos.hapsigntool.utils.StringUtils;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * elf file Signature signer.
- *
- * @since 2023/11/21
- */
-public class SignElf {
- /**
- * codesign sign block type
- */
- public static final char CODESIGN_BLOCK_TYPE = 3;
-
- private static final Logger LOGGER = LogManager.getLogger(SignElf.class);
-
- private static final String CODESIGN_OFF = "0";
-
- private static int blockNum = 0;
-
- private static final int PAGE_SIZE = 4096;
-
- private static final int FILE_BUFFER_BLOCK = 16384;
-
- /**
- * Constructor of Method
- */
- private SignElf() {
- }
-
- /**
- * Sign the elf file.
- *
- * @param signerConfig Config of the elf file to be signed.
- * @param signParams The input parameters of sign elf.
- * @return true if sign successfully; false otherwise.
- */
- public static boolean sign(SignerConfig signerConfig, Map signParams) {
- boolean isSuccess = false;
- /* 1. Make block head, write to output file. */
- String inputFile = signParams.get(ParamConstants.PARAM_BASIC_INPUT_FILE);
- String tmpFile = alignFileBy4kBytes(inputFile);
- if (tmpFile == null) {
- LOGGER.error("copy input File failed");
- return isSuccess;
- }
- String outputFile = signParams.get(ParamConstants.PARAM_BASIC_OUTPUT_FILE);
- String profileSigned = signParams.get(ParamConstants.PARAM_BASIC_PROFILE_SIGNED);
- if (!writeBlockDataToFile(signerConfig, tmpFile, outputFile, profileSigned, signParams)) {
- LOGGER.error("The block head data made failed.`");
- ParamProcessUtil.delDir(new File(outputFile));
- return isSuccess;
- }
- LOGGER.info("The block head data made success.");
-
- /* 2. Make sign data, and write to output file */
- if (!writeSignHeadDataToOutputFile(tmpFile, outputFile, blockNum)) {
- LOGGER.error("The sign head data made failed.");
- ParamProcessUtil.delDir(new File(outputFile));
- } else {
- isSuccess = true;
- }
- return isSuccess;
- }
-
- private static String alignFileBy4kBytes(String inputFile) {
- String tmp = "tmpFile" + new Date().getTime();
- File tmpFile = new File(tmp);
- try {
- tmpFile.createNewFile();
- } catch (IOException e) {
- LOGGER.error("create tmp file Failed");
- return null;
- }
- try (FileOutputStream output = new FileOutputStream(tmpFile);
- FileInputStream input = new FileInputStream(inputFile)) {
- byte[] buffer = new byte[FILE_BUFFER_BLOCK];
- int read;
- while ((read = input.read(buffer)) != FileUtils.FILE_END) {
- output.write(buffer, 0, read);
- }
-
- long addLength = PAGE_SIZE - (tmpFile.length() % PAGE_SIZE);
- if (isLongOverflowInteger(addLength)) {
- LOGGER.error("File alignment error");
- return null;
- }
- byte[] bytes = new byte[(int) addLength];
- java.util.Arrays.fill(bytes, (byte) 0);
- FileUtils.writeByteToOutFile(bytes, tmp);
- } catch (IOException e) {
- LOGGER.error("copy inFile Failed");
- return null;
- }
- return tmp;
- }
-
- private static boolean writeBlockDataToFile(SignerConfig signerConfig,
- String inputFile, String outputFile, String profileSigned, Map signParams) {
- try {
- String profileFile = signParams.get(ParamConstants.PARAM_BASIC_PROFILE);
-
- List signDataList = new ArrayList<>();
-
- long binFileLen = FileUtils.getFileLen(inputFile);
- if (binFileLen == -1) {
- LOGGER.error("file length is invalid, elf file len: " + binFileLen);
- throw new IOException();
- }
- // 1. generate sign data
- if (!StringUtils.isEmpty(signParams.get(ParamConstants.PARAM_BASIC_PROFILE))) {
- signDataList.add(generateProfileSignByte(profileFile, profileSigned));
- }
- blockNum = signDataList.size() + 1; // other sign block num + codesign block 1
- SignBlockData codeSign = generateCodeSignByte(signerConfig, signParams, inputFile, blockNum, binFileLen);
- if (codeSign != null) {
- signDataList.add(0, codeSign);
- }
- blockNum = signDataList.size();
- // 2. use sign data generate offset and sign block head
- generateSignBlockHead(signDataList);
-
- return writeSignedElf(inputFile, signDataList, outputFile);
- } catch (IOException e) {
- LOGGER.error("writeBlockDataToFile failed.", e);
- return false;
- } catch (FsVerityDigestException | CodeSignException | HapFormatException | ProfileException e) {
- LOGGER.error("codesign failed.", e);
- return false;
- }
- }
-
- private static boolean writeSignedElf(String inputFile, List signBlockList, String outputFile) {
- try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
- DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream)) {
- // 1. write the input file to the output file.
- if (!FileUtils.writeFileToDos(inputFile, dataOutputStream)) {
- LOGGER.error("Failed to write information of input file: " + inputFile
- + " to outputFile: " + outputFile);
- throw new IOException();
- }
-
- // 2. write block head to the output file.
- for (SignBlockData signBlockData : signBlockList) {
- if (!FileUtils.writeByteToDos(signBlockData.getBlockHead(), dataOutputStream)) {
- LOGGER.error("Failed to write Block Head to output file: " + outputFile);
- throw new IOException();
- }
- }
-
- // 3. write block data to the output file.
- for (SignBlockData signBlockData : signBlockList) {
- boolean isSuccess;
- if (signBlockData.isByte()) {
- isSuccess = FileUtils.writeByteToDos(signBlockData.getSignData(), dataOutputStream);
- } else {
- isSuccess = FileUtils.writeFileToDos(signBlockData.getSignFile(), dataOutputStream);
- }
-
- if (!isSuccess) {
- LOGGER.error("Failed to write Block Data to output file: " + outputFile);
- throw new IOException();
- }
- }
- } catch (IOException e) {
- LOGGER.error("writeSignedElf failed.", e);
- return false;
- }
- return true;
- }
-
- private static void generateSignBlockHead(List signDataList)
- throws IOException {
- long offset = (long) HwBlockHead.getElfBlockLen() * signDataList.size();
-
- for (int i = 0; i < signDataList.size(); i++) {
- SignBlockData signBlockData = signDataList.get(i);
-
- signBlockData.setBlockHead(HwBlockHead.getBlockHeadLittleEndian(signBlockData.getType(),
- SignatureBlockTags.DEFAULT, (int) signBlockData.getLen(), (int) offset));
- offset += signBlockData.getLen();
- if (isLongOverflowInteger(offset)) {
- LOGGER.error("The sign block " + i + "offset is overflow integer, offset: " + offset);
- throw new IOException();
- }
- }
- }
-
- private static SignBlockData generateProfileSignByte(String profileFile, String profileSigned) throws IOException {
- long profileDataLen = FileUtils.getFileLen(profileFile);
-
- if (profileDataLen == -1 || isLongOverflowShort(profileDataLen)) {
- LOGGER.error("file length is invalid, profileDataLen: " + profileDataLen);
- throw new IOException();
- }
-
- char isSigned = SignatureBlockTypes.getProfileBlockTypes(profileSigned);
- return new SignBlockData(profileFile, isSigned);
- }
-
- private static SignBlockData generateCodeSignByte(SignerConfig signerConfig, Map signParams,
- String inputFile, int blockNum, long binFileLen) throws IOException,
- FsVerityDigestException, CodeSignException, HapFormatException, ProfileException {
- if (CODESIGN_OFF.equals(signParams.get(ParamConstants.PARAM_SIGN_CODE))) {
- return null;
- }
- CodeSigning codeSigning = new CodeSigning(signerConfig);
- long offset = binFileLen + (long) HwBlockHead.getElfBlockLen() * blockNum;
- String profileContent = signParams.get(ParamConstants.PARAM_PROFILE_JSON_CONTENT);
- byte[] codesignData = codeSigning.getElfCodeSignBlock(new File(inputFile), offset,
- signParams.get(ParamConstants.PARAM_IN_FORM), profileContent);
- return new SignBlockData(codesignData, CODESIGN_BLOCK_TYPE);
- }
-
- private static boolean writeSignHeadDataToOutputFile(String inputFile, String outputFile, int blockNum) {
- long size = FileUtils.getFileLen(outputFile) - FileUtils.getFileLen(inputFile);
- if (isLongOverflowInteger(size)) {
- LOGGER.error("File size is Overflow integer range.");
- return false;
- }
- HwSignHead signHeadData = new HwSignHead();
- byte[] signHeadByte = signHeadData.getSignHeadLittleEndian((int) size, blockNum);
- if (signHeadByte == null) {
- LOGGER.error("Failed to get sign head data.");
- return false;
- }
- return FileUtils.writeByteToOutFile(signHeadByte, outputFile);
- }
-
- private static boolean isLongOverflowInteger(long num) {
- return (num - (num & 0xffffffffL)) != 0;
- }
-
- private static boolean isLongOverflowShort(long num) {
- return (num - (num & 0xffffL)) != 0;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java
index 3ea5a842ae688887d7e2a1bee4c435ee5a45fe52..eede0eaab64946ffd2011a6bd7bfcc4e20fd9e18 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/sign/SignHap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -19,11 +19,8 @@ import com.ohos.hapsigntool.api.model.Options;
import com.ohos.hapsigntool.hap.config.SignerConfig;
import com.ohos.hapsigntool.hap.entity.Pair;
import com.ohos.hapsigntool.hap.entity.SigningBlock;
-import com.ohos.hapsigntool.hap.exception.HapFormatException;
import com.ohos.hapsigntool.hap.exception.SignatureException;
-import com.ohos.hapsigntool.utils.FileUtils;
import com.ohos.hapsigntool.utils.HapUtils;
-import com.ohos.hapsigntool.utils.StringUtils;
import com.ohos.hapsigntool.zip.ZipDataInput;
import java.io.IOException;
@@ -32,6 +29,8 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.DigestException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -40,10 +39,8 @@ import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
-import java.util.stream.Collectors;
/**
- *
* Hap Signature Scheme signer
*
* @since 2021/12/21
@@ -66,168 +63,96 @@ public abstract class SignHap {
return BLOCK_SIZE;
}
+ /**
+ * Get all entries' name from hap which is opened as a jar-file.
+ *
+ * @param hap input hap-file which is opened as a jar-file.
+ * @return list of entries' names.
+ */
+ public static List getEntryNamesFromHap(JarFile hap) {
+ List result = new ArrayList();
+ for (Enumeration e = hap.entries(); e.hasMoreElements();) {
+ JarEntry entry = e.nextElement();
+ if (!entry.isDirectory()) {
+ result.add(entry.getName());
+ }
+ }
+ return result;
+ }
+
/**
* Copy the jar file and align the storage entries.
*
+ * @param entryNames list of entries' name
* @param in input hap-file which is opened as a jar-file.
* @param out output stream of jar.
* @param timestamp ZIP file timestamps
* @param defaultAlignment default value of alignment.
* @throws IOException io error.
- * @throws HapFormatException hap format error.
*/
- public static void copyFiles(JarFile in,
- JarOutputStream out, long timestamp, int defaultAlignment) throws IOException, HapFormatException {
- // split compressed and uncompressed
- List entryListStored = in.stream()
- .filter(jarFile -> jarFile.getMethod() == JarEntry.STORED).collect(Collectors.toList());
-
- // uncompressed special files and place in front
- entryListStored = storedEntryListOfSort(entryListStored);
+ public static void copyFiles(List entryNames, JarFile in,
+ JarOutputStream out, long timestamp, int defaultAlignment) throws IOException {
+ Collections.sort(entryNames);
long offset = INIT_OFFSET_LEN;
- String lastAlignmentEntryName = "";
- for (JarEntry inEntry : entryListStored) {
- String entryName = inEntry.getName();
- if (!FileUtils.isRunnableFile(entryName)) {
- lastAlignmentEntryName = entryName;
- break;
- }
- }
- for (JarEntry inEntry : entryListStored) {
- if (inEntry == null) {
+ for (String name : entryNames) {
+ JarEntry inEntry = in.getJarEntry(name);
+ if (inEntry.getMethod() != JarEntry.STORED) {
continue;
}
offset += JarFile.LOCHDR;
- JarEntry outEntry = getJarEntry(timestamp, inEntry);
+ JarEntry outEntry = new JarEntry(inEntry);
+ outEntry.setTime(timestamp);
+
+ outEntry.setComment(null);
+ outEntry.setExtra(null);
+
offset += outEntry.getName().length();
- int alignment = getStoredEntryDataAlignment(inEntry.getName(), defaultAlignment, lastAlignmentEntryName);
+ int alignment = getStoredEntryDataAlignment(name, defaultAlignment);
if (alignment > 0 && (offset % alignment != 0)) {
int needed = alignment - (int) (offset % alignment);
outEntry.setExtra(new byte[needed]);
offset += needed;
}
- out.putNextEntry(outEntry);
- offset = writeOutputStreamAndGetOffset(in, out, inEntry, offset);
- }
- List entryListNotStored = in.stream()
- .filter(jarFile -> jarFile.getMethod() != JarEntry.STORED).collect(Collectors.toList());
- // process byte alignment of the first compressed file
- boolean isAlignmentFlag = StringUtils.isEmpty(lastAlignmentEntryName);
- if (isAlignmentFlag) {
- if (entryListNotStored.isEmpty()) {
- throw new HapFormatException("Hap format is error, file missing");
- }
- JarEntry firstEntry = entryListNotStored.get(0);
- offset += JarFile.LOCHDR;
- JarEntry outEntry = getFirstJarEntry(firstEntry, offset, timestamp);
out.putNextEntry(outEntry);
byte[] buffer = new byte[BUFFER_LENGTH];
- writeOutputStream(in, out, firstEntry, buffer);
- }
-
- copyFilesExceptStoredFile(entryListNotStored, in, out, timestamp, isAlignmentFlag);
- }
-
- /**
- * uncompressed special files are placed in front
- *
- * @param entryListStored stored file entry list
- * @return List jarEntryList
- */
- private static List storedEntryListOfSort(List entryListStored) {
- return entryListStored.stream().sorted((entry1, entry2) -> {
- String name1 = entry1.getName();
- String name2 = entry2.getName();
- // files ending with .abc or .so are placed before other files
- boolean isSpecial1 = FileUtils.isRunnableFile(name1);
- boolean isSpecial2 = FileUtils.isRunnableFile(name2);
- if (isSpecial1 && !isSpecial2) {
- return -1;
- } else if (!isSpecial1 && isSpecial2) {
- return 1;
- } else {
- // if all files are special files or none of them are special files,the files are sorted lexically
- return name1.compareTo(name2);
+ try (InputStream data = in.getInputStream(inEntry)) {
+ int num;
+ while ((num = data.read(buffer)) > 0) {
+ out.write(buffer, 0, num);
+ offset += num;
+ }
+ out.flush();
}
- }).collect(Collectors.toList());
- }
-
- private static JarEntry getFirstJarEntry(JarEntry firstEntry, long offset, long timestamp) {
- long currentOffset = offset;
- JarEntry outEntry = getJarEntry(timestamp, firstEntry);
- currentOffset += outEntry.getName().length();
- if (currentOffset % STORED_ENTRY_SO_ALIGNMENT != 0) {
- int needed = STORED_ENTRY_SO_ALIGNMENT - (int) (currentOffset % STORED_ENTRY_SO_ALIGNMENT);
- outEntry.setExtra(new byte[needed]);
}
- return outEntry;
- }
- /**
- * write first not stored entry to outputStream
- *
- * @param in jar file
- * @param out jarOutputStream
- * @param firstEntry jarEntry
- * @param buffer byte[]
- * @throws IOException IOExpcetion
- */
- private static void writeOutputStream(JarFile in, JarOutputStream out, JarEntry firstEntry, byte[] buffer)
- throws IOException {
- try (InputStream data = in.getInputStream(firstEntry)) {
- int num;
- while ((num = data.read(buffer)) > 0) {
- out.write(buffer, 0, num);
- }
- out.flush();
- }
+ copyFilesExceptStoredFile(entryNames, in, out, timestamp);
}
- private static long writeOutputStreamAndGetOffset(JarFile in, JarOutputStream out, JarEntry inEntry, long offset)
- throws IOException {
+ private static void copyFilesExceptStoredFile(List entryNames, JarFile in,
+ JarOutputStream out, long timestamp) throws IOException {
byte[] buffer = new byte[BUFFER_LENGTH];
- long currentOffset = offset;
- try (InputStream data = in.getInputStream(inEntry)) {
- int num;
- while ((num = data.read(buffer)) > 0) {
- out.write(buffer, 0, num);
- currentOffset += num;
- }
- out.flush();
- }
- return currentOffset;
- }
-
- private static JarEntry getJarEntry(long timestamp, JarEntry inEntry) {
- JarEntry outEntry = new JarEntry(inEntry);
- outEntry.setTime(timestamp);
- outEntry.setComment(null);
- outEntry.setExtra(null);
- return outEntry;
- }
-
- private static void copyFilesExceptStoredFile(List entryListNotStored, JarFile in,
- JarOutputStream out, long timestamp, boolean isAlignmentFlag) throws IOException {
- byte[] buffer = new byte[BUFFER_LENGTH];
- int index = 0;
- if (isAlignmentFlag) {
- index = 1;
- }
- for (; index < entryListNotStored.size(); index++) {
- JarEntry inEntry = entryListNotStored.get(index);
- if (inEntry == null || inEntry.getMethod() == JarEntry.STORED) {
+ for (String name : entryNames) {
+ JarEntry inEntry = in.getJarEntry(name);
+ if (inEntry.getMethod() == JarEntry.STORED) {
continue;
}
- JarEntry outEntry = new JarEntry(inEntry.getName());
+ JarEntry outEntry = new JarEntry(name);
outEntry.setTime(timestamp);
out.putNextEntry(outEntry);
- writeOutputStream(in, out, inEntry, buffer);
+
+ try (InputStream data = in.getInputStream(inEntry);) {
+ int num;
+ while ((num = data.read(buffer)) > 0) {
+ out.write(buffer, 0, num);
+ }
+ out.flush();
+ }
}
}
@@ -236,18 +161,13 @@ public abstract class SignHap {
*
* @param entryName name of entry
* @param defaultAlignment default value of alignment.
- * @param lastAlignmentEntryName lastAlignmentEntryName
* @return value of alignment.
*/
- private static int getStoredEntryDataAlignment(String entryName, int defaultAlignment,
- String lastAlignmentEntryName) {
+ private static int getStoredEntryDataAlignment(String entryName, int defaultAlignment) {
if (defaultAlignment <= 0) {
return 0;
}
- if (!StringUtils.isEmpty(lastAlignmentEntryName) && entryName.equals(lastAlignmentEntryName)) {
- return STORED_ENTRY_SO_ALIGNMENT;
- }
- if (FileUtils.isRunnableFile(entryName)) {
+ if (entryName.endsWith(".so")) {
return STORED_ENTRY_SO_ALIGNMENT;
}
return defaultAlignment;
@@ -258,7 +178,7 @@ public abstract class SignHap {
List optionalBlocks,
SignerConfig signerConfig,
ZipDataInput[] hapData)
- throws SignatureException {
+ throws SignatureException {
/**
* Compute digests of Hap contents
* Sign the digests and wrap the signature and signer info into the Hap Signing Block
@@ -266,7 +186,7 @@ public abstract class SignHap {
byte[] hapSignatureBytes = null;
try {
Map contentDigests =
- HapUtils.computeDigests(contentDigestAlgorithms, hapData, optionalBlocks);
+ HapUtils.computeDigests(contentDigestAlgorithms, hapData, optionalBlocks);
hapSignatureBytes = generateHapSigningBlock(signerConfig, contentDigests, optionalBlocks);
} catch (DigestException | IOException e) {
throw new SignatureException("Failed to compute digests of HAP", e);
@@ -284,29 +204,35 @@ public abstract class SignHap {
}
private static byte[] generateHapSigningBlock(byte[] hapSignatureSchemeBlock,
- List optionalBlocks, int compatibleVersion) {
+ List optionalBlocks, int compatibleVersion) {
// FORMAT:
// Proof-of-Rotation pairs(optional):
// uint32:type
// uint32:length
// uint32:offset
+
// Property pairs(optional):
// uint32:type
// uint32:length
// uint32:offset
+
// Profile capability pairs(optional):
// uint32:type
// uint32:length
// uint32:offset
+
// length bytes : app signing pairs
// uint32:type
// uint32:length
// uint32:offset
+
// repeated ID-value pairs(reserved extensions):
// length bytes : Proof-of-Rotation values
// length bytes : property values
// length bytes : profile capability values
// length bytes : signature schema values
+
+ // uint32: block count
// uint64: size
// uint128: magic
// uint32: version
@@ -314,6 +240,7 @@ public abstract class SignHap {
for (SigningBlock optionalBlock : optionalBlocks) {
optionalBlockSize += optionalBlock.getLength();
}
+
long resultSize =
((OPTIONAL_TYPE_SIZE + OPTIONAL_LENGTH_SIZE + OPTIONAL_OFFSET_SIZE) * (optionalBlocks.size() + 1))
+ optionalBlockSize // optional pair
@@ -329,8 +256,8 @@ public abstract class SignHap {
result.order(ByteOrder.LITTLE_ENDIAN);
Map typeAndOffsetMap = new HashMap();
- int currentOffset = ((OPTIONAL_TYPE_SIZE + OPTIONAL_LENGTH_SIZE
- + OPTIONAL_OFFSET_SIZE) * (optionalBlocks.size() + 1));
+ int currentOffset = ((OPTIONAL_TYPE_SIZE + OPTIONAL_LENGTH_SIZE +
+ OPTIONAL_OFFSET_SIZE) * (optionalBlocks.size() + 1));
int currentOffsetInBlockValue = 0;
int blockValueSizes = (int) (optionalBlockSize + hapSignatureSchemeBlock.length);
byte[] blockValues = new byte[blockValueSizes];
@@ -347,12 +274,20 @@ public abstract class SignHap {
hapSignatureSchemeBlock, 0, blockValues, currentOffsetInBlockValue, hapSignatureSchemeBlock.length);
typeAndOffsetMap.put(HapUtils.HAP_SIGNATURE_SCHEME_V1_BLOCK_ID, currentOffset);
- extractedResult(optionalBlocks, result, typeAndOffsetMap);
+ int offset = 0;
+ for (SigningBlock optionalBlock : optionalBlocks) {
+ result.putInt(optionalBlock.getType()); // type
+ result.putInt(optionalBlock.getLength()); // length
+ offset = typeAndOffsetMap.get(optionalBlock.getType());
+ result.putInt(offset); // offset
+ }
result.putInt(HapUtils.HAP_SIGNATURE_SCHEME_V1_BLOCK_ID); // type
result.putInt(hapSignatureSchemeBlock.length); // length
- int offset = typeAndOffsetMap.get(HapUtils.HAP_SIGNATURE_SCHEME_V1_BLOCK_ID);
+ offset = typeAndOffsetMap.get(HapUtils.HAP_SIGNATURE_SCHEME_V1_BLOCK_ID);
result.putInt(offset); // offset
+
result.put(blockValues);
+
result.putInt(optionalBlocks.size() + 1); // Signing block count
result.putLong(resultSize); // length of hap signing block
result.put(HapUtils.getHapSigningBlockMagic(compatibleVersion)); // magic
@@ -360,17 +295,6 @@ public abstract class SignHap {
return result.array();
}
- private static void extractedResult(List optionalBlocks, ByteBuffer result,
- Map typeAndOffsetMap) {
- int offset;
- for (SigningBlock optionalBlock : optionalBlocks) {
- result.putInt(optionalBlock.getType()); // type
- result.putInt(optionalBlock.getLength()); // length
- offset = typeAndOffsetMap.get(optionalBlock.getType());
- result.putInt(offset); // offset
- }
- }
-
private static byte[] generateHapSignatureSchemeBlock(
SignerConfig signerConfig, Map contentDigests) throws SignatureException {
byte[] signerBlock = null;
@@ -386,7 +310,7 @@ public abstract class SignHap {
SignerConfig signerConfig, Map contentDigests) throws SignatureException {
String mode = signerConfig.getOptions().getString(Options.MODE);
if (!("remoteSign".equalsIgnoreCase(mode)) && signerConfig.getCertificates().isEmpty()) {
- throw new SignatureException("No certificates configured for signer");
+ throw new SignatureException("No certificates configured for signer");
}
List> digests =
@@ -418,7 +342,7 @@ public abstract class SignHap {
* @throws SignatureException if an error occurs when sign hap file.
*/
public static byte[] sign(ZipDataInput[] contents, SignerConfig signerConfig, List optionalBlocks)
- throws SignatureException {
+ throws SignatureException {
Set contentDigestAlgorithms = new HashSet();
for (SignatureAlgorithm signatureAlgorithm : signerConfig.getSignatureAlgorithms()) {
contentDigestAlgorithms.add(signatureAlgorithm.getContentDigestAlgorithm());
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/HapVerify.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/HapVerify.java
index a889fc9c67586920213c49af039563eb53fb7d38..abfb465b46bd6e8263c11c1b473000eba997d5f6 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/HapVerify.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/HapVerify.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -91,17 +91,8 @@ public class HapVerify {
private JcaX509CRLConverter crlConverter = new JcaX509CRLConverter();
- private boolean isPrintCert;
+ private boolean printCert;
- /**
- * Init Zip HapVerify
- *
- * @param beforeApkSigningBlock beforeApkSigningBlock
- * @param signatureSchemeBlock signatureSchemeBlock
- * @param centralDirectoryBlock centralDirectoryBlock
- * @param eocd eocd
- * @param optionalBlocks optionalBlocks
- */
public HapVerify(
ZipDataInput beforeApkSigningBlock,
ByteBuffer signatureSchemeBlock,
@@ -115,12 +106,6 @@ public class HapVerify {
this.optionalBlocks = optionalBlocks;
}
- /**
- * init HapVerify
- */
- public HapVerify() {
- }
-
/**
* Verify hap signature.
*
@@ -130,22 +115,12 @@ public class HapVerify {
return parserSigner(signatureSchemeBlock);
}
- /**
- * Verify elf signature.
- *
- * @param profile profile byte
- * @return verify result.
- */
- public VerifyResult verifyElfProfile(byte[] profile) {
- return parserSigner(ByteBuffer.wrap(profile), false);
- }
-
- public void setIsPrintCert(boolean isPrintCert) {
- this.isPrintCert = isPrintCert;
+ public void setPrintCert(boolean printCert) {
+ this.printCert = printCert;
}
private boolean checkCRL(X509CRL crl, List certificates) {
- boolean isRet = false;
+ boolean ret = false;
for (X509Certificate cert : certificates) {
if (!crl.getIssuerDN().getName().equals(cert.getIssuerDN().getName())) {
continue;
@@ -154,12 +129,12 @@ public class HapVerify {
if (entry != null) {
LOGGER.info("cert(subject DN = {}) is revoked by crl (IssuerDN = {})",
cert.getSubjectDN().getName(), crl.getIssuerDN().getName());
- isRet = false;
+ ret = false;
break;
}
- isRet = true;
+ ret = true;
}
- return isRet;
+ return ret;
}
private boolean verifyCRL(X509CRL crl, X509Certificate cert, List certificates)
@@ -177,33 +152,33 @@ public class HapVerify {
}
private boolean verifyCRL(X509CRL crl, List certificates) throws SignatureException {
- boolean isRevoked = true;
+ boolean revoked = true;
for (X509Certificate cert : certificates) {
if (!crl.getIssuerDN().getName().equals(cert.getSubjectDN().getName())) {
continue;
}
if (!verifyCRL(crl, cert, certificates)) {
- isRevoked = false;
+ revoked = false;
}
}
- return isRevoked;
+ return revoked;
}
private void verifyCRLs(List crls, List certificates) throws VerifyHapException {
if (crls == null) {
return;
}
- boolean isRevoked = true;
+ boolean revoked = true;
try {
for (X509CRL crl : crls) {
if (!verifyCRL(crl, certificates)) {
- isRevoked = false;
+ revoked = false;
}
}
} catch (SignatureException e) {
throw new VerifyHapException("Verify CRL error!", e);
}
- if (!isRevoked) {
+ if (!revoked) {
throw new VerifyHapException("Certificate is revoked!");
}
}
@@ -211,8 +186,8 @@ public class HapVerify {
private CMSSignedData verifyCmsSignedData(byte[] signingBlock) throws VerifyHapException {
try {
CMSSignedData cmsSignedData = new CMSSignedData(signingBlock);
- boolean isVerifyResult = VerifyUtils.verifyCmsSignedData(cmsSignedData);
- if (!isVerifyResult) {
+ boolean verifyResult = VerifyUtils.verifyCmsSignedData(cmsSignedData);
+ if (!verifyResult) {
throw new VerifyHapException("Verify PKCS7 cms data failed!");
}
return cmsSignedData;
@@ -222,10 +197,6 @@ public class HapVerify {
}
private VerifyResult parserSigner(ByteBuffer signer) {
- return parserSigner(signer, true);
- }
-
- private VerifyResult parserSigner(ByteBuffer signer, boolean verifyContent) {
byte[] signingBlock = new byte[signer.remaining()];
signer.get(signingBlock);
try {
@@ -233,9 +204,7 @@ public class HapVerify {
List certificates = getCertChain(cmsSignedData);
List crlList = getCrlList(cmsSignedData);
verifyCRLs(crlList, certificates);
- if (verifyContent) {
- checkContentDigest(cmsSignedData);
- }
+ checkContentDigest(cmsSignedData);
List signerInfos = getSignerInformations(cmsSignedData);
VerifyResult result = new VerifyResult(true, VerifyResult.RET_SUCCESS, "Verify success");
result.setCrls(crlList);
@@ -245,7 +214,7 @@ public class HapVerify {
result.setOptionalBlocks(optionalBlocks);
return result;
} catch (VerifyHapException e) {
- LOGGER.error("Verify profile error!", e);
+ LOGGER.error("Verify Hap error!", e);
return new VerifyResult(false, VerifyResult.RET_UNKNOWN_ERROR, e.getMessage());
}
}
@@ -269,8 +238,8 @@ public class HapVerify {
throw new VerifyHapException("PKCS cms content is not a byte array!");
}
try {
- boolean isCheckResult = parserContentinfo(contentBytes);
- if (!isCheckResult) {
+ boolean checkResult = parserContentinfo(contentBytes);
+ if (!checkResult) {
throw new VerifyHapException("Hap content digest check failed.");
}
} catch (DigestException | SignatureException | IOException e) {
@@ -285,7 +254,7 @@ public class HapVerify {
if (certificateList == null || certificateList.size() == 0) {
throw new VerifyHapException("Certificate chain is empty!");
}
- if (isPrintCert) {
+ if (printCert) {
for (int i = 0; i < certificateList.size(); i++) {
LOGGER.info("+++++++++++++++++++++++++++certificate #{} +++++++++++++++++++++++++++++++", i);
printCert(certificateList.get(i));
@@ -320,7 +289,7 @@ public class HapVerify {
}
private List certStoreToCertList(Store certificates)
- throws CertificateException {
+ throws CertificateException {
if (certificates == null) {
return Collections.emptyList();
}
@@ -339,6 +308,7 @@ public class HapVerify {
private boolean parserContentinfo(byte[] data)
throws DigestException, SignatureException, IOException {
+ boolean result = true;
ByteBuffer digestDatas = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
while (digestDatas.remaining() > 4) {
/**
@@ -374,22 +344,22 @@ public class HapVerify {
Set keySet = digestMap.keySet();
Map actualDigestMap = HapUtils.computeDigests(
keySet, new ZipDataInput[]{beforeApkSigningBlock, centralDirectoryBlock, eocd}, optionalBlocks);
- boolean isResult = true;
+
for (Entry entry : digestMap.entrySet()) {
ContentDigestAlgorithm digestAlg = entry.getKey();
byte[] exceptDigest = entry.getValue();
byte[] actualDigest = actualDigestMap.get(digestAlg);
if (!Arrays.equals(actualDigest, exceptDigest)) {
- isResult = false;
+ result = false;
LOGGER.error(
- "degist data do not match! DigestAlgorithm: {}, actualDigest: <{}> VS exceptDigest : <{}>",
- digestAlg.getDigestAlgorithm(),
- HapUtils.toHex(actualDigest, ""),
- HapUtils.toHex(exceptDigest, ""));
+ "degist data do not match! DigestAlgorithm: {}, actualDigest: <{}> VS exceptDigest : <{}>",
+ digestAlg.getDigestAlgorithm(),
+ HapUtils.toHex(actualDigest, ""),
+ HapUtils.toHex(exceptDigest, ""));
}
- LOGGER.info("Digest verify result: {}, DigestAlgorithm: {}", isResult, digestAlg.getDigestAlgorithm());
+ LOGGER.info("Digest verify result: {}, DigestAlgorithm: {}", result, digestAlg.getDigestAlgorithm());
}
- return isResult;
+ return result;
}
private void printCert(X509Certificate cert) throws CertificateEncodingException {
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java
deleted file mode 100644
index 1a1fc80f736f96e236a115287ced1244cd90e884..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyElf.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.hap.verify;
-
-import com.ohos.hapsigntool.api.model.Options;
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-import com.ohos.hapsigntool.codesigning.sign.VerifyCodeSignature;
-import com.ohos.hapsigntool.hap.entity.ElfBlockData;
-import com.ohos.hapsigntool.hap.entity.HwBlockHead;
-import com.ohos.hapsigntool.hap.entity.HwSignHead;
-import com.ohos.hapsigntool.hap.entity.SignatureBlockTypes;
-import com.ohos.hapsigntool.hap.entity.SigningBlock;
-import com.ohos.hapsigntool.hap.exception.ProfileException;
-import com.ohos.hapsigntool.hap.sign.SignElf;
-import com.ohos.hapsigntool.utils.FileUtils;
-import com.ohos.hapsigntool.utils.ParamConstants;
-import com.ohos.hapsigntool.utils.StringUtils;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.CMSSignedData;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.Security;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Class of verify ELF.
- *
- * @since 2023/11/23
- */
-public class VerifyElf {
- private static final Logger LOGGER = LogManager.getLogger(VerifyElf.class);
-
- static {
- Security.addProvider(new BouncyCastleProvider());
- }
-
- private static String getProfileContent(byte[] profile) throws ProfileException {
- try {
- CMSSignedData cmsSignedData = new CMSSignedData(profile);
- if (!VerifyUtils.verifyCmsSignedData(cmsSignedData)) {
- throw new ProfileException("Verify profile pkcs7 failed! Profile is invalid");
- }
- Object contentObj = cmsSignedData.getSignedContent().getContent();
- if (!(contentObj instanceof byte[])) {
- throw new ProfileException("Check profile failed, signed profile content is not byte array!");
- }
- return new String((byte[]) contentObj, StandardCharsets.UTF_8);
- } catch (CMSException e) {
- return new String(profile, StandardCharsets.UTF_8);
- }
- }
-
-
- /**
- * Check whether parameters are valid
- *
- * @param options input parameters used to verify ELF.
- * @return true, if all parameters are valid.
- */
- public boolean checkParams(Options options) {
- if (!options.containsKey(ParamConstants.PARAM_VERIFY_CERTCHAIN_FILE)) {
- LOGGER.error("Missing parameter: {}", ParamConstants.PARAM_VERIFY_CERTCHAIN_FILE);
- return false;
- }
- if (!options.containsKey(ParamConstants.PARAM_VERIFY_PROFILE_FILE)) {
- LOGGER.error("Missing parameter: {}", ParamConstants.PARAM_VERIFY_PROFILE_FILE);
- return false;
- }
- if (!options.containsKey(ParamConstants.PARAM_VERIFY_PROOF_FILE)) {
- LOGGER.warn("Missing parameter: {}", ParamConstants.PARAM_VERIFY_PROOF_FILE);
- }
- return true;
- }
-
- /**
- * verify elf file.
- *
- * @param options input parameters used to verify elf.
- * @return true, if verify successfully.
- */
- public boolean verify(Options options) {
- VerifyResult verifyResult;
- try {
- if (!checkParams(options)) {
- LOGGER.error("Check params failed!");
- throw new IOException();
- }
- String filePath = options.getString(ParamConstants.PARAM_BASIC_INPUT_FILE);
- if (StringUtils.isEmpty(filePath)) {
- LOGGER.error("Not found verify file path!");
- throw new IOException();
- }
- File signedFile = new File(filePath);
- if (!checkSignFile(signedFile)) {
- LOGGER.error("Check input signature ELF false!");
- throw new IOException();
- }
- verifyResult = verifyElf(filePath);
- if (!verifyResult.isVerified()) {
- LOGGER.error("verify: {}", verifyResult.getMessage());
- throw new IOException();
- }
- String outputCertPath = options.getString(ParamConstants.PARAM_VERIFY_CERTCHAIN_FILE);
- if (verifyResult.getCertificates() != null) {
- writeCertificate(outputCertPath, verifyResult.getCertificates());
- }
- } catch (IOException e) {
- LOGGER.error("Write certificate chain error", e);
- return false;
- }
-
- String outputProfileFile = options.getString(ParamConstants.PARAM_VERIFY_PROFILE_FILE);
- try {
- outputOptionalBlocks(outputProfileFile, verifyResult);
- } catch (IOException e) {
- LOGGER.error("Output optional blocks error", e);
- return false;
- }
-
- LOGGER.info("verify: {}", verifyResult.getMessage());
- return true;
- }
-
- private void writeCertificate(String destFile, List certificates) throws IOException {
- try (JcaPEMWriter writer = new JcaPEMWriter(new FileWriter(destFile))) {
- for (final X509Certificate cert : certificates) {
- writer.write(cert.getSubjectDN().toString() + System.lineSeparator());
- writer.writeObject(cert);
- }
- LOGGER.info("Write certificate chain success!");
- }
- }
-
- private void outputOptionalBlocks(String outputProfileFile, VerifyResult verifyResult) throws IOException {
- byte[] profile = verifyResult.getProfile();
- if (profile != null) {
- writeOptionalBytesToFile(profile, outputProfileFile);
- }
- }
-
- private void writeOptionalBytesToFile(byte[] data, String outputFile) throws IOException {
- if (outputFile == null || outputFile.isEmpty()) {
- return;
- }
- try (OutputStream out = Files.newOutputStream(Paths.get(outputFile))) {
- out.write(data);
- out.flush();
- }
- }
-
- private boolean checkSignFile(File signedFile) {
- try {
- FileUtils.isValidFile(signedFile);
- } catch (IOException e) {
- LOGGER.error("signedFile is invalid.", e);
- return false;
- }
- return true;
- }
-
- /**
- * Verify elf file.
- *
- * @param binFile path of elf file.
- * @return true, if verify successfully.
- */
- public VerifyResult verifyElf(String binFile) {
- VerifyResult result = new VerifyResult(true, VerifyResult.RET_SUCCESS, "verify signature success");
- File bin = new File(binFile);
- try {
- byte[] bytes = FileUtils.readFile(bin);
- ElfBlockData elfSignBlockData = getElfSignBlockData(bytes);
- String profileJson;
- byte[] profileByte;
- Map signBlock = getSignBlock(bytes, elfSignBlockData);
- if (signBlock.containsKey(SignatureBlockTypes.PROFILE_NOSIGNED_BLOCK)) {
- profileByte = signBlock.get(SignatureBlockTypes.PROFILE_NOSIGNED_BLOCK).getValue();
- profileJson = new String(profileByte, StandardCharsets.UTF_8);
- result.setProfile(profileByte);
- LOGGER.warn("profile is not signed");
- } else if (signBlock.containsKey(SignatureBlockTypes.PROFILE_SIGNED_BLOCK)) {
- // verify signed profile
- SigningBlock profileSign = signBlock.get(SignatureBlockTypes.PROFILE_SIGNED_BLOCK);
- profileByte = profileSign.getValue();
- profileJson = getProfileContent(profileByte);
- result = new HapVerify().verifyElfProfile(profileSign.getValue());
- result.setProfile(profileByte);
- LOGGER.info("verify profile success");
- } else {
- LOGGER.warn("can not found profile sign block");
- profileJson = null;
- }
-
- if (signBlock.containsKey(SignElf.CODESIGN_BLOCK_TYPE)) {
- // verify codesign
- SigningBlock codesign = signBlock.get(SignElf.CODESIGN_BLOCK_TYPE);
- if (!VerifyCodeSignature.verifyElf(bin, codesign.getOffset(), codesign.getLength(),
- "elf", profileJson)) {
- String errMsg = "Verify codesign error!";
- result = new VerifyResult(false, VerifyResult.RET_IO_ERROR, errMsg);
- }
- LOGGER.info("verify codesign success");
- } else {
- LOGGER.warn("can not found code sign block");
- }
- } catch (IOException e) {
- LOGGER.error("Verify file has IO error!", e);
- result = new VerifyResult(false, VerifyResult.RET_IO_ERROR, e.getMessage());
- } catch (FsVerityDigestException | VerifyCodeSignException e) {
- LOGGER.error("Verify codesign error!", e);
- result = new VerifyResult(false, VerifyResult.RET_IO_ERROR, e.getMessage());
- } catch (CMSException | ProfileException e) {
- LOGGER.error("Verify profile error!", e);
- result = new VerifyResult(false, VerifyResult.RET_IO_ERROR, e.getMessage());
- }
- return result;
- }
-
- private ElfBlockData getElfSignBlockData(byte[] bytes) throws IOException {
- int offset = bytes.length - HwSignHead.SIGN_HEAD_LEN;
- byte[] magicByte = readByteArrayOffset(bytes, offset, HwSignHead.ELF_MAGIC.length);
- offset += HwSignHead.ELF_MAGIC.length;
- byte[] versionByte = readByteArrayOffset(bytes, offset, HwSignHead.VERSION.length);
- offset += HwSignHead.VERSION.length;
- for (int i = 0; i < HwSignHead.ELF_MAGIC.length; i++) {
- if (HwSignHead.ELF_MAGIC[i] != magicByte[i]) {
- throw new IOException("elf magic verify failed");
- }
- }
- for (int i = 0; i < HwSignHead.VERSION.length; i++) {
- if (HwSignHead.VERSION[i] != versionByte[i]) {
- throw new IOException("elf sign version verify failed");
- }
- }
- int intByteLength = 4;
- byte[] blockSizeByte = readByteArrayOffset(bytes, offset, intByteLength);
- offset += intByteLength;
- byte[] blockNumByte = readByteArrayOffset(bytes, offset, intByteLength);
- ByteBuffer blockNumBf = ByteBuffer.wrap(blockNumByte).order(ByteOrder.LITTLE_ENDIAN);
- int blockNum = blockNumBf.getInt();
-
- ByteBuffer blockSizeBf = ByteBuffer.wrap(blockSizeByte).order(ByteOrder.LITTLE_ENDIAN);
- int blockSize = blockSizeBf.getInt();
-
- int blockStart = bytes.length - HwSignHead.SIGN_HEAD_LEN - blockSize;
- return new ElfBlockData(blockNum, blockStart);
- }
-
- private Map getSignBlock(byte[] bytes, ElfBlockData elfBlockData) throws ProfileException {
- int offset = elfBlockData.getBlockStart();
-
- Map blockMap = new HashMap<>();
- for (int i = 0; i < elfBlockData.getBlockNum(); i++) {
- byte[] blockByte = readByteArrayOffset(bytes, offset, HwBlockHead.ELF_BLOCK_LEN);
- ByteBuffer blockBuffer = ByteBuffer.wrap(blockByte).order(ByteOrder.LITTLE_ENDIAN);
- char type = blockBuffer.getChar();
- char tag = blockBuffer.getChar();
- int length = blockBuffer.getInt();
- int blockOffset = blockBuffer.getInt();
- byte[] value = readByteArrayOffset(bytes, elfBlockData.getBlockStart() + blockOffset, length);
- blockMap.put(type, new SigningBlock(type, value, elfBlockData.getBlockStart() + blockOffset));
- offset += HwBlockHead.ELF_BLOCK_LEN;
- }
- return blockMap;
- }
-
- private byte[] readByteArrayOffset(byte[] bytes, int offset, int length) {
- byte[] output = new byte[length];
- System.arraycopy(bytes, offset, output, 0, length);
- return output;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java
index 56e634bd9b0d06442a5bf00560bdc8bc454595a6..c5c5834cd78020f1436df6da0773e29b6104fc07 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyHap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -16,13 +16,9 @@
package com.ohos.hapsigntool.hap.verify;
import com.ohos.hapsigntool.api.model.Options;
-import com.ohos.hapsigntool.codesigning.exception.FsVerityDigestException;
-import com.ohos.hapsigntool.codesigning.exception.VerifyCodeSignException;
-import com.ohos.hapsigntool.codesigning.sign.VerifyCodeSignature;
import com.ohos.hapsigntool.hap.entity.Pair;
import com.ohos.hapsigntool.hap.entity.SigningBlock;
import com.ohos.hapsigntool.hap.exception.HapFormatException;
-import com.ohos.hapsigntool.hap.exception.ProfileException;
import com.ohos.hapsigntool.hap.exception.SignatureNotFoundException;
import com.ohos.hapsigntool.utils.FileUtils;
import com.ohos.hapsigntool.utils.HapUtils;
@@ -30,41 +26,34 @@ import com.ohos.hapsigntool.utils.ParamConstants;
import com.ohos.hapsigntool.utils.StringUtils;
import com.ohos.hapsigntool.zip.ByteBufferZipDataInput;
import com.ohos.hapsigntool.zip.RandomAccessFileZipDataInput;
-import com.ohos.hapsigntool.zip.UnsignedDecimalUtil;
import com.ohos.hapsigntool.zip.ZipDataInput;
import com.ohos.hapsigntool.zip.ZipFileInfo;
import com.ohos.hapsigntool.zip.ZipUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.util.Arrays;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
/**
* Class of verify hap.
*
- * @since 2021/12/23
+ * @2021/12/23
*/
public class VerifyHap {
private static final Logger LOGGER = LogManager.getLogger(VerifyHap.class);
@@ -72,37 +61,20 @@ public class VerifyHap {
private static final int ZIP_HEAD_OF_SIGNING_BLOCK_COUNT_OFFSET_REVERSE = 28;
private static final int ZIP_HEAD_OF_SUBSIGNING_BLOCK_LENGTH = 12;
- static {
- Security.addProvider(new BouncyCastleProvider());
- }
-
- private final boolean isPrintCert;
+ private final boolean printCert;
public VerifyHap() {
this(true);
}
- public VerifyHap(boolean isPrintCert) {
- this.isPrintCert = isPrintCert;
+ public VerifyHap(boolean printCert) {
+ this.printCert = printCert;
}
- private static String getProfileContent(byte[] profile) throws ProfileException {
- try {
- CMSSignedData cmsSignedData = new CMSSignedData(profile);
- if (!VerifyUtils.verifyCmsSignedData(cmsSignedData)) {
- throw new ProfileException("Verify profile pkcs7 failed! Profile is invalid");
- }
- Object contentObj = cmsSignedData.getSignedContent().getContent();
- if (!(contentObj instanceof byte[])) {
- throw new ProfileException("Check profile failed, signed profile content is not byte array!");
- }
- return new String((byte[]) contentObj, StandardCharsets.UTF_8);
- } catch (CMSException e) {
- return new String(profile, StandardCharsets.UTF_8);
- }
+ static {
+ Security.addProvider(new BouncyCastleProvider());
}
-
/**
* Check whether parameters are valid
*
@@ -138,6 +110,7 @@ public class VerifyHap {
throw new IOException();
}
String filePath = options.getString(ParamConstants.PARAM_BASIC_INPUT_FILE);
+ String outputCertPath = options.getString(ParamConstants.PARAM_VERIFY_CERTCHAIN_FILE);
if (StringUtils.isEmpty(filePath)) {
LOGGER.error("Not found verify file path!");
throw new IOException();
@@ -152,10 +125,8 @@ public class VerifyHap {
LOGGER.error("verify: {}", verifyResult.getMessage());
throw new IOException();
}
- String outputCertPath = options.getString(ParamConstants.PARAM_VERIFY_CERTCHAIN_FILE);
- if (verifyResult.getCertificates() != null) {
- writeCertificate(outputCertPath, verifyResult.getCertificates());
- }
+
+ writeCertificate(outputCertPath, verifyResult.getCertificates());
} catch (IOException e) {
LOGGER.error("Write certificate chain error", e);
return false;
@@ -186,7 +157,7 @@ public class VerifyHap {
}
private void outputOptionalBlocks(String outputProfileFile, String outputProofFile, String outputPropertyFile,
- VerifyResult verifyResult) throws IOException {
+ VerifyResult verifyResult) throws IOException {
List optionalBlocks = verifyResult.getOptionalBlocks();
if (optionalBlocks != null && optionalBlocks.size() > 0) {
for (SigningBlock optionalBlock : optionalBlocks) {
@@ -206,17 +177,13 @@ public class VerifyHap {
}
}
}
- byte[] profile = verifyResult.getProfile();
- if (profile != null) {
- writeOptionalBytesToFile(profile, outputProfileFile);
- }
}
private void writeOptionalBytesToFile(byte[] data, String outputFile) throws IOException {
if (outputFile == null || outputFile.isEmpty()) {
return;
}
- try (OutputStream out = Files.newOutputStream(Paths.get(outputFile))) {
+ try (OutputStream out = new FileOutputStream(outputFile)) {
out.write(data);
out.flush();
}
@@ -232,6 +199,31 @@ public class VerifyHap {
return true;
}
+ /**
+ * Verify signature of hap.
+ *
+ * @param hapFilePath path of hap file
+ * @param outCertPath path to output certificate file
+ * @param outProvisionFile path to output provision file
+ * @return verify result
+ */
+ public VerifyResult verifyHap(String hapFilePath, String outCertPath, String outProvisionFile) {
+ VerifyResult verifyResult = verifyHap(hapFilePath);
+ if (!verifyResult.isVerified()) {
+ return verifyResult;
+ }
+ List certificates = verifyResult.getCertificates();
+ try {
+ writeCertificate(outCertPath, certificates);
+ outputOptionalBlocks(outProvisionFile, null, null, verifyResult);
+ } catch (IOException e) {
+ LOGGER.error("Write certificate chain or profile error", e);
+ verifyResult.setResult(false);
+ return verifyResult;
+ }
+ return verifyResult;
+ }
+
/**
* Verify hap file.
*
@@ -256,12 +248,16 @@ public class VerifyHap {
ByteBuffer signatureSchemeBlock = blockPair.getFirst();
List optionalBlocks = blockPair.getSecond();
Collections.reverse(optionalBlocks);
- if (!checkCodeSign(hapFilePath, optionalBlocks)) {
- String errMsg = "code sign verify failed";
- return new VerifyResult(false, VerifyResult.RET_CODESIGN_DATA_ERROR, errMsg);
- }
- HapVerify verifyEngine = getHapVerify(hapFile, zipInfo, hapSigningBlockAndOffsetInFile,
- signatureSchemeBlock, optionalBlocks);
+ long signingBlockOffset = hapSigningBlockAndOffsetInFile.getOffset();
+ ZipDataInput beforeHapSigningBlock = hapFile.slice(0, signingBlockOffset);
+ ZipDataInput centralDirectoryBlock = hapFile.slice(zipInfo.getCentralDirectoryOffset(),
+ zipInfo.getCentralDirectorySize());
+ ByteBuffer eocdBbyteBuffer = zipInfo.getEocd();
+ ZipUtils.setCentralDirectoryOffset(eocdBbyteBuffer, signingBlockOffset);
+ ZipDataInput eocdBlock = new ByteBufferZipDataInput(eocdBbyteBuffer);
+ HapVerify verifyEngine = new HapVerify(beforeHapSigningBlock, signatureSchemeBlock,
+ centralDirectoryBlock, eocdBlock, optionalBlocks);
+ verifyEngine.setPrintCert(printCert);
result = verifyEngine.verify();
result.setSignBlockVersion(hapSigningBlockAndOffsetInFile.getVersion());
} catch (IOException e) {
@@ -273,97 +269,19 @@ public class VerifyHap {
} catch (HapFormatException e) {
LOGGER.error("Verify Hap failed, unsupported format hap.", e);
result = new VerifyResult(false, VerifyResult.RET_UNSUPPORTED_FORMAT_ERROR, e.getMessage());
- } catch (FsVerityDigestException e) {
- LOGGER.error("Verify Hap failed, fs-verity digest generate failed.", e);
- result = new VerifyResult(false, VerifyResult.RET_DIGEST_ERROR, e.getMessage());
- } catch (VerifyCodeSignException e) {
- LOGGER.error("Verify Hap failed, code sign block verify failed.", e);
- result = new VerifyResult(false, VerifyResult.RET_CODE_SIGN_BLOCK_ERROR, e.getMessage());
- } catch (CMSException e) {
- LOGGER.error("Verify Hap failed, code signature verify failed.", e);
- result = new VerifyResult(false, VerifyResult.RET_SIGNATURE_ERROR, e.getMessage());
- } catch (ProfileException e) {
- LOGGER.error("Verify Hap failed, parse app-identifier from profile failed, profile is invalid", e);
- return new VerifyResult(false, VerifyResult.RET_CODE_SIGN_BLOCK_ERROR, e.getMessage());
}
return result;
}
- private HapVerify getHapVerify(ZipDataInput hapFile, ZipFileInfo zipInfo,
- HapUtils.HapSignBlockInfo hapSigningBlockAndOffsetInFile,
- ByteBuffer signatureSchemeBlock, List optionalBlocks) {
- long signingBlockOffset = hapSigningBlockAndOffsetInFile.getOffset();
- ZipDataInput beforeHapSigningBlock = hapFile.slice(0, signingBlockOffset);
- ZipDataInput centralDirectoryBlock = hapFile.slice(zipInfo.getCentralDirectoryOffset(),
- zipInfo.getCentralDirectorySize());
- ByteBuffer eocdBbyteBuffer = zipInfo.getEocd();
- ZipUtils.setCentralDirectoryOffset(eocdBbyteBuffer, signingBlockOffset);
- ZipDataInput eocdBlock = new ByteBufferZipDataInput(eocdBbyteBuffer);
- HapVerify verifyEngine = new HapVerify(beforeHapSigningBlock, signatureSchemeBlock,
- centralDirectoryBlock, eocdBlock, optionalBlocks);
- verifyEngine.setIsPrintCert(isPrintCert);
- return verifyEngine;
- }
-
- /**
- * code sign check
- *
- * @param hapFilePath hap file path
- * @param optionalBlocks optional blocks
- * @return true or false
- * @throws FsVerityDigestException FsVerity digest on error
- * @throws IOException IO error
- * @throws VerifyCodeSignException verify code sign on error
- * @throws CMSException cms on error
- * @throws ProfileException profile of the hap error
- */
- private boolean checkCodeSign(String hapFilePath, List optionalBlocks)
- throws FsVerityDigestException, IOException, VerifyCodeSignException, CMSException, ProfileException {
- Map map = optionalBlocks.stream()
- .collect(Collectors.toMap(SigningBlock::getType, SigningBlock::getValue));
- byte[] propertyBlockArray = map.get(HapUtils.HAP_PROPERTY_BLOCK_ID);
- if (propertyBlockArray != null && propertyBlockArray.length > 0) {
- LOGGER.info("trying verify codesign block");
- String[] fileNameArray = hapFilePath.split("\\.");
- if (fileNameArray.length < ParamConstants.FILE_NAME_MIN_LENGTH) {
- LOGGER.error("ZIP64 format not supported");
- return false;
- }
- ByteBuffer byteBuffer = ByteBuffer.wrap(propertyBlockArray);
- ByteBuffer header = HapUtils.reverseSliceBuffer(byteBuffer, 0, ZIP_HEAD_OF_SUBSIGNING_BLOCK_LENGTH);
- long blockOffset = UnsignedDecimalUtil.getUnsignedInt(header);
- int blockLength = header.getInt();
- int blockType = header.getInt();
- if (blockType != HapUtils.HAP_CODE_SIGN_BLOCK_ID) {
- LOGGER.error("Verify Hap has no code sign data error!");
- return false;
- }
- File outputFile = new File(hapFilePath);
- byte[] profileArray = map.get(HapUtils.HAP_PROFILE_BLOCK_ID);
- String profileContent = getProfileContent(profileArray);
- String suffix = fileNameArray[fileNameArray.length - 1];
- boolean isCodeSign = VerifyCodeSignature.verifyHap(outputFile, blockOffset, blockLength,
- suffix, profileContent);
- if (!isCodeSign) {
- LOGGER.error("Verify Hap has no code sign data error!");
- return false;
- }
- LOGGER.info("verify codesign success");
- return true;
- }
- LOGGER.info("can not find codesign block");
- return true;
- }
-
private Pair> getHapSignatureSchemeBlockAndOptionalBlocks(ByteBuffer hapSigningBlock)
throws SignatureNotFoundException {
try {
ByteBuffer header = HapUtils.reverseSliceBuffer(
- hapSigningBlock,
- hapSigningBlock.capacity() - ZIP_HEAD_OF_SIGNING_BLOCK_LENGTH,
- hapSigningBlock.capacity());
+ hapSigningBlock,
+ hapSigningBlock.capacity() - ZIP_HEAD_OF_SIGNING_BLOCK_LENGTH,
+ hapSigningBlock.capacity());
ByteBuffer value = HapUtils.reverseSliceBuffer(hapSigningBlock, 0,
- hapSigningBlock.capacity() - ZIP_HEAD_OF_SIGNING_BLOCK_LENGTH);
+ hapSigningBlock.capacity() - ZIP_HEAD_OF_SIGNING_BLOCK_LENGTH);
byte[] signatureValueBytes = new byte[value.capacity()];
value.get(signatureValueBytes, 0, signatureValueBytes.length);
@@ -383,8 +301,8 @@ public class VerifyHap {
blockLength = value.getInt();
blockType = value.getInt();
if (blockOffset + blockLength > signatureValueBytes.length) {
- throw new SignatureNotFoundException("block end pos: " + (blockOffset + blockLength)
- + " is larger than block len: " + signatureValueBytes.length);
+ throw new SignatureNotFoundException("block end pos: " + (blockOffset + blockLength) +
+ " is larger than block len: " + signatureValueBytes.length);
}
if (HapUtils.getHapSignatureOptionalBlockIds().contains(blockType)) {
byte[] blockValue = Arrays.copyOfRange(signatureValueBytes, blockOffset, blockOffset + blockLength);
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyResult.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyResult.java
index ba032e84625eca6fdf6e1c75f217f20462f8ddec..484a23c6eb9f463ba89886f394c4ee4bbb55697e 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyResult.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/hap/verify/VerifyResult.java
@@ -16,7 +16,6 @@
package com.ohos.hapsigntool.hap.verify;
import com.ohos.hapsigntool.hap.entity.SigningBlock;
-
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.util.Store;
@@ -91,17 +90,7 @@ public class VerifyResult {
*/
public static final int RET_CRL_ERROR = 10011;
- /**
- * Return code of file code sign data error.
- */
- public static final int RET_CODESIGN_DATA_ERROR = 10012;
-
- /**
- * Return code of verify code sign error.
- */
- public static final int RET_CODE_SIGN_BLOCK_ERROR = 10013;
-
- private boolean isResult;
+ private boolean result;
private int code;
private String message;
@@ -117,8 +106,6 @@ public class VerifyResult {
private int signBlockVersion;
- private byte[] profile;
-
/**
* Empty constructor
*/
@@ -128,22 +115,22 @@ public class VerifyResult {
/**
* Verify result constructor
*
- * @param isResult verify result
+ * @param result verify result
* @param code error code
* @param message error message
*/
- public VerifyResult(boolean isResult, int code, String message) {
- this.isResult = isResult;
+ public VerifyResult(boolean result, int code, String message) {
+ this.result = result;
this.code = code;
this.message = message;
}
public boolean isVerified() {
- return isResult;
+ return result;
}
- public void setIsResult(boolean isResult) {
- this.isResult = isResult;
+ public void setResult(boolean result) {
+ this.result = result;
}
public int getCode() {
@@ -209,12 +196,4 @@ public class VerifyResult {
public void setSignBlockVersion(int signBlockVersion) {
this.signBlockVersion = signBlockVersion;
}
-
- public byte[] getProfile() {
- return profile;
- }
-
- public void setProfile(byte[] profile) {
- this.profile = profile;
- }
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/IProvisionVerifier.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/IProvisionVerifier.java
index 3c88f3cebf24d80b24118b48dedec1d4d504da72..db420e14af926081391e4cb38f4e4e2b2263cdae 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/IProvisionVerifier.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/IProvisionVerifier.java
@@ -15,7 +15,6 @@
package com.ohos.hapsigntool.profile;
-import com.ohos.hapsigntool.error.VerifyException;
import com.ohos.hapsigntool.profile.model.VerificationResult;
/**
@@ -30,7 +29,6 @@ public interface IProvisionVerifier {
*
* @param p7b signed p7b content
* @return result
- * @throws VerifyException verify p7b failed
*/
- VerificationResult verify(byte[] p7b) throws VerifyException;
+ VerificationResult verify(byte[] p7b);
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java
index a71cbdde570b0798ab8cdef5e5ea48c630ae40a3..cc58c3fb869b9eff68541c0f9f05761573edb06f 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/ProfileSignTool.java
@@ -18,7 +18,6 @@ package com.ohos.hapsigntool.profile;
import com.ohos.hapsigntool.api.LocalizationAdapter;
import com.ohos.hapsigntool.error.CustomException;
import com.ohos.hapsigntool.error.ERROR;
-import com.ohos.hapsigntool.error.VerifyException;
import com.ohos.hapsigntool.profile.model.VerificationResult;
import com.ohos.hapsigntool.signer.ISigner;
import com.ohos.hapsigntool.signer.SignerFactory;
@@ -89,12 +88,7 @@ public final class ProfileSignTool {
ISigner signer = new SignerFactory().getSigner(adapter);
byte[] p7b = signProfile(content, signer, adapter.getSignAlg());
VerifyHelper verifyHelper = new VerifyHelper();
- VerificationResult verificationResult = null;
- try {
- verificationResult = verifyHelper.verify(p7b);
- } catch (VerifyException e) {
- CustomException.throwException(ERROR.VERIFY_ERROR, "Generate Profile Failed! " + e.getMessage());
- }
+ VerificationResult verificationResult = verifyHelper.verify(p7b);
ValidateUtils.throwIfNotMatches(verificationResult.isVerifiedPassed(), ERROR.SIGN_ERROR,
verificationResult.getMessage());
return p7b;
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java
index 71d691cd11ced2bd27bf9f11abb34abd403afa71..575d50d2a624e26260991e3a5e94fc164bf885e3 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/profile/VerifyHelper.java
@@ -18,7 +18,6 @@ package com.ohos.hapsigntool.profile;
import com.google.gson.JsonObject;
import com.ohos.hapsigntool.error.CustomException;
import com.ohos.hapsigntool.error.ERROR;
-import com.ohos.hapsigntool.error.VerifyException;
import com.ohos.hapsigntool.hap.verify.VerifyUtils;
import com.ohos.hapsigntool.profile.model.VerificationResult;
import com.ohos.hapsigntool.utils.CertChainUtils;
@@ -130,10 +129,9 @@ public class VerifyHelper implements IProvisionVerifier {
*
* @param p7b signed p7b content
* @return result
- * @throws VerifyException verify p7b failed
*/
@Override
- public VerificationResult verify(byte[] p7b) throws VerifyException {
+ public VerificationResult verify(byte[] p7b) {
VerificationResult result = new VerificationResult();
try {
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java
index 28f4e3e8b468f6fdec282de5ed72a9c8be0f0dc9..1ddd9dce9bd8a44715d028a809629625fe88b4a8 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/CertChainUtils.java
@@ -17,7 +17,6 @@ package com.ohos.hapsigntool.utils;
import com.ohos.hapsigntool.error.CustomException;
import com.ohos.hapsigntool.error.ERROR;
-import com.ohos.hapsigntool.error.VerifyException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -89,10 +88,9 @@ public class CertChainUtils {
* @param serial serial number
* @param root root cert
* @param signTime signing time
- * @throws VerifyException verifyException
*/
public static void verifyCertChain(List certificates, X500Principal issuer, BigInteger serial,
- X509Certificate root, Date signTime) throws VerifyException {
+ X509Certificate root, Date signTime) {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
@@ -117,7 +115,8 @@ public class CertChainUtils {
}
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | IOException | CertificateException
| KeyStoreException | CertPathBuilderException | CertPathValidatorException exception) {
- throw new VerifyException("Cert chain verify failed! " + exception.getMessage());
+ LOGGER.debug(exception.getMessage(), exception);
+ CustomException.throwException(ERROR.VERIFY_ERROR, "Failed to verify signature: " + exception.getMessage());
}
}
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java
index b61266aeeb79be65d51c146f8f46d65c6e84570f..cc8d917f487594fcac05e88c72c3d915ebec73bd 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/FileUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -18,7 +18,6 @@ package com.ohos.hapsigntool.utils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ohos.hapsigntool.error.ERROR;
-
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -36,10 +35,6 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* Common file operation.
@@ -47,36 +42,27 @@ import java.util.regex.Pattern;
* @since 2021/12/28
*/
public final class FileUtils {
+
/**
* LOGGER.
*/
private static final Logger LOGGER = LogManager.getLogger(FileUtils.class);
-
- /**
- * suffix regex map
- */
- public static final Map SUFFIX_REGEX_MAP = new HashMap<>();
-
/**
* add GSON static.
*/
public static final Gson GSON = (new GsonBuilder()).disableHtmlEscaping().create();
-
/**
* add GSON_PRETTY_PRINT static.
*/
public static final Gson GSON_PRETTY_PRINT = (new GsonBuilder()).disableHtmlEscaping().setPrettyPrinting().create();
-
/**
* File reader block size
*/
- public static final int FILE_BUFFER_BLOCK = 1024 * 1024;
-
+ public static final int FILE_BUFFER_BLOCK = 4096;
/**
* File end
*/
public static final int FILE_END = -1;
-
/**
* Expected split string length
*/
@@ -84,10 +70,6 @@ public final class FileUtils {
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
- static {
- SUFFIX_REGEX_MAP.put("so", Pattern.compile("\\.so(\\.[0-9]*){0,3}$"));
- }
-
private FileUtils() {
}
@@ -114,7 +96,7 @@ public final class FileUtils {
* @throws IOException Read failed
*/
public static byte[] readFile(File file) throws IOException {
- return read(Files.newInputStream(file.toPath()));
+ return read(new FileInputStream(file));
}
/**
@@ -137,68 +119,6 @@ public final class FileUtils {
}
}
- /**
- * Read byte from input file.
- *
- * @param file input file
- * @param offset offset
- * @param length length
- * @return data bytes
- */
- public static byte[] readFileByOffsetAndLength(File file, long offset, long length) throws IOException {
- try (FileInputStream input = new FileInputStream(file)) {
- return readInputByOffsetAndLength(input, offset, length);
- }
- }
-
- /**
- * Read byte from input stream.
- *
- * @param input input stream
- * @param offset offset
- * @param length length
- * @return data bytes
- * @throws IOException read exception
- */
- public static byte[] readInputByOffsetAndLength(InputStream input, long offset, long length) throws IOException {
- input.skip(offset);
- return readInputByLength(input, length);
- }
-
- /**
- * Read byte from input stream.
- *
- * @param input InputStream
- * @param length length
- * @return data bytes
- */
- public static byte[] readInputByLength(InputStream input, long length) throws IOException {
- try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
- if (length > Integer.MAX_VALUE) {
- throw new IOException("Size cannot be greater than Integer max value: " + length);
- }
- writeInputToOutPut(input, output, length);
- return output.toByteArray();
- }
- }
-
- /**
- * write input to output by length
- */
- private static void writeInputToOutPut(InputStream input, OutputStream output, long length) throws IOException {
- byte[] buffer = new byte[FILE_BUFFER_BLOCK];
- long hasReadLen = 0L;
- while (hasReadLen < length) {
- int readLen = (int) Math.min(length - hasReadLen, FILE_BUFFER_BLOCK);
- int len = input.read(buffer, 0, readLen);
- if (len != readLen) {
- throw new IOException("read" + hasReadLen + "bytes data less than " + length);
- }
- output.write(buffer, 0, len);
- hasReadLen += len;
- }
- }
-
/**
* Out put content to file.
*
@@ -214,29 +134,6 @@ public final class FileUtils {
}
}
- /**
- * Write data in file to output stream
- *
- * @param inFile input file path.
- * @param out output file path.
- * @param offset file read offset
- * @param size file read size
- * @return true, if write successfully.
- */
- public static boolean appendWriteFileByOffsetToFile(String inFile, FileOutputStream out, long offset, long size) {
- File inputFile = new File(inFile);
- try (FileInputStream fis = new FileInputStream(inputFile)) {
- fis.skip(offset);
- writeInputToOutPut(fis, out, size);
- return true;
- } catch (FileNotFoundException e) {
- LOGGER.error("Failed to get input stream object.");
- } catch (IOException e) {
- LOGGER.error("Failed to read or write data.");
- }
- return false;
- }
-
/**
* Check file exist or not.
*
@@ -324,13 +221,10 @@ public final class FileUtils {
* @return true, if write successfully.
*/
public static boolean writeByteToDos(byte[] data, DataOutputStream dos) {
- if (data == null) {
- return true;
- }
try {
dos.write(data);
} catch (IOException e) {
- LOGGER.error("Failed to write data to output stream.");
+ LOGGER.error("Faile to write data to output stream.");
return false;
}
return true;
@@ -353,32 +247,14 @@ public final class FileUtils {
/**
* Write byte array data to output file.
*
- * @param bytes byte array data.
+ * @param signHeadByte byte array data.
* @param outFile output file path.
* @return true, if write successfully.
*/
- public static boolean writeByteToOutFile(byte[] bytes, String outFile) {
+ public static boolean writeByteToOutFile(byte[] signHeadByte, String outFile) {
try (OutputStream ops = new FileOutputStream(outFile, true)) {
- return writeByteToOutFile(bytes, ops);
- } catch (FileNotFoundException e) {
- LOGGER.error("Failed to get output stream object, outfile: " + outFile);
- } catch (IOException e) {
- LOGGER.error("Failed to write data to ops, outfile: " + outFile);
- }
- return false;
- }
-
- /**
- * Write byte array data to output file.
- *
- * @param bytes byte array data.
- * @param outFile output file path.
- * @return true, if write successfully.
- */
- public static boolean writeByteToOutFile(byte[] bytes, OutputStream outFile) {
- try {
- outFile.write(bytes, 0, bytes.length);
- outFile.flush();
+ ops.write(signHeadByte, 0, signHeadByte.length);
+ ops.flush();
return true;
} catch (FileNotFoundException e) {
LOGGER.error("Failed to get output stream object, outfile: " + outFile);
@@ -410,7 +286,6 @@ public final class FileUtils {
/**
* Open an input stream of input file safely.
- *
* @param file input file.
* @return an input stream of input file
* @throws IOException file is a directory or can't be read.
@@ -491,26 +366,4 @@ public final class FileUtils {
}
}
}
-
- /**
- * regex filename
- *
- * @param name filename
- * @return boolean
- */
- public static boolean isRunnableFile(String name) {
- if (StringUtils.isEmpty(name)) {
- return false;
- }
- if (name.endsWith(".an") || name.endsWith(".abc")) {
- return true;
- }
- for (Pattern pattern : SUFFIX_REGEX_MAP.values()) {
- Matcher matcher = pattern.matcher(name);
- if (matcher.find()) {
- return true;
- }
- }
- return false;
- }
}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/HapUtils.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/HapUtils.java
index 172f8a75789ce473b2aa459476b2d4cef5f80169..e51a3f59505ded067c6a171757b0e1966c9843db 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/HapUtils.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/HapUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -38,12 +38,12 @@ import java.nio.ByteOrder;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Collections;
/**
* Hap util, parse hap, find signature block.
@@ -73,11 +73,6 @@ public class HapUtils {
*/
public static final int HAP_PROPERTY_BLOCK_ID = 0x20000003;
- /**
- * ID of property block
- */
- public static final int HAP_CODE_SIGN_BLOCK_ID = 0x30000001;
-
/**
* The size of data block used to get digest
*/
@@ -102,12 +97,12 @@ public class HapUtils {
/**
* int size
*/
- public static final int INT_SIZE = 4;
+ public static final int INT_SIZE = 4;
/**
* block number
*/
- public static final int BLOCK_NUMBER = 1;
+ public static final int BLOCK_NUMBER = 1;
/**
* hap sign schema v2 signature block version
@@ -129,67 +124,55 @@ public class HapUtils {
*/
public static final long HAP_SIG_BLOCK_MAGIC_HI_V2 = 0x3234206b636f6c42L;
+ private HapUtils() {
+ }
+
/**
- * The value of lower 8 bytes of magic word
+ * The set of IDs of optional blocks in hap signature block.
*/
- public static final long HAP_SIG_BLOCK_MAGIC_LO_V3 = 0x676973207061683cL;
+ private static final Set HAP_SIGNATURE_OPTIONAL_BLOCK_IDS ;
/**
- * The value of higher 8 bytes of magic word
+ * Minimum api version for hap sign schema v3.
*/
- public static final long HAP_SIG_BLOCK_MAGIC_HI_V3 = 0x3e6b636f6c62206eL;
+ private static final int MIN_COMPATIBLE_VERSION_FOR_SCHEMA_V3 = 8;
/**
- * Size of hap signature block header
+ * Magic word of hap signature block v2
*/
- public static final int HAP_SIG_BLOCK_HEADER_SIZE = 32;
+ private static final byte[] HAP_SIGNING_BLOCK_MAGIC_V2 =
+ new byte[] {0x48, 0x41, 0x50, 0x20, 0x53, 0x69, 0x67, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x34, 0x32};
/**
- * The min size of hap signature block
+ * Magic word of hap signature block
*/
- public static final int HAP_SIG_BLOCK_MIN_SIZE = HAP_SIG_BLOCK_HEADER_SIZE;
+ private static final byte[] HAP_SIGNING_BLOCK_MAGIC_V3 =
+ new byte[] {0x3c, 0x68, 0x61, 0x70, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3e};
/**
- * The set of IDs of optional blocks in hap signature block.
+ * The value of lower 8 bytes of magic word
*/
- private static final Set HAP_SIGNATURE_OPTIONAL_BLOCK_IDS ;
+ public static final long HAP_SIG_BLOCK_MAGIC_LO_V3 = 0x676973207061683cL;
/**
- * Minimum api version for hap sign schema v3.
+ * The value of higher 8 bytes of magic word
*/
- private static final int MIN_COMPATIBLE_VERSION_FOR_SCHEMA_V3 = 8;
+ public static final long HAP_SIG_BLOCK_MAGIC_HI_V3 = 0x3e6b636f6c62206eL;
/**
- * Magic word of hap signature block v2
+ * Size of hap signature block header
*/
- private static final byte[] HAP_SIGNING_BLOCK_MAGIC_V2 =
- new byte[] {0x48, 0x41, 0x50, 0x20, 0x53, 0x69, 0x67, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x34, 0x32};
+ public static final int HAP_SIG_BLOCK_HEADER_SIZE = 32;
/**
- * Magic word of hap signature block
+ * The min size of hap signature block
*/
- private static final byte[] HAP_SIGNING_BLOCK_MAGIC_V3 =
- new byte[] {0x3c, 0x68, 0x61, 0x70, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3e};
+ public static final int HAP_SIG_BLOCK_MIN_SIZE = HAP_SIG_BLOCK_HEADER_SIZE;
private static final byte ZIP_FIRST_LEVEL_CHUNK_PREFIX = 0x5a;
private static final byte ZIP_SECOND_LEVEL_CHUNK_PREFIX = (byte) 0xa5;
private static final int DIGEST_PRIFIX_LENGTH = 5;
private static final int BUFFER_LENGTH = 4096;
- private static final char[] HEX_CHAR_ARRAY = "0123456789ABCDEF".toCharArray();
-
- /**
- * The set of IDs of optional blocks in hap signature block.
- */
- static {
- Set blockIds = new HashSet();
- blockIds.add(HAP_PROOF_OF_ROTATION_BLOCK_ID);
- blockIds.add(HAP_PROFILE_BLOCK_ID);
- blockIds.add(HAP_PROPERTY_BLOCK_ID);
- HAP_SIGNATURE_OPTIONAL_BLOCK_IDS = Collections.unmodifiableSet(blockIds);
- }
-
- private HapUtils() {
- }
/**
* Get HAP_SIGNATURE_OPTIONAL_BLOCK_IDS
@@ -226,6 +209,17 @@ public class HapUtils {
return HAP_SIGN_SCHEME_V2_BLOCK_VERSION;
}
+ /**
+ * The set of IDs of optional blocks in hap signature block.
+ */
+ static {
+ Set blockIds = new HashSet();
+ blockIds.add(HAP_PROOF_OF_ROTATION_BLOCK_ID);
+ blockIds.add(HAP_PROFILE_BLOCK_ID);
+ blockIds.add(HAP_PROPERTY_BLOCK_ID);
+ HAP_SIGNATURE_OPTIONAL_BLOCK_IDS = Collections.unmodifiableSet(blockIds);
+ }
+
/**
* Read data from hap file.
*
@@ -235,7 +229,7 @@ public class HapUtils {
*/
public static byte[] readFileToByte(String file) throws IOException {
try (FileInputStream in = new FileInputStream(file);
- ByteArrayOutputStream out = new ByteArrayOutputStream(in.available());) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream(in.available());) {
byte[] buf = new byte[BUFFER_LENGTH];
int len = 0;
while ((len = in.read(buf)) != -1) {
@@ -248,8 +242,8 @@ public class HapUtils {
private static long getChunkCount(ZipDataInput[] contents) {
long chunkCount = 0L;
for (ZipDataInput content : contents) {
- chunkCount += ((content.size() + CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES - 1)
- / CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
+ chunkCount += ((content.size() + CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES - 1) /
+ CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
}
return chunkCount;
}
@@ -273,7 +267,7 @@ public class HapUtils {
}
int chunkCount = (int) chunkCountLong;
ContentDigestAlgorithm[] contentDigestAlgorithms = digestAlgorithms.toArray(
- new ContentDigestAlgorithm[digestAlgorithms.size()]);
+ new ContentDigestAlgorithm[digestAlgorithms.size()]);
MessageDigest[] messageDigests = new MessageDigest[contentDigestAlgorithms.length];
int[] digestOutputSizes = new int[contentDigestAlgorithms.length];
byte[][] digestOfChunks = new byte[contentDigestAlgorithms.length][];
@@ -312,7 +306,7 @@ public class HapUtils {
for (int i = 0; i < contentDigestAlgorithms.length; i++) {
int expectedDigestSizeBytes = digestOutputSizes[i];
int actualDigestSizeBytes = messageDigests[i].digest(digestOfChunks[i],
- chunkIndex * expectedDigestSizeBytes + DIGEST_PRIFIX_LENGTH, expectedDigestSizeBytes);
+ chunkIndex * expectedDigestSizeBytes + DIGEST_PRIFIX_LENGTH, expectedDigestSizeBytes);
if (actualDigestSizeBytes != expectedDigestSizeBytes) {
throw new DigestException("Unexpected output size of " + messageDigests[i].getAlgorithm()
+ " digest: " + actualDigestSizeBytes);
@@ -340,7 +334,7 @@ public class HapUtils {
}
private static Map getContentDigestAlgorithmMap(List optionalBlocks,
- ContentDigestAlgorithm[] contentDigestAlgorithms, MessageDigest[] messageDigests, byte[][] digestOfChunks) {
+ ContentDigestAlgorithm[] contentDigestAlgorithms, MessageDigest[] messageDigests, byte[][] digestOfChunks) {
Map result = new HashMap<>(contentDigestAlgorithms.length);
for (int i = 0; i < contentDigestAlgorithms.length; i++) {
messageDigests[i].update(digestOfChunks[i]);
@@ -358,6 +352,8 @@ public class HapUtils {
}
}
+ private static final char[] HEX_CHAR_ARRAY = "0123456789ABCDEF".toCharArray();
+
/**
* Slice buffer to target size.
*
@@ -388,7 +384,7 @@ public class HapUtils {
int capacity = source.capacity();
if (startPos < 0 || endPos < startPos || endPos > capacity) {
throw new IllegalArgumentException(
- "startPos: " + startPos + ", endPos: " + endPos + ", capacity: " + capacity);
+ "startPos: " + startPos + ", endPos: " + endPos + ", capacity: " + capacity);
}
int limit = source.limit();
int position = source.position();
@@ -442,7 +438,7 @@ public class HapUtils {
int encodeSize = 0;
encodeSize += INT_SIZE + INT_SIZE;
for (Pair pair : pairList) {
- encodeSize += INT_SIZE + INT_SIZE + INT_SIZE + pair.getSecond().length;
+ encodeSize += INT_SIZE+INT_SIZE+INT_SIZE + pair.getSecond().length;
}
ByteBuffer encodeBytes = ByteBuffer.allocate(encodeSize);
encodeBytes.order(ByteOrder.LITTLE_ENDIAN);
@@ -450,7 +446,7 @@ public class HapUtils {
encodeBytes.putInt(BLOCK_NUMBER); // block number
for (Pair pair : pairList) {
byte[] second = pair.getSecond();
- encodeBytes.putInt(INT_SIZE + INT_SIZE + second.length);
+ encodeBytes.putInt(INT_SIZE+INT_SIZE + second.length);
encodeBytes.putInt(pair.getFirst());
encodeBytes.putInt(second.length);
encodeBytes.put(second);
@@ -511,21 +507,11 @@ public class HapUtils {
long hapSignBlockMagicLo = hapSigningBlockHeader.getLong();
long hapSignBlockMagicHi = hapSigningBlockHeader.getLong();
int version = hapSigningBlockHeader.getInt();
- long hapSigningBlockOffset = verifySignBlock(hapSigBlockSize,
- hapSignBlockMagicLo, hapSignBlockMagicHi, version, centralDirectoryStartOffset);
- ByteBuffer hapSigningBlockByteBuffer = hap.createByteBuffer(hapSigningBlockOffset, (int) hapSigBlockSize)
- .order(ByteOrder.LITTLE_ENDIAN);
- LOGGER.info("Find Hap Signing Block success, version: {}, block count: {}", version, blockCount);
- return new HapSignBlockInfo(hapSigningBlockOffset, version, hapSigningBlockByteBuffer);
- }
-
- private static long verifySignBlock(long hapSigBlockSize, long hapSignBlockMagicLo,
- long hapSignBlockMagicHi, int version, long centralDirectoryStartOffset) throws SignatureNotFoundException {
if (!isVersionAndMagicNumValid(version, hapSignBlockMagicLo, hapSignBlockMagicHi)) {
throw new SignatureNotFoundException("No Hap Signing Block before ZIP Central Directory");
}
- if ((hapSigBlockSize < HAP_SIG_BLOCK_HEADER_SIZE)
- || (hapSigBlockSize > Integer.MAX_VALUE - SignHap.getBlockSize())) {
+ if ((hapSigBlockSize < HAP_SIG_BLOCK_HEADER_SIZE) ||
+ (hapSigBlockSize > Integer.MAX_VALUE - SignHap.getBlockSize())) {
throw new SignatureNotFoundException("Hap Signing Block size out of range: " + hapSigBlockSize);
}
int totalSize = (int) hapSigBlockSize;
@@ -533,7 +519,10 @@ public class HapUtils {
if (hapSigningBlockOffset < 0) {
throw new SignatureNotFoundException("Hap Signing Block offset out of range: " + hapSigningBlockOffset);
}
- return hapSigningBlockOffset;
+ ByteBuffer hapSigningBlockByteBuffer = hap.createByteBuffer(hapSigningBlockOffset, totalSize)
+ .order(ByteOrder.LITTLE_ENDIAN);
+ LOGGER.info("Find Hap Signing Block success, version: {}, block count: {}", version, blockCount);
+ return new HapSignBlockInfo(hapSigningBlockOffset, version, hapSigningBlockByteBuffer);
}
private static boolean isVersionAndMagicNumValid(int version, long hapSignBlockMagicLo, long hapSignBlockMagicHi) {
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/ParamConstants.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/ParamConstants.java
index e856abe65d9af2f2033b0febaab2f58ab94f6604..3b1dbde6f783da007716b57a82f6bc557d008fa6 100644
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/ParamConstants.java
+++ b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/utils/ParamConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -136,11 +136,6 @@ public class ParamConstants {
*/
public static final String PARAM_BASIC_PROFILE = "profileFile";
- /**
- * json type content of Hap-file's capability profile
- */
- public static final String PARAM_PROFILE_JSON_CONTENT = "profileContent";
-
/**
* Hap-file's proof-of-rotation
*/
@@ -241,27 +236,12 @@ public class ParamConstants {
*/
public static final String PARAM_RESIGN_CONFIG_FILE = "resignconfig";
- /**
- * sign file type bin or zip or elf
- */
- public static final String PARAM_IN_FORM = "inForm";
-
- /**
- * The code sign params of resign hap
- */
- public static final String PARAM_SIGN_CODE = "signCode";
-
- /**
- * file name split . of min length
- */
- public static final int FILE_NAME_MIN_LENGTH = 2;
-
/**
* Enumerated value of whether a profile is signed
*/
public enum ProfileSignFlag {
- DISABLE_SIGN_CODE("0"),
- ENABLE_SIGN_CODE("1");
+ UNSIGNED_PROFILE("0"),
+ SIGNED_PROFILE("1");
private String signFlag;
@@ -273,22 +253,4 @@ public class ParamConstants {
return signFlag;
}
}
-
- /**
- * Enumerated value of whether a code sign is signed.
- */
- public enum SignCodeFlag {
- DISABLE_SIGN_CODE("0"),
- ENABLE_SIGN_CODE("1");
-
- private String signCodeFlag;
-
- SignCodeFlag(String signCodeFlag) {
- this.signCodeFlag = signCodeFlag;
- }
-
- public String getSignCodeFlag() {
- return signCodeFlag;
- }
- }
}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/CentralDirectory.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/CentralDirectory.java
deleted file mode 100644
index 04adc9b4260579ab487baa6b3a972068313d03bd..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/CentralDirectory.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import com.ohos.hapsigntool.error.ZipException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-
-/**
- * resolve zip CentralDirectory data
- * CentralDirectory format for:
- * central file header signature 4 bytes (0x02014b50)
- * version made by 2 bytes
- * version needed to extract 2 bytes
- * general purpose bit flag 2 bytes
- * compression method 2 bytes
- * last mod file time 2 bytes
- * last mod file date 2 bytes
- * crc-32 4 bytes
- * compressed size 4 bytes
- * uncompressed size 4 bytes
- * file name length 2 bytes
- * extra field length 2 bytes
- * file comment length 2 bytes
- * disk number start 2 bytes
- * internal file attributes 2 bytes
- * external file attributes 4 bytes
- * relative offset of local header 4 bytes
- * file name (variable size)
- * extra field (variable size)
- * file comment (variable size)
- *
- * @since 2023/12/02
- */
-public class CentralDirectory {
- /**
- * central directory invariable bytes length
- */
- public static final int CD_LENGTH = 46;
-
- /**
- * 4 bytes , central directory signature
- */
- public static final int SIGNATURE = 0x02014b50;
-
- /**
- * 2 bytes
- */
- private short version;
-
- /**
- * 2 bytes
- */
- private short versionExtra;
-
- /**
- * 2 bytes
- */
- private short flag;
-
- /**
- * 2 bytes
- */
- private short method;
-
- /**
- * 2 bytes
- */
- private short lastTime;
-
- /**
- * 2 bytes
- */
- private short lastDate;
-
- /**
- * 4 bytes
- */
- private int crc32;
-
- /**
- * 4 bytes
- */
- private long compressedSize;
-
- /**
- * 4 bytes
- */
- private long unCompressedSize;
-
- /**
- * 2 bytes
- */
- private int fileNameLength;
-
- /**
- * 2 bytes
- */
- private int extraLength;
-
- /**
- * 2 bytes
- */
- private int commentLength;
-
- /**
- * 2 bytes
- */
- private int diskNumStart;
-
- /**
- * 2 bytes
- */
- private short internalFile;
-
- /**
- * 4 bytes
- */
- private int externalFile;
-
- /**
- * 4 bytes
- */
- private long offset;
-
- /**
- * n bytes
- */
- private String fileName;
-
- /**
- * n bytes
- */
- private byte[] extraData;
-
- /**
- * n bytes
- */
- private byte[] comment;
-
- private int length;
-
- /**
- * get Central Directory
- *
- * @param bf ByteBuffer
- * @return CentralDirectory
- * @throws ZipException read Central Directory exception
- */
- public static CentralDirectory getCentralDirectory(ByteBuffer bf) throws ZipException {
- CentralDirectory cd = new CentralDirectory();
- if (bf.getInt() != SIGNATURE) {
- throw new ZipException("find zip central directory failed");
- }
-
- cd.setVersion(bf.getShort());
- cd.setVersionExtra(bf.getShort());
- cd.setFlag(bf.getShort());
- cd.setMethod(bf.getShort());
- cd.setLastTime(bf.getShort());
- cd.setLastDate(bf.getShort());
- cd.setCrc32(bf.getInt());
- cd.setCompressedSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- cd.setUnCompressedSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- cd.setFileNameLength(UnsignedDecimalUtil.getUnsignedShort(bf));
- cd.setExtraLength(UnsignedDecimalUtil.getUnsignedShort(bf));
- cd.setCommentLength(UnsignedDecimalUtil.getUnsignedShort(bf));
- cd.setDiskNumStart(UnsignedDecimalUtil.getUnsignedShort(bf));
- cd.setInternalFile(bf.getShort());
- cd.setExternalFile(bf.getInt());
- cd.setOffset(UnsignedDecimalUtil.getUnsignedInt(bf));
- if (cd.getFileNameLength() > 0) {
- byte[] readFileName = new byte[cd.getFileNameLength()];
- bf.get(readFileName);
- cd.setFileName(new String(readFileName, StandardCharsets.UTF_8));
- }
- if (cd.getExtraLength() > 0) {
- byte[] extra = new byte[cd.getExtraLength()];
- bf.get(extra);
- cd.setExtraData(extra);
- }
- if (cd.getCommentLength() > 0) {
- byte[] readComment = new byte[cd.getCommentLength()];
- bf.get(readComment);
- cd.setComment(readComment);
- }
- cd.setLength(CD_LENGTH + cd.getFileNameLength() + cd.getExtraLength() + cd.getCommentLength());
- return cd;
- }
-
- /**
- * change Central Directory to bytes
- *
- * @return bytes
- */
- public byte[] toBytes() {
- ByteBuffer bf = ByteBuffer.allocate(length).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(SIGNATURE);
- UnsignedDecimalUtil.setUnsignedShort(bf, version);
- UnsignedDecimalUtil.setUnsignedShort(bf, versionExtra);
- UnsignedDecimalUtil.setUnsignedShort(bf, flag);
- UnsignedDecimalUtil.setUnsignedShort(bf, method);
- UnsignedDecimalUtil.setUnsignedShort(bf, lastTime);
- UnsignedDecimalUtil.setUnsignedShort(bf, lastDate);
- UnsignedDecimalUtil.setUnsignedInt(bf, crc32);
- UnsignedDecimalUtil.setUnsignedInt(bf, compressedSize);
- UnsignedDecimalUtil.setUnsignedInt(bf, unCompressedSize);
- UnsignedDecimalUtil.setUnsignedShort(bf, fileNameLength);
- UnsignedDecimalUtil.setUnsignedShort(bf, extraLength);
- UnsignedDecimalUtil.setUnsignedShort(bf, commentLength);
- UnsignedDecimalUtil.setUnsignedShort(bf, diskNumStart);
- UnsignedDecimalUtil.setUnsignedShort(bf, internalFile);
- UnsignedDecimalUtil.setUnsignedInt(bf, externalFile);
- UnsignedDecimalUtil.setUnsignedInt(bf, offset);
- if (fileNameLength > 0) {
- bf.put(fileName.getBytes(StandardCharsets.UTF_8));
- }
- if (extraLength > 0) {
- bf.put(extraData);
- }
- if (commentLength > 0) {
- bf.put(extraData);
- }
- return bf.array();
- }
-
- public static int getCdLength() {
- return CD_LENGTH;
- }
-
- public static int getSIGNATURE() {
- return SIGNATURE;
- }
-
- public short getVersion() {
- return version;
- }
-
- public void setVersion(short version) {
- this.version = version;
- }
-
- public short getVersionExtra() {
- return versionExtra;
- }
-
- public void setVersionExtra(short versionExtra) {
- this.versionExtra = versionExtra;
- }
-
- public short getFlag() {
- return flag;
- }
-
- public void setFlag(short flag) {
- this.flag = flag;
- }
-
- public short getMethod() {
- return method;
- }
-
- public void setMethod(short method) {
- this.method = method;
- }
-
- public short getLastTime() {
- return lastTime;
- }
-
- public void setLastTime(short lastTime) {
- this.lastTime = lastTime;
- }
-
- public short getLastDate() {
- return lastDate;
- }
-
- public void setLastDate(short lastDate) {
- this.lastDate = lastDate;
- }
-
- public int getCrc32() {
- return crc32;
- }
-
- public void setCrc32(int crc32) {
- this.crc32 = crc32;
- }
-
- public long getCompressedSize() {
- return compressedSize;
- }
-
- public void setCompressedSize(long compressedSize) {
- this.compressedSize = compressedSize;
- }
-
- public long getUnCompressedSize() {
- return unCompressedSize;
- }
-
- public void setUnCompressedSize(long unCompressedSize) {
- this.unCompressedSize = unCompressedSize;
- }
-
- public int getFileNameLength() {
- return fileNameLength;
- }
-
- public void setFileNameLength(int fileNameLength) {
- this.fileNameLength = fileNameLength;
- }
-
- public int getExtraLength() {
- return extraLength;
- }
-
- public void setExtraLength(int extraLength) {
- this.extraLength = extraLength;
- }
-
- public int getCommentLength() {
- return commentLength;
- }
-
- public void setCommentLength(int commentLength) {
- this.commentLength = commentLength;
- }
-
- public int getDiskNumStart() {
- return diskNumStart;
- }
-
- public void setDiskNumStart(int diskNumStart) {
- this.diskNumStart = diskNumStart;
- }
-
- public short getInternalFile() {
- return internalFile;
- }
-
- public void setInternalFile(short internalFile) {
- this.internalFile = internalFile;
- }
-
- public int getExternalFile() {
- return externalFile;
- }
-
- public void setExternalFile(int externalFile) {
- this.externalFile = externalFile;
- }
-
- public long getOffset() {
- return offset;
- }
-
- public void setOffset(long offset) {
- this.offset = offset;
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- public byte[] getExtraData() {
- return extraData;
- }
-
- public void setExtraData(byte[] extraData) {
- this.extraData = extraData;
- }
-
- public byte[] getComment() {
- return comment;
- }
-
- public void setComment(byte[] comment) {
- this.comment = comment;
- }
-
- public int getLength() {
- return length;
- }
-
- public void setLength(int length) {
- this.length = length;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/DataDescriptor.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/DataDescriptor.java
deleted file mode 100644
index fb521bf5cad9dd9074172b11a4138597cd460d17..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/DataDescriptor.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import com.ohos.hapsigntool.error.ZipException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * resolve zip DataDescriptor data
- * DataDescriptor format:
- * crc-32 4 bytes
- * compressed size 4 bytes
- * uncompressed size 4 bytes
- *
- * @since 2023/12/02
- */
-public class DataDescriptor {
- /**
- * DataDescriptor invariable bytes length
- */
- public static final int DES_LENGTH = 16;
-
- /**
- * 4 bytes , DataDescriptor signature
- */
- public static final int SIGNATURE = 0x08074b50;
-
- /**
- * 4 bytes
- */
- private int crc32;
-
- /**
- * 4 bytes
- */
- private long compressedSize;
-
- /**
- * 4 bytes
- */
- private long unCompressedSize;
-
- /**
- * get Data Descriptor
- *
- * @param bytes DataDescriptor bytes
- * @return DataDescriptor
- * @throws ZipException read data descriptor exception
- */
- public static DataDescriptor getDataDescriptor(byte[] bytes) throws ZipException {
- if (bytes.length != DES_LENGTH) {
- throw new ZipException("read Data Descriptor failed");
- }
- ByteBuffer bf = ByteBuffer.wrap(bytes);
- bf.order(ByteOrder.LITTLE_ENDIAN);
- DataDescriptor data = new DataDescriptor();
- if (bf.getInt() != SIGNATURE) {
- throw new ZipException("read Data Descriptor failed");
- }
- data.setCrc32(bf.getInt());
- data.setCompressedSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- data.setUnCompressedSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- return data;
- }
-
- /**
- * change DataDescriptor to bytes
- *
- * @return bytes
- */
- public byte[] toBytes() {
- ByteBuffer bf = ByteBuffer.allocate(DES_LENGTH).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(SIGNATURE);
- bf.putInt(crc32);
- UnsignedDecimalUtil.setUnsignedInt(bf, compressedSize);
- UnsignedDecimalUtil.setUnsignedInt(bf, unCompressedSize);
- return bf.array();
- }
-
- public static int getDesLength() {
- return DES_LENGTH;
- }
-
- public static int getSIGNATURE() {
- return SIGNATURE;
- }
-
- public int getCrc32() {
- return crc32;
- }
-
- public void setCrc32(int crc32) {
- this.crc32 = crc32;
- }
-
- public long getCompressedSize() {
- return compressedSize;
- }
-
- public void setCompressedSize(long compressedSize) {
- this.compressedSize = compressedSize;
- }
-
- public long getUnCompressedSize() {
- return unCompressedSize;
- }
-
- public void setUnCompressedSize(long unCompressedSize) {
- this.unCompressedSize = unCompressedSize;
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/EndOfCentralDirectory.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/EndOfCentralDirectory.java
deleted file mode 100644
index 92d211b305612c48bfd453e3478ab2ab3d7be970..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/EndOfCentralDirectory.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Optional;
-
-/**
- * resolve zip EndOfCentralDirectory data
- * EndOfCentralDirectory format for:
- * end of central dir signature 4 bytes (0x06054b50)
- * number of this disk 2 bytes
- * number of the disk with the
- * start of the central directory 2 bytes
- * total number of entries in the
- * central directory on this disk 2 bytes
- * total number of entries in
- * the central directory 2 bytes
- * size of the central directory 4 bytes
- * offset of start of central
- * directory with respect to
- * the starting disk number 4 bytes
- * .ZIP file comment length 2 bytes
- * .ZIP file comment (variable size)
- *
- * @since 2023/12/04
- */
-public class EndOfCentralDirectory {
- /**
- * EndOfCentralDirectory invariable bytes length
- */
- public static final int EOCD_LENGTH = 22;
-
- /**
- * 4 bytes , central directory signature
- */
- public static final int SIGNATURE = 0x06054b50;
-
- /**
- * 2 bytes
- */
- private int diskNum;
-
- /**
- * 2 bytes
- */
- private int cDStartDiskNum;
-
- /**
- * 2 bytes
- */
- private int thisDiskCDNum;
-
- /**
- * 2 bytes
- */
- private int cDTotal;
-
- /**
- * 4 bytes
- */
- private long cDSize;
-
- /**
- * 4 bytes
- */
- private long offset;
-
- /**
- * 2 bytes
- */
- private int commentLength;
-
- /**
- * n bytes
- */
- private byte[] comment;
-
- private int length;
-
- /**
- * init End Of Central Directory, default offset is 0
- *
- * @param bytes End Of Central Directory bytes
- * @return End Of Central Directory
- */
- public static Optional getEOCDByBytes(byte[] bytes) {
- return getEOCDByBytes(bytes, 0);
- }
-
- /**
- * init End Of Central Directory
- *
- * @param bytes End Of Central Directory bytes
- * @param offset offset
- * @return End Of Central Directory
- */
- public static Optional getEOCDByBytes(byte[] bytes, int offset) {
- EndOfCentralDirectory eocd = new EndOfCentralDirectory();
- int remainingDataLen = bytes.length - offset;
- if (remainingDataLen < EOCD_LENGTH) {
- return Optional.empty();
- }
- ByteBuffer bf = ByteBuffer.wrap(bytes, offset, remainingDataLen);
- bf.order(ByteOrder.LITTLE_ENDIAN);
- if (bf.getInt() != SIGNATURE) {
- return Optional.empty();
- }
- eocd.setDiskNum(UnsignedDecimalUtil.getUnsignedShort(bf));
- eocd.setcDStartDiskNum(UnsignedDecimalUtil.getUnsignedShort(bf));
- eocd.setThisDiskCDNum(UnsignedDecimalUtil.getUnsignedShort(bf));
- eocd.setcDTotal(UnsignedDecimalUtil.getUnsignedShort(bf));
- eocd.setcDSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- eocd.setOffset(UnsignedDecimalUtil.getUnsignedInt(bf));
- eocd.setCommentLength(UnsignedDecimalUtil.getUnsignedShort(bf));
- if (bf.remaining() != eocd.getCommentLength()) {
- return Optional.empty();
- }
- if (eocd.getCommentLength() > 0) {
- byte[] readComment = new byte[eocd.getCommentLength()];
- bf.get(readComment);
- eocd.setComment(readComment);
- }
- eocd.setLength(EOCD_LENGTH + eocd.getCommentLength());
- if (bf.remaining() != 0) {
- return Optional.empty();
- }
- return Optional.of(eocd);
- }
-
- /**
- * change End Of Central Directory to bytes
- *
- * @return bytes
- */
- public byte[] toBytes() {
- ByteBuffer bf = ByteBuffer.allocate(length).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(SIGNATURE);
- UnsignedDecimalUtil.setUnsignedShort(bf, diskNum);
- UnsignedDecimalUtil.setUnsignedShort(bf, cDStartDiskNum);
- UnsignedDecimalUtil.setUnsignedShort(bf, thisDiskCDNum);
- UnsignedDecimalUtil.setUnsignedShort(bf, cDTotal);
- UnsignedDecimalUtil.setUnsignedInt(bf, cDSize);
- UnsignedDecimalUtil.setUnsignedInt(bf, offset);
- UnsignedDecimalUtil.setUnsignedShort(bf, commentLength);
- if (commentLength > 0) {
- bf.put(comment);
- }
- return bf.array();
- }
-
- public static int getEocdLength() {
- return EOCD_LENGTH;
- }
-
- public static int getSIGNATURE() {
- return SIGNATURE;
- }
-
- public int getDiskNum() {
- return diskNum;
- }
-
- public void setDiskNum(int diskNum) {
- this.diskNum = diskNum;
- }
-
- public int getcDStartDiskNum() {
- return cDStartDiskNum;
- }
-
- public void setcDStartDiskNum(int cDStartDiskNum) {
- this.cDStartDiskNum = cDStartDiskNum;
- }
-
- public int getThisDiskCDNum() {
- return thisDiskCDNum;
- }
-
- public void setThisDiskCDNum(int thisDiskCDNum) {
- this.thisDiskCDNum = thisDiskCDNum;
- }
-
- public int getcDTotal() {
- return cDTotal;
- }
-
- public void setcDTotal(int cDTotal) {
- this.cDTotal = cDTotal;
- }
-
- public long getcDSize() {
- return cDSize;
- }
-
- public void setcDSize(long cDSize) {
- this.cDSize = cDSize;
- }
-
- public long getOffset() {
- return offset;
- }
-
- public void setOffset(long offset) {
- this.offset = offset;
- }
-
- public int getCommentLength() {
- return commentLength;
- }
-
- public void setCommentLength(int commentLength) {
- this.commentLength = commentLength;
- }
-
- public byte[] getComment() {
- return comment;
- }
-
- public void setComment(byte[] comment) {
- this.comment = comment;
- }
-
- public int getLength() {
- return length;
- }
-
- public void setLength(int length) {
- this.length = length;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/UnsignedDecimalUtil.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/UnsignedDecimalUtil.java
deleted file mode 100644
index 0625b2fc78f54d04227f2d031f541b0fed694ee3..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/UnsignedDecimalUtil.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import java.nio.ByteBuffer;
-
-/**
- * Unsigned Decimal Util
- *
- * @since 2023/12/09
- */
-public class UnsignedDecimalUtil {
- /**
- * max unsigned int value
- */
- public static final long MAX_UNSIGNED_INT_VALUE = 0xFFFFFFFFL;
-
- /**
- * max unsigned int value
- */
- public static final int MAX_UNSIGNED_SHORT_VALUE = 0xFFFF;
-
- private static final int BIT_SIZE = 8;
-
- private static final int DOUBLE_BIT_SIZE = 16;
-
- private static final int TRIPLE_BIT_SIZE = 24;
-
- /**
- * get unsigned int to long
- *
- * @param bf byteBuffer
- * @return long
- */
- public static long getUnsignedInt(ByteBuffer bf) {
- return bf.getInt() & MAX_UNSIGNED_INT_VALUE;
- }
-
- /**
- * get unsigned short to int
- *
- * @param bf byteBuffer
- * @return int
- */
- public static int getUnsignedShort(ByteBuffer bf) {
- return bf.getShort() & MAX_UNSIGNED_SHORT_VALUE;
- }
-
- /**
- * set long to unsigned int
- *
- * @param bf byteBuffer
- * @param value long
- */
- public static void setUnsignedInt(ByteBuffer bf, long value) {
- byte[] bytes = new byte[] {
- (byte) (value & 0xFF),
- (byte) ((value >> BIT_SIZE) & 0xFF),
- (byte) ((value >> DOUBLE_BIT_SIZE) & 0xFF),
- (byte) ((value >> TRIPLE_BIT_SIZE) & 0xFF)
- };
- bf.put(bytes);
- }
-
- /**
- * set int to unsigned short
- *
- * @param bf byteBuffer
- * @param value int
- */
- public static void setUnsignedShort(ByteBuffer bf, int value) {
- byte[] bytes = new byte[] {
- (byte) (value & 0xFF),
- (byte) ((value >> BIT_SIZE) & 0xFF)
- };
- bf.put(bytes);
- }
-}
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java
deleted file mode 100644
index 7ab9bdc2ed2b9a31894b6837620bd6b1d93411f9..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/Zip.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import com.ohos.hapsigntool.error.CustomException;
-import com.ohos.hapsigntool.error.ERROR;
-import com.ohos.hapsigntool.error.ZipException;
-import com.ohos.hapsigntool.utils.FileUtils;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * resolve zip data
- *
- * @since 2023/12/02
- */
-public class Zip {
- private static final Logger LOGGER = LogManager.getLogger(Zip.class);
-
- /**
- * file is uncompress file flag
- */
- public static final int FILE_UNCOMPRESS_METHOD_FLAG = 0;
-
- /**
- * max comment length
- */
- public static final int MAX_COMMENT_LENGTH = 65535;
-
- private List zipEntries;
-
- private long signingOffset;
-
- private byte[] signingBlock;
-
- private long cDOffset;
-
- private long eOCDOffset;
-
- private EndOfCentralDirectory endOfCentralDirectory;
-
- private String file;
-
- /**
- * create Zip by file
- *
- * @param inputFile file
- */
- public Zip(File inputFile) {
- try {
- this.file = inputFile.getCanonicalPath();
- if (!inputFile.exists()) {
- throw new ZipException("read zip file failed");
- }
- long start = System.currentTimeMillis();
- // 1. get eocd data
- endOfCentralDirectory = getZipEndOfCentralDirectory(inputFile);
- cDOffset = endOfCentralDirectory.getOffset();
- long eocdEnd = System.currentTimeMillis();
- LOGGER.debug("getZipEndOfCentralDirectory use {} ms", eocdEnd - start);
- // 2. use eocd's cd offset, get cd data
- getZipCentralDirectory(inputFile);
- long cdEnd = System.currentTimeMillis();
- LOGGER.debug("getZipCentralDirectory use {} ms", cdEnd - start);
- // 3. use cd's entry offset and file size, get entry data
- getZipEntries(inputFile);
- ZipEntry endEntry = zipEntries.get(zipEntries.size() - 1);
- CentralDirectory endCD = endEntry.getCentralDirectory();
- ZipEntryData endEntryData = endEntry.getZipEntryData();
- signingOffset = endCD.getOffset() + endEntryData.getLength();
- long entryEnd = System.currentTimeMillis();
- LOGGER.debug("getZipEntries use {} ms", entryEnd - start);
- // 4. file all data - eocd - cd - entry = sign block
- signingBlock = getSigningBlock(inputFile);
- } catch (IOException e) {
- CustomException.throwException(ERROR.ZIP_ERROR, e.getMessage());
- }
- }
-
- private EndOfCentralDirectory getZipEndOfCentralDirectory(File file) throws IOException {
- if (file.length() < EndOfCentralDirectory.EOCD_LENGTH) {
- throw new ZipException("find zip eocd failed");
- }
-
- // try to read EOCD without comment
- int eocdLength = EndOfCentralDirectory.EOCD_LENGTH;
- eOCDOffset = file.length() - eocdLength;
- byte[] bytes = FileUtils.readFileByOffsetAndLength(file, eOCDOffset, eocdLength);
- Optional eocdByBytes = EndOfCentralDirectory.getEOCDByBytes(bytes);
- if (eocdByBytes.isPresent()) {
- return eocdByBytes.get();
- }
-
- // try to search EOCD with comment
- long eocdMaxLength = Math.min(EndOfCentralDirectory.EOCD_LENGTH + MAX_COMMENT_LENGTH, file.length());
- eOCDOffset = file.length() - eocdMaxLength;
- bytes = FileUtils.readFileByOffsetAndLength(file, eOCDOffset, eocdMaxLength);
- for (int start = 0; start < eocdMaxLength; start++) {
- eocdByBytes = EndOfCentralDirectory.getEOCDByBytes(bytes, start);
- if (eocdByBytes.isPresent()) {
- eOCDOffset += start;
- return eocdByBytes.get();
- }
- }
- throw new ZipException("read zip failed: can not find eocd in file");
- }
-
- private void getZipCentralDirectory(File file) throws IOException {
- zipEntries = new ArrayList<>(endOfCentralDirectory.getcDTotal());
- // read full central directory bytes
- byte[] cdBytes = FileUtils.readFileByOffsetAndLength(file, cDOffset, endOfCentralDirectory.getcDSize());
- if (cdBytes.length < CentralDirectory.CD_LENGTH) {
- throw new ZipException("find zip cd failed");
- }
- ByteBuffer bf = ByteBuffer.wrap(cdBytes);
- bf.order(ByteOrder.LITTLE_ENDIAN);
- int offset = 0;
- // one by one format central directory
- while (offset < cdBytes.length) {
- CentralDirectory cd = CentralDirectory.getCentralDirectory(bf);
- ZipEntry entry = new ZipEntry();
- entry.setCentralDirectory(cd);
- zipEntries.add(entry);
- offset += cd.getLength();
- }
- if (offset + cDOffset != eOCDOffset) {
- throw new ZipException("cd end offset not equals to eocd offset, maybe this is a zip64 file");
- }
- }
-
- private byte[] getSigningBlock(File file) throws IOException {
- long size = cDOffset - signingOffset;
- if (size < 0) {
- throw new ZipException("signing offset in front of entry end");
- }
- if (size == 0) {
- return new byte[0];
- }
- return FileUtils.readFileByOffsetAndLength(file, signingOffset, size);
- }
-
- private void getZipEntries(File file) throws IOException {
- // use central directory data, find entry data
- for (ZipEntry entry : zipEntries) {
- CentralDirectory cd = entry.getCentralDirectory();
- long offset = cd.getOffset();
- long unCompressedSize = cd.getUnCompressedSize();
- long compressedSize = cd.getCompressedSize();
- long fileSize = cd.getMethod() == FILE_UNCOMPRESS_METHOD_FLAG ? unCompressedSize : compressedSize;
-
- ZipEntryData zipEntryData = ZipEntryData.getZipEntry(file, offset, fileSize);
- if (cDOffset - offset < zipEntryData.getLength()) {
- throw new ZipException("cd offset in front of entry end");
- }
- entry.setZipEntryData(zipEntryData);
- }
- }
-
- /**
- * output zip to zip file
- *
- * @param outFile file path
- */
- public void toFile(String outFile) {
- try (FileOutputStream fos = new FileOutputStream(outFile)) {
- for (ZipEntry entry : zipEntries) {
- ZipEntryData zipEntryData = entry.getZipEntryData();
- FileUtils.writeByteToOutFile(zipEntryData.getZipEntryHeader().toBytes(), fos);
- boolean isSuccess = FileUtils.appendWriteFileByOffsetToFile(file, fos,
- zipEntryData.getFileOffset(), zipEntryData.getFileSize());
- if (!isSuccess) {
- throw new ZipException("write zip data failed");
- }
- if (zipEntryData.getDataDescriptor() != null) {
- FileUtils.writeByteToOutFile(zipEntryData.getDataDescriptor().toBytes(), fos);
- }
- }
- if (signingBlock != null) {
- FileUtils.writeByteToOutFile(signingBlock, fos);
- }
- for (ZipEntry entry : zipEntries) {
- CentralDirectory cd = entry.getCentralDirectory();
- FileUtils.writeByteToOutFile(cd.toBytes(), fos);
- }
- FileUtils.writeByteToOutFile(endOfCentralDirectory.toBytes(), fos);
- } catch (IOException e) {
- CustomException.throwException(ERROR.ZIP_ERROR, e.getMessage());
- }
- }
-
- /**
- * alignment uncompress entry
- *
- * @param alignment int alignment
- */
- public void alignment(int alignment) {
- try {
- sort();
- boolean isFirstUnRunnableFile = true;
- for (ZipEntry entry : zipEntries) {
- ZipEntryData zipEntryData = entry.getZipEntryData();
- short method = zipEntryData.getZipEntryHeader().getMethod();
- if (method != FILE_UNCOMPRESS_METHOD_FLAG && !isFirstUnRunnableFile) {
- // only align uncompressed entry and the first compress entry.
- break;
- }
- int alignBytes;
- if (method == FILE_UNCOMPRESS_METHOD_FLAG && FileUtils.isRunnableFile(
- zipEntryData.getZipEntryHeader().getFileName())) {
- // .abc and .so file align 4096 byte.
- alignBytes = 4096;
- } else if (isFirstUnRunnableFile) {
- // the first file after runnable file, align 4096 byte.
- alignBytes = 4096;
- isFirstUnRunnableFile = false;
- } else {
- // normal file align 4 byte.
- alignBytes = alignment;
- }
- int add = entry.alignment(alignBytes);
- if (add > 0) {
- resetOffset();
- }
- }
- } catch (ZipException e) {
- CustomException.throwException(ERROR.ZIP_ERROR, e.getMessage());
- }
- }
-
- /**
- * remove sign block
- */
- public void removeSignBlock() {
- signingBlock = null;
- resetOffset();
- }
-
- /**
- * sort uncompress entry in the front.
- */
- private void sort() {
- // sort uncompress file (so, abc, an) - other uncompress file - compress file
- zipEntries.sort((entry1, entry2) -> {
- short entry1Method = entry1.getZipEntryData().getZipEntryHeader().getMethod();
- short entry2Method = entry2.getZipEntryData().getZipEntryHeader().getMethod();
- String entry1FileName = entry1.getZipEntryData().getZipEntryHeader().getFileName();
- String entry2FileName = entry2.getZipEntryData().getZipEntryHeader().getFileName();
- if (entry1Method == FILE_UNCOMPRESS_METHOD_FLAG && entry2Method == FILE_UNCOMPRESS_METHOD_FLAG) {
- boolean isRunnableFile1 = FileUtils.isRunnableFile(entry1FileName);
- boolean isRunnableFile2 = FileUtils.isRunnableFile(entry2FileName);
- if (isRunnableFile1 && isRunnableFile2) {
- return entry1FileName.compareTo(entry2FileName);
- } else if (isRunnableFile1) {
- return -1;
- } else if (isRunnableFile2) {
- return 1;
- }
- } else if (entry1Method == FILE_UNCOMPRESS_METHOD_FLAG) {
- return -1;
- } else if (entry2Method == FILE_UNCOMPRESS_METHOD_FLAG) {
- return 1;
- }
- return entry1FileName.compareTo(entry2FileName);
- });
- resetOffset();
- }
-
- private void resetOffset() {
- long offset = 0L;
- long cdLength = 0L;
- for (ZipEntry entry : zipEntries) {
- entry.getCentralDirectory().setOffset(offset);
- offset += entry.getZipEntryData().getLength();
- cdLength += entry.getCentralDirectory().getLength();
- }
- if (signingBlock != null) {
- offset += signingBlock.length;
- }
- cDOffset = offset;
- endOfCentralDirectory.setOffset(offset);
- endOfCentralDirectory.setcDSize(cdLength);
- offset += cdLength;
- eOCDOffset = offset;
- }
-
- public List getZipEntries() {
- return zipEntries;
- }
-
- public void setZipEntries(List zipEntries) {
- this.zipEntries = zipEntries;
- }
-
- public long getSigningOffset() {
- return signingOffset;
- }
-
- public void setSigningOffset(long signingOffset) {
- this.signingOffset = signingOffset;
- }
-
- public byte[] getSigningBlock() {
- return signingBlock;
- }
-
- public void setSigningBlock(byte[] signingBlock) {
- this.signingBlock = signingBlock;
- }
-
- public long getCDOffset() {
- return cDOffset;
- }
-
- public void setCDOffset(long cDOffset) {
- this.cDOffset = cDOffset;
- }
-
- public long getEOCDOffset() {
- return eOCDOffset;
- }
-
- public void setEOCDOffset(long eOCDOffset) {
- this.eOCDOffset = eOCDOffset;
- }
-
- public EndOfCentralDirectory getEndOfCentralDirectory() {
- return endOfCentralDirectory;
- }
-
- public void setEndOfCentralDirectory(EndOfCentralDirectory endOfCentralDirectory) {
- this.endOfCentralDirectory = endOfCentralDirectory;
- }
-
- public String getFile() {
- return file;
- }
-
- public void setFile(String file) {
- this.file = file;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntry.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntry.java
deleted file mode 100644
index ff66339ad690b1ddacba48b9ec301cb80c16dc5e..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntry.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import com.ohos.hapsigntool.error.ZipException;
-
-import java.util.Arrays;
-
-/**
- * ZipEntry and CentralDirectory data
- *
- * @since 2023/12/02
- */
-public class ZipEntry {
- private ZipEntryData zipEntryData;
-
- private CentralDirectory fileEntryIncentralDirectory;
-
- /**
- * alignment one entry
- *
- * @param alignNum need align bytes length
- * @return add bytes length
- * @throws ZipException alignment exception
- */
- public int alignment(int alignNum) throws ZipException {
- // if cd extra len bigger than entry extra len, make cd and entry extra length equals
- int padding = calZeroPaddingLengthForEntryExtra();
- int remainder = (int) ((zipEntryData.getZipEntryHeader().getLength()
- + fileEntryIncentralDirectory.getOffset()) % alignNum);
-
- if (remainder == 0) {
- return padding;
- }
- int add = alignNum - remainder;
- int newExtraLength = zipEntryData.getZipEntryHeader().getExtraLength() + add;
- if (newExtraLength > UnsignedDecimalUtil.MAX_UNSIGNED_SHORT_VALUE) {
- throw new ZipException("can not align " + zipEntryData.getZipEntryHeader().getFileName());
- }
- setEntryHeaderNewExtraLength(newExtraLength);
- setCenterDirectoryNewExtraLength(newExtraLength);
-
- return add;
- }
-
- private int calZeroPaddingLengthForEntryExtra() throws ZipException {
- int entryExtraLen = zipEntryData.getZipEntryHeader().getExtraLength();
- int cdExtraLen = fileEntryIncentralDirectory.getExtraLength();
- if (cdExtraLen > entryExtraLen) {
- setEntryHeaderNewExtraLength(cdExtraLen);
- return cdExtraLen - entryExtraLen;
- }
- if (cdExtraLen < entryExtraLen) {
- setCenterDirectoryNewExtraLength(entryExtraLen);
- return entryExtraLen - cdExtraLen;
- }
- return 0;
- }
-
- private void setCenterDirectoryNewExtraLength(int newLength) throws ZipException {
- byte[] newCDExtra = getAlignmentNewExtra(newLength, fileEntryIncentralDirectory.getExtraData());
- fileEntryIncentralDirectory.setExtraData(newCDExtra);
- fileEntryIncentralDirectory.setExtraLength(newLength);
- fileEntryIncentralDirectory.setLength(CentralDirectory.CD_LENGTH
- + fileEntryIncentralDirectory.getFileNameLength()
- + fileEntryIncentralDirectory.getExtraLength() + fileEntryIncentralDirectory.getCommentLength());
- }
-
- private void setEntryHeaderNewExtraLength(int newLength) throws ZipException {
- ZipEntryHeader zipEntryHeader = zipEntryData.getZipEntryHeader();
- byte[] newExtra = getAlignmentNewExtra(newLength, zipEntryHeader.getExtraData());
- zipEntryHeader.setExtraData(newExtra);
- zipEntryHeader.setExtraLength(newLength);
- zipEntryHeader.setLength(ZipEntryHeader.HEADER_LENGTH + zipEntryHeader.getExtraLength()
- + zipEntryHeader.getFileNameLength());
- zipEntryData.setLength(zipEntryHeader.getLength() + zipEntryData.getFileSize()
- + (zipEntryData.getDataDescriptor() == null ? 0 : DataDescriptor.DES_LENGTH));
- }
-
- private byte[] getAlignmentNewExtra(int newLength, byte[] old) throws ZipException {
- if (old == null) {
- return new byte[newLength];
- }
- if (newLength < old.length) {
- throw new ZipException("can not align " + zipEntryData.getZipEntryHeader().getFileName());
- }
- return Arrays.copyOf(old, newLength);
- }
-
- public ZipEntryData getZipEntryData() {
- return zipEntryData;
- }
-
- public void setZipEntryData(ZipEntryData zipEntryData) {
- this.zipEntryData = zipEntryData;
- }
-
- public CentralDirectory getCentralDirectory() {
- return fileEntryIncentralDirectory;
- }
-
- public void setCentralDirectory(CentralDirectory centralDirectory) {
- this.fileEntryIncentralDirectory = centralDirectory;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntryData.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntryData.java
deleted file mode 100644
index 35b19e7ad5833b31343f479a92d321a808507651..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntryData.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import com.ohos.hapsigntool.utils.FileUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * resolve zip ZipEntry data
- *
- * @since 2023/12/04
- */
-public class ZipEntryData {
- /**
- * data descriptor has or not mask
- */
- public static final short HAS_DATA_DESCRIPTOR_MASK = 0x08;
-
- /**
- * data descriptor has or not flag mask
- */
- public static final short NOT_HAS_DATA_DESCRIPTOR_FLAG = 0;
-
- private ZipEntryHeader zipEntryHeader;
-
- private long fileOffset;
-
- private long fileSize;
-
- private DataDescriptor dataDescriptor;
-
- private long length;
-
- public ZipEntryHeader getZipEntryHeader() {
- return zipEntryHeader;
- }
-
- /**
- * init zip entry by file
- *
- * @param file zip file
- * @param entryOffset entry start offset
- * @param fileSize compress file size
- * @return zip entry
- * @throws IOException read zip exception
- */
- public static ZipEntryData getZipEntry(File file, long entryOffset, long fileSize)
- throws IOException {
- try (FileInputStream input = new FileInputStream(file)) {
- long offset = entryOffset;
- // read entry header by file and offset.
- byte[] headBytes = FileUtils.readInputByOffsetAndLength(input, entryOffset, ZipEntryHeader.HEADER_LENGTH);
- ZipEntryHeader entryHeader = ZipEntryHeader.getZipEntryHeader(headBytes);
- offset += ZipEntryHeader.HEADER_LENGTH;
-
- // read entry file name and extra by offset.
- if (entryHeader.getFileNameLength() > 0) {
- byte[] fileNameBytes = FileUtils.readInputByLength(input, entryHeader.getFileNameLength());
- entryHeader.readFileName(fileNameBytes);
- offset += entryHeader.getFileNameLength();
- }
-
- if (entryHeader.getExtraLength() > 0) {
- byte[] extraBytes = FileUtils.readInputByLength(input, entryHeader.getExtraLength());
- entryHeader.readExtra(extraBytes);
- offset += entryHeader.getExtraLength();
- }
-
- // skip file data , save file offset and size.
- ZipEntryData entry = new ZipEntryData();
- entry.setFileOffset(offset);
- entry.setFileSize(fileSize);
- input.skip(fileSize);
-
- long entryLength = entryHeader.getLength() + fileSize;
- short flag = entryHeader.getFlag();
- // set desc null flag
- boolean hasDesc = (flag & HAS_DATA_DESCRIPTOR_MASK) != NOT_HAS_DATA_DESCRIPTOR_FLAG;
- if (hasDesc) {
- // if entry has data descriptor, read entry data descriptor.
- byte[] desBytes = FileUtils.readInputByLength(input, DataDescriptor.DES_LENGTH);
- DataDescriptor dataDesc = DataDescriptor.getDataDescriptor(desBytes);
- entryLength += DataDescriptor.DES_LENGTH;
- entry.setDataDescriptor(dataDesc);
- }
- entry.setZipEntryHeader(entryHeader);
- entry.setLength(entryLength);
- return entry;
- }
- }
-
- public void setZipEntryHeader(ZipEntryHeader zipEntryHeader) {
- this.zipEntryHeader = zipEntryHeader;
- }
-
- public DataDescriptor getDataDescriptor() {
- return dataDescriptor;
- }
-
- public void setDataDescriptor(DataDescriptor dataDescriptor) {
- this.dataDescriptor = dataDescriptor;
- }
-
- public long getFileOffset() {
- return fileOffset;
- }
-
- public void setFileOffset(long fileOffset) {
- this.fileOffset = fileOffset;
- }
-
- public long getFileSize() {
- return fileSize;
- }
-
- public void setFileSize(long fileSize) {
- this.fileSize = fileSize;
- }
-
- public long getLength() {
- return length;
- }
-
- public void setLength(long length) {
- this.length = length;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntryHeader.java b/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntryHeader.java
deleted file mode 100644
index 7c880a6bea5a14cb38fa5da1a9e7a777a0ef890f..0000000000000000000000000000000000000000
--- a/hapsigntool/hap_sign_tool_lib/src/main/java/com/ohos/hapsigntool/zip/ZipEntryHeader.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ohos.hapsigntool.zip;
-
-import com.ohos.hapsigntool.error.ZipException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-
-/**
- * resolve zip ZipEntryHeader data
- * end of central dir signature 4 bytes (0x06054b50)
- * number of this disk 2 bytes
- * number of the disk with the
- * start of the central directory 2 bytes
- * total number of entries in the
- * central directory on this disk 2 bytes
- * total number of entries in
- * the central directory 2 bytes
- * size of the central directory 4 bytes
- * offset of start of central
- * directory with respect to
- * the starting disk number 4 bytes
- * .ZIP file comment length 2 bytes
- * .ZIP file comment (variable size)
- *
- * @since 2023/12/02
- */
-public class ZipEntryHeader {
- /**
- * ZipEntryHeader invariable bytes length
- */
- public static final int HEADER_LENGTH = 30;
-
- /**
- * 4 bytes , entry header signature
- */
- public static final int SIGNATURE = 0x04034b50;
-
- /**
- * 2 bytes
- */
- private short version;
-
- /**
- * 2 bytes
- */
- private short flag;
-
- /**
- * 2 bytes
- */
- private short method;
-
- /**
- * 2 bytes
- */
- private short lastTime;
-
- /**
- * 2 bytes
- */
- private short lastDate;
-
- /**
- * 4 bytes
- */
- private int crc32;
-
- /**
- * 4 bytes
- */
- private long compressedSize;
-
- /**
- * 4 bytes
- */
- private long unCompressedSize;
-
- /**
- * 2 bytes
- */
- private int fileNameLength;
-
- /**
- * 2 bytes
- */
- private int extraLength;
-
- /**
- * n bytes
- */
- private String fileName;
-
- /**
- * n bytes
- */
- private byte[] extraData;
-
- private int length;
-
- /**
- * get Zip Entry Header
- *
- * @param bytes ZipEntryHeader bytes
- * @return ZipEntryHeader
- * @throws ZipException read entry header exception
- */
- public static ZipEntryHeader getZipEntryHeader(byte[] bytes) throws ZipException {
- ZipEntryHeader entryHeader = new ZipEntryHeader();
- ByteBuffer bf = ByteBuffer.wrap(bytes);
- bf.order(ByteOrder.LITTLE_ENDIAN);
- if (bf.getInt() != ZipEntryHeader.SIGNATURE) {
- throw new ZipException("find zip entry head failed");
- }
- entryHeader.setVersion(bf.getShort());
- entryHeader.setFlag(bf.getShort());
- entryHeader.setMethod(bf.getShort());
- entryHeader.setLastTime(bf.getShort());
- entryHeader.setLastDate(bf.getShort());
- entryHeader.setCrc32(bf.getInt());
- entryHeader.setCompressedSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- entryHeader.setUnCompressedSize(UnsignedDecimalUtil.getUnsignedInt(bf));
- entryHeader.setFileNameLength(UnsignedDecimalUtil.getUnsignedShort(bf));
- entryHeader.setExtraLength(UnsignedDecimalUtil.getUnsignedShort(bf));
- entryHeader.setLength(HEADER_LENGTH + entryHeader.getFileNameLength() + entryHeader.getExtraLength());
- return entryHeader;
- }
-
- /**
- * set entry header name
- *
- * @param bytes name bytes
- */
- public void readFileName(byte[] bytes) {
- ByteBuffer bf = ByteBuffer.wrap(bytes);
- bf.order(ByteOrder.LITTLE_ENDIAN);
- if (fileNameLength > 0) {
- byte[] nameBytes = new byte[fileNameLength];
- bf.get(nameBytes);
- this.fileName = new String(nameBytes, StandardCharsets.UTF_8);
- }
- }
-
- /**
- * set entry header extra
- *
- * @param bytes extra bytes
- */
- public void readExtra(byte[] bytes) {
- ByteBuffer bf = ByteBuffer.wrap(bytes);
- bf.order(ByteOrder.LITTLE_ENDIAN);
- if (extraLength > 0) {
- byte[] extra = new byte[extraLength];
- bf.get(extra);
- this.extraData = extra;
- }
- }
-
- /**
- * change Zip Entry Header to bytes
- *
- * @return bytes
- */
- public byte[] toBytes() {
- ByteBuffer bf = ByteBuffer.allocate(length).order(ByteOrder.LITTLE_ENDIAN);
- bf.putInt(SIGNATURE);
- bf.putShort(version);
- bf.putShort(flag);
- bf.putShort(method);
- bf.putShort(lastTime);
- bf.putShort(lastDate);
- bf.putInt(crc32);
- UnsignedDecimalUtil.setUnsignedInt(bf, compressedSize);
- UnsignedDecimalUtil.setUnsignedInt(bf, unCompressedSize);
- UnsignedDecimalUtil.setUnsignedShort(bf, fileNameLength);
- UnsignedDecimalUtil.setUnsignedShort(bf, extraLength);
- if (fileNameLength > 0) {
- bf.put(fileName.getBytes(StandardCharsets.UTF_8));
- }
- if (extraLength > 0) {
- bf.put(extraData);
- }
- return bf.array();
- }
-
- public static int getHeaderLength() {
- return HEADER_LENGTH;
- }
-
- public static int getSIGNATURE() {
- return SIGNATURE;
- }
-
- public short getVersion() {
- return version;
- }
-
- public void setVersion(short version) {
- this.version = version;
- }
-
- public short getFlag() {
- return flag;
- }
-
- public void setFlag(short flag) {
- this.flag = flag;
- }
-
- public short getMethod() {
- return method;
- }
-
- public void setMethod(short method) {
- this.method = method;
- }
-
- public short getLastTime() {
- return lastTime;
- }
-
- public void setLastTime(short lastTime) {
- this.lastTime = lastTime;
- }
-
- public short getLastDate() {
- return lastDate;
- }
-
- public void setLastDate(short lastDate) {
- this.lastDate = lastDate;
- }
-
- public int getCrc32() {
- return crc32;
- }
-
- public void setCrc32(int crc32) {
- this.crc32 = crc32;
- }
-
- public long getCompressedSize() {
- return compressedSize;
- }
-
- public void setCompressedSize(long compressedSize) {
- this.compressedSize = compressedSize;
- }
-
- public long getUnCompressedSize() {
- return unCompressedSize;
- }
-
- public void setUnCompressedSize(long unCompressedSize) {
- this.unCompressedSize = unCompressedSize;
- }
-
- public int getFileNameLength() {
- return fileNameLength;
- }
-
- public void setFileNameLength(int fileNameLength) {
- this.fileNameLength = fileNameLength;
- }
-
- public int getExtraLength() {
- return extraLength;
- }
-
- public void setExtraLength(int extraLength) {
- this.extraLength = extraLength;
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- public byte[] getExtraData() {
- return extraData;
- }
-
- public void setExtraData(byte[] extraData) {
- this.extraData = extraData;
- }
-
- public int getLength() {
- return length;
- }
-
- public void setLength(int length) {
- this.length = length;
- }
-}
\ No newline at end of file
diff --git a/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java b/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java
index 5fc3110c399d28ac3fb7f185526180b2112e2755..df437f6e4e1de5ee03f0f997578ec9cb3a3a7731 100644
--- a/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java
+++ b/hapsigntool/hap_sign_tool_lib/src/test/java/com/ohos/hapsigntool/ProfileTest.java
@@ -17,9 +17,6 @@ package com.ohos.hapsigntool;
import com.ohos.hapsigntool.api.LocalizationAdapter;
import com.ohos.hapsigntool.api.model.Options;
-import com.ohos.hapsigntool.error.CustomException;
-import com.ohos.hapsigntool.error.ERROR;
-import com.ohos.hapsigntool.error.VerifyException;
import com.ohos.hapsigntool.key.KeyPairTools;
import com.ohos.hapsigntool.profile.ProfileSignTool;
import com.ohos.hapsigntool.profile.VerifyHelper;
@@ -143,12 +140,7 @@ public class ProfileTest {
byte[] p7b = ProfileSignTool.signProfile(provisionContent, signer, adapter.getSignAlg());
assertNotNull(p7b);
VerifyHelper verifyHelper = new VerifyHelper();
- VerificationResult verificationResult = null;
- try {
- verificationResult = verifyHelper.verify(p7b);
- } catch (VerifyException e) {
- CustomException.throwException(ERROR.VERIFY_ERROR, e.getMessage());
- }
+ VerificationResult verificationResult = verifyHelper.verify(p7b);
assertTrue(verificationResult.isVerifiedPassed());
try {
diff --git a/tools/app-sign-srv-ca1.cer b/tools/app-sign-srv-ca1.cer
new file mode 100644
index 0000000000000000000000000000000000000000..b89ed745b57f35376992a54a8fd0d2ee21acdb39
--- /dev/null
+++ b/tools/app-sign-srv-ca1.cer
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICHDCCAcKgAwIBAgIFAM1hgkMwCgYIKoZIzj0EAwIwVTELMAkGA1UEBhMCQ04x
+FDASBgNVBAoMC09wZW5IYXJtb255MR4wHAYDVQQLDBVPcGVuSGFybW9ueSBDb21t
+dW5pdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMjIwMzA0MDI0NjUxWhcNMjMwMzA0
+MDI0NjUxWjBuMQswCQYDVQQGEwJDTjEUMBIGA1UECgwLT3Blbkhhcm1vbnkxHjAc
+BgNVBAsMFU9wZW5IYXJtb255IENvbW11bml0eTEpMCcGA1UEAwwgQXBwbGljYXRp
+b24gU2lnbmF0dXJlIFNlcnZpY2UgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AAQrUbzV/Qa2LjwtTzp1MUpXwN73BNQRluZLCahN9e6IWLNsCifvTNuD+aDhZiA0
+AZ5SpWoY7J1GjwOMmLP7MGEeo2YwZDAdBgNVHQ4EFgQUkWt6dNOoPEKVXkGNtC5Z
+hyWkGdMwHwYDVR0jBBgwFoAUcsPzleL32qFRbaDiIHxr3U7dMo8wEgYDVR0TAQH/
+BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAPHT
+mL3jEbeAf1Uo7j0h5kdfwF/wSCoTKyDfljvawkghAiAeidOkKzA+GjSapKkW27Xx
+piaCQxb8O7hL6BGL8M4SZw==
+-----END CERTIFICATE-----
diff --git a/tools/auto_test.py b/tools/auto_test.py
index 3cf38a9a1310ccef3f6a7cbd93d0d6ecc01111e1..f569d86445b0b17263089166527c6f76192dd1b3 100644
--- a/tools/auto_test.py
+++ b/tools/auto_test.py
@@ -298,11 +298,10 @@ def run_target(case, cmd):
if len(error) > 0:
f.writelines(cmd + "\r\n")
for line in error:
+ success = False
f.writelines(str(line.strip()) + "\r\n")
- code = command.wait()
- if code != 0:
- success = False
+ command.wait()
end = time.time()
case_result['total_cost'] = case_result['total_cost'] + (end - start)
diff --git a/tools/commands.config b/tools/commands.config
index f82dfe209dc4d6eb92dca9dbd8ecaea6e7d680f6..559d8c1c93c508bd9a1bb432dad4127d1eac8096 100644
--- a/tools/commands.config
+++ b/tools/commands.config
@@ -85,33 +85,11 @@
'verify-profile -inFile "app1-profile1.p7b"',
'verify-profile -inFile "app1-profile1.p7b" -outFile',
'verify-profile -inFile "app1-profile-cert-outTime.p7b" -outFile "result.json"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -inForm "zip" -profileSigned "1" -extCfgFile "111.txt"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-unsignedcode.hap" -inForm "zip" -profileSigned "1" -extCfgFile "111.txt" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -inForm "zip" -profileSigned "1" -extCfgFile "111.txt" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin" ',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/elf_unittest.elf" -keystoreFile "ohtest_pass.jks" -outFile "output-elf-codesign-profile" -keyPwd "123456" -keystorePwd "123456" -profileSigned "1" -signCode "1" -inForm elf',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -inFile "test/elf_unittest.elf" -keystoreFile "ohtest_pass.jks" -outFile "output-elf-codesign" -keyPwd "123456" -keystorePwd "123456" -signCode "1" -inForm elf',
- 'verify-app -inFile "app1-signedcode.hap" -outCertChain "app-sign-srv-ca1.cer" -outProfile "app1-profile.p7b"',
- 'verify-app -inFile "output-elf-codesign-profile" -outCertChain "app-sign-srv-ca1.cer" -outProfile "app1-profile.p7b" -inForm elf',
- 'verify-app -inFile "output-elf-codesign" -outCertChain "app-sign-srv-ca1.cer" -outProfile "app1-profile.p7b" -inForm elf',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/elf_unittest.elf" -keystoreFile "ohtest_pass.jks" -outFile "output-elf-codesign-profile" -keyPwd "123456" -keystorePwd "123456" -profileSigned "1" -signCode "1" -inForm elf',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -inFile "test/elf_unittest.elf" -keystoreFile "ohtest_pass.jks" -outFile "output-elf-codesign" -keyPwd "123456" -keystorePwd "123456" -signCode "1" -inForm elf',
- 'verify-app -inFile "app1-signedcode.hap" -outCertChain "app-sign-srv-ca1.cer" -outProfile "app1-profile1.p7b"',
- 'verify-app -inFile "output-elf-codesign-profile" -outCertChain "app-sign-srv-ca1.cer" -outProfile "app1-profile1.p7b" -inForm elf',
- 'verify-app -inFile "output-elf-codesign" -outCertChain "app-sign-srv-ca1.cer" -outProfile "app1-profile1.p7b" -inForm elf'
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signed.hap" -inForm "zip" -profileSigned "1" -extCfgFile "111.txt"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin" ',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -inForm "bin"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0"'
],
'case-assert-false': [
'generate-keypair -keyPwd 123456 -keyAlg ECC -keySize NIST-P-384 -keystoreFile "ohtest.jks" -keystorePwd 123456 -extCfgFile "111.txt"',
@@ -361,126 +339,45 @@
'verify-profile -outFile "verify-result.json" -inFile "app1-profile1.jks"',
'verify-profile -inFile "app1-profile1-changed.p7b" -outFile "verify-result.json"',
'verify-profile -inFile "app1-profile1.p7b" -outFile "verify-result.js00on"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "remoteSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "remoteSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "remoteSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "rewrw@%$" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "rewrw@%$" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "rewrw@%$" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1-222" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1-222" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1-222" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456789" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456789" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456789" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile1-changed.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile1-changed.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile1-changed.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "1" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "1" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "5"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "5" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "5" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "String"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "String" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "String" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "notexist\test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "notexist\test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "notexist\test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "HMAC" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "HMAC" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "HMAC" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohnull.p12" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohnull.p12" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohnull.p12" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.txt" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.txt" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.txt" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-unsignedcode.hap" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456789"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456789" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456789" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -signCode "1"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "remoteSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "rewrw@%$" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1-222" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456789" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile1-changed.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "1"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "5"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456" -profileSigned "String"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "notexist\test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "profile.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "HMAC" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withRSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v2" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohnull.p12" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.txt" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signed.hap" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456789"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile "app1-signed.hap" -keyPwd "123456"',
'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_pass.jks" -outFile -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
'sign-profile -keyAlias "oh-profile1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -profileCertFile "profile1_error.pem" -inFile "app1-profile-release.json" -keystoreFile "ohtest_pass.jks" -outFile "app1-profile.p7b" -keyPwd "123456" -keystorePwd "123456"',
'sign-profile -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -profileCertFile "profile1.pem" -inFile "app1-profile-release.json" -keystoreFile "ohtest.jks" -outFile "app1-profile.p7b" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1_error.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1_error.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1_error.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-profile1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456"',
- 'sign-app -keyAlias "oh-profile1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-unsignedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "0"',
- 'sign-app -keyAlias "oh-profile1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-signedcode.hap" -keyPwd "123456" -keystorePwd "123456" -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -inForm -profileSigned -extCfgFile ',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-unsignedcode.hap" -inForm -profileSigned -extCfgFile -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -inForm -profileSigned -extCfgFile -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -keyPwd "123456" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -inForm -profileSigned -extCfgFile ',
- 'sign-app -keyAlias "oh-app1-key-v1" -keyPwd "123456" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-unsignedcode.hap" -inForm -profileSigned -extCfgFile -signCode "0"',
- 'sign-app -keyAlias "oh-app1-key-v1" -keyPwd "123456" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signedcode.hap" -inForm -profileSigned -extCfgFile -signCode "1"',
- 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "profile.json" -inFile "test/elf_unittest" -keystoreFile "ohtest_pass.jks" -outFile "output-elf-codesign-profile" -keyPwd "123456" -keystorePwd "123456" -profileSigned "0" -signCode "1"',
- 'verify-app -inFile "app1-signedcode.hap" -outCertChain "" -outProfile "app1-profile-error.p7b"',
- 'verify-app -inFile "app1-signedcode.hap" -outCertChain "app1.cer" -outProfile ""',
- 'verify-app -inFile "app1-signedcode.hap" -outCertChain "" -outProfile ""',
- 'verify-app -inFile "app1-signedcode.hap" -outCertChain "app1.ce7778r" -outProfile "app1-profile-error.p7b"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1_error.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-profile1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app1.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest.jks" -outFile "app1-signed.hap" -keyPwd "123456" -keystorePwd "123456"',
+ 'sign-app -keyAlias "oh-app1-key-v1" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signed.hap" -inForm -profileSigned -extCfgFile ',
+ 'sign-app -keyAlias "oh-app1-key-v1" -keyPwd "123456" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile "app2.pem" -profileFile "app1-profile.p7b" -inFile "test/app1-unsigned.hap" -keystoreFile "ohtest_nopass.jks" -outFile "app1-signed.hap" -inForm -profileSigned -extCfgFile '
]
}
\ No newline at end of file
diff --git a/tools/root-ca1.cer b/tools/root-ca1.cer
new file mode 100644
index 0000000000000000000000000000000000000000..af02c6a4e41249f644f3745f3801f20c2e2cffc9
--- /dev/null
+++ b/tools/root-ca1.cer
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB4TCCAYegAwIBAgIEJlDuCzAKBggqhkjOPQQDAjBVMQswCQYDVQQGEwJDTjEU
+MBIGA1UECgwLT3Blbkhhcm1vbnkxHjAcBgNVBAsMFU9wZW5IYXJtb255IENvbW11
+bml0eTEQMA4GA1UEAwwHUm9vdCBDQTAeFw0yMjAzMDQwMjQ2NDdaFw0yMzAzMDQw
+MjQ2NDdaMFUxCzAJBgNVBAYTAkNOMRQwEgYDVQQKDAtPcGVuSGFybW9ueTEeMBwG
+A1UECwwVT3Blbkhhcm1vbnkgQ29tbXVuaXR5MRAwDgYDVQQDDAdSb290IENBMFkw
+EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0kXaGsjyBd94GqKieIAcoXOjVIx6lPEk
+RlzjHUh7ixAYQtyPo+pBG8VX7l6bMtICj9AdXz9lguaINvrSJyXzm6NFMEMwHQYD
+VR0OBBYEFHLD85Xi99qhUW2g4iB8a91O3TKPMBIGA1UdEwEB/wQIMAYBAf8CAQAw
+DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIQCrZwpSiqyrGc7L978Q
+cwydhj2zKhOzPsVQxWiJAgWFLwIgac56zDrBGwDegtnN1/FgfNE3od/qiJy5Yf9g
+Bwm84pM=
+-----END CERTIFICATE-----
diff --git a/tools/test/elf_unittest.elf b/tools/test/elf_unittest.elf
deleted file mode 100644
index deffa1c72a2447c57c35616d89c8f459401c45ea..0000000000000000000000000000000000000000
--- a/tools/test/elf_unittest.elf
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- elf test file
\ No newline at end of file