1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ZIP_PKG_FILE_H 17 #define ZIP_PKG_FILE_H 18 19 #include <map> 20 #include "pkg_pkgfile.h" 21 #include "pkg_utils.h" 22 23 namespace Hpackage { 24 // Local file header: descript in APPNOTE-6.3.4 25 // local file header signature 4 bytes (0x04034b50) 26 // version needed to extract 2 bytes 27 // general purpose bit flag 2 bytes 28 // compression method 2 bytes 29 // last mod file time 2 bytes 30 // last mod file date 2 bytes 31 // crc-32 4 bytes 32 // compressed size 4 bytes 33 // uncompressed size 4 bytes 34 // file name length 2 bytes 35 // extra field length 2 bytes 36 struct __attribute__((packed)) LocalFileHeader { 37 uint32_t signature = 0; 38 uint16_t versionNeeded = 0; 39 uint16_t flags = 0; 40 uint16_t compressionMethod = 0; 41 uint16_t modifiedTime = 0; 42 uint16_t modifiedDate = 0; 43 uint32_t crc = 0; 44 uint32_t compressedSize = 0; 45 uint32_t uncompressedSize = 0; 46 uint16_t nameSize = 0; 47 uint16_t extraSize = 0; 48 }; 49 50 // central file header 51 // Central File header: 52 // central file header signature 4 bytes (0x02014b50) 53 // version made by 2 bytes 54 // version needed to extract 2 bytes 55 // general purpose bit flag 2 bytes 56 // compression method 2 bytes 57 // last mod file time 2 bytes 58 // last mod file date 2 bytes 59 // crc-32 4 bytes 60 // compressed size 4 bytes 61 // uncompressed size 4 bytes 62 // file name length 2 bytes 63 // extra field length 2 bytes 64 // file comment length 2 bytes 65 // disk number start 2 bytes 66 // internal file attributes 2 bytes 67 // external file attributes 4 bytes 68 // relative offset of local header 4 bytes 69 struct __attribute__((packed)) CentralDirEntry { 70 uint32_t signature = 0; 71 uint16_t versionMade = 0; 72 uint16_t versionNeeded = 0; 73 uint16_t flags = 0; // general purpose bit flag 74 uint16_t compressionMethod = 0; 75 uint16_t modifiedTime = 0; 76 uint16_t modifiedDate = 0; 77 uint32_t crc = 0; 78 uint32_t compressedSize = 0; 79 uint32_t uncompressedSize = 0; 80 uint16_t nameSize = 0; 81 uint16_t extraSize = 0; 82 uint16_t commentSize = 0; 83 uint16_t diskNumStart = 0; 84 uint16_t internalAttr = 0; 85 uint32_t externalAttr = 0; 86 uint32_t localHeaderOffset = 0; 87 }; 88 89 struct __attribute__((packed)) EndCentralDir { 90 uint32_t signature = 0; 91 uint16_t numDisk = 0; 92 uint16_t startDiskOfCentralDir = 0; 93 uint16_t totalEntriesInThisDisk = 0; 94 uint16_t totalEntries = 0; 95 uint32_t sizeOfCentralDir = 0; 96 uint32_t offset = 0; 97 uint16_t commentLen = 0; 98 }; 99 100 struct __attribute__((packed)) DataDescriptor { 101 uint32_t signature = 0; 102 uint32_t crc = 0; 103 uint32_t compressedSize = 0; 104 uint32_t uncompressedSize = 0; 105 }; 106 107 struct __attribute__((packed)) Zip64EndCentralDirRecord { 108 uint32_t signature = 0; // 0x06064b50 109 uint64_t size = 0; 110 uint16_t versionMadeBy = 0; 111 uint16_t versionNeedToExtra = 0; 112 uint32_t numberOfThisDisk = 0; 113 uint32_t startOfthisDisk = 0; 114 uint64_t totalEntriesInThisDisk = 0; 115 uint64_t totalEntries = 0; 116 uint64_t sizeOfCentralDir = 0; 117 uint64_t offset = 0; 118 }; 119 120 struct __attribute__((packed)) Zip64EndCentralDirLocator { 121 uint32_t signature = 0; // 0x07064b50 122 uint32_t numberOfDisk = 0; 123 uint64_t endOfCentralDirectoryRecord = 0; 124 uint32_t totalNumberOfDisks = 0; 125 }; 126 127 class ZipFileEntry : public PkgEntry { 128 public: ZipFileEntry(PkgFilePtr pkgFile,uint32_t nodeId)129 ZipFileEntry(PkgFilePtr pkgFile, uint32_t nodeId) : PkgEntry(pkgFile, nodeId) {} 130 ~ZipFileEntry()131 ~ZipFileEntry() override {} 132 133 int32_t Init(const PkgManager::FileInfoPtr fileInfo, PkgStreamPtr inStream) override; 134 GetFileInfo()135 const FileInfo *GetFileInfo() const override 136 { 137 return &fileInfo_.fileInfo; 138 }; 139 140 int32_t EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) override; 141 142 int32_t Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) override; 143 144 int32_t Unpack(PkgStreamPtr outStream) override; 145 146 int32_t DecodeHeader(const PkgBuffer &buffer, size_t headOffset, size_t dataOffset, 147 size_t &decodeLen) override; 148 149 int32_t EncodeCentralDirEntry(const PkgStreamPtr stream, size_t startOffset, size_t &encodeLen); 150 151 int32_t DecodeCentralDirEntry(PkgStreamPtr inStream, PkgBuffer &buffer, size_t currentPos, 152 size_t &decodeLen); 153 154 protected: 155 ZipFileInfo fileInfo_ {}; 156 uint32_t crc32_ {0}; 157 158 private: 159 int32_t DecodeLocalFileHeaderCheck(PkgStreamPtr inStream, const PkgBuffer &data, size_t currentPos); 160 161 int32_t DecodeLocalFileHeader(PkgStreamPtr inStream, const PkgBuffer &data, size_t currentPos, 162 size_t &decodeLen); 163 164 int32_t EncodeLocalFileHeader(uint8_t *buffer, size_t bufferLen, bool hasDataDesc, size_t nameLen); 165 166 int32_t EncodeDataDescriptor(const PkgStreamPtr stream, size_t startOffset, uint32_t &encodeLen) const; 167 168 void CombineTimeAndDate(time_t &time, uint16_t modifiedTime, uint16_t modifiedDate) const; 169 }; 170 171 class ZipPkgFile : public PkgFile { 172 public: ZipPkgFile(PkgManager::PkgManagerPtr manager,PkgStreamPtr stream)173 explicit ZipPkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream) 174 : PkgFile(manager, stream, PkgFile::PKG_TYPE_ZIP) 175 { 176 pkgInfo_.signMethod = PKG_SIGN_METHOD_RSA; 177 pkgInfo_.digestMethod = PKG_DIGEST_TYPE_SHA256; 178 } ~ZipPkgFile()179 ~ZipPkgFile() override {} 180 181 int32_t AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream) override; 182 183 int32_t SavePackage(size_t &signOffset) override; 184 185 int32_t LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier = nullptr) override; 186 187 private: 188 int32_t LoadPackage(std::vector<std::string> &fileNames, const PkgBuffer &buffer, 189 uint32_t endDirLen, size_t endDirPos, size_t &readLen); 190 int32_t ParseFileEntries(std::vector<std::string> &fileNames, const EndCentralDir &endDir, 191 size_t currentPos, size_t fileLen); 192 193 private: 194 PkgInfo pkgInfo_ {}; 195 size_t currentOffset_ = 0; 196 }; 197 } // namespace Hpackage 198 #endif 199