/* 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 sgxwall.cpp @author Stan Kladko @date 2020 */ #include <csignal> #include <stdbool.h> #include "ExitHandler.h" #include "BLSCrypto.h" #include "ServerInit.h" #include "SEKManager.h" #include "SGXWalletServer.h" #include <fstream> #include "TestUtils.h" #include "zmq_src/ZMQServer.h" #include "testw.h" #include "sgxwall.h" #include "sgxwallet.h" void SGXWallet::printUsage() { cerr << "\nAvailable flags:\n"; cerr << "\nDebug flags:\n\n"; cerr << " -v Verbose mode: turn on debug output\n"; cerr << " -V Detailed verbose mode: turn on debug and trace outputs\n"; cerr << "\nBackup, restore, update flags:\n\n"; cerr << " -b filename Restore from back up or software update. You will need to put backup key into a file in sgx_data dir. \n"; cerr << " -y Do not ask user to acknowledge receipt of the backup key \n"; cerr << "\nSecurity flags flags:\n\n"; cerr << " -n Use http instead of https. Default is to use https with a selg-signed server cert. Insecure! \n"; cerr << " -c Disable client authentication using certificates. Insecure!\n"; cerr << " -s Sign client certificates without human confirmation. Insecure! \n"; cerr << " -e Only owner of the key can access it.\n"; } void SGXWallet::serializeKeys(const vector<string>& _ecdsaKeyNames, const vector<string>& _blsKeyNames, const string& _fileName) { Json::Value top(Json::objectValue); Json::Value ecdsaKeysJson(Json::objectValue); Json::Value blsKeysJson(Json::objectValue); for (uint i = 0; i < _ecdsaKeyNames.size(); i++) { auto key = to_string(i + 1); string keyFull(3 - key.size(), '0'); keyFull.append(key); ecdsaKeysJson[keyFull] = _ecdsaKeyNames[i]; blsKeysJson[keyFull] = _blsKeyNames[i]; } top["ecdsaKeyNames"] = ecdsaKeysJson; top["blsKeyNames"] = blsKeysJson; ofstream fs; fs.open(_fileName); fs << top; fs.close(); } void SGXWallet::signalHandler( int signalNo ) { spdlog::info("Received exit signal {}.", signalNo); ExitHandler::exitHandler( signalNo ); } int main(int argc, char *argv[]) { bool enterBackupKeyOption = false; bool useHTTPSOption = true; bool printDebugInfoOption = false; bool printTraceInfoOption = false; bool autoconfirmOption = false; bool checkClientCertOption = true; bool autoSignClientCertOption = false; bool generateTestKeys = false; bool checkKeyOwnership = false; std::signal(SIGABRT, SGXWallet::signalHandler); int opt; if (argc > 1 && strlen(argv[1]) == 1) { SGXWallet::printUsage(); exit(-21); } while ((opt = getopt(argc, argv, "cshd0abyvVneT")) != -1) { switch (opt) { case 'h': SGXWallet::printUsage(); exit(-22); case 'c': checkClientCertOption = false; break; case 's': autoSignClientCertOption = true; break; case 'd': printDebugInfoOption = true; break; case 'v': printDebugInfoOption = true; break; case 'V': printDebugInfoOption = true; printTraceInfoOption = true; break; case '0': useHTTPSOption = false; break; case 'n': useHTTPSOption = false; checkKeyOwnership = false; break; case 'e': checkKeyOwnership = true; break; case 'a': enterBackupKeyOption = false; break; case 'b': enterBackupKeyOption = true; break; case 'y': autoconfirmOption = true; break; case 'T': generateTestKeys = true; break; default: SGXWallet::printUsage(); exit(-23); break; } } uint64_t logLevel = L_INFO; if (printDebugInfoOption) { logLevel = L_DEBUG; } if (printTraceInfoOption) { logLevel = L_TRACE; } setFullOptions(logLevel, useHTTPSOption, autoconfirmOption, enterBackupKeyOption); uint32_t enclaveLogLevel = L_INFO; if (printDebugInfoOption) { enclaveLogLevel = L_DEBUG; } if (printTraceInfoOption) { enclaveLogLevel = L_TRACE; } cerr << "Calling initAll ..." << endl; initAll(enclaveLogLevel, checkClientCertOption, checkClientCertOption, autoSignClientCertOption, generateTestKeys, checkKeyOwnership); cerr << "Completed initAll." << endl; //check if test keys already exist string TEST_KEYS_4_NODE = "sgx_data/4node.json"; ifstream is(TEST_KEYS_4_NODE); auto keysExist = is.good(); if (keysExist) { cerr << "Found test keys." << endl; } if (generateTestKeys && !keysExist && !ExitHandler::shouldExit()) { cerr << "Generating test keys ..." << endl; HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); vector<string> ecdsaKeyNames; vector<string> blsKeyNames; int schainID = 1; int dkgID = 1; TestUtils::doDKG(c, 4, 3, ecdsaKeyNames, blsKeyNames, schainID, dkgID); SGXWallet::serializeKeys(ecdsaKeyNames, blsKeyNames, "sgx_data/4node.json"); schainID = 2; dkgID = 2; TestUtils::doDKG(c, 16, 11, ecdsaKeyNames, blsKeyNames, schainID, dkgID); SGXWallet::serializeKeys(ecdsaKeyNames, blsKeyNames, "sgx_data/16node.json"); cerr << "Successfully completed generating test keys into sgx_data" << endl; } while ( !ExitHandler::shouldExit() ) { sleep(10); } ExitHandler::exit_code_t exitCode = ExitHandler::requestedExitCode(); int signal = ExitHandler::getSignal(); spdlog::info("Will exit with exit code {}", exitCode); exitAll(); spdlog::info("Exiting with exit code {} and signal", exitCode, signal); return exitCode; }