SGXRegistrationServer.cpp 5.81 KB
Newer Older
Chadwick Strange's avatar
Chadwick Strange committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
    Copyright (C) 2019-Present SKALE Labs

    This file is part of sgxwallet.

    sgxwallet is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    sgxwallet is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with sgxwallet.  If not, see <https://www.gnu.org/licenses/>.

    @file SGXRegistrationServer.cpp
    @author Stan Kladko
    @date 2019
*/
23

24 25 26 27
#include <iostream>
#include <fstream>
#include <sstream>

28
#include <third_party/cryptlite/sha256.h>
29 30 31 32 33 34
#include <jsonrpccpp/server/connectors/httpserver.h>

#include <stdio.h>

#include "sgxwallet_common.h"

35
#include "SGXException.h"
36 37 38 39 40 41 42
#include "LevelDB.h"

#include <thread>
#include <time.h>

#include <functional>

43
#include "SGXRegistrationServer.h"
44
#include "LevelDB.h"
45

kladko's avatar
kladko committed
46
#include "Log.h"
kladko's avatar
kladko committed
47
#include "common.h"
48

kladko's avatar
kladko committed
49 50 51 52
int printDebugInfo = -1;
int useHTTPS = -1;
int encryptKeys = -1;
int autoconfirm = -1;
53

kladko's avatar
kladko committed
54 55
shared_ptr <SGXRegistrationServer> SGXRegistrationServer::server = nullptr;
shared_ptr <HttpServer> SGXRegistrationServer::httpServer = nullptr;
56 57

SGXRegistrationServer::SGXRegistrationServer(AbstractServerConnector &connector,
kladko's avatar
kladko committed
58
                                             serverVersion_t type, bool _autoSign)
kladko's avatar
kladko committed
59
        : AbstractRegServer(connector, type), autoSign(_autoSign) {}
kladko's avatar
kladko committed
60 61 62


Json::Value signCertificateImpl(const string &_csr, bool _autoSign = false) {
kladko's avatar
kladko committed
63
    spdlog::info(__FUNCTION__);
kladko's avatar
kladko committed
64 65 66 67
    INIT_RESULT(result)

    result["result"] = false;

kladko's avatar
kladko committed
68
    try {
kladko's avatar
kladko committed
69

kladko's avatar
kladko committed
70
        string hash = cryptlite::sha256::hash_hex(_csr);
kladko's avatar
kladko committed
71 72 73 74

        if (system("ls " CERT_DIR "/" CERT_CREATE_COMMAND) != 0) {
            spdlog::error("cert/create_client_cert does not exist");
            throw SGXException(FAIL_TO_CREATE_CERTIFICATE, "CLIENT CERTIFICATE GENERATION FAILED");
kladko's avatar
kladko committed
75 76
        }

kladko's avatar
kladko committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

        string csr_name = string(CERT_DIR) + "/" + hash + ".csr";
        ofstream outfile(csr_name);
        outfile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
        outfile << _csr << endl;
        outfile.close();

        if (system(("ls " + csr_name).c_str()) != 0) {
            spdlog::error("could not create csr file");
            throw SGXException(FAIL_TO_CREATE_CERTIFICATE, "CLIENT CERTIFICATE GENERATION FAILED");
        }

        if (system(("openssl req -in " + csr_name).c_str()) != 0) {
            spdlog::error("Incorrect CSR format: {}", _csr);
            throw SGXException(FAIL_TO_CREATE_CERTIFICATE, "Incorrect CSR format ");
        }
kladko's avatar
kladko committed
93

kladko's avatar
kladko committed
94

kladko's avatar
kladko committed
95 96
        if (_autoSign) {

kladko's avatar
kladko committed
97 98 99
            string genCert = string("cd ") + CERT_DIR + "&& ./"
                    + CERT_CREATE_COMMAND + " " + hash ;

kladko's avatar
kladko committed
100 101

            if (system(genCert.c_str()) == 0) {
kladko's avatar
kladko committed
102
                spdlog::info("Client cert " + hash + " generated");
kladko's avatar
kladko committed
103 104 105
                string db_key = "CSR:HASH:" + hash + "STATUS:";
                string status = "0";
                LevelDB::getCsrStatusDb()->writeDataUnique(db_key, status);
kladko's avatar
kladko committed
106

kladko's avatar
kladko committed
107
            } else {
kladko's avatar
kladko committed
108 109

                spdlog::error("Client cert generation failed: {} ", genCert);
110
                throw SGXException(FAIL_TO_CREATE_CERTIFICATE, "CLIENT CERTIFICATE GENERATION FAILED");
kladko's avatar
kladko committed
111
            }
kladko's avatar
kladko committed
112 113 114
        } else {
            string db_key = "CSR:HASH:" + hash;
            LevelDB::getCsrStatusDb()->writeDataUnique(db_key, _csr);
kladko's avatar
kladko committed
115 116 117 118 119
        }

        result["result"] = true;
        result["hash"] = hash;

kladko's avatar
kladko committed
120
    } HANDLE_SGX_EXCEPTION(result)
121

kladko's avatar
kladko committed
122
    return result;
123 124
}

