Combine Signature Steps
[platform/core/appfw/app-installers.git] / src / common / step / security / step_signature.cc
1 // Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/security/step_signature.h"
6
7 #include <pkgmgr_installer.h>
8
9 #include <cassert>
10 #include <cstdlib>
11 #include <string>
12
13 #include "common/certificate_validation.h"
14
15 namespace bf = boost::filesystem;
16 namespace ci = common_installer;
17
18 namespace {
19
20 pkgmgr_privilege_level ConvertToPkgmgrPrivilegeLevel(ci::PrivilegeLevel level) {
21   pkgmgr_privilege_level pkgmgr_level;
22
23   switch (level) {
24     case ci::PrivilegeLevel::UNTRUSTED:
25       pkgmgr_level = PM_PRIVILEGE_UNTRUSTED;
26       break;
27     case ci::PrivilegeLevel::PUBLIC:
28       pkgmgr_level = PM_PRIVILEGE_PUBLIC;
29       break;
30     case ci::PrivilegeLevel::PARTNER:
31       pkgmgr_level = PM_PRIVILEGE_PARTNER;
32       break;
33     case ci::PrivilegeLevel::PLATFORM:
34       pkgmgr_level = PM_PRIVILEGE_PLATFORM;
35       break;
36     default:
37       pkgmgr_level = PM_PRIVILEGE_UNKNOWN;
38   }
39
40   return pkgmgr_level;
41 }
42
43 }  // namespace
44
45 namespace common_installer {
46 namespace security {
47
48 Step::Status StepSignature::precheck() {
49   if (context_->unpacked_dir_path.get().empty()) {
50     LOG(ERROR) << "unpacked_dir_path attribute is empty";
51     return Step::Status::INVALID_VALUE;
52   }
53   if (!boost::filesystem::exists(context_->unpacked_dir_path.get())) {
54     LOG(ERROR) << "unpacked_dir_path ("
55                << context_->unpacked_dir_path.get()
56                << ") path does not exist";
57     return Step::Status::INVALID_VALUE;
58   }
59
60   if (save_signature_ && context_->pkgid.get().empty())
61     return Step::Status::INVALID_VALUE;
62
63   return Step::Status::OK;
64 }
65
66 boost::filesystem::path StepSignature::GetSignatureRoot() const {
67   return context_->unpacked_dir_path.get();
68 }
69
70 Step::Status StepSignature::CheckPrivilegeLevel(PrivilegeLevel level) {
71   std::string error_message;
72   if (!context_->is_readonly_package.get()) {
73     if (!ValidatePrivilegeLevel(level, context_->uid.get(),
74         context_->manifest_data.get()->api_version,
75         context_->manifest_data.get()->privileges, &error_message)) {
76       if (!error_message.empty()) {
77         LOG(ERROR) << "error_message: " << error_message;
78         on_error(Status::SIGNATURE_ERROR, error_message);
79       }
80       return Status::SIGNATURE_ERROR;
81     }
82   }
83   return Status::OK;
84 }
85
86 Step::Status StepSignature::process() {
87   signature_ = std::unique_ptr<Signature>(
88       new Signature(context_->request_type.get(),
89                     context_->pkgid.get(),
90                     context_->is_readonly_package.get(),
91                     context_->skip_check_reference.get(),
92                     &context_->certificate_info.get()));
93   PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
94   std::string error_message;
95   if (!signature_->GetPrivilegeLevel(GetSignatureRoot(),
96       &level, error_message)) {
97     on_error(Status::CERT_ERROR, error_message);
98     return Status::CERT_ERROR;
99   }
100
101   if (level == PrivilegeLevel::UNTRUSTED) {
102     std::string error_message =
103         "Unsigned applications can not be installed";
104     on_error(Status::CERT_ERROR, error_message);
105     return Status::SIGNATURE_ERROR;
106   }
107
108   LOG(INFO) << "Privilege level: " << PrivilegeLevelToString(level);
109   context_->privilege_level.set(level);
110
111   pkgmgr_installer_set_privilege_level(ConvertToPkgmgrPrivilegeLevel(level));
112
113   Status status = CheckPrivilegeLevel(level);
114   if (status != Status::OK)
115     return status;
116
117   if (!signature_->CheckMetadataPrivilege(level, context_->manifest_data.get(),
118                                           error_message)) {
119     if (!error_message.empty()) {
120       LOG(ERROR) << "error_message: " << error_message;
121       on_error(Status::SIGNATURE_ERROR, error_message);
122     }
123     return Status::SIGNATURE_ERROR;
124   }
125
126   if (save_signature_) {
127     if (!signature_->SaveSignature(context_->unpacked_dir_path.get()))
128       return Step::Status::OK;
129   }
130
131   return Step::Status::OK;
132 }
133
134 Step::Status StepSignature::undo() {
135   bf::remove(signature_->GetFilePath());
136   if (bf::exists(signature_->GetBackupPath()))
137     bf::rename(signature_->GetBackupPath(), signature_->GetFilePath());
138
139   return Step::Status::OK;
140 }
141
142 Step::Status StepSignature::clean() {
143   if (bf::exists(signature_->GetBackupPath()))
144     bf::remove(signature_->GetBackupPath());
145
146   return Step::Status::OK;
147 }
148
149 }  // namespace security
150 }  // namespace common_installer