2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file injected_bundle_decryption_support.cpp
18 * @author Jihoon Chung (jihoon.chung@samsung.com)
22 #include "injected_bundle_decryption_support.h"
28 #include <ss_manager.h>
29 #include <openssl/sha.h>
30 #include <openssl/hmac.h>
31 #include <openssl/evp.h>
32 #include <openssl/bio.h>
33 #include <openssl/buffer.h>
35 #include <dpl/log/log.h>
36 #include <dpl/assert.h>
37 #include <dpl/string.h>
38 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
39 #include <dpl/wrt-dao-ro/global_config.h>
40 #include <dpl/utils/mime_type_utils.h>
42 namespace InjectedBundle {
44 const char * const SCHEME_FILE_SLASH = "file://";
45 const char * const DATA_STRING = "data:";
46 const char * const BASE64_STRING = ";base64,";
47 const char QUESTION_MARK = '?';
48 const char ASTERISK_MARK = '#';
51 //Implementation class
52 class DecryptionSupportImplementation
57 WrtDB::TizenAppId m_appId;
58 WrtDB::EncryptedFileList m_encryptedFiles;
60 std::set<WrtDB::EncryptedFileInfo>::iterator m_targetIt;
62 WrtDB::TizenPkgId m_pkgId;
65 std::string getFilePath(const std::string& url)
67 std::string filePath = url;
69 size_t pos = filePath.find_first_not_of(SCHEME_FILE_SLASH);
70 if (pos != std::string::npos) {
71 filePath = filePath.substr(pos - 1);
74 pos = filePath.find_first_of(ASTERISK_MARK);
75 if (pos != std::string::npos) {
76 filePath = filePath.substr(0, pos);
79 pos = filePath.find_first_of(QUESTION_MARK);
80 if (pos != std::string::npos) {
81 filePath = filePath.substr(0, pos);
87 int ssmDecrypt(const std::string pkgId, const char* inBuf, int inSize, char** outBuf, int* outSize)
90 return ssm_decrypt_preloaded_application(inBuf, inSize, outBuf,
93 return ssm_decrypt(pkgId.c_str(), pkgId.length(), inBuf, inSize, outBuf, outSize);
97 std::string doDecrypt(std::string filePath, int size)
100 if (0 == stat(filePath.c_str(), &buf)) {
101 const std::size_t fileSize = buf.st_size;
102 std::unique_ptr<unsigned char[]> inChunk;
104 FILE* fp = fopen(filePath.c_str(), "rb");
106 LogDebug("Couldnot open file : " << filePath);
107 return std::string();
110 std::unique_ptr<unsigned char[]> DecryptedString(new unsigned
112 std::string pkgid(DPL::ToUTF8String(m_pkgId));
116 unsigned char getDecSize[4];
117 memset(getDecSize, 0x00, sizeof(getDecSize));
119 size_t readSize = fread(getDecSize, sizeof(unsigned char), sizeof(getDecSize), fp);
121 unsigned int readBufSize = 0;
122 std::istringstream(std::string((char*)getDecSize)) >> readBufSize;
123 inChunk.reset(new unsigned char[readBufSize]);
125 size_t decReadSize = fread(inChunk.get(), sizeof(unsigned char), readBufSize, fp);
127 if (0 != decReadSize) {
128 char *outChunk = NULL;
130 if (0 != ssmDecrypt(pkgid, (char*)inChunk.get(), (int)decReadSize, &outChunk, &outSize))
132 LogError("Failed to get decrypted resource");
134 return std::string();
136 memcpy(DecryptedString.get() + writeCount, outChunk, outSize);
137 writeCount += outSize;
140 } while( 0 == std::feof(fp));
142 memset(DecryptedString.get() + size, '\n', fileSize - size);
143 LogDebug("resource need to encoding base64");
147 b64 = BIO_new(BIO_f_base64());
148 bmem = BIO_new(BIO_s_mem());
149 b64 = BIO_push(b64, bmem);
150 BIO_write(b64, DecryptedString.get(), fileSize);
152 BIO_get_mem_ptr(b64, &bptr);
154 std::string base64Enc((char *)bptr->data, bptr->length - 1);
159 return std::string();
163 DecryptionSupportImplementation() :
164 m_initialized(false),
165 m_isEncrypted(false),
170 void initialize(WrtDB::TizenAppId appId)
172 LogInfo("initialize");
175 WrtDB::WidgetDAOReadOnly dao(m_appId);
176 dao.getEncryptedFileList(m_encryptedFiles);
177 if (!m_encryptedFiles.empty()) {
178 m_isEncrypted = true;
179 LogDebug("encrypted application");
181 m_pkgId = dao.getTzPkgId();
183 std::string installedPath =
184 DPL::ToUTF8String(*dao.getWidgetInstalledPath());
185 std::string preloadPath(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath());
186 if (0 == installedPath.compare(0, preloadPath.length(), preloadPath)) {
188 LogDebug("preload application");
191 m_initialized = true;
194 void deinitialize(void)
196 LogInfo("deinitialize");
198 m_encryptedFiles.clear();
199 m_targetIt = m_encryptedFiles.end();
200 m_isEncrypted = false;
201 m_appId = DPL::String(L"");
202 m_initialized = false;
205 bool isNeedDecryption(std::string url)
207 if (!m_initialized) {
208 LogInfo("not initialize");
212 if (0 != strncmp(url.c_str(), SCHEME_FILE_SLASH, strlen(SCHEME_FILE_SLASH))) {
216 std::set<WrtDB::EncryptedFileInfo>::iterator it;
217 WrtDB::EncryptedFileInfo info;
218 std::string filePath = getFilePath(url);
219 info.fileName = DPL::FromUTF8String(filePath);
220 if (m_encryptedFiles.end() != (it = m_encryptedFiles.find(info))) {
221 LogDebug(" info file name : " << it->fileName);
222 LogDebug(" info file size : " << it->fileSize);
229 std::string decryptResource(std::string url)
231 if (!m_initialized) {
232 LogInfo("not initialize");
233 return std::string();
236 std::string filePath = getFilePath(url);
237 if (filePath != DPL::ToUTF8String(m_targetIt->fileName)) {
238 if (!isNeedDecryption(filePath)) {
239 return std::string();
243 std::string decryptString =
244 doDecrypt(DPL::ToUTF8String(m_targetIt->fileName),
245 m_targetIt->fileSize);
246 if (!decryptString.empty()) {
247 std::string destString = DATA_STRING;
249 std::string mimeString =
251 MimeTypeUtils::identifyFileMimeType(
252 DPL::FromUTF8String(url)));
254 destString += mimeString;
255 destString += BASE64_STRING;
257 decryptString.insert(0, destString);
259 return decryptString;
263 DecryptionSupport::DecryptionSupport() :
264 m_impl(new DecryptionSupportImplementation)
268 DecryptionSupport::~DecryptionSupport()
272 void DecryptionSupport::initialize(WrtDB::TizenAppId appId)
274 m_impl->initialize(appId);
277 void DecryptionSupport::deinitialize(void)
279 m_impl->deinitialize();
282 bool DecryptionSupport::isNeedDecryption(std::string url)
284 return m_impl->isNeedDecryption(url);
287 std::string DecryptionSupport::decryptResource(std::string url)
289 return m_impl->decryptResource(url);
291 } // namespace InjectedBundle