1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "keymanager/keymanager_instance.h"
8 #include <ckm/ckm-manager.h>
12 #include "common/logger.h"
13 #include "common/picojson.h"
14 #include "common/platform_result.h"
17 namespace keymanager {
20 const char* kTypeRSA = "RSA";
21 const char* kTypeECDSA = "ECDSA";
24 KeyManagerInstance::KeyManagerInstance() {
25 using std::placeholders::_1;
26 using std::placeholders::_2;
28 RegisterSyncHandler("KeyManager_getKeyAliasList",
29 std::bind(&KeyManagerInstance::GetKeyAliasList, this, _1, _2));
30 RegisterSyncHandler("KeyManager_getCertificatesAliasList",
31 std::bind(&KeyManagerInstance::GetCertificateAliasList, this, _1, _2));
32 RegisterSyncHandler("KeyManager_getDataAliasList",
33 std::bind(&KeyManagerInstance::GetDataAliasList, this, _1, _2));
34 RegisterSyncHandler("KeyManager_getKey",
35 std::bind(&KeyManagerInstance::GetKey, this, _1, _2));
36 RegisterSyncHandler("KeyManager_saveKey",
37 std::bind(&KeyManagerInstance::SaveKey, this, _1, _2));
38 RegisterSyncHandler("KeyManager_removeKey",
39 std::bind(&KeyManagerInstance::RemoveKey, this, _1, _2));
40 RegisterSyncHandler("KeyManager_generateKeyPair",
41 std::bind(&KeyManagerInstance::GenerateKeyPair, this, _1, _2));
42 RegisterSyncHandler("KeyManager_getCertificate",
43 std::bind(&KeyManagerInstance::GetCertificate, this, _1, _2));
44 RegisterSyncHandler("KeyManager_saveCertificate",
45 std::bind(&KeyManagerInstance::SaveCertificate, this, _1, _2));
48 KeyManagerInstance::~KeyManagerInstance() {
51 void KeyManagerInstance::GetAliasList(
52 std::function<int(CKM::AliasVector&)> coreFunc, picojson::object& out) {
54 CKM::AliasVector result;
55 int ret = coreFunc(result);
56 if (ret != CKM_API_SUCCESS) {
57 LoggerE("Failed to fetch list of alias: %d", ret);
58 ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
59 "Failed to fetch list of alias"), &out);
61 picojson::array aliases;
62 for (auto& item: result) {
63 aliases.push_back(picojson::value(item));
65 picojson::value res(aliases);
66 ReportSuccess(res, out);
70 void KeyManagerInstance::GetKeyAliasList(const picojson::value& args,
71 picojson::object& out) {
73 using std::placeholders::_1;
75 std::bind(&CKM::Manager::getKeyAliasVector, CKM::Manager::create(), _1),
79 void KeyManagerInstance::GetCertificateAliasList(const picojson::value& args,
80 picojson::object& out) {
82 using std::placeholders::_1;
84 std::bind(&CKM::Manager::getCertificateAliasVector, CKM::Manager::create(), _1),
88 void KeyManagerInstance::GetDataAliasList(const picojson::value& args,
89 picojson::object& out) {
91 using std::placeholders::_1;
93 std::bind(&CKM::Manager::getDataAliasVector, CKM::Manager::create(), _1),
97 void KeyManagerInstance::SaveKey(const picojson::value& args,
98 picojson::object& out) {
101 const picojson::value& key_object = args.get("key");
102 const std::string& alias = key_object.get("name").get<std::string>();
103 std::string password;
104 if (key_object.get("password").is<std::string>()) {
105 password = key_object.get("password").get<std::string>();
107 std::string base64 = args.get("rawKey").get<std::string>();
108 pcrecpp::RE_Options opt;
109 opt.set_multiline(true);
110 //remove first line and last line
111 pcrecpp::RE("-----[^-]*-----", opt).GlobalReplace("", &base64);
113 guchar* raw_data = g_base64_decode(base64.c_str(), &len);
114 CKM::RawBuffer raw_buffer;
115 raw_buffer.assign(raw_data, raw_data + len);
117 CKM::Password pass(password.c_str());
118 CKM::KeyShPtr key = CKM::Key::create(raw_buffer, pass);
119 CKM::Policy policy(pass, key_object.get("extractable").get<bool>());
120 CKM::ManagerAsync::ObserverPtr observer(new SaveKeyObserver(this,
121 args.get("callbackId").get<double>()));
122 m_manager.saveKey(observer, alias, key, policy);
127 void KeyManagerInstance::OnSaveKey(double callbackId,
128 const common::PlatformResult& result) {
130 picojson::value::object dict;
131 dict["callbackId"] = picojson::value(callbackId);
132 if (result.IsError()) {
133 LoggerE("There was an error");
134 ReportError(result, &dict);
136 picojson::value res(dict);
137 PostMessage(res.serialize().c_str());
140 void KeyManagerInstance::RemoveKey(const picojson::value& args,
141 picojson::object& out) {
144 const std::string& alias = args.get("key").get("name").get<std::string>();
145 int ret = CKM::Manager::create()->removeAlias(alias);
146 if (ret != CKM_API_SUCCESS) {
147 LoggerE("Failed to remove key alias: %d", ret);
148 if (ret == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
149 ReportError(common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR,
150 "Key alias not found"), &out);
152 ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
153 "Failed to remove key alias"), &out);
160 void KeyManagerInstance::GenerateKeyPair(const picojson::value& args,
161 picojson::object& out) {
164 const picojson::value& priv_key = args.get("privKeyName");
165 const picojson::value& pub_key = args.get("pubKeyName");
166 const std::string& priv_name = priv_key.get("name").get<std::string>();
167 const std::string& pub_name = pub_key.get("name").get<std::string>();
168 const std::string& type = args.get("type").get<std::string>();
169 int size = std::stoi(args.get("size").get<std::string>());
171 CKM::ManagerAsync::ObserverPtr observer(new CreateKeyObserver(this,
172 args.get("callbackId").get<double>()));
175 if (priv_key.get("password").is<std::string>()) {
176 pass = priv_key.get("password").get<std::string>().c_str();
178 CKM::Policy priv_policy(pass, priv_key.get("extractable").get<bool>());
180 if (pub_key.get("password").is<std::string>()) {
181 pass = pub_key.get("password").get<std::string>().c_str();
185 CKM::Policy pub_policy(pass, pub_key.get("extractable").get<bool>());
187 if (type == kTypeRSA) {
188 m_manager.createKeyPairRSA(observer, size, priv_name, pub_name, priv_policy, pub_policy);
189 } else if (type == kTypeECDSA) {
190 CKM::ElipticCurve eliptic = CKM::ElipticCurve::prime192v1;
191 if (args.get("ellipticCurveType").is<std::string>()) {
192 const std::string& eType = args.get("ellipticCurveType").get<std::string>();
193 if (eType == "PRIME256V1") {
194 eliptic = CKM::ElipticCurve::prime256v1;
195 } else if (eType == "EC_SECP384R1") {
196 eliptic = CKM::ElipticCurve::secp384r1;
199 m_manager.createKeyPairECDSA(observer, eliptic, priv_name, pub_name, priv_policy, pub_policy);
201 m_manager.createKeyPairDSA(observer, size, priv_name, pub_name, priv_policy, pub_policy);
207 void KeyManagerInstance::OnCreateKeyPair(double callbackId,
208 const common::PlatformResult& result) {
210 picojson::value::object dict;
211 dict["callbackId"] = picojson::value(callbackId);
212 if (result.IsError()) {
213 LoggerE("There was an error");
214 ReportError(result, &dict);
216 picojson::value res(dict);
217 PostMessage(res.serialize().c_str());
220 std::string RawBufferToBase64(const CKM::RawBuffer &buf) {
223 gchar* base64 = g_base64_encode(&buf[0], buf.size());
230 void KeyManagerInstance::GetKey(const picojson::value& args, picojson::object& out) {
234 const std::string& alias = args.get("name").get<std::string>();
236 if (args.get("password").is<std::string>()) {
237 pass = args.get("password").get<std::string>().c_str();
241 int ret = CKM::Manager::create()->getKey(alias, pass, key);
242 if (ret != CKM_API_SUCCESS) {
243 LoggerE("Failed to get key: %d", ret);
244 if (ret == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
245 ReportError(common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR,
246 "Key alias not found"), &out);
248 ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
249 "Failed to get key"), &out);
252 picojson::object dict;
253 dict["name"] = args.get("name");
254 if (args.get("password").is<std::string>()) {
255 dict["password"] = args.get("password");
257 switch (key->getType()) {
258 case KeyType::KEY_NONE:
259 dict["keyType"] = picojson::value("KEY_NONE");
261 case KeyType::KEY_RSA_PUBLIC:
262 dict["keyType"] = picojson::value("KEY_RSA_PUBLIC");
264 case KeyType::KEY_RSA_PRIVATE:
265 dict["keyType"] = picojson::value("KEY_RSA_PRIVATE");
267 case KeyType::KEY_ECDSA_PUBLIC:
268 dict["keyType"] = picojson::value("KEY_ECDSA_PUBLIC");
270 case KeyType::KEY_ECDSA_PRIVATE:
271 dict["keyType"] = picojson::value("KEY_ECDSA_PRIVATE");
273 case KeyType::KEY_DSA_PUBLIC:
274 dict["keyType"] = picojson::value("KEY_DSA_PUBLIC");
276 case KeyType::KEY_DSA_PRIVATE:
277 dict["keyType"] = picojson::value("KEY_DSA_PRIVATE");
279 case KeyType::KEY_AES:
280 dict["keyType"] = picojson::value("KEY_AES");
283 dict["rawKey"] = picojson::value(RawBufferToBase64(key->getDER()));
284 //if key was retrieved it is extractable from db
285 dict["extractable"] = picojson::value(true);
287 picojson::value res(dict);
288 ReportSuccess(res, out);
292 void KeyManagerInstance::GetCertificate(const picojson::value& args,
293 picojson::object& out) {
297 if (args.get("password").is<std::string>()) {
298 pass = args.get("password").get<std::string>().c_str();
300 const std::string& alias = args.get("name").get<std::string>();
301 CKM::CertificateShPtr cert;
302 int ret = CKM::Manager::create()->getCertificate(alias, pass, cert);
303 if (ret != CKM_API_SUCCESS) {
304 LoggerE("Failed to get cert: %d", ret);
305 if (ret == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
306 ReportError(common::PlatformResult(common::ErrorCode::NOT_FOUND_ERR,
307 "Cert alias not found"), &out);
309 ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
310 "Failed to get cert"), &out);
313 picojson::object dict;
314 dict["name"] = args.get("name");
315 if (args.get("password").is<std::string>()) {
316 dict["password"] = args.get("password");
318 //if cert was retrieved it is extractable from db
319 dict["extractable"] = picojson::value(true);
320 dict["rawCert"] = picojson::value(RawBufferToBase64(cert->getDER()));
322 picojson::value res(dict);
323 ReportSuccess(res, out);
327 void KeyManagerInstance::SaveCertificate(const picojson::value& args,
328 picojson::object& out) {
331 const picojson::value& crt = args.get("certificate");
332 const std::string& alias = crt.get("name").get<std::string>();
333 std::string password;
334 if (crt.get("password").is<std::string>()) {
335 password = crt.get("password").get<std::string>();
337 std::string base64 = args.get("rawCert").get<std::string>();
338 pcrecpp::RE_Options opt;
339 opt.set_multiline(true);
340 //remove first line and last line
341 pcrecpp::RE("-----[^-]*-----", opt).GlobalReplace("", &base64);
343 guchar* rawData = g_base64_decode(base64.c_str(), &len);
344 CKM::RawBuffer rawBuffer;
345 rawBuffer.assign(rawData, rawData + len);
347 CKM::Password pass(password.c_str());
348 CKM::CertificateShPtr cert = CKM::Certificate::create(rawBuffer,
349 CKM::DataFormat::FORM_DER);
350 CKM::Policy policy(pass, crt.get("extractable").get<bool>());
351 CKM::ManagerAsync::ObserverPtr observer(new SaveCertObserver(this,
352 args.get("callbackId").get<double>()));
353 m_manager.saveCertificate(observer, alias, cert, policy);
358 void KeyManagerInstance::OnSaveCert(double callbackId,
359 const common::PlatformResult& result) {
361 picojson::value::object dict;
362 dict["callbackId"] = picojson::value(callbackId);
363 if (result.IsError()) {
364 LoggerE("There was an error");
365 ReportError(result, &dict);
367 picojson::value res(dict);
368 PostMessage(res.serialize().c_str());
371 } // namespace keymanager
372 } // namespace extension