[Keymanager] Implementation merged from tizen_2.4_tv
[platform/core/api/webapi-plugins.git] / src / keymanager / keymanager_instance.cc
old mode 100644 (file)
new mode 100755 (executable)
index fd9e491..1493d40
-// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
 
 #include "keymanager/keymanager_instance.h"
 
-#include <functional>
-#include <ckm/ckm-manager.h>
+#include <ckmc/ckmc-manager.h>
 #include <glib.h>
-#include <pcrecpp.h>
-#include <fstream>
+#include <pkgmgr-info.h>
 
 #include "common/logger.h"
-#include "common/picojson.h"
+#include "common/optional.h"
 #include "common/platform_result.h"
+#include "common/scope_exit.h"
+#include "common/task-queue.h"
+#include "common/tools.h"
+#include "common/current_application.h"
 
 namespace extension {
 namespace keymanager {
 
+using common::ErrorCode;
+using common::optional;
+using common::PlatformResult;
+using common::TaskQueue;
+
 namespace {
-const char* kTypeRSA = "RSA";
-const char* kTypeECDSA = "ECDSA";
+
+typedef std::vector<unsigned char> RawBuffer;
+
+typedef int (*AliasListFunction)(ckmc_alias_list_s**);
+
+void GetGenericAliasList(AliasListFunction func, picojson::object* out) {
+  LoggerD("Enter");
+
+  ckmc_alias_list_s* alias_list = nullptr;
+  int ret = func(&alias_list);
+
+  picojson::value result{picojson::array{}};
+
+  if (CKMC_ERROR_NONE == ret) {
+    auto& aliases = result.get<picojson::array>();
+
+    picojson::value resultElem = picojson::value(picojson::object());
+    picojson::object& obj = resultElem.get<picojson::object>();
+    ckmc_alias_list_s* head = alias_list;
+
+    while (head) {
+      //aliases.push_back(picojson::value(head->alias ? head->alias : ""));
+      if(head->alias) {
+        char* tokenized = strtok(head->alias," ");
+        obj["packageId"] = picojson::value(tokenized);
+        tokenized = strtok(NULL," ");
+        obj["name"] = picojson::value(tokenized);
+
+        aliases.push_back(resultElem);
+      }
+
+      head = head->next;
+    }
+
+    if (alias_list) {
+      ckmc_alias_list_all_free(alias_list);
+    }
+  }
+
+  common::tools::ReportSuccess(result, *out);
 }
+}  // namespace
 
 KeyManagerInstance::KeyManagerInstance() {
+  LoggerD("Enter");
   using std::placeholders::_1;
   using std::placeholders::_2;
 
-  RegisterSyncHandler("KeyManager_getKeyAliasList",
-      std::bind(&KeyManagerInstance::GetKeyAliasList, this, _1, _2));
-  RegisterSyncHandler("KeyManager_getCertificatesAliasList",
-      std::bind(&KeyManagerInstance::GetCertificateAliasList, this, _1, _2));
   RegisterSyncHandler("KeyManager_getDataAliasList",
       std::bind(&KeyManagerInstance::GetDataAliasList, this, _1, _2));
-  RegisterSyncHandler("KeyManager_getKey",
-      std::bind(&KeyManagerInstance::GetKey, this, _1, _2));
-  RegisterSyncHandler("KeyManager_saveKey",
-      std::bind(&KeyManagerInstance::SaveKey, this, _1, _2));
-  RegisterSyncHandler("KeyManager_removeKey",
-      std::bind(&KeyManagerInstance::RemoveKey, this, _1, _2));
-  RegisterSyncHandler("KeyManager_generateKeyPair",
-      std::bind(&KeyManagerInstance::GenerateKeyPair, this, _1, _2));
-  RegisterSyncHandler("KeyManager_getCertificate",
-      std::bind(&KeyManagerInstance::GetCertificate, this, _1, _2));
-  RegisterSyncHandler("KeyManager_saveCertificate",
-      std::bind(&KeyManagerInstance::SaveCertificate, this, _1, _2));
-  RegisterSyncHandler("KeyManager_loadCertificateFromFile",
-      std::bind(&KeyManagerInstance::LoadCertificateFromFile, this, _1, _2));
-}
 
-KeyManagerInstance::~KeyManagerInstance() {
-}
+  RegisterSyncHandler("KeyManager_saveData",
+      std::bind(&KeyManagerInstance::SaveData, this, _1, _2));
 
-void KeyManagerInstance::GetAliasList(
-    std::function<int(CKM::AliasVector&)> coreFunc, picojson::object& out) {
-  LoggerD("Enter");
-  CKM::AliasVector result;
-  int ret = coreFunc(result);
-  if (ret != CKM_API_SUCCESS) {
-      LoggerE("Failed to fetch list of alias: %d", ret);
-      ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
-        "Failed to fetch list of alias"), &out);
-  } else {
-      picojson::array aliases;
-      for (auto& item: result) {
-          aliases.push_back(picojson::value(item));
-      }
-      picojson::value res(aliases);
-      ReportSuccess(res, out);
-  }
-}
+  RegisterSyncHandler("KeyManager_getData",
+      std::bind(&KeyManagerInstance::GetData, this, _1, _2));
 
-void KeyManagerInstance::GetKeyAliasList(const picojson::value& args,
-    picojson::object& out) {
-  LoggerD("Enter");
-  using std::placeholders::_1;
-  GetAliasList(
-      std::bind(&CKM::Manager::getKeyAliasVector, CKM::Manager::create(), _1),
-      out);
-}
+  RegisterSyncHandler("KeyManager_removeAlias",
+      std::bind(&KeyManagerInstance::RemoveAlias, this, _1, _2));
 
-void KeyManagerInstance::GetCertificateAliasList(const picojson::value& args,
-    picojson::object& out) {
-  LoggerD("Enter");
-  using std::placeholders::_1;
-  GetAliasList(
-      std::bind(&CKM::Manager::getCertificateAliasVector, CKM::Manager::create(), _1),
-      out);
+  RegisterSyncHandler("KeyManager_setPermissions",
+      std::bind(&KeyManagerInstance::SetPermission, this, _1, _2));
 }
 
 void KeyManagerInstance::GetDataAliasList(const picojson::value& args,
-    picojson::object& out) {
+                                          picojson::object& out) {
   LoggerD("Enter");
-  using std::placeholders::_1;
-  GetAliasList(
-      std::bind(&CKM::Manager::getDataAliasVector, CKM::Manager::create(), _1),
-      out);
+  GetGenericAliasList(ckmc_get_data_alias_list, &out);
 }
 
-void KeyManagerInstance::SaveKey(const picojson::value& args,
-    picojson::object& out) {
-  LoggerD("Enter");
-
-  const picojson::value& key_object = args.get("key");
-  const std::string& alias = key_object.get("name").get<std::string>();
-  std::string password;
-  if (key_object.get("password").is<std::string>()) {
-    password = key_object.get("password").get<std::string>();
+PlatformResult KeyManagerInstance::GetError(int ret) {
+  char* error = get_error_message(ret);
+  if(CKMC_ERROR_NONE == ret) {
+    return PlatformResult(ErrorCode::NO_ERROR);
   }
-  std::string base64 = args.get("rawKey").get<std::string>();
-  pcrecpp::RE_Options opt;
-  opt.set_multiline(true);
-  //remove first line and last line
-  pcrecpp::RE("-----[^-]*-----", opt).GlobalReplace("", &base64);
-  gsize len = 0;
-  guchar* raw_data = g_base64_decode(base64.c_str(), &len);
-  CKM::RawBuffer raw_buffer;
-  raw_buffer.assign(raw_data, raw_data + len);
-  g_free(raw_data);
-  CKM::Password pass(password.c_str());
-  CKM::KeyShPtr key = CKM::Key::create(raw_buffer, pass);
-  CKM::Policy policy(pass, key_object.get("extractable").get<bool>());
-  CKM::ManagerAsync::ObserverPtr observer(new SaveKeyObserver(this,
-    args.get("callbackId").get<double>()));
-  m_manager.saveKey(observer, alias, key, policy);
-
-  ReportSuccess(out);
-}
-
-void KeyManagerInstance::OnSaveKey(double callbackId,
-    const common::PlatformResult& result) {
-  LoggerD("Enter");
-  picojson::value::object dict;
-  dict["callbackId"] = picojson::value(callbackId);
-  if (result.IsError()) {
-    LoggerE("There was an error");
-    ReportError(result, &dict);
+  else if(CKMC_ERROR_INVALID_PARAMETER == ret) {
+    LoggerD("%s", error);
+    return PlatformResult(ErrorCode::INVALID_VALUES_ERR, error);
+  }
+  else if(CKMC_ERROR_DB_ALIAS_UNKNOWN == ret) {
+    LoggerD("%s",error);
+    return PlatformResult(ErrorCode::NOT_FOUND_ERR, error);
+  }
+  else if(CKMC_ERROR_AUTHENTICATION_FAILED == ret) {
+    LoggerD("%s",error);
+    return PlatformResult(ErrorCode::VERIFICATION_ERR, error);
+  }
+  else {
+    LoggerD("%s", error);
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, error);
   }
-  picojson::value res(dict);
-  PostMessage(res.serialize().c_str());
 }
 
-void KeyManagerInstance::RemoveKey(const picojson::value& args,
-    picojson::object& out) {
+void KeyManagerInstance::SaveData(const picojson::value& args,
+                                  picojson::object& out) {
   LoggerD("Enter");
 
-  const std::string& alias = args.get("key").get("name").get<std::string>();
-  int ret = CKM::Manager::create()->removeAlias(alias);
-  if (ret != CKM_API_SUCCESS) {
-    LoggerE("Failed to remove key alias: %d", ret);
-    if (ret == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-      ReportError(common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR,
-        "Key alias not found"), &out);
-    } else {
-      ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
-        "Failed to remove key alias"), &out);
-    }
-  } else {
-    ReportSuccess(out);
+  std::string data_raw = args.get("rawData").get<std::string>();
+  std::string alias = args.get("aliasName").get<std::string>();
+  const auto& password_value = args.get("password");
+
+  double callback_id = args.get("callbackId").get<double>();
+
+  const char* password = nullptr;
+
+  if (password_value.is<std::string>()) {
+    password = (password_value.get<std::string>()).c_str();
+    LoggerE("password %s ", password);
   }
-}
 
-void KeyManagerInstance::GenerateKeyPair(const picojson::value& args,
-    picojson::object& out) {
-  LoggerD("Enter");
+  auto save_data = [data_raw, password, alias](const std::shared_ptr<picojson::value>& result) {
 
-  const picojson::value& priv_key = args.get("privKeyName");
-  const picojson::value& pub_key = args.get("pubKeyName");
-  const std::string& priv_name = priv_key.get("name").get<std::string>();
-  const std::string& pub_name = pub_key.get("name").get<std::string>();
-  const std::string& type = args.get("type").get<std::string>();
-  int size = std::stoi(args.get("size").get<std::string>());
+    unsigned char* data = new unsigned char[data_raw.size()];
+    std::copy(data_raw.begin(), data_raw.end(), data);
 
-  CKM::ManagerAsync::ObserverPtr observer(new CreateKeyObserver(this,
-    args.get("callbackId").get<double>()));
+    ckmc_raw_buffer_s raw_data { data, data_raw.size() };
+    ckmc_policy_s policy { const_cast<char*>(password), true };
 
-  CKM::Password pass;
-  if (priv_key.get("password").is<std::string>()) {
-    pass = priv_key.get("password").get<std::string>().c_str();
-  }
-  CKM::Policy priv_policy(pass, priv_key.get("extractable").get<bool>());
+    int ret = ckmc_save_data(alias.c_str(), raw_data, policy);
 
-  if (pub_key.get("password").is<std::string>()) {
-    pass = pub_key.get("password").get<std::string>().c_str();
-  } else {
-    pass = "";
-  }
-  CKM::Policy pub_policy(pass, pub_key.get("extractable").get<bool>());
-
-  if (type == kTypeRSA) {
-    m_manager.createKeyPairRSA(observer, size, priv_name, pub_name, priv_policy, pub_policy);
-  } else if (type == kTypeECDSA) {
-    CKM::ElipticCurve eliptic = CKM::ElipticCurve::prime192v1;
-    if (args.get("ellipticCurveType").is<std::string>()) {
-      const std::string& eType = args.get("ellipticCurveType").get<std::string>();
-      if (eType == "PRIME256V1") {
-        eliptic = CKM::ElipticCurve::prime256v1;
-      } else if (eType == "EC_SECP384R1") {
-        eliptic = CKM::ElipticCurve::secp384r1;
-      }
+    PlatformResult success = GetError(ret);
+
+    if (success) {
+      common::tools::ReportSuccess(result->get<picojson::object>());
+    } else {
+      LoggerE("Failed to save data: %d", ret);
+      common::tools::ReportError(success, &result->get<picojson::object>());
     }
-    m_manager.createKeyPairECDSA(observer, eliptic, priv_name, pub_name, priv_policy, pub_policy);
-  } else {
-    m_manager.createKeyPairDSA(observer, size, priv_name, pub_name, priv_policy, pub_policy);
-  }
+
+    delete[] data;
+  };
+
+  auto save_data_result = [this, callback_id](const std::shared_ptr<picojson::value>& result) {
+    result->get<picojson::object>()["callbackId"] = picojson::value{callback_id};
+    Instance::PostMessage(this, result->serialize().c_str());
+  };
+
+  auto queue_data = std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
+
+  TaskQueue::GetInstance().Queue<picojson::value>(
+      save_data,
+      save_data_result,
+      queue_data);
 
   ReportSuccess(out);
 }
 
-void KeyManagerInstance::OnCreateKeyPair(double callbackId,
-    const common::PlatformResult& result) {
+void KeyManagerInstance::GetData(const picojson::value& args,
+                                 picojson::object& out) {
   LoggerD("Enter");
-  picojson::value::object dict;
-  dict["callbackId"] = picojson::value(callbackId);
-  if (result.IsError()) {
-    LoggerE("There was an error");
-    ReportError(result, &dict);
-  }
-  picojson::value res(dict);
-  PostMessage(res.serialize().c_str());
-}
 
-std::string RawBufferToBase64(const CKM::RawBuffer &buf) {
-  std::string result;
-  if (!buf.empty()) {
-    gchar* base64 = g_base64_encode(&buf[0], buf.size());
-    result = base64;
-    g_free(base64);
-  }
-  return result;
-}
+  const auto& data_alias = args.get("name").get<std::string>();
+  const auto& password_value = args.get("password");
 
-void KeyManagerInstance::GetKey(const picojson::value& args, picojson::object& out) {
-  LoggerD("Enter");
-  using CKM::KeyType;
+  const char* password = nullptr;
 
-  const std::string& alias = args.get("name").get<std::string>();
-  CKM::Password pass;
-  if (args.get("password").is<std::string>()) {
-    pass = args.get("password").get<std::string>().c_str();
+  if (password_value.is<std::string>()) {
+    password = (password_value.get<std::string>()).c_str();
   }
 
-  CKM::KeyShPtr key;
-  int ret = CKM::Manager::create()->getKey(alias, pass, key);
-  if (ret != CKM_API_SUCCESS) {
-    LoggerE("Failed to get key: %d", ret);
-    if (ret == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-      ReportError(common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR,
-        "Key alias not found"), &out);
-    } else {
-      ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
-        "Failed to get key"), &out);
-    }
-  } else {
-    picojson::object dict;
-    dict["name"] = args.get("name");
-    if (args.get("password").is<std::string>()) {
-      dict["password"] = args.get("password");
-    }
-    switch (key->getType()) {
-      case KeyType::KEY_NONE:
-        dict["keyType"] = picojson::value("KEY_NONE");
-        break;
-      case KeyType::KEY_RSA_PUBLIC:
-        dict["keyType"] = picojson::value("KEY_RSA_PUBLIC");
-        break;
-      case KeyType::KEY_RSA_PRIVATE:
-        dict["keyType"] = picojson::value("KEY_RSA_PRIVATE");
-        break;
-      case KeyType::KEY_ECDSA_PUBLIC:
-        dict["keyType"] = picojson::value("KEY_ECDSA_PUBLIC");
-        break;
-      case KeyType::KEY_ECDSA_PRIVATE:
-        dict["keyType"] = picojson::value("KEY_ECDSA_PRIVATE");
-        break;
-      case KeyType::KEY_DSA_PUBLIC:
-        dict["keyType"] = picojson::value("KEY_DSA_PUBLIC");
-        break;
-      case KeyType::KEY_DSA_PRIVATE:
-        dict["keyType"] = picojson::value("KEY_DSA_PRIVATE");
-        break;
-      case KeyType::KEY_AES:
-        dict["keyType"] = picojson::value("KEY_AES");
-        break;
-    }
-    dict["rawKey"] = picojson::value(RawBufferToBase64(key->getDER()));
-    //if key was retrieved it is extractable from db
-    dict["extractable"] = picojson::value(true);
+  LoggerD("data_alias: %s", data_alias.c_str());
 
-    picojson::value res(dict);
-    ReportSuccess(res, out);
-  }
-}
+  ckmc_raw_buffer_s* data = nullptr;
+  int ret = ckmc_get_data(data_alias.c_str(), password, &data);
 
-void KeyManagerInstance::GetCertificate(const picojson::value& args,
-    picojson::object& out) {
-  LoggerD("Enter");
+  if (CKMC_ERROR_NONE == ret) {
+    picojson::object result;
 
-  CKM::Password pass;
-  if (args.get("password").is<std::string>()) {
-    pass = args.get("password").get<std::string>().c_str();
-  }
-  const std::string& alias = args.get("name").get<std::string>();
-  CKM::CertificateShPtr cert;
-  int ret = CKM::Manager::create()->getCertificate(alias, pass, cert);
-  if (ret != CKM_API_SUCCESS) {
-    LoggerE("Failed to get cert: %d", ret);
-    if (ret == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-      ReportError(common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR,
-        "Cert alias not found"), &out);
-    } else {
-      ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
-        "Failed to get cert"), &out);
-    }
-  } else {
-    picojson::object dict;
-    dict["name"] = args.get("name");
-    if (args.get("password").is<std::string>()) {
-      dict["password"] = args.get("password");
-    }
-    //if cert was retrieved it is extractable from db
-    dict["extractable"] = picojson::value(true);
-    dict["rawCert"] = picojson::value(RawBufferToBase64(cert->getDER()));
+    result["rawData"] = picojson::value(std::string (data->data, data->data + data->size));
 
-    picojson::value res(dict);
-    ReportSuccess(res, out);
-  }
-}
+    ckmc_buffer_free(data);
+    ReportSuccess(picojson::value{result}, out);
+  } else {
+    LoggerE("Failed to get data: %d", ret);
 
-void KeyManagerInstance::SaveCertificate(const picojson::value& args,
-    picojson::object& out) {
-  LoggerD("Enter");
+    PlatformResult error = GetError(ret);
 
-  const picojson::value& crt = args.get("certificate");
-  const std::string& alias = crt.get("name").get<std::string>();
-  std::string password;
-  if (crt.get("password").is<std::string>()) {
-    password = crt.get("password").get<std::string>();
+    ReportError(error, &out);
   }
-  std::string base64 = args.get("rawCert").get<std::string>();
-
-  SaveCert(base64,
-      password,
-      alias,
-      crt.get("extractable").get<bool>(),
-      args.get("callbackId").get<double>());
-  ReportSuccess(out);
 }
 
-void KeyManagerInstance::SaveCert(std::string &base64,
-    const std::string &password,
-    const std::string &alias,
-    bool extractable,
-    double callbackId) {
+KeyManagerInstance::~KeyManagerInstance() {
   LoggerD("Enter");
-  pcrecpp::RE_Options opt;
-  opt.set_multiline(true);
-  //remove first line and last line
-  pcrecpp::RE("-----[^-]*-----", opt).GlobalReplace("", &base64);
-  gsize len = 0;
-  guchar* rawData = g_base64_decode(base64.c_str(), &len);
-  CKM::RawBuffer rawBuffer;
-  rawBuffer.assign(rawData, rawData + len);
-  g_free(rawData);
-  CKM::Password pass(password.c_str());
-  CKM::CertificateShPtr cert = CKM::Certificate::create(rawBuffer,
-      CKM::DataFormat::FORM_DER);
-  CKM::Policy policy(pass, extractable);
-  CKM::ManagerAsync::ObserverPtr observer(new SaveCertObserver(this,
-    callbackId));
-  m_manager.saveCertificate(observer, alias, cert, policy);
 }
 
-void KeyManagerInstance::OnSaveCert(double callbackId,
-    const common::PlatformResult& result) {
+void KeyManagerInstance::RemoveAlias(const picojson::value& args,
+                                   picojson::object& out) {
   LoggerD("Enter");
-  picojson::value::object dict;
-  dict["callbackId"] = picojson::value(callbackId);
-  if (result.IsError()) {
-    LoggerE("There was an error");
-    ReportError(result, &dict);
+
+  const std::string& alias = args.get("aliasName").get<std::string>();
+  int ret = ckmc_remove_alias(alias.c_str());
+
+  if (CKMC_ERROR_NONE != ret) {
+    LoggerE("Failed to remove alias [%d]", ret);
+    PlatformResult result = GetError(ret);
+    ReportError(result, &out);
+  } else {
+    ReportSuccess(out);
   }
-  picojson::value res(dict);
-  PostMessage(res.serialize().c_str());
 }
 
-void KeyManagerInstance::LoadCertificateFromFile(const picojson::value& args,
-    picojson::object& out) {
+void KeyManagerInstance::SetPermission(const picojson::value& args,
+                                            picojson::object& out) {
   LoggerD("Enter");
 
-  const picojson::value& crt = args.get("certificate");
-  const std::string& file = args.get("fileURI").get<std::string>();
-  std::string password;
-  if (crt.get("password").is<std::string>()) {
-    password = crt.get("password").get<std::string>();
+  const std::string& data_name = args.get("aliasName").get<std::string>();
+  const std::string& id = args.get("packageId").get<std::string>();
+  const double callback_id = args.get("callbackId").get<double>();
+  const std::string& access = args.get("permissionType").get<std::string>();
+
+  int permissions = CKMC_PERMISSION_NONE;
+  if( "NONE" == access) {
+    permissions = CKMC_PERMISSION_NONE;
+  }
+  else if ("READ" == access) {
+    permissions = CKMC_PERMISSION_READ;
+  }
+  else if ("REMOVE" == access) {
+    permissions = CKMC_PERMISSION_REMOVE;
+  }
+  else if("READ_REMOVE" == access) {
+    permissions = CKMC_PERMISSION_READ | CKMC_PERMISSION_REMOVE;
   }
-  LoadFileCert* reader = new LoadFileCert(this,
-    args.get("callbackId").get<double>(),
-    password,
-    crt.get("name").get<std::string>(),
-    crt.get("extractable").get<bool>());
-  reader->LoadFileAsync(file);
 
-  ReportSuccess(out);
-}
+  auto set_permissions = [data_name, id, permissions](const std::shared_ptr<picojson::value>& response) -> void {
+    int ret = ckmc_set_permission(data_name.c_str(), id.c_str(), permissions);
 
-void KeyManagerInstance::OnCertFileLoaded(LoadFileCert* reader,
-    const common::PlatformResult& result) {
-  LoggerD("Enter");
+    if (CKMC_ERROR_NONE != ret) {
+      PlatformResult result = GetError(ret);
+      common::tools::ReportError(result, &response->get<picojson::object>());
+    } else {
+      common::tools::ReportSuccess(response->get<picojson::object>());
+    }
+  };
 
-  if (result.IsError()) {
-    LoggerE("There was an error");
-    picojson::value::object dict;
-    dict["callbackId"] = picojson::value(reader->callbackId);
-    ReportError(result, &dict);
-    picojson::value res(dict);
-    PostMessage(res.serialize().c_str());
-  } else {
-    SaveCert(reader->fileContent, reader->password, reader->alias,
-      reader->extractable, reader->callbackId);
-  }
-  delete reader;
+  auto set_permissions_response = [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
+    picojson::object& obj = response->get<picojson::object>();
+    obj.insert(std::make_pair("callbackId", picojson::value(callback_id)));
+    Instance::PostMessage(this, response->serialize().c_str());
+  };
+
+  auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
+  TaskQueue::GetInstance().Queue<picojson::value>(
+      set_permissions,
+      set_permissions_response,
+      std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
 }
 
 } // namespace keymanager