Add StepSaveSignature step
[platform/core/appfw/app-installers.git] / src / common / step / security / step_recover_signature.cc
1 // Copyright (c) 2016 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_recover_signature.h"
6
7 #include <boost/filesystem/path.hpp>
8
9 #include <string>
10
11 #include "common/certificate_validation.h"
12 #include "common/utils/file_util.h"
13
14 namespace bf = boost::filesystem;
15
16 namespace {
17
18 bf::path GetSignatureFilePath(bool is_readonly) {
19   return bf::path((is_readonly) ?
20       tzplatform_getenv(TZ_SYS_RO_SHARE) : tzplatform_getenv(TZ_SYS_SHARE)) /
21           "signature";
22 }
23
24 bool RecoverSignatureFile(const std::string& pkgid, bool is_readonly) {
25   bf::path path = GetSignatureFilePath(is_readonly);
26   bf::path target_path = bf::path(path) / std::string(pkgid + ".txt");
27   bf::path backup_path = bf::path(path) / std::string(pkgid + "_backup.txt");
28
29   if (bf::exists(backup_path) &&
30       !common_installer::MoveFile(backup_path, target_path, true))
31     return false;
32
33   return true;
34 }
35
36 }  // namespace
37
38 namespace common_installer {
39 namespace security {
40
41 Step::Status StepRecoverSignature::RecoveryNew() {
42   bf::path path = GetSignatureFilePath(context_->is_readonly_package.get());
43   path /= std::string(context_->pkgid.get() + ".txt");
44   if (!common_installer::Remove(path))
45     return Status::CERT_ERROR;
46
47   return Status::OK;
48 }
49
50 Step::Status StepRecoverSignature::RecoveryUpdate() {
51   std::string error_message;
52   PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
53   if (!ValidateSignatures(GetSignatureRoot(), &level,
54                          &context_->certificate_info.get(), false,
55                          &error_message)) {
56     LOG(ERROR) << "Failed to verify signature: " << error_message;
57     return Status::CERT_ERROR;
58   }
59
60   if (level == PrivilegeLevel::UNTRUSTED) {
61     // if priv level is untrusted, get priv level from backed up signature file
62     if (!GetSignatureFromFile(context_->pkgid.get(),
63         context_->is_readonly_package.get(), &level,
64         &context_->certificate_info.get())) {
65       LOG(INFO) << "Unable to get privilege level from file";
66       return Status::CERT_ERROR;
67     }
68   }
69
70   if (!RecoverSignatureFile(context_->pkgid.get(),
71                             context_->is_readonly_package.get()))
72     return Status::CERT_ERROR;
73
74   context_->privilege_level.set(level);
75   return Status::OK;
76 }
77
78 Step::Status StepRecoverSignature::RecoveryReadonlyUpdateInstall() {
79   std::string error_message;
80   PrivilegeLevel level = PrivilegeLevel::PLATFORM;
81   bf::path signature_root =
82       bf::path(GetRootAppPath(context_->is_readonly_package.get(),
83           context_->uid.get())) / context_->pkgid.get();
84   if (!ValidateSignatures(signature_root, &level,
85                          &context_->certificate_info.get(), false,
86                          &error_message)) {
87     LOG(ERROR) << "Failed to verify signature: " << error_message;
88     return Status::CERT_ERROR;
89   }
90
91   if (level == PrivilegeLevel::UNTRUSTED) {
92     if (!GetSignatureFromFile(context_->pkgid.get(),
93         context_->is_readonly_package.get(), &level,
94         &context_->certificate_info.get())) {
95       LOG(INFO) << "Unable to get privilege level from file";
96       return Status::CERT_ERROR;
97     }
98   }
99
100   if (!RecoverSignatureFile(context_->pkgid.get(), false))
101     return Status::CERT_ERROR;
102
103   context_->privilege_level.set(level);
104   return Status::OK;
105 }
106
107 }  // namespace security
108 }  // namespace common_installer