SEKManager.cpp 6.68 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
    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 SEKManager.cpp
    @author Stan Kladko
21
    @date 2020
22 23 24
*/

#include "SEKManager.h"
25
#include "SGXException.h"
26 27 28 29
#include "BLSCrypto.h"
#include "LevelDB.h"

#include <iostream>
30
#include <algorithm>
31 32

#include "sgxwallet_common.h"
kladko's avatar
kladko committed
33
#include "common.h"
34 35
#include "sgxwallet.h"

36 37 38
#include "ServerDataChecker.h"
#include "spdlog/spdlog.h"

39 40 41 42 43 44 45
bool case_insensitive_match(string s1, string s2) {
  //convert s1 and s2 into lower case strings
  transform(s1.begin(), s1.end(), s1.begin(), ::tolower);
  transform(s2.begin(), s2.end(), s2.begin(), ::tolower);
  return s1.compare(s2);
}

svetaro's avatar
svetaro committed
46 47 48 49 50 51 52 53 54 55
void create_test_key(){
  int errStatus =  0;
  vector<char> errMsg(1024,0);
  uint32_t enc_len;

  uint8_t encrypted_key[BUF_LEN];
  memset(encrypted_key, 0, BUF_LEN);

  std::string key = TEST_VALUE;

56
  status = trustedEncryptKeyAES(eid, &errStatus, errMsg.data(), key.c_str(), encrypted_key, &enc_len);
svetaro's avatar
svetaro committed
57
  if ( status != 0){
svetaro's avatar
svetaro committed
58
    std::cerr << "encrypt test key failed with status " << status << std::endl;
59
    throw SGXException(status, errMsg.data()) ;
svetaro's avatar
svetaro committed
60 61
  }

svetaro's avatar
svetaro committed
62 63
  //std::cerr << "enc len is " << enc_len << std::endl;

svetaro's avatar
svetaro committed
64 65 66 67
  vector<char> hexEncrKey(2 * enc_len + 1, 0);

  carray2Hex(encrypted_key, enc_len, hexEncrKey.data());

svetaro's avatar
svetaro committed
68 69 70 71 72
  uint64_t test_len;
  vector<uint8_t>test_encr_key(1024, 0);
  if (!hex2carray(hexEncrKey.data(), &test_len, test_encr_key.data())){
    std::cerr << "wrong encrypted test key" << std::endl;
  }
svetaro's avatar
svetaro committed
73

74

svetaro's avatar
svetaro committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
  LevelDB::getLevelDb() -> writeDataUnique("TEST_KEY", hexEncrKey.data());
}

bool check_SEK(std::string SEK){
   std::shared_ptr <std::string> test_key_ptr = LevelDB::getLevelDb() -> readString("TEST_KEY");
//  if (test_key_ptr == nullptr){
//    spdlog::error("empty db" );
//    exit(-1);
//  }
//  else{
    vector<uint8_t> encr_test_key(BUF_LEN, 0);
    uint64_t len;
    if ( !hex2carray(test_key_ptr->c_str(), &len, encr_test_key.data())){
      spdlog::error("wrong test key" );
      exit(-1);
    }

    vector<char> decr_key(1024,0);
    vector<char> errMsg(1024,0);
    int err_status = 0;

    vector<uint8_t> encr_SEK(1024,0);

    uint32_t l = len;
    std::cerr << " l is " << l << std::endl;

101
    status = trustedSetSEK_backup(eid, &err_status, errMsg.data(), encr_SEK.data(), &l, SEK.c_str() );
svetaro's avatar
svetaro committed
102 103
    if (status != SGX_SUCCESS){
      cerr << "RPCException thrown with status " << status << endl;
104
      throw SGXException(status, errMsg.data());
svetaro's avatar
svetaro committed
105 106
    }

107
    status = trustedDecryptKeyAES(eid, &err_status, errMsg.data(), encr_test_key.data(), len, decr_key.data());
svetaro's avatar
svetaro committed
108
    if (status != SGX_SUCCESS || err_status != 0){
svetaro's avatar
svetaro committed
109
      spdlog::error("failed to decrypt test key" );
svetaro's avatar
svetaro committed
110
      spdlog::error(errMsg.data());
svetaro's avatar
svetaro committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124
      exit(-1);
    }


    std::string test_key = TEST_VALUE;
    if (test_key.compare(decr_key.data())!= 0){
      std::cerr << "decrypted key is " << decr_key.data() << std::endl;
      spdlog::error("Invalid SEK" );
      return false;
    }
    return true;
 // }
}