kladko's avatar
kladko committed
125
Json::Value getCertificateImpl(const string &hash) {
kladko's avatar
kladko committed
126 127 128 129 130
    Json::Value result;

    string cert;
    try {
        string db_key = "CSR:HASH:" + hash + "STATUS:";
kladko's avatar
kladko committed
131
        shared_ptr <string> status_str_ptr = LevelDB::getCsrStatusDb()->readString(db_key);
kladko's avatar
kladko committed
132
        if (status_str_ptr == nullptr) {
kladko's avatar
kladko committed
133
            throw SGXException(CERT_REQUEST_DOES_NOT_EXIST, "Data with this name does not exist in csr db");
kladko's avatar
kladko committed
134 135 136 137
        }
        int status = atoi(status_str_ptr->c_str());

        if (status == 0) {
kladko's avatar
kladko committed
138
            string crtPath = "cert/" + hash + ".crt";
kladko's avatar
kladko committed
139

kladko's avatar
kladko committed
140 141
            if (system(("ls " + crtPath).c_str()) != 0) {
                throw SGXException(FILE_NOT_FOUND, "Certificate does not exist");
kladko's avatar
kladko committed
142
            }
kladko's avatar
kladko committed
143 144 145 146 147 148 149

            ifstream infile(crtPath);
            infile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
            ostringstream ss;
            ss << infile.rdbuf();
            infile.close();
            cert = ss.str();
kladko's avatar
kladko committed
150 151 152 153 154
        }

        result["status"] = status;
        result["cert"] = cert;

kladko's avatar
kladko committed
155
    } HANDLE_SGX_EXCEPTION(result)
156

kladko's avatar
kladko committed
157
    return result;
158 159 160
}


161
Json::Value SGXRegistrationServer::SignCertificate(const string &csr) {
kladko's avatar
kladko committed
162 163
    spdlog::info(__FUNCTION__);
    LOCK(m)
kladko's avatar
kladko committed
164
    return signCertificateImpl(csr, autoSign);
165 166
}

167
Json::Value SGXRegistrationServer::GetCertificate(const string &hash) {
kladko's avatar
kladko committed
168 169
    spdlog::info(__FUNCTION__);
    LOCK(m)
kladko's avatar
kladko committed
170
    return getCertificateImpl(hash);
171 172
}

kladko's avatar
kladko committed
173

kladko's avatar
kladko committed
174
int SGXRegistrationServer::initRegistrationServer(bool _autoSign) {
175

kladko's avatar
kladko committed
176 177
    httpServer = make_shared<HttpServer>(BASE_PORT + 1);
    server = make_shared<SGXRegistrationServer>(*httpServer,
kladko's avatar
kladko committed
178 179
                                                JSONRPC_SERVER_V2,
                                                _autoSign); // hybrid server (json-rpc 1.0 & 2.0)
180

kladko's avatar
kladko committed
181
    if (!server->StartListening()) {
kladko's avatar
kladko committed
182
        spdlog::error("Registration server could not start listening on port {}", BASE_PORT + 1);
kladko's avatar
kladko committed
183 184 185 186
        exit(-1);
    } else {
        spdlog::info("Registration server started on port {}", BASE_PORT + 1);
    }
187 188


kladko's avatar
kladko committed
189
    return 0;
190 191
}

kladko's avatar
kladko committed
192 193 194 195 196 197

shared_ptr<SGXRegistrationServer> SGXRegistrationServer::getServer() {
    CHECK_STATE(server);
    return server;
}