• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }