1 /*
2 * Copyright (c) 2023-2024 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 "network_security_config.h"
17
18 #include <sys/stat.h>
19 #include <fstream>
20 #include <dirent.h>
21 #include <unistd.h>
22 #include <dlfcn.h>
23 #include <regex>
24 #include <sstream>
25 #include <securec.h>
26
27 #include "openssl/evp.h"
28 #include "net_mgr_log_wrapper.h"
29 #include "net_manager_constants.h"
30 #include "netmanager_base_common_utils.h"
31 #include "net_bundle.h"
32
33 namespace OHOS {
34 namespace NetManagerStandard {
35
36 const std::string TAG_NETWORK_SECURITY_CONFIG("network-security-config");
37 const std::string TAG_BASE_CONFIG("base-config");
38 const std::string TAG_DOMAIN_CONFIG("domain-config");
39 const std::string TAG_TRUST_ANCHORS("trust-anchors");
40 const std::string TAG_CERTIFICATES("certificates");
41 const std::string TAG_DOMAINS("domains");
42 const std::string TAG_INCLUDE_SUBDOMAINS("include-subdomains");
43 const std::string TAG_NAME("name");
44 const std::string TAG_PIN_SET("pin-set");
45 const std::string TAG_EXPIRATION("expiration");
46 const std::string TAG_PIN("pin");
47 const std::string TAG_DIGEST_ALGORITHM("digest-algorithm");
48 const std::string TAG_DIGEST("digest");
49
50 const std::string REHASHD_CA_CERTS_DIR("/data/storage/el2/base/files/rehashed_ca_certs");
51 #ifdef WINDOWS_PLATFORM
52 const char OS_PATH_SEPARATOR = '\\';
53 #else
54 const char OS_PATH_SEPARATOR = '/';
55 #endif
56
57 #ifdef __LP64__
58 const std::string LIB_LOAD_PATH = "/system/lib64/platformsdk/libnet_bundle_utils.z.so";
59 #else
60 const std::string LIB_LOAD_PATH = "/system/lib/platformsdk/libnet_bundle_utils.z.so";
61 #endif
62
63 using GetNetBundleClass = INetBundle *(*)();
64
NetworkSecurityConfig()65 NetworkSecurityConfig::NetworkSecurityConfig()
66 {
67 if (GetConfig() != NETMANAGER_SUCCESS) {
68 NETMGR_LOG_E("GetConfig failed");
69 } else {
70 NETMGR_LOG_D("Succeed to get NetworkSecurityConfig");
71 }
72 }
73
~NetworkSecurityConfig()74 NetworkSecurityConfig::~NetworkSecurityConfig() {}
75
GetInstance()76 NetworkSecurityConfig &NetworkSecurityConfig::GetInstance()
77 {
78 static NetworkSecurityConfig gInstance;
79 return gInstance;
80 }
81
IsCACertFileName(const char * fileName)82 bool NetworkSecurityConfig::IsCACertFileName(const char *fileName)
83 {
84 std::string str;
85 auto ext = strrchr(fileName, '.');
86 if (ext != nullptr) {
87 str = ext + 1;
88 }
89
90 for (auto &c : str) {
91 c = tolower(c);
92 }
93
94 return (str == "pem" || str == "crt");
95 }
96
GetCAFilesFromPath(const std::string caPath,std::vector<std::string> & caFiles)97 void NetworkSecurityConfig::GetCAFilesFromPath(const std::string caPath, std::vector<std::string> &caFiles)
98 {
99 DIR *dir = opendir(caPath.c_str());
100 if (dir == nullptr) {
101 NETMGR_LOG_E("open CA path[%{public}s] fail. [%{public}d]", caPath.c_str(), errno);
102 return;
103 }
104
105 struct dirent *entry = readdir(dir);
106 while (entry != nullptr) {
107 if (IsCACertFileName(entry->d_name)) {
108 if (caPath.back() != OS_PATH_SEPARATOR) {
109 caFiles.push_back(caPath + OS_PATH_SEPARATOR + entry->d_name);
110 } else {
111 caFiles.push_back(caPath + entry->d_name);
112 }
113 NETMGR_LOG_D("Read CA File [%{public}s] from CA Path", entry->d_name);
114 }
115 entry = readdir(dir);
116 }
117
118 closedir(dir);
119 }
120
AddSurfixToCACertFileName(const std::string & caPath,std::set<std::string> & allFileNames,std::string & caFile)121 void NetworkSecurityConfig::AddSurfixToCACertFileName(const std::string &caPath, std::set<std::string> &allFileNames,
122 std::string &caFile)
123 {
124 uint32_t count = 0;
125 for (auto &fileName : allFileNames) {
126 if (fileName.find(caFile) != std::string::npos) {
127 count++;
128 }
129 }
130
131 caFile = caFile + '.' + std::to_string(count);
132 allFileNames.insert(caFile);
133 }
134
ReadCertFile(const std::string & fileName)135 X509 *NetworkSecurityConfig::ReadCertFile(const std::string &fileName)
136 {
137 std::ifstream certFile(fileName.c_str());
138 if (!certFile.is_open()) {
139 NETMGR_LOG_E("Fail to read cert fail [%{public}s]", fileName.c_str());
140 return nullptr;
141 }
142
143 std::stringstream certStream;
144 certStream << certFile.rdbuf();
145
146 const std::string &certData = certStream.str();
147 BIO *bio = BIO_new_mem_buf(certData.c_str(), -1);
148 if (bio == nullptr) {
149 NETMGR_LOG_E("Fail to call BIO_new_mem_buf");
150 return nullptr;
151 }
152
153 X509 *x509 = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
154 if (x509 == nullptr) {
155 NETMGR_LOG_E("Fail to call PEM_read_bio_X509.");
156 }
157
158 BIO_free(bio);
159 return x509;
160 }
161
GetRehashedCADirName(const std::string & caPath)162 std::string NetworkSecurityConfig::GetRehashedCADirName(const std::string &caPath)
163 {
164 unsigned char hashedHex[EVP_MAX_MD_SIZE];
165 auto ret = EVP_Digest(reinterpret_cast<const unsigned char *>(caPath.c_str()), caPath.size(), hashedHex, nullptr,
166 EVP_sha256(), nullptr);
167 if (ret != 1) {
168 return "";
169 }
170
171 /* Encode the hashed string by base16 */
172 constexpr unsigned int HASHED_DIR_NAME_LEN = 32;
173 constexpr unsigned int BASE16_ELE_SIZE = 2;
174 char hashedStr[HASHED_DIR_NAME_LEN + 1] = {0};
175 for (unsigned int i = 0; i < HASHED_DIR_NAME_LEN / BASE16_ELE_SIZE; i++) {
176 if (sprintf_s(&hashedStr[BASE16_ELE_SIZE * i], sizeof(hashedStr) - BASE16_ELE_SIZE * i, "%02x", hashedHex[i]) <
177 0) {
178 return "";
179 }
180 }
181
182 return hashedStr;
183 }
184
BuildRehasedCAPath(const std::string & caPath)185 std::string NetworkSecurityConfig::BuildRehasedCAPath(const std::string &caPath)
186 {
187 if (access(REHASHD_CA_CERTS_DIR.c_str(), F_OK) == -1) {
188 if (mkdir(REHASHD_CA_CERTS_DIR.c_str(), S_IRWXU | S_IRWXG) == -1) {
189 NETMGR_LOG_E("Fail to make a rehased caCerts dir [%{public}d]", errno);
190 return "";
191 }
192 }
193
194 auto dirName = GetRehashedCADirName(caPath);
195 if (dirName.empty()) {
196 NETMGR_LOG_E("Fail to make a rehased caCerts dir for [%{public}s]", caPath.c_str());
197 return "";
198 }
199
200 auto rehashedCertpath = REHASHD_CA_CERTS_DIR + OS_PATH_SEPARATOR + dirName;
201 if (access(rehashedCertpath.c_str(), F_OK) == -1) {
202 if (mkdir(rehashedCertpath.c_str(), S_IRWXU | S_IRWXG) == -1) {
203 NETMGR_LOG_E("Fail to make a rehased caCerts dir [%{public}d]", errno);
204 return "";
205 }
206 }
207
208 NETMGR_LOG_D("Build dir [%{public}s]", rehashedCertpath.c_str());
209 return rehashedCertpath;
210 }
211
GetRehasedCAPath(const std::string & caPath)212 std::string NetworkSecurityConfig::GetRehasedCAPath(const std::string &caPath)
213 {
214 if (access(REHASHD_CA_CERTS_DIR.c_str(), F_OK) == -1) {
215 return "";
216 }
217
218 auto dirName = GetRehashedCADirName(caPath);
219 if (dirName.empty()) {
220 return "";
221 }
222
223 auto rehashedCertpath = REHASHD_CA_CERTS_DIR + OS_PATH_SEPARATOR + dirName;
224 if (access(rehashedCertpath.c_str(), F_OK) == -1) {
225 return "";
226 }
227
228 return rehashedCertpath;
229 }
230
ReHashCAPathForX509(const std::string & caPath)231 std::string NetworkSecurityConfig::ReHashCAPathForX509(const std::string &caPath)
232 {
233 std::set<std::string> allFiles;
234 std::vector<std::string> caFiles;
235
236 GetCAFilesFromPath(caPath, caFiles);
237 if (caFiles.empty()) {
238 NETMGR_LOG_D("No customized CA certs.");
239 return "";
240 }
241
242 auto rehashedCertpath = BuildRehasedCAPath(caPath);
243 if (rehashedCertpath.empty()) {
244 return rehashedCertpath;
245 }
246
247 for (auto &caFile : caFiles) {
248 auto x509 = ReadCertFile(caFile);
249 if (x509 == nullptr) {
250 continue;
251 }
252
253 constexpr int X509_HASH_LEN = 16;
254 char buf[X509_HASH_LEN] = {0};
255 if (sprintf_s(buf, sizeof(buf), "%08lx", X509_subject_name_hash(x509)) < 0) {
256 return "";
257 }
258 X509_free(x509);
259 x509 = nullptr;
260
261 std::string hashName(buf);
262 AddSurfixToCACertFileName(rehashedCertpath, allFiles, hashName);
263
264 std::string rehashedCaFile = rehashedCertpath + OS_PATH_SEPARATOR + hashName;
265 if (access(rehashedCaFile.c_str(), F_OK) == 0) {
266 NETMGR_LOG_D("File [%{public}s] exists.", rehashedCaFile.c_str());
267 continue;
268 }
269
270 std::ifstream src(caFile);
271 std::ofstream dst(rehashedCaFile);
272 if (!src.is_open() || !dst.is_open()) {
273 NETMGR_LOG_E("fail to open cert file.");
274 continue;
275 }
276 dst << src.rdbuf();
277 NETMGR_LOG_D("Rehased cert generated. [%{public}s]", rehashedCaFile.c_str());
278 }
279
280 return rehashedCertpath;
281 }
282
CreateRehashedCertFiles()283 int32_t NetworkSecurityConfig::CreateRehashedCertFiles()
284 {
285 for (auto &cert : baseConfig_.trustAnchors_.certs_) {
286 ReHashCAPathForX509(cert);
287 }
288 for (auto &domainConfig : domainConfigs_) {
289 for (auto &cert : domainConfig.trustAnchors_.certs_) {
290 ReHashCAPathForX509(cert);
291 }
292 }
293
294 return NETMANAGER_SUCCESS;
295 }
296
ValidateDate(const std::string & dateStr)297 bool NetworkSecurityConfig::ValidateDate(const std::string &dateStr)
298 {
299 if (dateStr.empty()) {
300 return true;
301 }
302 std::tm tm = {};
303 std::istringstream ss(dateStr);
304 if (!(ss >> std::get_time(&tm, "%Y-%m-%d"))) {
305 return false;
306 }
307 time_t expiryTime = mktime(&tm);
308 if (expiryTime == -1) {
309 return false;
310 }
311 auto expiryPoint = std::chrono::system_clock::from_time_t(expiryTime);
312 auto nowPoint = std::chrono::system_clock::now();
313 if (nowPoint > expiryPoint) {
314 return false;
315 }
316 return true;
317 }
318
GetConfig()319 int32_t NetworkSecurityConfig::GetConfig()
320 {
321 std::string json;
322 auto ret = GetJsonFromBundle(json);
323 if (ret != NETMANAGER_SUCCESS) {
324 NETMGR_LOG_E("Get json failed.");
325 return ret;
326 }
327
328 ret = ParseJsonConfig(json);
329 if (ret != NETMANAGER_SUCCESS) {
330 return ret;
331 }
332
333 ret = CreateRehashedCertFiles();
334 if (ret != NETMANAGER_SUCCESS) {
335 return ret;
336 }
337
338 NETMGR_LOG_D("NetworkSecurityConfig Cached.");
339 return NETMANAGER_SUCCESS;
340 }
341
GetJsonProfile()342 __attribute__((no_sanitize("cfi"))) std::string NetworkSecurityConfig::GetJsonProfile()
343 {
344 void *handler = dlopen(LIB_LOAD_PATH.c_str(), RTLD_LAZY | RTLD_NODELETE);
345 if (handler == nullptr) {
346 NETMGR_LOG_E("load failed, failed reason : %{public}s", dlerror());
347 return "";
348 }
349 GetNetBundleClass getNetBundle = (GetNetBundleClass)dlsym(handler, "GetNetBundle");
350 if (getNetBundle == nullptr) {
351 NETMGR_LOG_E("GetNetBundle faild, failed reason : %{public}s", dlerror());
352 dlclose(handler);
353 return "";
354 }
355 auto netBundle = getNetBundle();
356 if (netBundle == nullptr) {
357 NETMGR_LOG_E("netBundle is nullptr");
358 dlclose(handler);
359 return "";
360 }
361 std::string jsonProfile;
362 auto ret = netBundle->GetJsonFromBundle(jsonProfile);
363 if (ret != NETMANAGER_SUCCESS) {
364 NETMGR_LOG_E("get profile failed");
365 dlclose(handler);
366 return "";
367 }
368 NETMGR_LOG_D("get profile success");
369 dlclose(handler);
370 return jsonProfile;
371 }
372
GetJsonFromBundle(std::string & jsonProfile)373 __attribute__((no_sanitize("cfi"))) int32_t NetworkSecurityConfig::GetJsonFromBundle(std::string &jsonProfile)
374 {
375 static std::string json = GetJsonProfile();
376 if (json.empty()) {
377 return NETMANAGER_ERR_INTERNAL;
378 }
379 jsonProfile = json;
380 return NETMANAGER_SUCCESS;
381 }
382
ParseJsonTrustAnchors(const cJSON * const root,TrustAnchors & trustAnchors)383 void NetworkSecurityConfig::ParseJsonTrustAnchors(const cJSON* const root, TrustAnchors &trustAnchors)
384 {
385 if (!cJSON_IsArray(root)) {
386 return;
387 }
388
389 uint32_t size = cJSON_GetArraySize(root);
390 for (uint32_t i = 0; i < size; i++) {
391 cJSON *trustAnchorsItem = cJSON_GetArrayItem(root, i);
392 cJSON *certificates = cJSON_GetObjectItem(trustAnchorsItem, TAG_CERTIFICATES.c_str());
393 std::string cert_path = cJSON_GetStringValue(certificates);
394 trustAnchors.certs_.push_back(cert_path);
395 }
396
397 return;
398 }
399
ParseJsonDomains(const cJSON * const root,std::vector<Domain> & domains)400 void NetworkSecurityConfig::ParseJsonDomains(const cJSON* const root, std::vector<Domain> &domains)
401 {
402 if (!cJSON_IsArray(root)) {
403 return;
404 }
405
406 uint32_t size = cJSON_GetArraySize(root);
407 for (uint32_t i = 0; i < size; i++) {
408 Domain domain;
409 cJSON *domainItem = cJSON_GetArrayItem(root, i);
410 cJSON *name = cJSON_GetObjectItem(domainItem, TAG_NAME.c_str());
411 if (name == nullptr || !cJSON_IsString(name)) {
412 continue;
413 }
414 domain.domainName_ = cJSON_GetStringValue(name);
415 NETMGR_LOG_D("domainName_: %{public}s", domain.domainName_.c_str());
416 cJSON *subDomains = cJSON_GetObjectItem(domainItem, TAG_INCLUDE_SUBDOMAINS.c_str());
417 if (subDomains != nullptr && cJSON_IsBool(subDomains)) {
418 domain.includeSubDomains_ = cJSON_IsTrue(subDomains);
419 NETMGR_LOG_D("includeSubDomains_: %{public}d", domain.includeSubDomains_);
420 } else {
421 domain.includeSubDomains_ = true;
422 }
423
424 domains.push_back(domain);
425 }
426
427 return;
428 }
429
ParseJsonPinSet(const cJSON * const root,PinSet & pinSet)430 void NetworkSecurityConfig::ParseJsonPinSet(const cJSON* const root, PinSet &pinSet)
431 {
432 if (root == nullptr) {
433 return;
434 }
435 cJSON *expiration = cJSON_GetObjectItem(root, TAG_EXPIRATION.c_str());
436 if (expiration != nullptr && cJSON_IsString(expiration)) {
437 pinSet.expiration_ = cJSON_GetStringValue(expiration);
438 NETMGR_LOG_D("expiration: %{public}s", pinSet.expiration_.c_str());
439 }
440 cJSON *pins = cJSON_GetObjectItem(root, TAG_PIN.c_str());
441 if (pins == nullptr || !cJSON_IsArray(pins)) {
442 return;
443 }
444 uint32_t size = cJSON_GetArraySize(pins);
445 for (uint32_t i = 0; i < size; i++) {
446 Pin pin;
447 cJSON *pinsItem = cJSON_GetArrayItem(pins, i);
448 cJSON *digestAlgorithm = cJSON_GetObjectItem(pinsItem, TAG_DIGEST_ALGORITHM.c_str());
449 if (digestAlgorithm == nullptr || !cJSON_IsString(digestAlgorithm)) {
450 continue;
451 }
452 pin.digestAlgorithm_ = cJSON_GetStringValue(digestAlgorithm);
453 NETMGR_LOG_D("digestAlgorithm: %{public}s", pin.digestAlgorithm_.c_str());
454 cJSON *digest = cJSON_GetObjectItem(pinsItem, TAG_DIGEST.c_str());
455 if (digest == nullptr || !cJSON_IsString(digest)) {
456 continue;
457 }
458 pin.digest_ = cJSON_GetStringValue(digest);
459 NETMGR_LOG_D("digest: %{public}s", pin.digest_.c_str());
460 pinSet.pins_.push_back(pin);
461 }
462 auto isOpenMode = cJSON_GetObjectItem(root, "openMode");
463 if (isOpenMode) {
464 pinSet.isOpenMode = cJSON_IsTrue(isOpenMode);
465 }
466 }
467
ParseJsonBaseConfig(const cJSON * const root,BaseConfig & baseConfig)468 void NetworkSecurityConfig::ParseJsonBaseConfig(const cJSON* const root, BaseConfig &baseConfig)
469 {
470 if (root == nullptr) {
471 return;
472 }
473
474 cJSON *trustAnchors = cJSON_GetObjectItem(root, TAG_TRUST_ANCHORS.c_str());
475 if (trustAnchors == nullptr) {
476 return;
477 }
478
479 ParseJsonTrustAnchors(trustAnchors, baseConfig.trustAnchors_);
480 }
481
ParseJsonDomainConfigs(const cJSON * const root,std::vector<DomainConfig> & domainConfigs)482 void NetworkSecurityConfig::ParseJsonDomainConfigs(const cJSON* const root, std::vector<DomainConfig> &domainConfigs)
483 {
484 if (!cJSON_IsArray(root)) {
485 return;
486 }
487 uint32_t size = cJSON_GetArraySize(root);
488 NETMGR_LOG_D("size: %{public}u", size);
489 for (uint32_t i = 0; i < size; i++) {
490 cJSON *domainConfigItem = cJSON_GetArrayItem(root, i);
491 DomainConfig domainConfig;
492 cJSON *domains = cJSON_GetObjectItem(domainConfigItem, TAG_DOMAINS.c_str());
493 ParseJsonDomains(domains, domainConfig.domains_);
494 cJSON *trustAnchors = cJSON_GetObjectItem(domainConfigItem, TAG_TRUST_ANCHORS.c_str());
495 ParseJsonTrustAnchors(trustAnchors, domainConfig.trustAnchors_);
496 cJSON *pinSet = cJSON_GetObjectItem(domainConfigItem, TAG_PIN_SET.c_str());
497 ParseJsonPinSet(pinSet, domainConfig.pinSet_);
498
499 domainConfigs.push_back(domainConfig);
500 }
501
502 return;
503 }
504
ParseJsonConfig(const std::string & content)505 int32_t NetworkSecurityConfig::ParseJsonConfig(const std::string &content)
506 {
507 if (content.empty()) {
508 return NETMANAGER_SUCCESS;
509 }
510
511 cJSON *root = cJSON_Parse(content.c_str());
512 if (root == nullptr) {
513 NETMGR_LOG_E("Failed to parse network json profile.");
514 return NETMANAGER_ERR_INTERNAL;
515 }
516
517 cJSON *networkSecurityConfig = cJSON_GetObjectItem(root, TAG_NETWORK_SECURITY_CONFIG.c_str());
518 if (networkSecurityConfig == nullptr) {
519 NETMGR_LOG_E("networkSecurityConfig is null");
520 cJSON_Delete(root);
521 return NETMANAGER_SUCCESS;
522 }
523 cJSON *baseConfig = cJSON_GetObjectItem(networkSecurityConfig, TAG_BASE_CONFIG.c_str());
524 cJSON *domainConfig = cJSON_GetObjectItem(networkSecurityConfig, TAG_DOMAIN_CONFIG.c_str());
525
526 ParseJsonBaseConfig(baseConfig, baseConfig_);
527 ParseJsonDomainConfigs(domainConfig, domainConfigs_);
528
529 cJSON_Delete(root);
530 return NETMANAGER_SUCCESS;
531 }
532
IsPinOpenMode(const std::string & hostname)533 bool NetworkSecurityConfig::IsPinOpenMode(const std::string &hostname)
534 {
535 if (hostname.empty()) {
536 return false;
537 }
538
539 PinSet *pPinSet = nullptr;
540 for (auto &domainConfig : domainConfigs_) {
541 for (const auto &domain : domainConfig.domains_) {
542 if (hostname == domain.domainName_) {
543 pPinSet = &domainConfig.pinSet_;
544 break;
545 } else if (domain.includeSubDomains_ && CommonUtils::UrlRegexParse(hostname, domain.domainName_)) {
546 pPinSet = &domainConfig.pinSet_;
547 break;
548 }
549 }
550 if (pPinSet != nullptr) {
551 break;
552 }
553 }
554
555 if (pPinSet == nullptr) {
556 return false;
557 }
558 return pPinSet->isOpenMode;
559 }
560
GetPinSetForHostName(const std::string & hostname,std::string & pins)561 int32_t NetworkSecurityConfig::GetPinSetForHostName(const std::string &hostname, std::string &pins)
562 {
563 if (hostname.empty()) {
564 NETMGR_LOG_E("Failed to get pinset, hostname is empty.");
565 return NETMANAGER_SUCCESS;
566 }
567
568 PinSet *pPinSet = nullptr;
569 for (auto &domainConfig : domainConfigs_) {
570 for (const auto &domain : domainConfig.domains_) {
571 if (hostname == domain.domainName_) {
572 pPinSet = &domainConfig.pinSet_;
573 break;
574 } else if (domain.includeSubDomains_ && CommonUtils::UrlRegexParse(hostname, domain.domainName_)) {
575 pPinSet = &domainConfig.pinSet_;
576 break;
577 }
578 }
579 if (pPinSet != nullptr) {
580 break;
581 }
582 }
583
584 if (pPinSet == nullptr) {
585 NETMGR_LOG_D("No pinned pubkey configured.");
586 return NETMANAGER_SUCCESS;
587 }
588
589 if (!ValidateDate(pPinSet->expiration_)) {
590 NETMGR_LOG_W("expiration date is invalid %{public}s", pPinSet->expiration_.c_str());
591 return NETMANAGER_SUCCESS;
592 }
593
594 std::stringstream ss;
595 for (const auto &pin : pPinSet->pins_) {
596 NETMGR_LOG_D("Got pinnned pubkey %{public}s", pin.digest_.c_str());
597 ss << pin.digestAlgorithm_ << "//" << pin.digest_ << ";";
598 }
599
600 pins = ss.str();
601 if (!pins.empty()) {
602 pins.pop_back();
603 }
604
605 return NETMANAGER_SUCCESS;
606 }
607
GetTrustAnchorsForHostName(const std::string & hostname,std::vector<std::string> & certs)608 int32_t NetworkSecurityConfig::GetTrustAnchorsForHostName(const std::string &hostname, std::vector<std::string> &certs)
609 {
610 if (hostname.empty()) {
611 NETMGR_LOG_E("Failed to get trust anchors, hostname is empty.");
612 return NETMANAGER_SUCCESS;
613 }
614
615 TrustAnchors *pTrustAnchors = nullptr;
616 for (auto &domainConfig: domainConfigs_) {
617 for (const auto &domain: domainConfig.domains_) {
618 if (hostname == domain.domainName_) {
619 pTrustAnchors = &domainConfig.trustAnchors_;
620 break;
621 } else if (domain.includeSubDomains_ && CommonUtils::UrlRegexParse(hostname, domain.domainName_)) {
622 pTrustAnchors = &domainConfig.trustAnchors_;
623 break;
624 }
625 }
626 if (pTrustAnchors != nullptr) {
627 break;
628 }
629 }
630
631 if (pTrustAnchors == nullptr) {
632 pTrustAnchors = &baseConfig_.trustAnchors_;
633 }
634
635 for (auto &certPath : pTrustAnchors->certs_) {
636 auto rehashedCertpath = GetRehasedCAPath(certPath);
637 if (!rehashedCertpath.empty()) {
638 certs.push_back(rehashedCertpath);
639 }
640 }
641
642 if (certs.empty()) {
643 NETMGR_LOG_D("No customized CA certs configured.");
644 }
645
646 return NETMANAGER_SUCCESS;
647 }
648
DumpConfigs()649 void NetworkSecurityConfig::DumpConfigs()
650 {
651 NETMGR_LOG_I("DumpConfigs:baseConfig_.trustAnchors_.certs");
652 for (auto &cert : baseConfig_.trustAnchors_.certs_) {
653 NETMGR_LOG_I("[%{public}s]", cert.c_str());
654 }
655
656 NETMGR_LOG_I("DumpConfigs:domainConfigs_");
657 for (auto &domainConfig : domainConfigs_) {
658 NETMGR_LOG_I("=======================");
659 for (auto &domain : domainConfig.domains_) {
660 NETMGR_LOG_I("domainConfigs_.domains_[%{public}s][%{public}s]", domain.domainName_.c_str(),
661 domain.includeSubDomains_ ? "include_subDomain" : "not_include_subDomain");
662 }
663 NETMGR_LOG_I("domainConfigs_.domains_.pinSet_.expiration_[%{public}s]",
664 domainConfig.pinSet_.expiration_.c_str());
665 for (auto &pin : domainConfig.pinSet_.pins_) {
666 NETMGR_LOG_I("domainConfigs_.domains_.pinSet_.pins[%{public}s][%{public}s]", pin.digestAlgorithm_.c_str(),
667 pin.digest_.c_str());
668 }
669 for (auto &cert : domainConfig.trustAnchors_.certs_) {
670 NETMGR_LOG_I("domainConfigs_.domains_.trustAnchors_.certs_[%{public}s]", cert.c_str());
671 }
672 }
673 }
674
675 } // namespace NetManagerStandard
676 } // namespace OHOS
677