--- /dev/null
+// 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.
+
+#include "keymanager/async_file_reader.h"
+#include "common/logger.h"
+
+namespace extension {
+namespace keymanager {
+
+const gsize kBufferSize = 4096;
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+AsyncFileReader::AsyncFileReader(): buffer_(nullptr) {}
+
+void AsyncFileReader::LoadFileAsync(const std::string& file_uri) {
+ LoggerD("Enter");
+ GFile* file = g_file_new_for_uri(file_uri.c_str());
+ g_file_read_async(file, G_PRIORITY_DEFAULT, nullptr, OnFileRead, this);
+}
+
+void AsyncFileReader::OnFileRead(GObject* source_object,
+ GAsyncResult* res, gpointer user_data) {
+ LoggerD("Enter");
+ AsyncFileReader* This = static_cast<AsyncFileReader*>(user_data);
+ GError* err = nullptr;
+ GFileInputStream* stream = g_file_read_finish(G_FILE(source_object),
+ res, &err);
+ g_object_unref(source_object);
+ if (stream == nullptr) {
+ LoggerE("Failed to read file: %d", err->code);
+ if (err->code == G_FILE_ERROR_NOENT) {
+ This->OnError(PlatformResult(ErrorCode::NOT_FOUND_ERR,
+ "File not found"));
+ } else {
+ This->OnError(PlatformResult(ErrorCode::IO_ERR,
+ "Failed to load file"));
+ }
+ return;
+ }
+
+ This->buffer_ = new guint8[kBufferSize];
+ g_input_stream_read_async(G_INPUT_STREAM(stream), This->buffer_, kBufferSize,
+ G_PRIORITY_DEFAULT, nullptr, OnStreamRead, This);
+}
+
+void AsyncFileReader::OnStreamRead(GObject* source_object,
+ GAsyncResult* res, gpointer user_data) {
+ LoggerD("Enter");
+
+ AsyncFileReader* This = static_cast<AsyncFileReader*>(user_data);
+ gssize size = g_input_stream_read_finish(G_INPUT_STREAM(source_object),
+ res, nullptr);
+ switch (size){
+ case -1:
+ LoggerE("Error occured");
+ This->OnError(PlatformResult(ErrorCode::IO_ERR,
+ "Failed to load file"));
+ g_object_unref(source_object);
+ break;
+ case 0:
+ LoggerD("End of file");
+ This->OnFileLoaded();
+ g_object_unref(source_object);
+ break;
+ default:
+ This->AppendBuffer(This->buffer_, size);
+ g_input_stream_read_async(G_INPUT_STREAM(source_object), This->buffer_,
+ kBufferSize, G_PRIORITY_DEFAULT, nullptr, OnStreamRead, This);
+ }
+}
+
+AsyncFileReader::~AsyncFileReader() {
+ delete[] buffer_;
+}
+
+} // namespace keymanager
+} // namespace extension
--- /dev/null
+// 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.
+
+#ifndef KEYMANAGER_ASYNC_FILE_READER_H_
+#define KEYMANAGER_ASYNC_FILE_READER_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+#include "common/platform_result.h"
+
+namespace extension {
+namespace keymanager {
+
+class AsyncFileReader {
+public:
+ AsyncFileReader();
+ void LoadFileAsync(const std::string &file_uri);
+ virtual ~AsyncFileReader();
+
+protected:
+ virtual void AppendBuffer(guint8* buffer, gssize size) = 0;
+ virtual void OnError(const common::PlatformResult& result) = 0;
+ virtual void OnFileLoaded() = 0;
+
+private:
+ guint8* buffer_;
+
+ static void OnFileRead(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data);
+ static void OnStreamRead(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data);
+};
+
+} // namespace keymanager
+} // namespace extension
+
+#endif // KEYMANAGER_ASYNC_FILE_READER_H_
+
],
'sources': [
'keymanager_api.js',
+ 'async_file_reader.cc',
+ 'async_file_reader.h',
'keymanager_extension.cc',
'keymanager_extension.h',
'keymanager_instance.cc',
std::bind(&KeyManagerInstance::CreateSignature, this, _1, _2));
RegisterSyncHandler("KeyManager_verifySignature",
std::bind(&KeyManagerInstance::VerifySignature, this, _1, _2));
+ RegisterSyncHandler("KeyManager_loadFromPKCS12File",
+ std::bind(&KeyManagerInstance::LoadFromPKCS12File, this, _1, _2));
}
KeyManagerInstance::~KeyManagerInstance() {
if (result.IsError()) {
LoggerE("There was an error");
picojson::value::object dict;
- dict["callbackId"] = picojson::value(reader->callbackId);
+ dict["callbackId"] = picojson::value(reader->callback_id);
ReportError(result, &dict);
picojson::value res(dict);
PostMessage(res.serialize().c_str());
} else {
- SaveCert(reader->fileContent, reader->password, reader->alias,
- reader->extractable, reader->callbackId);
+ SaveCert(reader->file_content, reader->password, reader->alias,
+ reader->extractable, reader->callback_id);
}
delete reader;
}
PostMessage(res.serialize().c_str());
}
+void KeyManagerInstance::LoadFromPKCS12File(const picojson::value& args,
+ picojson::object& out) {
+ LoggerD("Enter");
+
+ const std::string& file = args.get("fileURI").get<std::string>();
+ const std::string& key_alias = args.get("privKeyName").get<std::string>();
+ const std::string& cert_alias = args.get("certificateName").get<std::string>();
+ std::string password;
+ if (args.get("password").is<std::string>()) {
+ password = args.get("password").get<std::string>();
+ }
+ LoadFilePKCS12* reader = new LoadFilePKCS12(this,
+ args.get("callbackId").get<double>(),
+ password,
+ key_alias,
+ cert_alias);
+ reader->LoadFileAsync(file);
+
+ ReportSuccess(out);
+}
+
+void KeyManagerInstance::OnPKCS12FileLoaded(LoadFilePKCS12* reader,
+ const common::PlatformResult& result) {
+ LoggerD("Enter");
+
+ if (result.IsError()) {
+ LoggerE("There was an error");
+ picojson::value::object dict;
+ dict["callbackId"] = picojson::value(reader->callback_id);
+ ReportError(result, &dict);
+ picojson::value res(dict);
+ PostMessage(res.serialize().c_str());
+ } else {
+ CKM::Password pass(reader->password.c_str());
+ CKM::PKCS12ShPtr pkcs = CKM::PKCS12::create(reader->file_content, pass);
+ if (!pkcs) {
+ LoggerE("Failed to parse PKCS12 file");
+ picojson::value::object dict;
+ dict["callbackId"] = picojson::value(reader->callback_id);
+ common::PlatformResult err(common::ErrorCode::INVALID_VALUES_ERR,
+ "Failed to parse PKCS12 file");
+ ReportError(err, &dict);
+ picojson::value res(dict);
+ PostMessage(res.serialize().c_str());
+ } else {
+ CKM::Policy keyPolicy;
+ CKM::Policy certPolicy;
+ CKM::ManagerAsync::ObserverPtr observer(new SavePKCS12Observer(this,
+ reader->callback_id));
+ m_manager.saveCertificate(observer, reader->cert_alias, pkcs->getCertificate(), certPolicy);
+ m_manager.saveKey(observer, reader->key_alias, pkcs->getKey(), keyPolicy);
+ }
+ }
+ delete reader;
+}
+
+void KeyManagerInstance::OnSavePKCS12(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);
+ }
+ picojson::value res(dict);
+ PostMessage(res.serialize().c_str());
+}
+
} // namespace keymanager
} // namespace extension
void OnSaveData(double callbackId, const common::PlatformResult& result);
void OnCreateSignature(double callbackId, const common::PlatformResult& result, CKM::RawBuffer buffer);
void OnVerifySignature(double callbackId, const common::PlatformResult& result);
+ void OnPKCS12FileLoaded(LoadFilePKCS12* reader, const common::PlatformResult& result);
+ void OnSavePKCS12(double callbackId, const common::PlatformResult& result);
+
private:
void GetAliasList(std::function<int(CKM::AliasVector&)> coreFunc,
picojson::object& out);
void GetData(const picojson::value& args, picojson::object& out);
void CreateSignature(const picojson::value& args, picojson::object& out);
void VerifySignature(const picojson::value& args, picojson::object& out);
+ void LoadFromPKCS12File(const picojson::value& args, picojson::object& out);
CKM::ManagerAsync m_manager;
};
const std::string &_password,
const std::string &_alias,
bool _extractable):
- callbackId(callbackId),
+ callback_id(callbackId),
password(_password),
alias(_alias),
extractable(_extractable),
- fileContent(""),
- buffer(NULL),
- listener(_listener) {}
-
-void LoadFileCert::LoadFileAsync(const std::string& fileUri) {
- LoggerD("Enter");
- GFile* file = g_file_new_for_uri(fileUri.c_str());
- g_file_read_async(file, G_PRIORITY_DEFAULT, NULL, OnFileRead, this);
+ file_content(""),
+ listener(_listener) {
}
-void LoadFileCert::OnFileRead(GObject* source_object,
- GAsyncResult* res, gpointer user_data) {
- LoggerD("Enter");
- LoadFileCert* This = static_cast<LoadFileCert*>(user_data);
- GError* err = NULL;
- GFileInputStream* stream = g_file_read_finish(G_FILE(source_object),
- res, &err);
- g_object_unref(source_object);
- if (stream == NULL) {
- LoggerE("Failed to read file: %d", err->code);
- if (err->code == G_FILE_ERROR_NOENT) {
- This->listener->OnCertFileLoaded(This,
- PlatformResult(ErrorCode::NOT_FOUND_ERR, "Certificate file not found"));
- } else {
- This->listener->OnCertFileLoaded(This,
- PlatformResult(ErrorCode::IO_ERR, "Failed to load certificate file"));
- }
- return;
- }
-
- This->buffer = new guint8[4096];
- g_input_stream_read_async(G_INPUT_STREAM(stream), This->buffer, 4096,
- G_PRIORITY_DEFAULT, NULL, OnStreamRead, This);
+void LoadFileCert::AppendBuffer(guint8* buffer, gssize size) {
+ file_content.append(buffer, buffer + size);
}
-void LoadFileCert::OnStreamRead(GObject* source_object,
- GAsyncResult* res, gpointer user_data) {
- LoggerD("Enter");
-
- LoadFileCert* This = static_cast<LoadFileCert*>(user_data);
- gssize size = g_input_stream_read_finish(G_INPUT_STREAM(source_object),
- res, NULL);
- switch (size){
- case -1:
- LoggerE("Error occured");
- This->listener->OnCertFileLoaded(This,
- PlatformResult(ErrorCode::IO_ERR, "Failed to load certificate file"));
- g_object_unref(source_object);
- break;
- case 0:
- LoggerD("End of file");
- This->listener->OnCertFileLoaded(This,
- PlatformResult(ErrorCode::NO_ERROR));
- g_object_unref(source_object);
- break;
- default:
- This->fileContent.append(This->buffer, This->buffer + size);
- g_input_stream_read_async(G_INPUT_STREAM(source_object), This->buffer,
- 4096, G_PRIORITY_DEFAULT, NULL, OnStreamRead, This);
- }
+void LoadFileCert::OnError(const common::PlatformResult& result) {
+ listener->OnCertFileLoaded(this, result);
}
-LoadFileCert::~LoadFileCert() {
- delete[] buffer;
+void LoadFileCert::OnFileLoaded() {
+ listener->OnCertFileLoaded(this, PlatformResult(ErrorCode::NO_ERROR));
}
SaveDataObserver::SaveDataObserver(KeyManagerListener* listener, double callbackId):
PlatformResult(ErrorCode::NO_ERROR)));
}
+LoadFilePKCS12::LoadFilePKCS12(KeyManagerListener* listener,
+ double callback_id,
+ const std::string &password,
+ const std::string &key_alias,
+ const std::string &cert_alias):
+ callback_id(callback_id),
+ password(password),
+ key_alias(key_alias),
+ cert_alias(cert_alias),
+ listener(listener) {
+}
+
+void LoadFilePKCS12::AppendBuffer(guint8* buffer, gssize size) {
+ file_content.insert(file_content.end(), buffer, buffer + size);
+}
+
+void LoadFilePKCS12::OnError(const common::PlatformResult& result) {
+ listener->OnPKCS12FileLoaded(this, result);
+}
+
+void LoadFilePKCS12::OnFileLoaded() {
+ listener->OnPKCS12FileLoaded(this, PlatformResult(ErrorCode::NO_ERROR));
+}
+
+SavePKCS12Observer::SavePKCS12Observer(KeyManagerListener* listener, double callback_id):
+ CommonObserver(listener, callback_id),
+ cert_saved(false), key_saved(false) {}
+
+void SavePKCS12Observer::ReceivedError(int error) {
+ LoggerD("Enter, error: %d", error);
+ ErrorCode code = ErrorCode::UNKNOWN_ERR;
+ if (error == CKM_API_ERROR_INPUT_PARAM) {
+ code = ErrorCode::INVALID_VALUES_ERR;
+ }
+ common::TaskQueue::GetInstance().Async(std::bind(
+ &KeyManagerListener::OnSavePKCS12, listener, callbackId,
+ PlatformResult(code, "Failed to save pkcs12 file")));
+}
+
+void SavePKCS12Observer::ReceivedSaveKey() {
+ LoggerD("Enter");
+ key_saved = true;
+ if (cert_saved) {
+ common::TaskQueue::GetInstance().Async(std::bind(
+ &KeyManagerListener::OnSavePKCS12, listener, callbackId,
+ PlatformResult(ErrorCode::NO_ERROR)));
+ }
+}
+
+void SavePKCS12Observer::ReceivedSaveCertificate() {
+ LoggerD("Enter");
+ cert_saved = true;
+ if (key_saved) {
+ common::TaskQueue::GetInstance().Async(std::bind(
+ &KeyManagerListener::OnSavePKCS12, listener, callbackId,
+ PlatformResult(ErrorCode::NO_ERROR)));
+ }
+}
+
} // namespace keymanager
} // namespace extension
#define KEYMANAGER_KEYMANAGER_OBSERVERS_H_
#include <ckm/ckm-manager-async.h>
-#include <gio/gio.h>
#include <string>
#include "common/platform_result.h"
+#include "keymanager/async_file_reader.h"
namespace extension {
namespace keymanager {
class LoadFileCert;
+class LoadFilePKCS12;
class KeyManagerListener {
public:
virtual void OnSaveData(double callbackId, const common::PlatformResult& result) = 0;
virtual void OnCreateSignature(double callbackId, const common::PlatformResult& result, CKM::RawBuffer buffer) = 0;
virtual void OnVerifySignature(double callbackId, const common::PlatformResult& result) = 0;
+ virtual void OnPKCS12FileLoaded(LoadFilePKCS12* reader,
+ const common::PlatformResult& result) = 0;
+ virtual void OnSavePKCS12(double callbackId, const common::PlatformResult& result) = 0;
virtual ~KeyManagerListener() {}
};
void ReceivedSaveCertificate();
};
-struct LoadFileCert {
+struct LoadFileCert: public AsyncFileReader {
LoadFileCert(KeyManagerListener* listener,
double callbackId,
const std::string &password,
const std::string &alias,
bool extractable);
- void LoadFileAsync(const std::string &fileUri);
- virtual ~LoadFileCert();
- double callbackId;
+ double callback_id;
std::string password;
const std::string alias;
bool extractable;
- std::string fileContent;
+ std::string file_content;
+
+protected:
+ void AppendBuffer(guint8* buffer, gssize size);
+ void OnError(const common::PlatformResult& result);
+ void OnFileLoaded();
+
private:
- guint8* buffer;
KeyManagerListener* listener;
+};
+
+struct LoadFilePKCS12: public AsyncFileReader {
+ LoadFilePKCS12(KeyManagerListener* listener,
+ double callbackId,
+ const std::string &password,
+ const std::string &keyAlias,
+ const std::string &certAlias);
+
+ double callback_id;
+ std::string password;
+ const std::string key_alias;
+ const std::string cert_alias;
+ CKM::RawBuffer file_content;
- static void OnFileRead(GObject *source_object,
- GAsyncResult *res,
- gpointer user_data);
- static void OnStreamRead(GObject *source_object,
- GAsyncResult *res,
- gpointer user_data);
+protected:
+ void AppendBuffer(guint8* buffer, gssize size);
+ void OnError(const common::PlatformResult& result);
+ void OnFileLoaded();
+
+private:
+ KeyManagerListener* listener;
};
struct SaveDataObserver: public CommonObserver {
void ReceivedVerifySignature();
};
+struct SavePKCS12Observer: public CommonObserver {
+ SavePKCS12Observer(KeyManagerListener* listener, double callback_id);
+ void ReceivedError(int error);
+ void ReceivedSaveKey();
+ void ReceivedSaveCertificate();
+
+private:
+ bool cert_saved;
+ bool key_saved;
+};
+
} // namespace keymanager
} // namespace extension