6c7abdd5303dc8e54e656dc5cf3c219b734e9224
[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 #include "common/utils/file_util.h"
15
16 namespace bf = boost::filesystem;
17 namespace ci = common_installer;
18
19 namespace {
20
21 pkgmgr_privilege_level ConvertToPkgmgrPrivilegeLevel(ci::PrivilegeLevel level) {
22   pkgmgr_privilege_level pkgmgr_level;
23
24   switch (level) {
25     case ci::PrivilegeLevel::UNTRUSTED:
26       pkgmgr_level = PM_PRIVILEGE_UNTRUSTED;
27       break;
28     case ci::PrivilegeLevel::PUBLIC:
29       pkgmgr_level = PM_PRIVILEGE_PUBLIC;
30       break;
31     case ci::PrivilegeLevel::PARTNER:
32       pkgmgr_level = PM_PRIVILEGE_PARTNER;
33       break;
34     case ci::PrivilegeLevel::PLATFORM:
35       pkgmgr_level = PM_PRIVILEGE_PLATFORM;
36       break;
37     default:
38       pkgmgr_level = PM_PRIVILEGE_UNKNOWN;
39   }
40
41   return pkgmgr_level;
42 }
43
44 }  // namespace
45
46 namespace common_installer {
47 namespace security {
48
49 Step::Status StepSignature::precheck() {
50   if (context_->unpacked_dir_path.get().empty()) {
51     LOG(ERROR) << "unpacked_dir_path attribute is empty";
52     return Step::Status::INVALID_VALUE;
53   }
54   if (!boost::filesystem::exists(context_->unpacked_dir_path.get())) {
55     LOG(ERROR) << "unpacked_dir_path ("
56                << context_->unpacked_dir_path.get()
57                << ") path does not exist";
58     return Step::Status::INVALID_VALUE;
59   }
60
61   if (save_signature_ && context_->pkgid.get().empty())
62     return Step::Status::INVALID_VALUE;
63
64   return Step::Status::OK;
65 }
66
67 boost::filesystem::path StepSignature::GetSignatureRoot() const {
68   return context_->unpacked_dir_path.get();
69 }
70
71 Step::Status StepSignature::CheckPrivilegeLevel(PrivilegeLevel level) {
72   std::string error_message;
73   if (!context_->is_readonly_package.get()) {
74     if (!ValidatePrivilegeLevel(level, context_->uid.get(),
75         context_->manifest_data.get()->api_version,
76         context_->manifest_data.get()->privileges, &error_message)) {
77       if (!error_message.empty()) {
78         LOG(ERROR) << "error_message: " << error_message;
79         on_error(Status::SIGNATURE_ERROR, error_message);
80       }
81       return Status::SIGNATURE_ERROR;
82     }
83   }
84   return Status::OK;
85 }
86
87 Step::Status StepSignature::process() {
88   signature_ = std::unique_ptr<Signature>(
89       new Signature(context_->request_type.get(),
90                     context_->pkgid.get(),
91                     context_->is_readonly_package.get(),
92                     context_->skip_check_reference.get(),
93                     &context_->certificate_info.get()));
94   PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
95   std::string error_message;
96   if (!signature_->GetPrivilegeLevel(GetSignatureRoot(),
97       &level, &error_message)) {
98     on_error(Status::CERT_ERROR, error_message);
99     return Status::CERT_ERROR;
100   }
101
102   if (level == PrivilegeLevel::UNTRUSTED) {
103     error_message = "Unsigned applications can not be installed";
104     on_error(Status::SIGNATURE_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   Remove(signature_->GetBackupPath());
144
145   return Step::Status::OK;
146 }
147
148 }  // namespace security
149 }  // namespace common_installer