1 /*
2 * Copyright (c) 2023 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 <vector>
17
18 #include "cert_mgr_adapter_impl.h"
19 #include "net_conn_client.h"
20 #include "nweb_log.h"
21 #include "securec.h"
22
23 using namespace OHOS::NWeb;
24
25 namespace OHOS::NWeb {
26
InitCertList(struct CertList ** cList)27 int32_t CertManagerAdapterImpl::InitCertList(struct CertList **cList)
28 {
29 *cList = static_cast<struct CertList *>(malloc(sizeof(struct CertList)));
30 if (*cList == nullptr) {
31 return CMR_ERROR_MALLOC_FAIL;
32 }
33
34 uint32_t buffSize = MAX_COUNT_CERTIFICATE * sizeof(struct CertAbstract);
35 (*cList)->certAbstract = static_cast<struct CertAbstract *>(malloc(buffSize));
36 if ((*cList)->certAbstract == nullptr) {
37 free(*cList);
38 *cList = nullptr;
39 return CMR_ERROR_MALLOC_FAIL;
40 }
41 (void)memset_s((*cList)->certAbstract, buffSize, 0, buffSize);
42 (*cList)->certsCount = MAX_COUNT_CERTIFICATE;
43
44 return CM_SUCCESS;
45 }
46
InitCertInfo(struct CertInfo * certInfo)47 int32_t CertManagerAdapterImpl::InitCertInfo(struct CertInfo *certInfo)
48 {
49 if (certInfo == nullptr) {
50 return CMR_ERROR_MALLOC_FAIL;
51 }
52
53 certInfo->certInfo.data = static_cast<uint8_t *>(malloc(MAX_LEN_CERTIFICATE));
54 if (certInfo->certInfo.data == nullptr) {
55 return CMR_ERROR_MALLOC_FAIL;
56 }
57 certInfo->certInfo.size = MAX_LEN_CERTIFICATE;
58
59 return CM_SUCCESS;
60 }
61
FreeCMBlobData(struct CmBlob * blob)62 void CertManagerAdapterImpl::FreeCMBlobData(struct CmBlob *blob)
63 {
64 if (blob == nullptr) {
65 return;
66 }
67
68 if (blob->data != nullptr) {
69 free(blob->data);
70 blob->data = nullptr;
71 }
72 blob->size = 0;
73 }
74
FreeCertList(CertList * certList)75 void CertManagerAdapterImpl::FreeCertList(CertList *certList)
76 {
77 if (certList == nullptr) {
78 return;
79 }
80
81 if (certList->certAbstract != nullptr) {
82 free(certList->certAbstract);
83 certList->certAbstract = nullptr;
84 }
85
86 free(certList);
87 certList = nullptr;
88 }
89
GetCertMaxSize()90 uint32_t CertManagerAdapterImpl::GetCertMaxSize()
91 {
92 return MAX_LEN_CERTIFICATE;
93 }
94
GetAppCertMaxSize()95 uint32_t CertManagerAdapterImpl::GetAppCertMaxSize()
96 {
97 return MAX_LEN_CERTIFICATE_CHAIN;
98 }
99
GetSytemRootCertSum()100 uint32_t CertManagerAdapterImpl::GetSytemRootCertSum()
101 {
102 uint32_t certSum = 0;
103 struct CertList *certList = nullptr;
104 int32_t ret = InitCertList(&certList);
105 if (ret != CM_SUCCESS) {
106 WVLOG_E("GetSytemRootCertSum, init cert list failed, ret = %{public}d ", ret);
107 FreeCertList(certList);
108 return certSum;
109 }
110
111 ret = CmGetCertList(CM_SYSTEM_TRUSTED_STORE, certList);
112 if (ret != CM_SUCCESS) {
113 WVLOG_E("GetSytemRootCertSum, get cert list failed, ret = %{public}d ", ret);
114 FreeCertList(certList);
115 return certSum;
116 }
117
118 if (certList != nullptr) {
119 certSum = certList->certsCount;
120 }
121
122 FreeCertList(certList);
123 return certSum;
124 }
125
GetCertInfo(char * uri,struct CertInfo * certInfo,int32_t certType)126 int32_t CertManagerAdapterImpl::GetCertInfo(char *uri, struct CertInfo *certInfo, int32_t certType)
127 {
128 unsigned int len = sizeof(struct CertInfo);
129 (void)memset_s(certInfo, len, 0, len);
130 int32_t ret = InitCertInfo(certInfo);
131 if (ret != CM_SUCCESS) {
132 WVLOG_E("GetCertInfo, init cert failed, ret = %{public}d", ret);
133 FreeCMBlobData(&(certInfo->certInfo));
134 return CM_FAILURE;
135 }
136
137 struct CmBlob uriBlob = {strlen(uri) + 1, reinterpret_cast<uint8_t *>(uri)};
138
139 if (certType == CM_USER_TRUSTED_STORE) {
140 ret = CmGetUserCertInfo(&uriBlob, certType, certInfo);
141 } else if (certType == CM_SYSTEM_TRUSTED_STORE) {
142 ret = CmGetCertInfo(&uriBlob, certType, certInfo);
143 } else {
144 WVLOG_E("GetCertInfo, unknow certType = %{public}d", certType);
145 FreeCMBlobData(&(certInfo->certInfo));
146 return CM_FAILURE;
147 }
148
149 if (ret != CM_SUCCESS) {
150 WVLOG_E("GetCertInfo, get cert info failed, ret = %{public}d", ret);
151 FreeCMBlobData(&(certInfo->certInfo));
152 return ret;
153 }
154
155 return CM_SUCCESS;
156 }
157
GetCertDataBySubject(const char * subjectName,uint8_t * certData,int32_t certType)158 int32_t CertManagerAdapterImpl::GetCertDataBySubject(const char *subjectName, uint8_t* certData, int32_t certType)
159 {
160 struct CertList *certList = nullptr;
161 int32_t ret = InitCertList(&certList);
162 if (ret != CM_SUCCESS) {
163 WVLOG_E("GetCertDataBySubject, init cert list failed, ret = %{public}d", ret);
164 return CM_FAILURE;
165 }
166
167 if (certType == CM_USER_TRUSTED_STORE) {
168 ret = CmGetUserCertList(certType, certList);
169 } else if (certType == CM_SYSTEM_TRUSTED_STORE) {
170 ret = CmGetCertList(certType, certList);
171 } else {
172 WVLOG_E("GetCertDataBySubject, unknow certType = %{public}d", certType);
173 FreeCertList(certList);
174 return CM_FAILURE;
175 }
176
177 if (ret != CM_SUCCESS) {
178 WVLOG_E("GetCertDataBySubject, get cert list failed, ret = %{public}d", ret);
179 FreeCertList(certList);
180 return CM_FAILURE;
181 }
182
183 char *uri = nullptr;
184 for (uint32_t i = 0; i < certList->certsCount; i++) {
185 if (0 == strcmp(subjectName, certList->certAbstract[i].subjectName)) {
186 uri = certList->certAbstract[i].uri;
187 break;
188 }
189 }
190
191 if (!uri) {
192 WVLOG_D("GetCertDataBySubject, can not find cert");
193 FreeCertList(certList);
194 return CM_FAILURE;
195 }
196
197 struct CertInfo certInfo;
198 ret = GetCertInfo(uri, &certInfo, certType);
199 if (ret != CM_SUCCESS) {
200 WVLOG_E("GetCertDataBySubject, get cert info failed, ret = %{public}d", ret);
201 FreeCertList(certList);
202 return CM_FAILURE;
203 }
204
205 ret = CM_SUCCESS;
206 if (memcpy_s(certData, MAX_LEN_CERTIFICATE, certInfo.certInfo.data, certInfo.certInfo.size) != EOK) {
207 WVLOG_E("GetCertDataBySubject, memory copy failed");
208 ret = CM_FAILURE;
209 }
210
211 FreeCMBlobData(&(certInfo.certInfo));
212 FreeCertList(certList);
213 return ret;
214 }
215
GetSytemRootCertData(uint32_t certCount,uint8_t * certData)216 int32_t CertManagerAdapterImpl::GetSytemRootCertData(uint32_t certCount, uint8_t* certData)
217 {
218 struct CertList *certList = nullptr;
219 int32_t ret = InitCertList(&certList);
220 if (ret != CM_SUCCESS) {
221 WVLOG_E("GetSytemRootCertData, init cert list failed, ret = %{public}d ", ret);
222 FreeCertList(certList);
223 return CM_FAILURE;
224 }
225
226 ret = CmGetCertList(CM_SYSTEM_TRUSTED_STORE, certList);
227 if (ret != CM_SUCCESS) {
228 WVLOG_E("GetSytemRootCertData, get cert list failed, ret = %{public}d ", ret);
229 FreeCertList(certList);
230 return CM_FAILURE;
231 }
232
233 struct CertInfo certInfo;
234 unsigned int len = sizeof(struct CertInfo);
235 (void)memset_s(&certInfo, len, 0, len);
236 ret = InitCertInfo(&certInfo);
237 if (ret != CM_SUCCESS) {
238 WVLOG_E("GetSytemRootCertData, init cert failed, ret = %{public}d ", ret);
239 FreeCMBlobData(&(certInfo.certInfo));
240 FreeCertList(certList);
241 return CM_FAILURE;
242 }
243
244 if (certCount > certList->certsCount) {
245 WVLOG_E("GetSytemRootCertData, cert count invailed, cert count = %{public}d ", certCount);
246 FreeCMBlobData(&(certInfo.certInfo));
247 FreeCertList(certList);
248 return CM_FAILURE;
249 }
250
251 char *uri = certList->certAbstract[certCount].uri;
252 struct CmBlob uriBlob = {strlen(uri) + 1, (uint8_t *)(uri)};
253
254 ret = CmGetCertInfo(&uriBlob, CM_SYSTEM_TRUSTED_STORE, &certInfo);
255 if (ret != CM_SUCCESS) {
256 WVLOG_E("GetSytemRootCertData, get cert info failed, ret = %{public}d ", ret);
257 FreeCMBlobData(&(certInfo.certInfo));
258 FreeCertList(certList);
259 return CM_FAILURE;
260 }
261
262 if (memcpy_s(certData, MAX_LEN_CERTIFICATE, certInfo.certInfo.data, certInfo.certInfo.size) != EOK) {
263 WVLOG_E("GetSytemRootCertData, memory copy failed");
264 FreeCMBlobData(&(certInfo.certInfo));
265 FreeCertList(certList);
266 return CM_FAILURE;
267 }
268
269 FreeCMBlobData(&(certInfo.certInfo));
270 FreeCertList(certList);
271 return CM_SUCCESS;
272 }
273
GetUserRootCertSum()274 uint32_t CertManagerAdapterImpl::GetUserRootCertSum()
275 {
276 uint32_t certSum = 0;
277 struct CertList *certList = nullptr;
278 int32_t ret = InitCertList(&certList);
279 if (ret != CM_SUCCESS) {
280 WVLOG_E("GetUserRootCertSum, init cert list failed, ret = %{public}d ", ret);
281 FreeCertList(certList);
282 return certSum;
283 }
284
285 ret = CmGetUserCertList(CM_USER_TRUSTED_STORE, certList);
286 if (ret != CM_SUCCESS) {
287 WVLOG_E("GetUserRootCertSum, get user cert list failed, ret = %{public}d ", ret);
288 FreeCertList(certList);
289 return certSum;
290 }
291
292 if (certList != nullptr) {
293 certSum = certList->certsCount;
294 }
295
296 FreeCertList(certList);
297 return certSum;
298 }
299
GetUserRootCertData(uint32_t certCount,uint8_t * certData)300 int32_t CertManagerAdapterImpl::GetUserRootCertData(uint32_t certCount, uint8_t* certData)
301 {
302 struct CertList *certList = nullptr;
303 int32_t ret = InitCertList(&certList);
304 if (ret != CM_SUCCESS) {
305 WVLOG_E("GetUserRootCertData, init cert list, ret = %{public}d ", ret);
306 FreeCertList(certList);
307 return CM_FAILURE;
308 }
309
310 ret = CmGetUserCertList(CM_USER_TRUSTED_STORE, certList);
311 if (ret != CM_SUCCESS) {
312 WVLOG_E("GetUserRootCertData, get user cert list failed, ret = %{public}d ", ret);
313 FreeCertList(certList);
314 return CM_FAILURE;
315 }
316
317 struct CertInfo certInfo;
318 unsigned int len = sizeof(struct CertInfo);
319 (void)memset_s(&certInfo, len, 0, len);
320 ret = InitCertInfo(&certInfo);
321 if (ret != CM_SUCCESS) {
322 WVLOG_E("GetUserRootCertData, init cert info failed, ret = %{public}d ", ret);
323 FreeCMBlobData(&(certInfo.certInfo));
324 FreeCertList(certList);
325 return CM_FAILURE;
326 }
327
328 if (certCount > certList->certsCount) {
329 WVLOG_E("GetUserRootCertData, cert count invailed, cert count = %{public}d ", certCount);
330 FreeCMBlobData(&(certInfo.certInfo));
331 FreeCertList(certList);
332 return CM_FAILURE;
333 }
334
335 char *uri = certList->certAbstract[certCount].uri;
336 struct CmBlob uriBlob = {strlen(uri) + 1, (uint8_t *)(uri)};
337
338 ret = CmGetUserCertInfo(&uriBlob, CM_USER_TRUSTED_STORE, &certInfo);
339 if (ret != CM_SUCCESS) {
340 WVLOG_E("GetUserRootCertData, get user cert info failed, ret = %{public}d ", ret);
341 FreeCMBlobData(&(certInfo.certInfo));
342 FreeCertList(certList);
343 return CM_FAILURE;
344 }
345
346 if (memcpy_s(certData, MAX_LEN_CERTIFICATE, certInfo.certInfo.data, certInfo.certInfo.size) != EOK) {
347 WVLOG_E("GetUserRootCertData, memory copy failed");
348 FreeCMBlobData(&(certInfo.certInfo));
349 FreeCertList(certList);
350 return CM_FAILURE;
351 }
352
353 FreeCMBlobData(&(certInfo.certInfo));
354 FreeCertList(certList);
355 return CM_SUCCESS;
356 }
357
GetAppCert(uint8_t * uriData,uint8_t * certData,uint32_t * len)358 int32_t CertManagerAdapterImpl::GetAppCert(uint8_t* uriData, uint8_t* certData, uint32_t* len)
359 {
360 struct Credential cred;
361 (void)memset_s(&cred, sizeof(struct Credential), 0, sizeof(struct Credential));
362 cred.credData.size = MAX_LEN_CERTIFICATE_CHAIN;
363 cred.credData.data = static_cast<uint8_t *>(malloc(MAX_LEN_CERTIFICATE_CHAIN));
364 if (cred.credData.data == nullptr) {
365 WVLOG_E("GetAppCert, malloc failed");
366 return CM_FAILURE;
367 }
368
369 struct CmBlob uri = { strlen((char*)uriData) + 1, uriData };
370 int32_t ret = CmGetAppCert(&uri, CM_CREDENTIAL_STORE, &cred);
371 if (ret != CM_SUCCESS) {
372 WVLOG_E("GetAppCert, get app cert failed, ret = %{public}d ", ret);
373 free(cred.credData.data);
374 cred.credData.data = nullptr;
375 return CM_FAILURE;
376 }
377
378 *len = cred.credData.size;
379 if (memcpy_s(certData, MAX_LEN_CERTIFICATE_CHAIN, cred.credData.data, cred.credData.size) != EOK) {
380 WVLOG_E("GetAppCert, memory copy failed");
381 free(cred.credData.data);
382 cred.credData.data = nullptr;
383 return CM_FAILURE;
384 }
385
386 free(cred.credData.data);
387 cred.credData.data = nullptr;
388 return CM_SUCCESS;
389 }
390
Sign(const uint8_t * uri,const uint8_t * certData,uint32_t certDataLen,uint8_t * signData,uint32_t signDataLen)391 int32_t CertManagerAdapterImpl::Sign(const uint8_t* uri, const uint8_t* certData, uint32_t certDataLen,
392 uint8_t* signData, uint32_t signDataLen)
393 {
394 uint64_t handleValue = 0;
395 struct CmBlob handle = { sizeof(uint64_t), (uint8_t *)&handleValue };
396 const struct CmBlob keyUri = { strlen((char*)uri) + 1, (uint8_t*)uri };
397 struct CmSignatureSpec spec = { CM_KEY_PURPOSE_SIGN, CM_PADDING_PSS, CM_DIGEST_SHA256 };
398
399 if (signData == nullptr) {
400 WVLOG_E("Sign, sign data is nullptr");
401 return CM_FAILURE;
402 }
403
404 int32_t ret = CmInit(&keyUri, &spec, &handle);
405 if (ret != CM_SUCCESS) {
406 WVLOG_E("Sign, init failed, ret = %{public}d ", ret);
407 return CM_FAILURE;
408 }
409
410 const struct CmBlob message = {certDataLen, const_cast<uint8_t *>(certData)};
411 ret = CmUpdate(&handle, &message);
412 if (ret != CM_SUCCESS) {
413 WVLOG_E("Sign, update failed, ret = %{public}d ", ret);
414 return CM_FAILURE;
415 }
416
417 struct CmBlob signature = { signDataLen, signData };
418 struct CmBlob inDataFinish = { 0, nullptr };
419 ret = CmFinish(&handle, &inDataFinish, &signature);
420 if (ret != CM_SUCCESS) {
421 WVLOG_E("Sign, finish failed, ret = %{public}d ", ret);
422 return CM_FAILURE;
423 }
424
425 ret = CmAbort(&handle);
426 if (ret != CM_SUCCESS) {
427 WVLOG_E("Sign, abort failed, ret = %{public}d ", ret);
428 return CM_FAILURE;
429 }
430
431 return CM_SUCCESS;
432 }
433
GetTrustAnchorsForHostName(const std::string & hostname,std::vector<std::string> & certs)434 bool CertManagerAdapterImpl::GetTrustAnchorsForHostName(
435 const std::string& hostname, std::vector<std::string>& certs)
436 {
437 int32_t ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().
438 GetTrustAnchorsForHostName(hostname, certs);
439 if (ret != OHOS::NetManagerStandard::NETMANAGER_SUCCESS) {
440 WVLOG_E("GetTrustAnchorsForHostName for hostname:%{public}s failed",
441 hostname.c_str());
442 return false;
443 }
444 return true;
445 }
446
GetPinSetForHostName(const std::string & hostname,std::vector<std::string> & pins)447 bool CertManagerAdapterImpl::GetPinSetForHostName(
448 const std::string& hostname, std::vector<std::string>& pins)
449 {
450 std::string pinsString;
451 int32_t ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().
452 GetPinSetForHostName(hostname, pinsString);
453 if (ret != OHOS::NetManagerStandard::NETMANAGER_SUCCESS) {
454 WVLOG_E("GetPinSetForHostName for hostname:%{public}s failed, ret:%{public}d",
455 hostname.c_str(), ret);
456 return false;
457 }
458
459 if (pinsString.empty()) {
460 WVLOG_D("GetPinSetForHostName for hostname:%{public}s is empty", hostname.c_str());
461 return true;
462 }
463 size_t start = 0;
464 size_t pos = pinsString.find(";", start);
465 while (pos != std::string::npos) {
466 pins.emplace_back(pinsString.substr(start, pos - start));
467 start = pos + 1;
468 pos = pinsString.find(";", start);
469 }
470 pins.emplace_back(pinsString.substr(start));
471 return true;
472 }
473 }
474