Unverified Commit b4d43f50 authored by svetaro's avatar svetaro

SKALE-1762 Add csr manager server

parent 85caea5a
//
// Created by kladko on 12/24/19.
//
#include "CSRManagerServer.h"
#include "RPCException.h"
#include "sgxwallet_common.h"
#include <iostream>
#include <fstream>
#include <jsonrpccpp/server/connectors/httpserver.h>
CSRManagerServer *cs = nullptr;
jsonrpc::HttpServer *hs3 = nullptr;
CSRManagerServer::CSRManagerServer(AbstractServerConnector &connector,
serverVersion_t type):abstractCSRManagerServer(connector, type){}
Json::Value GetUnsignedCSRsImpl(){
std::cerr << "Enter GetUnsignedCSRsImpl" << std::endl;
Json::Value result;
result["status"] = 0;
result["errorMessage"] = "";
//result["hashes"] =;
try{
std::vector<std::string> hashes_vect = csrDb->writeKeysToVector1(MAX_CSR_NUM);
//std::cerr << " vector size is " << hashes_vect.size() << std::endl;
for (int i = 0; i < hashes_vect.size(); i++){
//std::cerr << " vector element is " << hashes_vect.at(i) << std::endl;
result["hashes"][i] = hashes_vect.at(i);
}
} catch (RPCException &_e) {
std::cerr << " err str " << _e.errString << std::endl;
result["status"] = _e.status;
result["errorMessage"] = _e.errString;
}
return result;
}
Json::Value SignByHashImpl(const std::string& hash, int status){
Json::Value result;
result["errorMessage"] = "";
try{
if ( !(status == 0 || status == 2)){
throw RPCException(-111, "Invalid csr status");
}
std::string csr_db_key = "CSR:HASH:" + hash;
std::shared_ptr<std::string> csr_ptr = csrDb->readString(csr_db_key);
if (status == 0) {
std::string csr_name = "cert/" + hash + ".csr";
std::ofstream outfile(csr_name);
outfile << *csr_ptr << std::endl;
outfile.close();
if (access(csr_name.c_str(), F_OK) != 0) {
throw RPCException(FILE_NOT_FOUND, "Csr does not exist");
}
std::string signClientCert = "cd cert && ./create_client_cert " + hash;
if (system(signClientCert.c_str()) == 0) {
std::cerr << "CLIENT CERTIFICATE IS SUCCESSFULLY GENERATED" << std::endl;
} else {
std::cerr << "CLIENT CERTIFICATE GENERATION FAILED" << std::endl;
csrDb->deleteKey(csr_db_key);
std::string status_db_key = "CSR:HASH:" + hash + "STATUS:";
csrStatusDb->deleteKey(status_db_key);
csrStatusDb->writeDataUnique(status_db_key, "-1");
throw RPCException(FAIL_TO_CREATE_CERTIFICATE, "CLIENT CERTIFICATE GENERATION FAILED");
//exit(-1);
}
}
csrDb->deleteKey(csr_db_key);
std::string status_db_key = "CSR:HASH:" + hash + "STATUS:";
csrStatusDb->deleteKey(status_db_key);
csrStatusDb->writeDataUnique(status_db_key, std::to_string(status));
result["status"] = status;
} catch (RPCException &_e) {
std::cerr << " err str " << _e.errString << std::endl;
result["status"] = _e.status;
result["errorMessage"] = _e.errString;
}
return result;
}
Json::Value CSRManagerServer::GetUnsignedCSRs(){
std::lock_guard<std::recursive_mutex> lock(m);
return GetUnsignedCSRsImpl();
}
Json::Value CSRManagerServer::SignByHash(const std::string& hash, int status){
std::lock_guard<std::recursive_mutex> lock(m);
return SignByHashImpl(hash, status);
}
int init_csrmanager_server(){
hs3 = new jsonrpc::HttpServer(BASE_PORT + 2);
hs3 -> BindLocalhost();
cs = new CSRManagerServer(*hs3, JSONRPC_SERVER_V2); // server (json-rpc 2.0)
if (!cs->StartListening()) {
std::cerr << "CSR manager server could not start listening" << std::endl;
exit(-1);
}
else {
std::cerr << "CSR manager server started on port " << BASE_PORT + 2 << std::endl;
}
std::cerr << "CSR manager inited" << std::endl;
return 0;
};
\ No newline at end of file
//
// Created by kladko on 12/24/19.
//
#ifndef SGXD_CSRMANAGERSERVER_H
#define SGXD_CSRMANAGERSERVER_H
#include "abstractCSRManagerServer.h"
#include "LevelDB.h"
#include <mutex>
using namespace jsonrpc;
class CSRManagerServer : public abstractCSRManagerServer {
std::recursive_mutex m;
public:
CSRManagerServer(AbstractServerConnector &connector, serverVersion_t type);
virtual Json::Value GetUnsignedCSRs();
virtual Json::Value SignByHash(const std::string& hash, int status);
};
extern int init_csrmanager_server();
#endif //SGXD_CSRMANAGERSERVER_H
......@@ -42,6 +42,9 @@ static ReadOptions readOptions;
LevelDB* levelDb = nullptr;
LevelDB* csrDb = nullptr;
LevelDB* csrStatusDb = nullptr;
std::shared_ptr<std::string> LevelDB::readString(const std::string &_key) {
......@@ -55,6 +58,10 @@ std::shared_ptr<std::string> LevelDB::readString(const std::string &_key) {
auto status = db->Get(readOptions, _key, &*result);
// if (result == nullptr) {
// throw RPCException(KEY_SHARE_DOES_NOT_EXIST, "Data with this name does not exist");
// }
std::cerr << "key to read from db: " << _key <<std::endl;
throwExceptionOnError(status);
......@@ -166,8 +173,6 @@ void LevelDB::throwExceptionOnError(Status _status) {
uint64_t LevelDB::visitKeys(LevelDB::KeyVisitor *_visitor, uint64_t _maxKeysToVisit) {
std::lock_guard<std::recursive_mutex> lock(mutex);
uint64_t readCounter = 0;
leveldb::Iterator *it = db->NewIterator(readOptions);
......@@ -184,6 +189,40 @@ uint64_t LevelDB::visitKeys(LevelDB::KeyVisitor *_visitor, uint64_t _maxKeysToVi
return readCounter;
}
std::vector<std::string> LevelDB::writeKeysToVector1(uint64_t _maxKeysToVisit){
uint64_t readCounter = 0;
std::vector<std::string> keys;
leveldb::Iterator *it = db->NewIterator(readOptions);
for (it->SeekToFirst(); it->Valid(); it->Next()) {
std::string cur_key(it->key().data(), it->key().size());
keys.push_back(cur_key);
// keys.push_back(it->key().data());
readCounter++;
if (readCounter >= _maxKeysToVisit) {
break;
}
}
delete it;
return keys;
}
void LevelDB::writeDataUnique(const std::string & Name, const std::string &value) {
auto key = Name;
if (readString(Name) != nullptr) {
std::cerr << "name " << Name << " already exists" << std::endl;
throw RPCException(KEY_SHARE_ALREADY_EXISTS, "Data with this name already exists");
}
writeString(key, value);
std::cerr << Name << " is written to db " << std::endl;
}
LevelDB::LevelDB(std::string &filename) {
......
......@@ -28,6 +28,7 @@
#include <memory>
#include <string>
#include <mutex>
#include <vector>
namespace leveldb {
class DB;
......@@ -49,7 +50,7 @@ public:
void writeString(const std::string &key1, const std::string &value1);
void writeDataUnique(const std::string & Name, const std::string &value);
void writeByteArray(const char *_key, size_t _keyLen, const char *value,
size_t _valueLen);
......@@ -80,10 +81,13 @@ public:
class KeyVisitor {
public:
virtual void visitDBKey(const char* _data) = 0;
virtual void writeDBKeysToVector(const char* _data, std::vector<const char*> & keys_vect) {}
};
uint64_t visitKeys(KeyVisitor* _visitor, uint64_t _maxKeysToVisit);
std::vector<std::string> writeKeysToVector1(uint64_t _maxKeysToVisit);
virtual ~LevelDB();
......@@ -92,4 +96,8 @@ public:
extern LevelDB* levelDb;
extern LevelDB* csrDb;
extern LevelDB* csrStatusDb;
#endif
\ No newline at end of file
......@@ -57,7 +57,7 @@ CLEANFILES = $(COMMON_ENCLAVE_SRC) secure_enclave.edl \
## The build target
bin_PROGRAMS = sgxwallet testw
bin_PROGRAMS = sgxwallet testw cert_util
## You can't use $(wildcard ...) with automake so all source files
......@@ -66,7 +66,7 @@ bin_PROGRAMS = sgxwallet testw
COMMON_SRC = sgx_stub.c sgx_detect_linux.c create_enclave.c oc_alloc.c
COMMON_ENCLAVE_SRC = secure_enclave_u.c secure_enclave_u.h
sgxwallet_SOURCES = sgxwallet.c SGXWalletServer.cpp SGXRegistrationServer.cpp RPCException.cpp BLSCrypto.cpp ECDSACrypto.cpp \
sgxwallet_SOURCES = sgxwallet.c SGXWalletServer.cpp SGXRegistrationServer.cpp CSRManagerServer.cpp RPCException.cpp BLSCrypto.cpp ECDSACrypto.cpp \
DKGCrypto.cpp ServerInit.cpp BLSPrivateKeyShareSGX.cpp LevelDB.cpp ServerDataChecker.cpp $(COMMON_SRC)
......@@ -102,7 +102,13 @@ sgxwallet_LDADD=-l$(SGX_URTS_LIB) -LlibBLS/deps/deps_inst/x86_or_x64/lib -Llevel
testw_SOURCES=testw.cpp stubclient.cpp SGXWalletServer.cpp RPCException.cpp BLSCrypto.cpp ServerInit.cpp LevelDB.cpp \
DKGCrypto.cpp BLSPrivateKeyShareSGX.cpp ECDSACrypto.cpp ServerDataChecker.cpp SGXRegistrationServer.cpp $(COMMON_SRC)
DKGCrypto.cpp BLSPrivateKeyShareSGX.cpp ECDSACrypto.cpp ServerDataChecker.cpp SGXRegistrationServer.cpp CSRManagerServer.cpp $(COMMON_SRC)
nodist_testw_SOURCES=${nodist_sgxwallet_SOURCES}
EXTRA_testw_DEPENDENCIES=${EXTRA_sgxwallet_DEPENDENCIES}
testw_LDADD= ${sgxwallet_LDADD}
cert_util_SOURCES=cert_util.cpp stubclient.cpp RPCException.cpp LevelDB.cpp SGXRegistrationServer.cpp CSRManagerServer.cpp
cert_util_LDADD=-LlibBLS/deps/deps_inst/x86_or_x64/lib -Lleveldb/build -LlibBLS/build \
-LlibBLS/build/libff/libff \
-l:libbls.a -l:libleveldb.a \
-l:libff.a -lgmp -ljsonrpccpp-stub -ljsonrpccpp-server -ljsonrpccpp-client -ljsonrpccpp-common -ljsoncpp -lmicrohttpd -lgnutls -lgcrypt -lcurl -lssl -lcrypto -lz -lpthread -ldl
......@@ -22,8 +22,9 @@
#include <functional>
#include "SGXRegistrationServer.h"
#include "LevelDB.h"
SGXRegistrationServer *sr = nullptr;
SGXRegistrationServer *regs = nullptr;
HttpServer *hs2 = nullptr;
bool cert_created = false;
......@@ -33,49 +34,53 @@ void set_cert_created1(bool b){
cert_created = b;
}
SGXRegistrationServer::SGXRegistrationServer(AbstractServerConnector &connector,
serverVersion_t type, bool auto_sign)
: AbstractRegServer(connector, type), is_cert_created(false), cert_auto_sign(auto_sign) {}
Json::Value SignSertificateImpl(const std::string& cert, bool auto_sign = false){
Json::Value SignCertificateImpl(const std::string& csr, bool auto_sign = false){
Json::Value result;
result["status"] = 0;
result["errorMessage"] = "";
try{
//std::hash = cryptlite::sha256::hash_hex(cert);
std::cerr << " going to create csr" << std::endl;
std::cerr << " enter SignCertificateImpl " << std::endl;
std::string status = "1";
std::string hash = cryptlite::sha256::hash_hex(csr);
if ( !auto_sign) {
std::string db_key = "CSR:HASH:" + hash;
csrDb->writeDataUnique(db_key, csr);
}
std::ofstream outfile ("cert/client.csr");
outfile << cert << std::endl;
outfile.close();
std::string csrPath = "cert/client.csr";
if (access(csrPath.c_str(), F_OK) != 0){
throw RPCException(FILE_NOT_FOUND, "Csr does not exist");
}
result["result"] = true;
std::thread thr(set_cert_created1, true);
thr.detach();
if (auto_sign) {
std::string csr_name = "cert/" + hash + ".csr";
std::ofstream outfile(csr_name);
outfile << csr << std::endl;
outfile.close();
if (access(csr_name.c_str(), F_OK) != 0) {
throw RPCException(FILE_NOT_FOUND, "Csr does not exist");
}
std::string genCert = "cd cert && ./create_client_cert " + hash;
if (system(genCert.c_str()) == 0){
std::cerr << "CLIENT CERTIFICATE IS SUCCESSFULLY GENERATED" << std::endl;
status = "0";
}
else{
std::cerr << "CLIENT CERTIFICATE GENERATION FAILED" << std::endl;
throw RPCException(FAIL_TO_CREATE_CERTIFICATE, "CLIENT CERTIFICATE GENERATION FAILED");
//exit(-1);
}
}
// std::thread timeout_thr (std::bind(&SGXRegistrationServer::set_cert_created, this, true));
result["result"] = true;
result["hash"] = hash;
if (auto_sign) {
std::string genCert = "cd cert && ./create_client_cert";
std::string db_key = "CSR:HASH:" + hash + "STATUS:";
csrStatusDb->writeDataUnique(db_key, status);
if (system(genCert.c_str()) == 0){
std::cerr << "CLIENT CERTIFICATE IS SUCCESSFULLY GENERATED" << std::endl;
}
else{
std::cerr << "CLIENT CERTIFICATE GENERATION FAILED" << std::endl;
exit(-1);
}
}
} catch (RPCException &_e) {
std::cerr << " err str " << _e.errString << std::endl;
result["status"] = _e.status;
......@@ -88,31 +93,49 @@ Json::Value SignSertificateImpl(const std::string& cert, bool auto_sign = false)
Json::Value GetSertificateImpl(const std::string& hash){
Json::Value result;
result["status"] = 0;
result["status"] = 1;
result["errorMessage"] = "";
std::string cert;
try{
if (!cert_created){
result["status"] = 1;
result["cert"] = "";
}
else {
std::ifstream infile("cert/client.crt");
if (!infile.is_open()) {
throw RPCException(FILE_NOT_FOUND, "Certificate does not exist");
} else {
ostringstream ss;
ss << infile.rdbuf();
cert = ss.str();
infile.close();
system("cd cert && rm -rf client.crt");
// std::string rejected_name = "rejected_" + hash + ".txt";
// if (access(rejected_name.c_str(), F_OK) == 0){
// result["status"] = 2;
// result["cert"] = "";
// return result;
// }
result["cert"] = cert;
result["status"] = 0;
std::string db_key = "CSR:HASH:" + hash + "STATUS:";
std::shared_ptr<string> status_str_ptr = csrStatusDb->readString(db_key);
if (status_str_ptr == nullptr){
throw RPCException(FILE_NOT_FOUND, "Data with this name does not exist in csr db");
}
int status = std::atoi(status_str_ptr->c_str());
if ( status == 0){
std::string crt_name = "cert/" + hash + ".crt";
//if (access(crt_name.c_str(), F_OK) == 0){
std::ifstream infile(crt_name);
if (!infile.is_open()) {
throw RPCException(FILE_NOT_FOUND, "Certificate does not exist");
} else {
ostringstream ss;
ss << infile.rdbuf();
cert = ss.str();
infile.close();
std::string remove_crt = "cd cert && rm -rf" + hash + ".crt";
system(remove_crt.c_str());
// result["cert"] = cert;
// result["status"] = 0;
}
}
// else if (access(crt_name.c_str(), F_OK) != 0){
// result["status"] = 1;
// result["cert"] = "";
// }
} catch (RPCException &_e) {
std::cerr << " err str " << _e.errString << std::endl;
result["status"] = _e.status;
......@@ -124,10 +147,10 @@ Json::Value GetSertificateImpl(const std::string& hash){
}
Json::Value SGXRegistrationServer::SignCertificate(const std::string& cert){
Json::Value SGXRegistrationServer::SignCertificate(const std::string& csr){
std::cerr << "Enter SignCertificate " << std::endl;
lock_guard<recursive_mutex> lock(m);
return SignSertificateImpl(cert, cert_auto_sign);
return SignCertificateImpl(csr, cert_auto_sign);
}
Json::Value SGXRegistrationServer::GetCertificate(const std::string& hash){
......@@ -161,13 +184,20 @@ int init_registration_server(bool sign_automatically) {
// }
// }
hs2 = new HttpServer(1031);
sr = new SGXRegistrationServer(*hs2,
hs2 = new HttpServer(BASE_PORT + 1);
regs = new SGXRegistrationServer(*hs2,
JSONRPC_SERVER_V2, sign_automatically); // hybrid server (json-rpc 1.0 & 2.0)
if (!sr->StartListening()) {
if (!regs->StartListening()) {
cerr << "Registration server could not start listening" << endl;
exit(-1);
}
else {
cerr << "Registration Server started on port " << BASE_PORT + 1 << endl;
}
return 0;
}
\ No newline at end of file
}
......@@ -25,7 +25,7 @@ public:
void set_cert_created(bool b);
virtual Json::Value SignCertificate(const std::string& cert);
virtual Json::Value SignCertificate(const std::string& csr);
virtual Json::Value GetCertificate(const std::string& hash);
};
......@@ -34,4 +34,5 @@ public:
extern int init_registration_server(bool sign_automatically = false);
#endif // SGXD_SGXREGISTRATIONSERVER_H
\ No newline at end of file
......@@ -46,8 +46,8 @@
#include "LevelDB.h"
#include "SGXWalletServer.h"
#include "SGXRegistrationServer.h"
#include "CSRManagerServer.h"
#include "BLSCrypto.h"
#include "ServerInit.h"
......@@ -63,9 +63,13 @@ void init_daemon() {
libff::init_alt_bn128_params();
static std::string dbName("./" WALLETDB_NAME);
levelDb = new LevelDB(dbName);
static std::string csr_dbname = "CSR_DB";
csrDb = new LevelDB(csr_dbname);
levelDb = new LevelDB(dbName);
static std::string csr_status_dbname = "CSR_STATUS_DB";
csrStatusDb = new LevelDB(csr_status_dbname);
}
......@@ -117,8 +121,6 @@ int sgxServerInited = 0;
void init_all(bool check_cert, bool sign_automatically) {
if (sgxServerInited == 1)
return;
......@@ -126,6 +128,7 @@ void init_all(bool check_cert, bool sign_automatically) {
init_server(check_cert);
init_registration_server(sign_automatically);
init_csrmanager_server();
init_enclave();
std::cerr << "enclave inited" << std::endl;
init_daemon();
......
#!/bin/bash
#sign csr
yes | openssl ca -config ca.config -in "client.csr" -out "client.crt"
CSREXT=".csr"
CRTEXT=".crt"
CSRFILE="$1$CSREXT"
CRTFILE="$1$CRTEXT"
yes | openssl ca -config ca.config -in $CSRFILE -out $CRTFILE
//
// Created by kladko on 12/27/19.
//
#include <iostream>
#include <cstring>
#include <jsonrpccpp/client/connectors/httpclient.h>
#include "stubclient.h"
#include <unistd.h>
int print_hashes(){
jsonrpc::HttpClient client("http://localhost:1028");
StubClient c(client, jsonrpc::JSONRPC_CLIENT_V2);
std::cout << "Client inited" << std::endl;
std::cout << c.GetUnsignedCSRs() << std::endl;
exit(0);
}
void sign_by_hash(std::string & hash, int status){
jsonrpc::HttpClient client("http://localhost:1028");
StubClient c(client, jsonrpc::JSONRPC_CLIENT_V2);
std::cout << "Client inited" << std::endl;
std::cout << c.SignByHash(hash, status) << std::endl;
exit(0);
}
int main(int argc, char *argv[]) {
int opt;
if (argc > 1 && strlen(argv[1]) == 1) {
fprintf(stderr, "option is too short %s\n", argv[1]);
exit(1);
}
if (argc == 1) {
std::cout << "You may use following flags:" << std::endl;
std::cout << " -p print all unsigned csr hashes " << std::endl;
std::cout << " -s [hash] sign csr by hash" << std::endl;
std::cout << " -r [hash] reject csr by hash" << std::endl;
exit(0);
}
std::string hash;
while ((opt = getopt(argc, argv, "ps:r:")) != -1) {
switch (opt) {
case 'p': print_hashes();
break;
case 's': hash = optarg;
sign_by_hash(hash, 0);
break;
case 'r': hash = optarg;
sign_by_hash(hash, 2);
break;
case '?': // fprintf(stderr, "unknown flag\n");
exit(1);
}
}
return 0;
}
......@@ -61,16 +61,15 @@ int main(int argc, char *argv[]) {
while ((opt = getopt(argc, argv, "csh")) != -1) {
switch (opt) {
// case 'h':
// if (strlen(argv[1]) == 2 ) {
// fprintf(stderr, "-c client certificate will not be checked\n");
// fprintf(stderr, "-s client certificate will be signed automatically\n");
// exit(0);
// } else {
// fprintf(stderr, "unknown flag %s\n", argv[1]);
// exit(1);
// }
case 'h':
if (strlen(argv[1]) == 2 ) {
fprintf(stderr, "-c client certificate will not be checked\n");
fprintf(stderr, "-s client certificate will be signed automatically\n");
exit(0);
} else {
fprintf(stderr, "unknown flag %s\n", argv[1]);
exit(1);
}
case 'c':
check_client_cert = false;
break;
......
......@@ -59,7 +59,13 @@
#define FILE_NOT_FOUND -44
#define SGX_ENCLAVE_ERROR -666;
#define FAIL_TO_CREATE_CERTIFICATE -55
#define SGX_ENCLAVE_ERROR -666
#define MAX_CSR_NUM 1000
#define BASE_PORT 1026
#define WALLETDB_NAME "sgxwallet.db"//"test_sgxwallet.db"//
#define ENCLAVE_NAME "secure_enclave.signed.so"
......
......@@ -197,6 +197,34 @@ class StubClient : public jsonrpc::Client
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
////CSRManagerServer
Json::Value GetUnsignedCSRs() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("GetUnsignedCSRs",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value SignByHash(const std::string& hash, int status) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p["hash"] = hash;
p["status"] = status;
Json::Value result = this->CallMethod("SignByHash",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
};
#endif //JSONRPC_CPP_STUB_STUBCLIENT_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment