• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "native_lib_info_segment.h"
16 
17 namespace OHOS {
18 namespace SignatureTools {
19 
NativeLibInfoSegment()20 NativeLibInfoSegment::NativeLibInfoSegment()
21 {
22     magic = MAGIC_NUM;
23     zeroPadding = std::vector<int8_t>(0);
24     fileNameListBlockSize = 0;
25     segmentSize = 0;
26     sectionNum = 0;
27     signInfoListBlockSize = 0;
28 }
29 
NativeLibInfoSegment(int32_t magic,int32_t segmentSize,int32_t sectionNum,const std::vector<SignedFilePos> & signedFilePosList,const std::vector<std::string> & fileNameList,const std::vector<SignInfo> & signInfoList,const std::vector<int8_t> & zeroPadding)30 NativeLibInfoSegment::NativeLibInfoSegment(int32_t magic,
31                                            int32_t segmentSize,
32                                            int32_t sectionNum,
33                                            const std::vector<SignedFilePos>& signedFilePosList,
34                                            const std::vector<std::string>& fileNameList,
35                                            const std::vector<SignInfo>& signInfoList,
36                                            const std::vector<int8_t>& zeroPadding)
37 {
38     this->magic = magic;
39     this->segmentSize = segmentSize;
40     this->sectionNum = sectionNum;
41     this->signedFilePosList = signedFilePosList;
42     this->fileNameList = fileNameList;
43     this->signInfoList = signInfoList;
44     this->zeroPadding = zeroPadding;
45     fileNameListBlockSize = 0;
46     signInfoListBlockSize = 0;
47 }
48 
SetSoInfoList(const std::vector<std::pair<std::string,SignInfo>> & soInfoList)49 void NativeLibInfoSegment::SetSoInfoList(const std::vector<std::pair<std::string, SignInfo>> &soInfoList)
50 {
51     this->soInfoList = soInfoList;
52     // Once map is set, update length, sectionNum as well
53     sectionNum = soInfoList.size();
54     // generate file name list and sign info list
55     GenerateList();
56 }
57 
GetSectionNum()58 int32_t NativeLibInfoSegment::GetSectionNum()
59 {
60     return sectionNum;
61 }
62 
GetFileNameList()63 std::vector<std::string>& NativeLibInfoSegment::GetFileNameList()
64 {
65     return fileNameList;
66 }
67 
GetSignInfoList()68 std::vector<OHOS::SignatureTools::SignInfo>& NativeLibInfoSegment::GetSignInfoList()
69 {
70     return signInfoList;
71 }
72 
Size()73 int32_t NativeLibInfoSegment::Size()
74 {
75     int blockSize = MAGIC_LENGTH_SECNUM_BYTES;
76     blockSize += signedFilePosList.size() * SIGNED_FILE_POS_SIZE;
77     blockSize += fileNameListBlockSize + zeroPadding.size() + signInfoListBlockSize;
78     return blockSize;
79 }
80 
ToByteArray(std::vector<int8_t> & ret)81 void NativeLibInfoSegment::ToByteArray(std::vector<int8_t> &ret)
82 {
83     std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(ByteBuffer(Size()));
84     std::vector<int8_t> empt(Size());
85     bf->PutData(empt.data(), empt.size());
86     bf->Clear();
87     bf->PutInt32(magic);
88     bf->PutInt32(segmentSize);
89     bf->PutInt32(sectionNum);
90     for (SignedFilePos &offsetAndSize : signedFilePosList) {
91         bf->PutInt32(offsetAndSize.GetFileNameOffset());
92         bf->PutInt32(offsetAndSize.GetFileNameSize());
93         bf->PutInt32(offsetAndSize.GetSignInfoOffset());
94         bf->PutInt32(offsetAndSize.GetSignInfoSize());
95     }
96     for (std::string &fileName : fileNameList) {
97         bf->PutData(fileName.c_str(), fileName.size() * sizeof(char));
98     }
99     bf->PutData(zeroPadding.data(), zeroPadding.size());
100     for (SignInfo &signInfo : signInfoList) {
101         std::vector<int8_t> signInfoArr;
102         signInfo.ToByteArray(signInfoArr);
103         bf->PutData(signInfoArr.data(), signInfoArr.size());
104     }
105     ret = std::vector<int8_t>(bf->GetBufferPtr(), bf->GetBufferPtr() + bf->GetPosition());
106     return;
107 }
108 
FromByteArray(std::vector<int8_t> & bytes)109 NativeLibInfoSegment NativeLibInfoSegment::FromByteArray(std::vector<int8_t> &bytes)
110 {
111     std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(ByteBuffer(bytes.size()));
112     bf->PutData(bytes.data(), bytes.size());
113     bf->Flip();
114     int32_t inMagic = 0;
115     int32_t inSegmentSize = 0;
116     int32_t inSectionNum = 0;
117     bool checkFlag = CheckBuffer(bf.get(), inMagic, inSegmentSize, inSectionNum);
118     if (!checkFlag) {
119         return NativeLibInfoSegment();
120     }
121     std::vector<SignedFilePos> inSignedFilePosList;
122     for (int i = 0; i < inSectionNum; i++) {
123         std::vector<int8_t> entry(SIGNED_FILE_POS_SIZE, 0);
124         bf->GetByte(entry.data(), entry.size());
125         inSignedFilePosList.push_back(SignedFilePos::FromByteArray(entry));
126     }
127     // parse file name list
128     std::vector<std::string> inFileNameList;
129     int fileNameListSize = 0;
130     for (SignedFilePos &pos : inSignedFilePosList) {
131         std::vector<char> fileNameBuffer(pos.GetFileNameSize(), 0);
132         fileNameListSize += pos.GetFileNameSize();
133         bf->SetPosition(pos.GetFileNameOffset());
134         bf->GetData(fileNameBuffer.data(), fileNameBuffer.size());
135         inFileNameList.push_back(std::string(fileNameBuffer.data(), fileNameBuffer.size()));
136     }
137     // parse zeroPadding
138     std::vector<int8_t> inZeroPadding((ALIGNMENT_FOR_SIGNINFO - fileNameListSize
139                                       % ALIGNMENT_FOR_SIGNINFO) % ALIGNMENT_FOR_SIGNINFO);
140     bf->GetByte(inZeroPadding.data(), inZeroPadding.size());
141     // parse sign info list
142     std::vector<OHOS::SignatureTools::SignInfo> inSignInfoList;
143     for (SignedFilePos &pos : inSignedFilePosList) {
144         if (pos.GetSignInfoOffset() % ALIGNMENT_FOR_SIGNINFO != 0) {
145             PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
146                                 "The offset of signature information must be an integer multiple of 4");
147             return NativeLibInfoSegment();
148         }
149         std::vector<int8_t> signInfoBuffer(pos.GetSignInfoSize());
150         bf->SetPosition(pos.GetSignInfoOffset());
151         bf->GetByte(signInfoBuffer.data(), signInfoBuffer.size());
152         inSignInfoList.push_back(OHOS::SignatureTools::SignInfo::FromByteArray(signInfoBuffer));
153     }
154     return NativeLibInfoSegment(inMagic, inSegmentSize, inSectionNum, inSignedFilePosList,
155                                 inFileNameList, inSignInfoList, inZeroPadding);
156 }
157 
CheckBuffer(ByteBuffer * bf,int32_t & inMagic,int32_t & inSegmentSize,int32_t & inSectionNum)158 bool NativeLibInfoSegment::CheckBuffer(ByteBuffer* bf, int32_t& inMagic, int32_t& inSegmentSize,
159     int32_t& inSectionNum)
160 {
161     bf->GetInt32(inMagic);
162     if (inMagic != MAGIC_NUM) {
163         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
164                             "The magic number of NativeLibInfoSegment is incorrect.");
165         return false;
166     }
167     bf->GetInt32(inSegmentSize);
168     if (inSegmentSize < 0) {
169         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
170                             "The segment size of NativeLibInfoSegment is incorrect.");
171         return false;
172     }
173     bf->GetInt32(inSectionNum);
174     if (inSectionNum < 0) {
175         PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
176                             "The section number of NativeLibInfoSegment is incorrect.");
177         return false;
178     }
179     return true;
180 }
181 
GenerateList()182 void NativeLibInfoSegment::GenerateList()
183 {
184     // empty all before generate list
185     fileNameList.clear();
186     signInfoList.clear();
187     signedFilePosList.clear();
188     int fileNameOffset = 0;
189     int signInfoOffset = 0;
190     for (std::pair<std::string, SignInfo> &soInfo :soInfoList) {
191         std::string fileName = soInfo.first;
192         SignInfo& signInfo = soInfo.second;
193         int fileNameSizeInBytes = fileName.size() * sizeof(char);
194         int signInfoSizeInBytes = signInfo.GetSize() * sizeof(char);
195         fileNameList.push_back(fileName);
196         signInfoList.push_back(signInfo);
197         std::unique_ptr<SignedFilePos> posPtr = std::make_unique<SignedFilePos>(fileNameOffset,
198             fileNameSizeInBytes, signInfoOffset, signInfoSizeInBytes);
199         signedFilePosList.push_back(*posPtr.get());
200         // increase fileNameOffset and signInfoOffset
201         fileNameOffset += fileNameSizeInBytes;
202         signInfoOffset += signInfoSizeInBytes;
203     }
204     fileNameListBlockSize = fileNameOffset;
205     signInfoListBlockSize = signInfoOffset;
206     // alignment for signInfo
207     zeroPadding = std::vector<int8_t>((ALIGNMENT_FOR_SIGNINFO - fileNameListBlockSize
208                                             % ALIGNMENT_FOR_SIGNINFO) % ALIGNMENT_FOR_SIGNINFO);
209     // after fileNameList and signInfoList is generated, update segment size
210     segmentSize = Size();
211     // adjust file name and sign info offset base on segment start
212     int fileNameOffsetBase = MAGIC_LENGTH_SECNUM_BYTES + signedFilePosList.size() * SIGNED_FILE_POS_SIZE;
213     int signInfoOffsetBase = fileNameOffsetBase + fileNameListBlockSize;
214     for (SignedFilePos &pos : signedFilePosList) {
215         pos.IncreaseFileNameOffset(fileNameOffsetBase);
216         pos.IncreaseSignInfoOffset(signInfoOffsetBase + zeroPadding.size());
217     }
218 }
219 
220 }
221 }
222