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