CKey::CKey(const CKey& b) { pkey = EC_KEY_dup(b.pkey); if (pkey == NULL) throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); fSet = b.fSet; }
CKey& CKey::operator=(const CKey& b) { if (!EC_KEY_copy(pkey, b.pkey)) throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); fSet = b.fSet; return (*this); }
// create a compact signature (65 bytes), which allows reconstructing the used public key // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y bool CKey::SignCompact(uint256 hash, std::vector<unsigned char> &vchSig) { bool fOk = false; ECDSA_SIG *sig = ECDSA_do_sign((unsigned char *)&hash, sizeof(hash), pkey); if (sig == NULL) return false; vchSig.clear(); vchSig.resize(65, 0); int nBitsR = BN_num_bits(sig->r); int nBitsS = BN_num_bits(sig->s); if (nBitsR <= 256 && nBitsS <= 256) { int nRecId = -1; for (int i = 0; i < 4; i++) { CKey keyRec; keyRec.fSet = true; if (fCompressedPubKey) keyRec.SetCompressedPubKey(); if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char *)&hash, sizeof(hash), i, 1) == 1) if (keyRec.GetPubKey() == this->GetPubKey()) { nRecId = i; break; } } if (nRecId == -1) throw key_error("CKey::SignCompact() : unable to construct recoverable key"); vchSig[0] = nRecId + 27 + (fCompressedPubKey ? 4 : 0); BN_bn2bin(sig->r, &vchSig[33 - (nBitsR + 7) / 8]); BN_bn2bin(sig->s, &vchSig[65 - (nBitsS + 7) / 8]); fOk = true; } ECDSA_SIG_free(sig); return fOk; }
void CKey::MakeNewKey(bool fCompressed) { if (!EC_KEY_generate_key(pkey)) throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); if (fCompressed) SetCompressedPubKey(); fSet = true; }
void CKey::Reset() { fCompressedPubKey = false; pkey = EC_KEY_new_by_curve_name(NID_sect571r1); if (pkey == NULL) throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); fSet = false; }
bool CKey::SetSecret(const std::vector<unsigned char>& vch) { EC_KEY_free(pkey); pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (pkey == NULL) throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); BIGNUM *bn = BN_bin2bn(&vch[0],vch.size(),BN_new()); if (bn == NULL) throw key_error("CKey::SetSecret() : BN_bin2bn failed"); if (!EC_KEY_regenerate_key(pkey,bn)) { BN_clear_free(bn); throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); } BN_clear_free(bn); fSet = true; SetCompressedPubKey(); return true; }
void CCryptKey::Reset() { fCompressedPubKey = false; if (pkey != NULL) EC_KEY_free(pkey); pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (pkey == NULL) throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); fSet = false; }
client::int_type client::recv_multi_bulk_reply_(string_set & out) { int_type length = recv_bulk_reply_(prefix_multi_bulk_reply); if (length == -1) throw key_error("no such key"); for (int_type i = 0; i < length; ++i) out.insert(recv_bulk_reply_()); return length; }
bool CKey::SetSecret(const CSecret &vchSecret, bool fCompressed) { EC_KEY_free(pkey); pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (pkey == NULL) throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); if (vchSecret.size() != 32) throw key_error("CKey::SetSecret() : secret must be 32 bytes"); BIGNUM *bn = BN_bin2bn(&vchSecret[0], 32, BN_new()); if (bn == NULL) throw key_error("CKey::SetSecret() : BN_bin2bn failed"); if (!EC_KEY_regenerate_key(pkey, bn)) { BN_clear_free(bn); throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); } BN_clear_free(bn); fSet = true; if (fCompressed || fCompressedPubKey) SetCompressedPubKey(); return true; }
void CCryptKey::EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted) { ies_ctx_t *ctx; char error[1024] = "Unknown error"; cryptogram_t *cryptogram; ctx = create_context(pkey); if (!EC_KEY_get0_public_key(ctx->user_key)) throw key_error("Given EC key is not public key"); cryptogram = ecies_encrypt(ctx, (unsigned char*)&data[0], data.size(), error); if (cryptogram == NULL) { free(ctx); ctx = NULL; throw key_error(std::string("Error in encryption: %s") + error); } encrypted.resize(cryptogram_data_sum_length(cryptogram)); unsigned char *key_data = cryptogram_key_data(cryptogram); memcpy(&encrypted[0], key_data, encrypted.size()); cryptogram_free(cryptogram); free(ctx); }
// create a compact signature (65 bytes), which allows reconstructing the used public key // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y bool CKey::SignCompact(uint256 hash, std::vector<unsigned char>& vchSig) { bool fOk = false; ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); if (sig==NULL) return false; const EC_GROUP *group = EC_KEY_get0_group(pkey); CBigNum order, halforder; EC_GROUP_get_order(group, &order, NULL); BN_rshift1(&halforder, &order); // enforce low S values, by negating the value (modulo the order) if above order/2. if (BN_cmp(sig->s, &halforder) > 0) { BN_sub(sig->s, &order, sig->s); } vchSig.clear(); vchSig.resize(65,0); int nBitsR = BN_num_bits(sig->r); int nBitsS = BN_num_bits(sig->s); if (nBitsR <= 256 && nBitsS <= 256) { int nRecId = -1; for (int i=0; i<4; i++) { CKey keyRec; keyRec.fSet = true; if (fCompressedPubKey) keyRec.SetCompressedPubKey(); if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) if (keyRec.GetPubKey() == this->GetPubKey()) { nRecId = i; break; } } if (nRecId == -1) { ECDSA_SIG_free(sig); throw key_error("CKey::SignCompact() : unable to construct recoverable key"); } vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0); BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]); BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]); fOk = true; } ECDSA_SIG_free(sig); return fOk; }
void Machine::reconfigure(size_t idx, const Config& c) { if(idx>=p_elements.size()) throw std::invalid_argument("element index out of range"); const std::string& etype(c.get<std::string>("type")); state_info::elements_t::iterator eit = p_info.elements.find(etype); if(eit==p_info.elements.end()) throw key_error(etype); element_builder_t *builder = eit->second; builder->rebuild(p_elements[idx], c); }
/** * Parse key/value pairs from the configuration file */ void config::parse_file() { vector<pair<int, string>> lines; vector<string> files{m_file}; std::function<void(int, string&&)> pushline = [&](int lineno, string&& line) { // Ignore empty lines and comments if (line.empty() || line[0] == ';' || line[0] == '#') { return; } string key, value; string::size_type pos; // Filter lines by: // - key/value pairs // - section headers if ((pos = line.find('=')) != string::npos) { key = forward<string>(string_util::trim(forward<string>(line.substr(0, pos)))); value = forward<string>(string_util::trim(line.substr(pos + 1))); } else if (line[0] != '[' || line[line.length() - 1] != ']') { return; } if (key == "include-file") { auto file_path = file_util::expand(value); if (file_path.empty() || !file_util::exists(file_path)) { throw value_error("Invalid include file \"" + file_path + "\" defined on line " + to_string(lineno)); } if (std::find(files.begin(), files.end(), file_path) != files.end()) { throw value_error("Recursive include file \"" + file_path + "\""); } files.push_back(file_util::expand(file_path)); m_log.trace("config: Including file \"%s\"", file_path); for (auto&& l : string_util::split(file_util::contents(file_path), '\n')) { pushline(lineno, forward<string>(l)); } files.pop_back(); } else { lines.emplace_back(make_pair(lineno, line)); } }; int lineno{0}; string line; std::ifstream in(m_file); while (std::getline(in, line)) { pushline(++lineno, string_util::replace_all(line, "\t", "")); } string section; for (auto&& l : lines) { auto& lineno = l.first; auto& line = l.second; // New section if (line[0] == '[' && line[line.length() - 1] == ']') { section = line.substr(1, line.length() - 2); continue; } else if (section.empty()) { continue; } size_t equal_pos; // Check for key-value pair equal sign if ((equal_pos = line.find('=')) == string::npos) { continue; } string key{forward<string>(string_util::trim(forward<string>(line.substr(0, equal_pos))))}; string value; auto it = m_sections[section].find(key); if (it != m_sections[section].end()) { throw key_error("Duplicate key name \"" + key + "\" defined on line " + to_string(lineno)); } if (equal_pos + 1 < line.size()) { value = forward<string>(string_util::trim(line.substr(equal_pos + 1))); size_t len{value.size()}; if (len > 2 && value[0] == '"' && value[len - 1] == '"') { value.erase(len - 1, 1).erase(0, 1); } } #if WITH_XRM // Initialize the xresource manage if there are any xrdb refs // present in the configuration if (!m_xrm && value.find("${xrdb") != string::npos) { m_xrm.reset(new xresource_manager{connection::make()}); } #endif m_sections[section].emplace_hint(it, move(key), move(value)); } }
Machine::Machine(const Config& c) :p_elements() ,p_trace(NULL) ,p_info() { std::string type(c.get<std::string>("sim_type")); info_mutex_t::scoped_lock G(info_mutex); p_state_infos_t::iterator it = p_state_infos.find(type); if(it==p_state_infos.end()) { std::ostringstream msg; msg<<"Unsupport sim_type '"<<type<<"'"; throw key_error(msg.str()); } p_info = it->second; typedef Config::vector_t elements_t; elements_t Es(c.get<elements_t>("elements")); p_elements_t result; result.reserve(Es.size()); size_t idx=0; for(elements_t::iterator it=Es.begin(), end=Es.end(); it!=end; ++it) { const Config& EC = *it; const std::string& etype(EC.get<std::string>("type")); state_info::elements_t::iterator eit = p_info.elements.find(etype); if(eit==p_info.elements.end()) throw key_error(etype); element_builder_t* builder = eit->second; ElementVoid *E; try{ E = builder->build(EC); }catch(key_error& e){ std::ostringstream strm; strm<<"Error while initializing element "<<idx<<" '"<<EC.get<std::string>("name", "<invalid>") <<"' : missing required parameter '"<<e.what()<<"'"; throw key_error(strm.str()); }catch(std::exception& e){ std::ostringstream strm; strm<<"Error while constructing element "<<idx<<" '"<<EC.get<std::string>("name", "<invalid>") <<"' : "<<e.what(); throw std::runtime_error(strm.str()); } *const_cast<size_t*>(&E->index) = idx++; // ugly result.push_back(E); } G.unlock(); p_elements.swap(result); }