1 /*
2 * Copyright (C) 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 <unistd.h>
17 #include <limits.h>
18 #include <securec.h>
19 #include "device_attest_oem_file.h"
20
21 #define MAX_ATTEST_MALLOC_BUFF_SIZE 1024
22
OEMGenFilePath(const char* dirPath, const char* fileName)23 char* OEMGenFilePath(const char* dirPath, const char* fileName)
24 {
25 if (dirPath == NULL || fileName == NULL) {
26 return NULL;
27 }
28 if ((strlen(dirPath) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
29 (strlen(fileName) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
30 (strlen(dirPath) + strlen(fileName)) >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
31 return NULL;
32 }
33 uint32_t filePathLen = strlen(dirPath) + 1 + strlen(fileName) + 1;
34 if (filePathLen > PATH_MAX) {
35 return NULL;
36 }
37 char* filePath = (char *)malloc(filePathLen);
38 if (filePath == NULL) {
39 return NULL;
40 }
41 (void)memset_s(filePath, filePathLen, 0, filePathLen);
42 if (sprintf_s(filePath, filePathLen, "%s%s%s", dirPath, "/", fileName) < 0) {
43 free(filePath);
44 return NULL;
45 }
46 return filePath;
47 }
48
OEMGetFileSize(const char* path, const char* fileName, uint32_t* result)49 int32_t OEMGetFileSize(const char* path, const char* fileName, uint32_t* result)
50 {
51 if (path == NULL || fileName == NULL || result == NULL) {
52 return DEVICE_ATTEST_OEM_ERR;
53 }
54
55 char* filePath = OEMGenFilePath(path, fileName);
56 if (filePath == NULL) {
57 return DEVICE_ATTEST_OEM_ERR;
58 }
59
60 char* formatPath = realpath(filePath, NULL);
61 if (formatPath == NULL) {
62 free(filePath);
63 return DEVICE_ATTEST_OEM_ERR;
64 }
65
66 FILE* fp = fopen(formatPath, "r");
67 if (fp == NULL) {
68 free(formatPath);
69 free(filePath);
70 return DEVICE_ATTEST_OEM_ERR;
71 }
72 if (fseek(fp, 0, SEEK_END) < 0) {
73 free(formatPath);
74 free(filePath);
75 (void)fclose(fp);
76 return DEVICE_ATTEST_OEM_ERR;
77 }
78 *result = ftell(fp);
79 free(formatPath);
80 free(filePath);
81 (void)fclose(fp);
82 return DEVICE_ATTEST_OEM_OK;
83 }
84
OEMWriteFile(const char* path, const char* fileName, const char* data, uint32_t dataLen)85 int32_t OEMWriteFile(const char* path, const char* fileName, const char* data, uint32_t dataLen)
86 {
87 if (path == NULL || fileName == NULL || data == NULL || dataLen == 0) {
88 return DEVICE_ATTEST_OEM_ERR;
89 }
90
91 char* filePath = OEMGenFilePath(path, fileName);
92 if (filePath == NULL) {
93 return DEVICE_ATTEST_OEM_ERR;
94 }
95
96 char* formatPath = realpath(filePath, NULL);
97 free(filePath);
98 if (formatPath == NULL) {
99 return DEVICE_ATTEST_OEM_ERR;
100 }
101
102 FILE* fp = fopen(formatPath, "wb+");
103 if (fp == NULL) {
104 free(formatPath);
105 return DEVICE_ATTEST_OEM_ERR;
106 }
107 int32_t ret = DEVICE_ATTEST_OEM_OK;
108 do {
109 if (fwrite(data, dataLen, 1, fp) != 1) {
110 ret = DEVICE_ATTEST_OEM_ERR;
111 break;
112 }
113 if (fflush(fp) != DEVICE_ATTEST_OEM_OK) {
114 ret = DEVICE_ATTEST_OEM_ERR;
115 break;
116 }
117 int fd = fileno(fp);
118 if (fsync(fd) != DEVICE_ATTEST_OEM_OK) {
119 ret = DEVICE_ATTEST_OEM_ERR;
120 break;
121 }
122 } while (0);
123 free(formatPath);
124 (void)fclose(fp);
125 return ret;
126 }
127
OEMReadFile(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)128 int32_t OEMReadFile(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)
129 {
130 if (path == NULL || fileName == NULL || buffer == NULL || bufferLen == 0) {
131 return DEVICE_ATTEST_OEM_ERR;
132 }
133
134 uint32_t fileSize = 0;
135 if (OEMGetFileSize(path, fileName, &fileSize) != 0 || fileSize > bufferLen) {
136 return DEVICE_ATTEST_OEM_ERR;
137 }
138
139 char* filePath = OEMGenFilePath(path, fileName);
140 if (filePath == NULL) {
141 return DEVICE_ATTEST_OEM_ERR;
142 }
143
144 char* formatPath = realpath(filePath, NULL);
145 free(filePath);
146 if (formatPath == NULL) {
147 return DEVICE_ATTEST_OEM_ERR;
148 }
149
150 FILE* fp = fopen(formatPath, "rb");
151 if (fp == NULL) {
152 free(formatPath);
153 return DEVICE_ATTEST_OEM_ERR;
154 }
155 if (fread(buffer, fileSize, 1, fp) != 1) {
156 free(formatPath);
157 (void)fclose(fp);
158 return DEVICE_ATTEST_OEM_ERR;
159 }
160 free(formatPath);
161 (void)fclose(fp);
162 return DEVICE_ATTEST_OEM_OK;
163 }
164
OEMCreateFileImpl(char* formatPath, const char* fileName)165 static int32_t OEMCreateFileImpl(char* formatPath, const char* fileName)
166 {
167 uint32_t realPathLen = strlen(formatPath) + 1 + strlen(fileName) + 1;
168 if (realPathLen > PATH_MAX) {
169 free(formatPath);
170 return DEVICE_ATTEST_OEM_ERR;
171 }
172 char* realPath = (char *)malloc(realPathLen);
173 if (realPath == NULL) {
174 free(formatPath);
175 return DEVICE_ATTEST_OEM_ERR;
176 }
177 (void)memset_s(realPath, realPathLen, 0, realPathLen);
178 if (sprintf_s(realPath, realPathLen, "%s%s%s", formatPath, "/", fileName) < 0) {
179 free(formatPath);
180 free(realPath);
181 return DEVICE_ATTEST_OEM_ERR;
182 }
183 free(formatPath);
184
185 FILE* fp = fopen(realPath, "w");
186 if (fp == NULL) {
187 free(realPath);
188 return DEVICE_ATTEST_OEM_ERR;
189 }
190 free(realPath);
191 int32_t ret = DEVICE_ATTEST_OEM_OK;
192 do {
193 if (fflush(fp) != DEVICE_ATTEST_OEM_OK) {
194 ret = DEVICE_ATTEST_OEM_ERR;
195 break;
196 }
197 int fd = fileno(fp);
198 if (fsync(fd) != DEVICE_ATTEST_OEM_OK) {
199 ret = DEVICE_ATTEST_OEM_ERR;
200 break;
201 }
202 } while (0);
203 (void)fclose(fp);
204 return ret;
205 }
206
OEMCreateFile(const char* path, const char* fileName)207 int32_t OEMCreateFile(const char* path, const char* fileName)
208 {
209 if (path == NULL || fileName == NULL) {
210 return DEVICE_ATTEST_OEM_ERR;
211 }
212 char* formatPath = realpath(path, NULL);
213 if (formatPath == NULL) {
214 return DEVICE_ATTEST_OEM_ERR;
215 }
216 if ((strlen(formatPath) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
217 (strlen(fileName) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
218 (strlen(formatPath) + strlen(fileName)) >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
219 free(formatPath);
220 return DEVICE_ATTEST_OEM_ERR;
221 }
222 return OEMCreateFileImpl(formatPath, fileName);
223 }