1 /*
2 * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "app_centraldirectory.h"
17 #include <fcntl.h>
18 #include <stdbool.h>
19 #include <string.h>
20 #include <sys/mman.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include "app_common.h"
25 #include "mbedtls/base64.h"
26 #include "mbedtls/md.h"
27 #include "mbedtls/pk.h"
28 #include "mbedtls/x509_crt.h"
29 #include "mbedtls_pkcs7.h"
30 #include "securec.h"
31
HapPutByte(const HapBuf * hapBuffer,int32_t offset,char value)32 void HapPutByte(const HapBuf *hapBuffer, int32_t offset, char value)
33 {
34 if (hapBuffer == NULL || hapBuffer->buffer == NULL) {
35 return;
36 }
37 if ((offset >= 0) && (hapBuffer->len - offset >= (int)(sizeof(value)))) {
38 *(char *)((char *)hapBuffer->buffer + offset) = value;
39 }
40 return;
41 }
42
HapPutData(const HapBuf * hapBuffer,int32_t offset,const unsigned char * data,int32_t len)43 void HapPutData(const HapBuf *hapBuffer, int32_t offset, const unsigned char *data, int32_t len)
44 {
45 if (hapBuffer == NULL || hapBuffer->buffer == NULL) {
46 return;
47 }
48 if ((data != NULL) && (offset >= 0) && len > 0 && ((hapBuffer->len - offset) >= len)) {
49 if (memcpy_s(((unsigned char *)hapBuffer->buffer + offset), (hapBuffer->len - offset), data, len) != EOK) {
50 LOG_ERROR("memcpy_s fail");
51 }
52 }
53 }
54
HapSetInt32(const HapBuf * buffer,int32_t offset,int32_t value)55 void HapSetInt32(const HapBuf *buffer, int32_t offset, int32_t value)
56 {
57 if (value < 0) {
58 LOG_ERROR("int32 value of out range: %d", value);
59 return;
60 }
61 if (buffer == NULL || buffer->buffer == NULL) {
62 return;
63 }
64 if ((offset >= 0) && ((buffer->len - offset) >= (int)(sizeof(value)))) {
65 HapPutInt32((unsigned char *)buffer->buffer + offset, buffer->len - offset, (int)(value));
66 }
67 return;
68 }
69
CreateHapBuffer(HapBuf * hapBuffer,int32_t len)70 bool CreateHapBuffer(HapBuf *hapBuffer, int32_t len)
71 {
72 if (hapBuffer == NULL || len <= 0) {
73 LOG_ERROR("create buf fail, buf is null");
74 return false;
75 }
76 hapBuffer->buffer = APPV_MALLOC(len);
77 if (hapBuffer->buffer == NULL) {
78 LOG_ERROR("create buf fail");
79 return false;
80 }
81 hapBuffer->len = len;
82 return true;
83 }
84
ClearHapBuffer(HapBuf * hapBuffer)85 void ClearHapBuffer(HapBuf *hapBuffer)
86 {
87 if (hapBuffer == NULL || hapBuffer->buffer == NULL) {
88 return;
89 }
90 (void)memset_s(hapBuffer->buffer, hapBuffer->len, 0, hapBuffer->len);
91 APPV_FREE(hapBuffer->buffer);
92 hapBuffer->buffer = NULL;
93 hapBuffer->len = 0;
94 }
95
GetEocd(const FileRead * hapFile,HapEocd * hapEocd,int32_t * eocdOffset)96 static bool GetEocd(const FileRead *hapFile, HapEocd *hapEocd, int32_t *eocdOffset)
97 {
98 MmapInfo mmapInfo = {0};
99 if (hapFile->len <= sizeof(MinEocd)) {
100 return false;
101 }
102 int32_t ret = HapMMap(hapFile->len, 0, &mmapInfo, hapFile);
103 if (ret != V_OK) {
104 LOG_ERROR("mmap not ok");
105 return false;
106 }
107 char *fileStart = (char *)(mmapInfo.mapAddr + mmapInfo.readMoreLen);
108 if (HapGetShort((unsigned char*)fileStart + hapFile->len - sizeof(short), sizeof(short)) == 0 &&
109 HapGetInt((unsigned char*)fileStart + hapFile->len - sizeof(MinEocd), sizeof(int)) == HAP_EOCD_MAGIC) {
110 if (memcpy_s(&hapEocd->eocdHead, sizeof(MinEocd),
111 fileStart + hapFile->len - sizeof(MinEocd), sizeof(MinEocd)) != EOK) {
112 HapMUnMap(mmapInfo.mapAddr, mmapInfo.mmapSize);
113 LOG_ERROR("copy error");
114 return false;
115 }
116 HapMUnMap(mmapInfo.mapAddr, mmapInfo.mmapSize);
117 *eocdOffset = hapFile->len - sizeof(MinEocd);
118 return true;
119 }
120 // only a few haps have comment and use this branch
121 int32_t maxReadLen = ((unsigned int)(hapFile->len - sizeof(MinEocd)) > UINT16_MAX_VALUE) ?
122 UINT16_MAX_VALUE : (hapFile->len - sizeof(MinEocd));
123 fileStart += hapFile->len - sizeof(MinEocd) - maxReadLen;
124 LOG_INFO("maxReadLen %d", maxReadLen);
125 for (int32_t i = 0; i < maxReadLen; i++) {
126 if ((HapGetShort((unsigned char*)fileStart + i + sizeof(MinEocd) - sizeof(short),
127 sizeof(short)) == (maxReadLen - i)) &&
128 (HapGetInt((unsigned char*)fileStart + i, sizeof(int)) == HAP_EOCD_MAGIC)) {
129 if (memcpy_s(&hapEocd->eocdHead, sizeof(MinEocd),
130 fileStart + i, sizeof(MinEocd)) != EOK) {
131 HapMUnMap(mmapInfo.mapAddr, mmapInfo.mmapSize);
132 LOG_ERROR("copy error");
133 return false;
134 }
135 HapMUnMap(mmapInfo.mapAddr, mmapInfo.mmapSize);
136 LOG_INFO("comment num %d", maxReadLen - i);
137 *eocdOffset = hapFile->len - sizeof(MinEocd) - (maxReadLen - i);
138 return true;
139 }
140 }
141 LOG_ERROR("can not find eocd");
142 HapMUnMap(mmapInfo.mapAddr, mmapInfo.mmapSize);
143 return false;
144 }
145
FindSignature(const FileRead * hapFile,SignatureInfo * signInfo)146 bool FindSignature(const FileRead *hapFile, SignatureInfo *signInfo)
147 {
148 if (hapFile == NULL || signInfo == NULL) {
149 return false;
150 }
151 int32_t eocdOffset = 0;
152 HapEocd hapEocd = {0};
153 if (!GetEocd(hapFile, &hapEocd, &eocdOffset)) {
154 LOG_ERROR("find Eocd fail");
155 return false;
156 }
157 signInfo->hapEocdOffset = eocdOffset;
158 signInfo->hapEocdSize = hapFile->len - eocdOffset;
159 signInfo->hapCoreDirOffset = HapGetInt((unsigned char*)(&(hapEocd.eocdHead.coreDirOffset)), sizeof(int));
160 if (signInfo->hapCoreDirOffset <= 0 || signInfo->hapCoreDirOffset >= eocdOffset ||
161 signInfo->hapEocdSize <= 0 || signInfo->hapEocdOffset <= 0) {
162 LOG_ERROR("core dir error");
163 return false;
164 }
165 return true;
166 }
167
ReadFileFullyFromOffset(const HapBuf * buffer,int32_t offset,const FileRead * file)168 int32_t ReadFileFullyFromOffset(const HapBuf *buffer, int32_t offset, const FileRead *file)
169 {
170 if (buffer == NULL || buffer->buffer == NULL || file == NULL) {
171 return DEST_BUFFER_IS_NULL;
172 }
173 if (offset < 0 || offset > file->len) {
174 return READ_OFFSET_OUT_OF_RANGE;
175 }
176 lseek(file->fp, offset, SEEK_SET);
177 int32_t readLen = read(file->fp, buffer->buffer, buffer->len);
178 if (readLen != buffer->len) {
179 LOG_ERROR("file read error %d --- %d", readLen, buffer->len);
180 return READ_OFFSET_OUT_OF_RANGE;
181 }
182 return buffer->len;
183 }
184