1 // Copyright (c) 2015 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 "wgt/step/encryption/step_encrypt_resources.h"
7 #include <web_app_enc.h>
9 #include <boost/filesystem/operations.hpp>
10 #include <boost/system/error_code.hpp>
12 #include <common/utils/file_util.h>
14 #include <manifest_parser/utils/logging.h>
24 const std::set<std::string> encryptSet { ".html", ".htm", ".css", ".js"};
30 namespace encryption {
32 namespace bf = boost::filesystem;
33 namespace bs = boost::system;
35 common_installer::Step::Status StepEncryptResources::precheck() {
36 backend_data_ = static_cast<WgtBackendData*>(context_->backend_data.get());
38 LOG(ERROR) << "no backend data";
39 return common_installer::Step::Status::ERROR;
45 LOG(ERROR) << "unpacked_dir_path attribute is empty";
46 return Step::Status::INVALID_VALUE;
48 if (!bf::exists(input_)) {
49 LOG(ERROR) << "unpacked_dir_path (" << input_ << ") path does not exist";
50 return Step::Status::INVALID_VALUE;
53 return common_installer::Step::Status::OK;
56 common_installer::Step::Status StepEncryptResources::process() {
57 if (!backend_data_->settings.get().encryption_enabled()) {
58 LOG(DEBUG) << "no encryption";
59 return common_installer::Step::Status::OK;
61 LOG(DEBUG) << "Encrypting";
63 if (!Encrypt(input_)) {
64 LOG(ERROR) << "Error during encryption";
65 return common_installer::Step::Status::ERROR;
68 return common_installer::Step::Status::OK;
71 bool StepEncryptResources::Encrypt(const bf::path &src) {
72 // traversing through src dir (recurrence if subdir found)
73 // for every file found, check if it should be encrypted (ToBeEncrypted)
74 // if yes, encrypt it (and replace original one)
76 for (bf::directory_iterator file(src);
77 file != bf::directory_iterator();
79 bs::error_code error_code;
80 bf::path current(file->path());
82 bool is_dir = bf::is_directory(current, error_code);
86 if (!Encrypt(current))
91 bool is_sym = bf::is_symlink(current, error_code);
95 continue; // TODO(p.sikorski) is it enough?
97 // it is regular file (not dir, not symlink)
98 if (ToBeEncrypted(current)) {
99 LOG(INFO) << "File for encryption: " << current;
100 if (!EncryptFile(current))
107 bool StepEncryptResources::EncryptFile(const bf::path &src) {
108 FILE *input = fopen(src.string().c_str(), "rb");
110 LOG(ERROR) << "Cannot open file for encryption: " << src;
115 fseek(input , 0 , SEEK_END);
116 size_t length = ftell(input);
118 // don't encrypt empty files because libwebappenc doesn't support it
126 char *input_buffer = new char[length];
127 if (length != fread(input_buffer, sizeof(char), length, input)) {
128 LOG(ERROR) << "Read error, file: " << src;
130 delete []input_buffer;
135 unsigned char* encrypted_data = nullptr;
136 size_t enc_data_len = 0;
137 // TODO(p.sikorski) check if it is Preloaded
139 if (context_->request_mode.get() == common_installer::RequestMode::GLOBAL)
140 ret = wae_encrypt_global_web_application(
141 context_->pkgid.get().c_str(),
142 context_->is_preload_request.get() ?
144 reinterpret_cast<const unsigned char*>(input_buffer),
149 ret = wae_encrypt_web_application(
151 context_->pkgid.get().c_str(),
152 reinterpret_cast<const unsigned char*>(input_buffer),
156 delete []input_buffer;
157 if (WAE_ERROR_NONE != ret) {
159 case WAE_ERROR_INVALID_PARAMETER:
160 LOG(ERROR) << "Error during encrypting: WAE_ERROR_INVALID_PARAMETER";
162 case WAE_ERROR_PERMISSION_DENIED:
163 LOG(ERROR) << "Error during encrypting: WAE_ERROR_PERMISSION_DENIED";
165 case WAE_ERROR_NO_KEY:
166 LOG(ERROR) << "Error during encrypting: WAE_ERROR_NO_KEY";
168 case WAE_ERROR_KEY_MANAGER:
169 LOG(ERROR) << "Error during encrypting: WAE_ERROR_KEY_MANAGER";
171 case WAE_ERROR_CRYPTO:
172 LOG(ERROR) << "Error during encrypting: WAE_ERROR_CRYPTO";
174 case WAE_ERROR_UNKNOWN:
175 LOG(ERROR) << "Error during encrypting: WAE_ERROR_UNKNOWN";
178 LOG(ERROR) << "Error during encrypting: UNKNOWN";
184 // original file is treated as destination!
185 FILE *output = fopen(src.string().c_str(), "wb");
187 LOG(ERROR) << "Cannot create encrypted file: " << src;
188 free(encrypted_data);
192 if (enc_data_len != fwrite(reinterpret_cast<const char*>(encrypted_data),
196 LOG(ERROR) << "Write error, file: " << src;
197 free(encrypted_data);
204 free(encrypted_data);
208 void StepEncryptResources::SetEncryptionRoot() {
209 input_ = context_->unpacked_dir_path.get();
212 bool StepEncryptResources::ToBeEncrypted(const bf::path &file) {
213 size_t found_key = file.string().rfind(".");
214 if (std::string::npos != found_key) {
215 std::string mimeType = file.string().substr(found_key);
216 std::transform(mimeType.begin(), mimeType.end(), mimeType.begin(),
218 return encryptSet.count(mimeType) > 0;
223 } // namespace encryption