• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cm_test_common.h"
17 
18 #include "cert_manager_api.h"
19 
20 #include "cm_cert_data_ecc.h"
21 #include "cm_cert_data_ed25519.h"
22 #include "cm_cert_data_part1_rsa.h"
23 #include "cm_cert_data_part2_rsa.h"
24 #include "cm_mem.h"
25 #include "cm_test_log.h"
26 
27 #include "accesstoken_kit.h"
28 #include "nativetoken_kit.h"
29 #include "token_setproc.h"
30 #include <unistd.h>
31 #include <unordered_map>
32 #include <thread>
33 #include <sstream>
34 #include <iostream>
35 
36 namespace CertmanagerTest {
37 using namespace OHOS::Security::AccessToken;
38 namespace {
39 
40 static const std::unordered_map<uint32_t, const uint8_t*> ALG_CODE_TO_CERT_DATA = {
41     { CERT_KEY_ALG_RSA, g_rsa2048P12CertInfo },
42     { CERT_KEY_ALG_ECC, g_eccP256P12CertInfo },
43     { CERT_KEY_ALG_RSA_512, g_rsa512P12CertInfo },
44     { CERT_KEY_ALG_RSA_1024, g_rsa1024P12CertInfo },
45     { CERT_KEY_ALG_RSA_3072, g_rsa3072P12CertInfo },
46     { CERT_KEY_ALG_RSA_4096, g_rsa4096P12CertInfo },
47     { CERT_KEY_ALG_ECC_P224, g_eccP224P12CertInfo },
48     { CERT_KEY_ALG_ECC_P384, g_eccP384P12CertInfo },
49     { CERT_KEY_ALG_ECC_P521, g_eccP521P12CertInfo },
50     { CERT_KEY_ALG_ED25519, g_ed25519P12CertInfo },
51     { CERT_KEY_ALG_SM2_1, g_sm2PfxCertInfo },
52     { CERT_KEY_ALG_SM2_2, g_sm2PfxCertInfo2 },
53 };
54 
55 static const std::unordered_map<uint32_t, uint32_t> ALG_CODE_TO_CERT_SIZE = {
56     { CERT_KEY_ALG_RSA, sizeof(g_rsa2048P12CertInfo) },
57     { CERT_KEY_ALG_ECC, sizeof(g_eccP256P12CertInfo) },
58     { CERT_KEY_ALG_RSA_512, sizeof(g_rsa512P12CertInfo) },
59     { CERT_KEY_ALG_RSA_1024, sizeof(g_rsa1024P12CertInfo) },
60     { CERT_KEY_ALG_RSA_3072, sizeof(g_rsa3072P12CertInfo) },
61     { CERT_KEY_ALG_RSA_4096, sizeof(g_rsa4096P12CertInfo) },
62     { CERT_KEY_ALG_ECC_P224, sizeof(g_eccP224P12CertInfo) },
63     { CERT_KEY_ALG_ECC_P384, sizeof(g_eccP384P12CertInfo) },
64     { CERT_KEY_ALG_ECC_P521, sizeof(g_eccP521P12CertInfo) },
65     { CERT_KEY_ALG_ED25519, sizeof(g_ed25519P12CertInfo) },
66     { CERT_KEY_ALG_SM2_1, sizeof(g_sm2PfxCertInfo) },
67     { CERT_KEY_ALG_SM2_2, sizeof(g_sm2PfxCertInfo2) },
68 };
69 
70 std::mutex g_lockSetToken;
71 uint64_t g_shellTokenId = 0;
72 const std::string BUNDLE_NAME = "test.bundlename";
73 const bool IS_SYSTEM_APP = true;
74 const std::vector<std::string> PERMISSION_LIST = {
75     "ohos.permission.ACCESS_CERT_MANAGER_INTERNAL",
76     "ohos.permission.ACCESS_CERT_MANAGER",
77     "ohos.permission.ACCESS_USER_TRUSTED_CERT",
78     "ohos.permission.ACCESS_SYSTEM_APP_CERT"
79 };
80 }
81 
MockNativeToken(const std::string & process)82 MockNativeToken::MockNativeToken(const std::string& process)
83 {
84     selfToken_ = GetSelfTokenID();
85     uint32_t tokenId = CmTestCommon::GetNativeTokenIdFromProcess(process);
86     SetSelfTokenID(tokenId);
87 }
88 
~MockNativeToken()89 MockNativeToken::~MockNativeToken()
90 {
91     SetSelfTokenID(selfToken_);
92 }
93 
MockHapToken()94 MockHapToken::MockHapToken()
95 {
96     selfToken_ = GetSelfTokenID();
97     AccessTokenIDEx tokenIdEx = CmTestCommon::SetupHapAndAllocateToken();
98     mockToken_ = tokenIdEx.tokenIdExStruct.tokenID;
99     SetSelfTokenID(tokenIdEx.tokenIDEx);
100 }
101 
~MockHapToken()102 MockHapToken::~MockHapToken()
103 {
104     if (mockToken_ != INVALID_TOKENID) {
105         CmTestCommon::DeleteTestHapToken(mockToken_);
106     }
107     SetSelfTokenID(selfToken_);
108 }
109 
SetTestEnvironment(uint64_t shellTokenId)110 void CmTestCommon::SetTestEnvironment(uint64_t shellTokenId)
111 {
112     std::lock_guard<std::mutex> lock(g_lockSetToken);
113     g_shellTokenId = shellTokenId;
114 }
115 
ResetTestEnvironment()116 void CmTestCommon::ResetTestEnvironment()
117 {
118     std::lock_guard<std::mutex> lock(g_lockSetToken);
119     g_shellTokenId = 0;
120 }
121 
GetShellTokenId()122 uint64_t CmTestCommon::GetShellTokenId()
123 {
124     std::lock_guard<std::mutex> lock(g_lockSetToken);
125     return g_shellTokenId;
126 }
127 
SetHapInfoAndPolicy(const std::string & bundle,const std::vector<std::string> & reqPerm,bool isSystemApp,HapInfoParams & hapInfo,HapPolicyParams & hapPolicy)128 void CmTestCommon::SetHapInfoAndPolicy(const std::string& bundle, const std::vector<std::string>& reqPerm,
129     bool isSystemApp, HapInfoParams& hapInfo, HapPolicyParams& hapPolicy)
130 {
131     hapInfo = {
132         .userID = 0,
133         .bundleName = bundle,
134         .instIndex = 0,
135         .appIDDesc = "CmTestAppID",
136         .apiVersion = CmTestCommon::DEFAULT_API_VERSION,
137         .isSystemApp = isSystemApp,
138         .appDistributionType = "",
139     };
140 
141     hapPolicy = {
142         .apl = APL_NORMAL,
143         .domain = "test.domain",
144     };
145     for (size_t i = 0; i < reqPerm.size(); ++i) {
146         PermissionDef permDefResult;
147         if (AccessTokenKit::GetDefPermission(reqPerm[i], permDefResult) != RET_SUCCESS) {
148             continue;
149         }
150         PermissionStateFull permState = {
151             .permissionName = reqPerm[i],
152             .isGeneral = true,
153             .resDeviceID = {"local3"},
154             .grantStatus = {PermissionState::PERMISSION_DENIED},
155             .grantFlags = {PermissionFlag::PERMISSION_DEFAULT_FLAG}
156         };
157         hapPolicy.permStateList.emplace_back(permState);
158         if (permDefResult.availableLevel > hapPolicy.apl) {
159             hapPolicy.aclRequestedList.emplace_back(reqPerm[i]);
160         }
161     }
162 }
163 
AllocTestHapToken(const HapInfoParams & hapInfo,HapPolicyParams & hapPolicy)164 AccessTokenIDEx CmTestCommon::AllocTestHapToken(
165     const HapInfoParams& hapInfo, HapPolicyParams& hapPolicy)
166 {
167     AccessTokenIDEx tokenIdEx = {0};
168     uint64_t selfTokenId = GetSelfTokenID();
169     for (auto& permissionStateFull : hapPolicy.permStateList) {
170         PermissionDef permDefResult;
171         if (AccessTokenKit::GetDefPermission(permissionStateFull.permissionName, permDefResult) != RET_SUCCESS) {
172             continue;
173         }
174         if (permDefResult.availableLevel > hapPolicy.apl) {
175             hapPolicy.aclRequestedList.emplace_back(permissionStateFull.permissionName);
176         }
177     }
178     if (CmTestCommon::GetNativeTokenIdFromProcess("foundation") == selfTokenId) {
179         AccessTokenKit::InitHapToken(hapInfo, hapPolicy, tokenIdEx);
180     } else {
181         // set sh token for self
182         MockNativeToken mock("foundation");
183         AccessTokenKit::InitHapToken(hapInfo, hapPolicy, tokenIdEx);
184 
185         // restore
186         SetSelfTokenID(selfTokenId);
187     }
188     return tokenIdEx;
189 }
190 
SetupHapAndAllocateToken()191 AccessTokenIDEx CmTestCommon::SetupHapAndAllocateToken()
192 {
193     HapInfoParams hapInfo;
194     HapPolicyParams hapPolicy;
195     CmTestCommon::SetHapInfoAndPolicy(BUNDLE_NAME, PERMISSION_LIST, IS_SYSTEM_APP,
196         hapInfo, hapPolicy);
197     AccessTokenIDEx tokenIdEx = CmTestCommon::AllocTestHapToken(hapInfo, hapPolicy);
198     return tokenIdEx;
199 }
200 
DeleteTestHapToken(AccessTokenID tokenID)201 int32_t CmTestCommon::DeleteTestHapToken(AccessTokenID tokenID)
202 {
203     uint64_t selfTokenId = GetSelfTokenID();
204     if (CmTestCommon::GetNativeTokenIdFromProcess("foundation") == selfTokenId) {
205         return AccessTokenKit::DeleteToken(tokenID);
206     }
207 
208     // set sh token for self
209     MockNativeToken mock("foundation");
210 
211     int32_t ret = AccessTokenKit::DeleteToken(tokenID);
212     // restore
213     SetSelfTokenID(selfTokenId);
214     return ret;
215 }
216 
GetNativeTokenIdFromProcess(const std::string & process)217 AccessTokenID CmTestCommon::GetNativeTokenIdFromProcess(const std::string &process)
218 {
219     uint64_t selfTokenId = GetSelfTokenID();
220     SetSelfTokenID(CmTestCommon::GetShellTokenId()); // set shell token
221 
222     std::string dumpInfo;
223     AtmToolsParamInfo info;
224     info.processName = process;
225     AccessTokenKit::DumpTokenInfo(info, dumpInfo);
226     size_t pos = dumpInfo.find("\"tokenID\": ");
227     if (pos == std::string::npos) {
228         return 0;
229     }
230     pos += std::string("\"tokenID\": ").length();
231     std::string numStr;
232     while (pos < dumpInfo.length() && std::isdigit(dumpInfo[pos])) {
233         numStr += dumpInfo[pos];
234         ++pos;
235     }
236     // restore
237     SetSelfTokenID(selfTokenId);
238 
239     std::istringstream iss(numStr);
240     AccessTokenID tokenID;
241     iss >> tokenID;
242     return tokenID;
243 }
244 
InitCertInfo(struct CertInfo * certInfo)245 int32_t InitCertInfo(struct CertInfo *certInfo)
246 {
247     if (certInfo == nullptr) {
248         return CMR_ERROR_MALLOC_FAIL;
249     }
250 
251     certInfo->certInfo.data =  static_cast<uint8_t *>(CmMalloc(MAX_LEN_CERTIFICATE));
252     if (certInfo->certInfo.data  == NULL) {
253         return CMR_ERROR_MALLOC_FAIL;
254     }
255     certInfo->certInfo.size = MAX_LEN_CERTIFICATE;
256 
257     return CM_SUCCESS;
258 }
259 
InitCertList(struct CertList ** cList)260 int32_t InitCertList(struct CertList **cList)
261 {
262     *cList = static_cast<struct CertList *>(CmMalloc(sizeof(struct CertList)));
263     if (*cList == nullptr) {
264         return CMR_ERROR_MALLOC_FAIL;
265     }
266 
267     uint32_t buffSize = MAX_COUNT_CERTIFICATE_ALL * sizeof(struct CertAbstract);
268     (*cList)->certAbstract = static_cast<struct CertAbstract *>(CmMalloc(buffSize));
269     if ((*cList)->certAbstract == NULL) {
270         return CMR_ERROR_MALLOC_FAIL;
271     }
272     (void)memset_s((*cList)->certAbstract, buffSize, 0, buffSize);
273     (*cList)->certsCount = MAX_COUNT_CERTIFICATE_ALL;
274 
275     return CM_SUCCESS;
276 }
277 
InitUserCertInfo(struct CertInfo ** cInfo)278 int32_t InitUserCertInfo(struct CertInfo **cInfo)
279 {
280     *cInfo = static_cast<struct CertInfo *>(CmMalloc(sizeof(struct CertInfo)));
281     if (*cInfo == nullptr) {
282         return CMR_ERROR_MALLOC_FAIL;
283     }
284     (void)memset_s(*cInfo, sizeof(struct CertInfo), 0, sizeof(struct CertInfo));
285 
286     (*cInfo)->certInfo.data = static_cast<uint8_t *>(CmMalloc(MAX_LEN_CERTIFICATE));
287     if ((*cInfo)->certInfo.data == NULL) {
288         return CMR_ERROR_MALLOC_FAIL;
289     }
290     (*cInfo)->certInfo.size = MAX_LEN_CERTIFICATE;
291 
292     return CM_SUCCESS;
293 }
294 
FreeCertList(struct CertList * certList)295 void FreeCertList(struct CertList *certList)
296 {
297     if (certList == nullptr || certList->certAbstract == nullptr) {
298         return;
299     }
300 
301     CmFree(certList->certAbstract);
302     certList->certAbstract = nullptr;
303 
304     CmFree(certList);
305 }
306 
307 
FreeCMBlobData(struct CmBlob * blob)308 void FreeCMBlobData(struct CmBlob *blob)
309 {
310     if (blob == nullptr) {
311         return;
312     }
313 
314     if (blob->data != nullptr) {
315         CmFree(blob->data);
316         blob->data = nullptr;
317     }
318     blob->size = 0;
319 }
320 
FreeCertInfo(struct CertInfo * cInfo)321 void FreeCertInfo(struct CertInfo *cInfo)
322 {
323     if (cInfo == nullptr || (cInfo->certInfo).data == nullptr) {
324         return;
325     }
326 
327     FreeCMBlobData(&(cInfo->certInfo));
328     CmFree(cInfo);
329 }
330 
CompareCert(const struct CertAbstract * firstCert,const struct CertAbstract * secondCert)331 static bool CompareCert(const struct CertAbstract *firstCert, const struct CertAbstract *secondCert)
332 {
333     if (firstCert == nullptr || secondCert == nullptr) {
334         CM_TEST_LOG_E("cert invalid parameter");
335         return false;
336     }
337     return ((strcmp(firstCert->uri, secondCert->uri) == 0) &&
338         (strcmp(firstCert->certAlias, secondCert->certAlias) == 0) &&
339         (strcmp(firstCert->subjectName, secondCert->subjectName) == 0) &&
340         (firstCert->status == secondCert->status));
341 }
342 
CompareCredentialList(const struct CredentialAbstract * firstCert,const struct CredentialAbstract * secondCert)343 bool CompareCredentialList(const struct CredentialAbstract *firstCert, const struct CredentialAbstract *secondCert)
344 {
345     if (firstCert == nullptr || secondCert == nullptr) {
346         CM_TEST_LOG_E("cert invalid parameter");
347         return false;
348     }
349     return ((strcmp(firstCert->type, secondCert->type) == 0) &&
350         (strcmp(firstCert->alias, secondCert->alias) == 0) &&
351         (strcmp(firstCert->keyUri, secondCert->keyUri) == 0));
352 }
353 
DumpCertAbstractInfo(const struct CertAbstract * certAbstract)354 std::string  DumpCertAbstractInfo(const struct CertAbstract *certAbstract)
355 {
356     if (certAbstract == nullptr) {
357         return " ";
358     }
359     std::string str  = "";
360     str += ENDOF;
361     str +=  certAbstract->uri;
362     str += DELIMITER;
363     str += certAbstract->certAlias;
364     str += DELIMITER;
365     str += certAbstract->subjectName;
366     str += DELIMITER;
367     str += (certAbstract->status) ? "true" : "false";
368     str += ENDOF;
369     return str;
370 }
371 
DumpCertList(struct CertList * certList)372 std::string DumpCertList(struct CertList *certList)
373 {
374     if (certList == nullptr) {
375         return " ";
376     }
377 
378     std::string  str  = "";
379     if (certList->certsCount > 0 && certList->certAbstract != nullptr) {
380         for (uint32_t i = 0; i < certList->certsCount; i++) {
381             str +=  DumpCertAbstractInfo(&(certList->certAbstract[i]));
382         }
383     }
384     return str;
385 }
386 
CompareCertInfo(const struct CertInfo * firstCert,const struct CertInfo * secondCert)387 bool CompareCertInfo(const struct CertInfo *firstCert, const struct CertInfo *secondCert)
388 {
389     if (firstCert == nullptr || secondCert == nullptr) {
390         return false;
391     }
392     return ((strcmp(firstCert->uri, secondCert->uri) == 0) &&
393             (strcmp(firstCert->certAlias, secondCert->certAlias) == 0) &&
394             (firstCert->status == secondCert->status) &&
395             (strcmp(firstCert->issuerName, secondCert->issuerName) == 0) &&
396             (strcmp(firstCert->subjectName, secondCert->subjectName) == 0) &&
397             (strcmp(firstCert->serial, secondCert->serial) == 0) &&
398             (strcmp(firstCert->notBefore, secondCert->notBefore) == 0) &&
399             (strcmp(firstCert->notAfter, secondCert->notAfter) == 0) &&
400             (strcmp(firstCert->fingerprintSha256, secondCert->fingerprintSha256) == 0));
401 }
402 
CompareCertData(const struct CmBlob * firstData,const struct CmBlob * secondData)403 bool CompareCertData(const struct CmBlob *firstData, const struct CmBlob *secondData)
404 {
405     if (firstData == nullptr || secondData == nullptr) {
406         return false;
407     }
408     return ((firstData->size == secondData->size) &&
409             (memcmp(firstData->data, secondData->data, static_cast<int32_t>(firstData->size)) == 0));
410 }
411 
DumpCertInfo(const struct CertInfo * certInfo)412 std::string DumpCertInfo(const struct CertInfo *certInfo)
413 {
414     if (certInfo == nullptr) {
415         return " ";
416     }
417     std::string str = "";
418     str += ENDOF;
419     str += certInfo->uri;
420     str += DELIMITER;
421     str += certInfo->certAlias;
422     str += DELIMITER;
423     str += certInfo->subjectName;
424     str += DELIMITER;
425     str += (certInfo->status) ? "true" : "false";
426     str += ENDOF;
427     return str;
428 }
429 
CompareCredential(const struct Credential * firstCredential,const struct Credential * secondCredential)430 bool CompareCredential(const struct Credential *firstCredential, const struct Credential *secondCredential)
431 {
432     if (firstCredential == nullptr || secondCredential == nullptr) {
433         return false;
434     }
435     return ((strcmp(firstCredential->type, secondCredential->type) == 0) &&
436             (strcmp(firstCredential->alias, secondCredential->alias) == 0) &&
437             (strcmp(firstCredential->keyUri, secondCredential->keyUri) == 0) &&
438             (firstCredential->certNum == secondCredential->certNum) &&
439             (firstCredential->keyNum == secondCredential->keyNum) &&
440             (firstCredential->credData.size == secondCredential->credData.size));
441 }
442 
ConstructAppCertData(uint32_t alg,struct CmBlob * appCert)443 static int32_t ConstructAppCertData(uint32_t alg, struct CmBlob *appCert)
444 {
445     auto iterSize = ALG_CODE_TO_CERT_SIZE.find(alg);
446     if (iterSize == ALG_CODE_TO_CERT_SIZE.end()) {
447         return CMR_ERROR_INVALID_ARGUMENT;
448     }
449     appCert->size = iterSize->second;
450 
451     auto iterData = ALG_CODE_TO_CERT_DATA.find(alg);
452     if (iterData == ALG_CODE_TO_CERT_DATA.end()) {
453         return CMR_ERROR_INVALID_ARGUMENT;
454     }
455     appCert->data = const_cast<uint8_t *>(iterData->second);
456     return CM_SUCCESS;
457 }
458 
TestGenerateAppCert(const struct CmBlob * alias,uint32_t alg,uint32_t store)459 int32_t TestGenerateAppCert(const struct CmBlob *alias, uint32_t alg, uint32_t store)
460 {
461     struct CmBlob appCert = { 0, NULL };
462     int32_t ret = ConstructAppCertData(alg, &appCert);
463     if (ret != CM_SUCCESS) {
464         return ret;
465     }
466 
467     struct CmBlob appCertPwd = { sizeof(g_certPwd), const_cast<uint8_t *>(g_certPwd) };
468     if (alg == CERT_KEY_ALG_SM2_1 || alg == CERT_KEY_ALG_SM2_2) {
469         appCertPwd.size = sizeof(g_sm2certPwd);
470         appCertPwd.data = const_cast<uint8_t *>(g_sm2certPwd);
471     }
472     uint8_t uriData[MAX_LEN_URI] = {0};
473     struct CmBlob keyUri = { sizeof(uriData), uriData };
474 
475     if (store == CM_SYS_CREDENTIAL_STORE) {
476         struct CmAppCertParam appCertParam = { &appCert, &appCertPwd,
477             (struct CmBlob *)alias, CM_SYS_CREDENTIAL_STORE, TEST_USERID };
478         return CmInstallSystemAppCert(&appCertParam, &keyUri);
479     }
480     return CmInstallAppCert(&appCert, &appCertPwd, alias, store, &keyUri);
481 }
482 
FindCertAbstract(const struct CertAbstract * abstract,const struct CertList * cList)483 bool FindCertAbstract(const struct CertAbstract *abstract, const struct CertList *cList)
484 {
485     if (abstract == nullptr || cList == nullptr || cList->certsCount == 0) {
486         return false;
487     }
488     for (uint32_t i = 0; i < cList->certsCount; ++i) {
489         if (CompareCert(abstract, &(cList->certAbstract[i]))) {
490             return true;
491         }
492     }
493     return false;
494 }
495 }
496