1 // Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/step/security/step_register_trust_anchor.h"
7 #include <trust-anchor.h>
12 #include "common/utils/file_util.h"
14 namespace common_installer {
17 namespace fs = std::filesystem;
21 const char kTpkTrustAnchorPath[] = "res/.trust-anchor";
22 const char kWgtTrustAnchorPath[] = ".trust-anchor";
23 const char kWgt[] = "wgt";
25 bool RemoveWgtTrustAnchorSymLinks(const fs::path& path) {
26 for (fs::directory_iterator file(path);
27 file != fs::directory_iterator(); ++file) {
28 fs::path current(file->path());
29 if (fs::is_symlink(symlink_status(current)) &&
38 StepRegisterTrustAnchor::StepRegisterTrustAnchor(
39 InstallerContext* context, RegisterType register_type)
41 register_type_(register_type) {
44 Step::Status StepRegisterTrustAnchor::precheck() {
45 if (context_->GetPkgPath().empty()) {
46 LOG(ERROR) << "pkg path is empty";
47 return Step::Status::INVALID_VALUE;
50 if (!context_->manifest_data.get()) {
51 LOG(ERROR) << "manifest_data attribute is empty";
52 return Step::Status::INVALID_VALUE;
55 return Step::Status::OK;
58 Step::Status StepRegisterTrustAnchor::process() {
60 fs::path pkg_certs_path = context_->GetPkgPath() / kTpkTrustAnchorPath;
61 manifest_x* manifest = context_->manifest_data.get();
63 if (register_type_ == RegisterType::UPDATE) {
64 ret = trust_anchor_uninstall(context_->pkgid.get().c_str(),
66 if (ret != TRUST_ANCHOR_ERROR_NONE) {
67 LOG(ERROR) << "Failed to unregister trust anchor. error : " << ret;
68 return Step::Status::SECURITY_ERROR;
71 if (!context_->partial_rw.get() &&
72 !context_->pkg_type.get().compare(kWgt)) {
73 if (fs::exists(pkg_certs_path) &&
74 !RemoveWgtTrustAnchorSymLinks(pkg_certs_path))
75 return Step::Status::APP_DIR_ERROR;
79 if (!manifest->use_system_certs)
80 return Step::Status::OK;
82 if (!context_->pkg_type.get().compare(kWgt) &&
83 (context_->request_type.get() != RequestType::ManifestPartialInstall &&
84 context_->request_type.get() != RequestType::ManifestPartialUpdate &&
85 context_->request_type.get() != RequestType::PartialUninstall &&
86 context_->request_type.get() != RequestType::ReadonlyUpdateUninstall)) {
88 // create [pkg_root]/res/.trust-anchor directory and create symbolic link
89 if (!common_installer::CreateDir(pkg_certs_path))
90 return Step::Status::APP_DIR_ERROR;
92 fs::path pkg_certs_src_path =
93 context_->GetPkgPath() / "res/wgt" / kWgtTrustAnchorPath;
94 for (fs::directory_iterator file(pkg_certs_src_path);
95 file != fs::directory_iterator(); ++file) {
96 fs::path current(file->path());
98 fs::create_symlink(current, pkg_certs_path / current.filename());
99 } catch (const fs::filesystem_error& error) {
100 LOG(ERROR) << "Failed to make trust anchor symlink : " << error.what();
101 return Step::Status::APP_DIR_ERROR;
106 ret = trust_anchor_install(context_->pkgid.get().c_str(),
107 context_->uid.get(), pkg_certs_path.c_str(),
108 (strcasecmp(manifest->use_system_certs, "true") == 0) ? true : false);
110 if (ret != TRUST_ANCHOR_ERROR_NONE) {
111 LOG(ERROR) << "Failed to register trust anchor. error : " << ret;
112 return Step::Status::SECURITY_ERROR;
115 return Step::Status::OK;
118 Step::Status StepRegisterTrustAnchor::undo() {
119 manifest_x* manifest = context_->manifest_data.get();
121 return Step::Status::SECURITY_ERROR;
123 if (!manifest->use_system_certs)
124 return Step::Status::OK;
126 int ret = trust_anchor_uninstall(context_->pkgid.get().c_str(),
127 context_->uid.get());
128 if (ret != TRUST_ANCHOR_ERROR_NONE) {
129 LOG(ERROR) << "Failed to unregister trust anchor. error : " << ret;
130 return Step::Status::SECURITY_ERROR;
133 // Re-registration of trust anchor with previous value
134 // should be performed after rollback files.
136 return Step::Status::OK;
139 } // namespace security
140 } // namespace common_installer