125
void gen_SEK(){
126

kladko's avatar
kladko committed
127
  vector<char> errMsg(1024,0);
128
  int err_status = 0;
kladko's avatar
kladko committed
129
  vector<uint8_t> encr_SEK(1024, 0);
130 131
  uint32_t enc_len = 0;

132 133 134 135
  //vector<char> SEK(65, 0);
  char SEK[65];
  memset(SEK, 0, 65);

136
  status = trustedGenerateSEK(eid, &err_status, errMsg.data(), encr_SEK.data(), &enc_len, SEK);
137
  if (status != SGX_SUCCESS ||  err_status != 0  ){
138
    throw SGXException(status, errMsg.data()) ;
139 140
  }

141
  vector<char> hexEncrKey(2 * enc_len + 1, 0);
142

kladko's avatar
kladko committed
143
  carray2Hex(encr_SEK.data(), enc_len, hexEncrKey.data());
144

145 146 147
  cout << "ATTENTION! THIS IS YOUR KEY FOR BACK UP. PLEASE COPY IT TO THE SAFE PLACE" << endl;
  cout << "key is " << SEK << endl;

svetaro's avatar
svetaro committed
148 149 150 151 152 153 154 155 156
  if (!autoconfirm) {
    std::string confirm_str = "I confirm";
    std::string buffer;
    do {
      std::cout << " DO YOU CONFIRM THAT YOU COPIED THE KEY? (if you confirm type - I confirm)"
                << std::endl;
      std::getline(std::cin, buffer);
    } while (case_insensitive_match(confirm_str, buffer)); //(strcmp(confirm_str.c_str(), buffer.c_str()) != 0);
  }
kladko's avatar
kladko committed
157 158 159 160 161

  if (system("reset") != 0) {
      cerr << "Could not execute reset" << endl;
  }

kladko's avatar
kladko committed
162
  LevelDB::getLevelDb()->writeDataUnique("SEK", hexEncrKey.data());
163

svetaro's avatar
svetaro committed
164
  create_test_key();
165
}
166

167
void trustedSetSEK(std::shared_ptr<std::string> hex_encr_SEK){
168 169 170 171
  vector<char> errMsg(1024,0);
  int err_status = 0;
  //vector<uint8_t> encr_SEK(1024, 0);

172 173
  uint8_t encr_SEK[BUF_LEN];
  memset(encr_SEK, 0, BUF_LEN);
174 175 176 177

  uint64_t len;

  if (!hex2carray(hex_encr_SEK->c_str(), &len, encr_SEK)){
178
    throw SGXException(INVALID_HEX, "Invalid encrypted SEK Hex");
179 180
  }

181
  status = trustedSetSEK(eid, &err_status, errMsg.data(), encr_SEK, len );
182
  if ( status != SGX_SUCCESS || err_status != 0 ){
183
    cerr << "RPCException thrown" << endl;
184
    throw SGXException(status, errMsg.data()) ;
185 186 187
  }

}
188 189 190 191 192 193 194

void enter_SEK(){
  vector<char> errMsg(1024,0);
  int err_status = 0;
  vector<uint8_t> encr_SEK(BUF_LEN, 0);
  uint32_t enc_len;

svetaro's avatar
svetaro committed
195 196 197 198 199 200
  std::shared_ptr <std::string> test_key_ptr = LevelDB::getLevelDb() -> readString("TEST_KEY");
  if (test_key_ptr == nullptr){
    spdlog::error("empty db" );
    exit(-1);
  }

201 202 203
  std::string SEK;
  std::cout << "ENTER BACKUP KEY" << std::endl;
  std::cin >> SEK;
svetaro's avatar
svetaro committed
204
  while (!checkHex(SEK, 16) || !check_SEK(SEK)){
205 206 207 208
    std::cout << "KEY IS INVALID.TRY ONCE MORE" << std::endl;
    SEK = "";
    std::cin >> SEK;
  }
svetaro's avatar
svetaro committed
209 210
//  if (DEBUG_PRINT)
//   std::cerr << "your key is " << SEK << std::endl;
svetaro's avatar
svetaro committed
211

212

213
  status = trustedSetSEK_backup(eid, &err_status, errMsg.data(), encr_SEK.data(), &enc_len, SEK.c_str() );
214 215
  if (status != SGX_SUCCESS){
    cerr << "RPCException thrown with status " << status << endl;
216
    throw SGXException(status, errMsg.data());
217 218 219 220 221 222 223 224 225 226
  }

  vector<char> hexEncrKey(2 * enc_len + 1, 0);

  carray2Hex(encr_SEK.data(), enc_len, hexEncrKey.data());

  LevelDB::getLevelDb() -> deleteKey("SEK");
  LevelDB::getLevelDb() -> writeDataUnique("SEK", hexEncrKey.data());
}

kladko's avatar
kladko committed
227
void initSEK(){
228 229
  std::shared_ptr<std::string> encr_SEK_ptr = LevelDB::getLevelDb()->readString("SEK");
  if (encr_SEK_ptr == nullptr){
230
    spdlog::error("SEK was not created yet. Going to create SEK");
231 232 233
    gen_SEK();
  }
  else{
234
    trustedSetSEK(encr_SEK_ptr);
235 236
  }
}
svetaro's avatar
svetaro committed
237

svetaro's avatar
svetaro committed
238
//a002e7ca685d46a32771d16fe2518e58