//subtract Keys (subtracts curve points)
 //AB = A - B where A, B are curve points
 void subKeys(key & AB, const key &A, const key &B) {
     ge_p3 B2, A2;
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_cached tmp2;
     ge_p3_to_cached(&tmp2, &B2);
     ge_p1p1 tmp3;
     ge_sub(&tmp3, &A2, &tmp2);
     ge_p1p1_to_p3(&A2, &tmp3);
     ge_p3_tobytes(AB.bytes, &A2);
 }
      void set_msg_addr(t_message * msg,
                        const boost::optional<std::vector<uint32_t>> & path = boost::none,
                        const boost::optional<cryptonote::network_type> & network_type = boost::none)
      {
        CHECK_AND_ASSERT_THROW_MES(msg, "Message is null");
        msg->clear_address_n();
        if (path){
          for(auto x : path.get()){
            msg->add_address_n(x);
          }
        } else {
          ensure_derivation_path();
          for (unsigned int i : DEFAULT_BIP44_PATH) {
            msg->add_address_n(i);
          }
          for (unsigned int i : m_wallet_deriv_path) {
            msg->add_address_n(i);
          }
        }

        if (network_type){
          msg->set_network_type(static_cast<uint32_t>(network_type.get()));
        } else {
          msg->set_network_type(static_cast<uint32_t>(this->network_type));
        }
      }
 //does a * P where a is a scalar and P is an arbitrary point
 void scalarmultKey(key & aP, const key &P, const key &a) {
     ge_p3 A;
     ge_p2 R;
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_scalarmult(&R, a.bytes, &A);
     ge_tobytes(aP.bytes, &R);
 }
 //addKeys3
 //aAbB = a*A + b*B where a, b are scalars, A, B are curve points
 //B must be input after applying "precomp"
 void addKeys3(key &aAbB, const key &a, const key &A, const key &b, const ge_dsmp B) {
     ge_p2 rv;
     ge_p3 A2;
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_double_scalarmult_precomp_vartime(&rv, a.bytes, &A2, b.bytes, B);
     ge_tobytes(aAbB.bytes, &rv);
 }
 //addKeys2
 //aGbB = aG + bB where a, b are scalars, G is the basepoint and B is a point
 void addKeys2(key &aGbB, const key &a, const key &b, const key & B) {
     ge_p2 rv;
     ge_p3 B2;
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_double_scalarmult_base_vartime(&rv, b.bytes, &B2, a.bytes);
     ge_tobytes(aGbB.bytes, &rv);
 }
 //Computes aH where H= toPoint(cn_fast_hash(G)), G the basepoint
 key scalarmultH(const key & a) {
     ge_p3 A;
     ge_p2 R;
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, H.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_scalarmult(&R, a.bytes, &A);
     key aP;
     ge_tobytes(aP.bytes, &R);
     return aP;
 }
Example #7
0
 //Generates a vector of secret key
 //Mainly used in testing
 keyV skvGen(size_t rows ) {
     CHECK_AND_ASSERT_THROW_MES(rows > 0, "0 keys requested");
     keyV rv(rows);
     size_t i = 0;
     for (i = 0 ; i < rows ; i++) {
         skGen(rv[i]);
     }
     return rv;
 }
Example #8
0
 //Generates a vector of secret key
 //Mainly used in testing
 keyV skvGen(size_t rows ) {
     CHECK_AND_ASSERT_THROW_MES(rows > 0, "0 keys requested");
     keyV rv(rows);
     size_t i = 0;
     crypto::rand(rows * sizeof(key), (uint8_t*)&rv[0]);
     for (i = 0 ; i < rows ; i++) {
         sc_reduce32(rv[i].bytes);
     }
     return rv;
 }
 key hashToPointSimple(const key & hh) {
     key pointk;
     ge_p1p1 point2;
     ge_p2 point;
     ge_p3 res;
     key h = cn_fast_hash(hh); 
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&res, h.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_p3_to_p2(&point, &res);
     ge_mul8(&point2, &point);
     ge_p1p1_to_p3(&res, &point2);
     ge_p3_tobytes(pointk.bytes, &res);
     return pointk;
 }    
Example #10
0
// methods:
connection_basic::connection_basic(boost::asio::ip::tcp::socket&& socket, boost::shared_ptr<socket_stats> stats)
	:
	m_stats(std::move(stats)),
	mI( new connection_basic_pimpl("peer") ),
	strand_(socket.get_io_service()),
	socket_(std::move(socket)),
	m_want_close_connection(false), 
	m_was_shutdown(false)
{
	// add nullptr checks if removed
	CHECK_AND_ASSERT_THROW_MES(bool(m_stats), "stats shared_ptr cannot be null");

	++(m_stats->sock_count); // increase the global counter
	mI->m_peer_number = m_stats->sock_number.fetch_add(1); // use, and increase the generated number

	std::string remote_addr_str = "?";
	try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ;

	_note("Spawned connection p2p#"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count);
}
Example #11
0
void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) {
  CHECK_AND_ASSERT_THROW_MES(!is_leaf, "A leaf routine is using a thread pool");
  boost::unique_lock<boost::mutex> lock(mutex);
  if (!leaf && ((active == max && !queue.empty()) || depth > 0)) {
    // if all available threads are already running
    // and there's work waiting, just run in current thread
    lock.unlock();
    ++depth;
    is_leaf = leaf;
    f();
    --depth;
    is_leaf = false;
  } else {
    if (obj)
      obj->inc();
    if (leaf)
      queue.push_front({obj, f, leaf});
    else
      queue.push_back({obj, f, leaf});
    has_work.notify_one();
  }
}
      std::shared_ptr<t_message>
      client_exchange(const std::shared_ptr<const google::protobuf::Message> &req,
                      const boost::optional<messages::MessageType> & resp_type = boost::none,
                      const boost::optional<std::vector<messages::MessageType>> & resp_types = boost::none,
                      const boost::optional<messages::MessageType*> & resp_type_ptr = boost::none,
                      bool open_session = false)
      {
        // Require strictly protocol buffers response in the template.
        BOOST_STATIC_ASSERT(boost::is_base_of<google::protobuf::Message, t_message>::value);
        const bool accepting_base = boost::is_same<google::protobuf::Message, t_message>::value;
        if (resp_types && !accepting_base){
          throw std::invalid_argument("Cannot specify list of accepted types and not using generic response");
        }

        // Determine type of expected message response
        const messages::MessageType required_type = accepting_base ? messages::MessageType_Success :
                  (resp_type ? resp_type.get() : MessageMapper::get_message_wire_number<t_message>());

        // Open session if required
        if (open_session){
          try {
            m_transport->open();
          } catch (const std::exception& e) {
            std::throw_with_nested(exc::SessionException("Could not open session"));
          }
        }

        // Scoped session closer
        BOOST_SCOPE_EXIT_ALL(&, this) {
          if (open_session){
            this->get_transport()->close();
          }
        };

        // Write/read the request
        CHECK_AND_ASSERT_THROW_MES(req, "Request is null");
        auto msg_resp = call_raw(req.get());

        bool processed = false;
        do {
          processed = message_handler(msg_resp);
        } while(processed);

        // Response section
        if (resp_type_ptr){
          *(resp_type_ptr.get()) = msg_resp.m_type;
        }

        if (msg_resp.m_type == messages::MessageType_Failure) {
          throw_failure_exception(dynamic_cast<messages::common::Failure *>(msg_resp.m_msg.get()));

        } else if (!accepting_base && msg_resp.m_type == required_type) {
          return message_ptr_retype<t_message>(msg_resp.m_msg);

        } else if (accepting_base && (!resp_types ||
                     std::find(resp_types.get().begin(), resp_types.get().end(), msg_resp.m_type) != resp_types.get().end())) {
            return message_ptr_retype<t_message>(msg_resp.m_msg);

        } else {
          throw exc::UnexpectedMessageException(msg_resp.m_type, msg_resp.m_msg);
        }
      }
 //Does some precomputation to make addKeys3 more efficient
 // input B a curve point and output a ge_dsmp which has precomputation applied
 void precomp(ge_dsmp rv, const key & B) {
     ge_p3 B2;
     CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
     ge_dsm_precomp(rv, &B2);
 }
Example #14
0
boost::asio::ssl::context ssl_options_t::create_context() const
{
  boost::asio::ssl::context ssl_context{boost::asio::ssl::context::tlsv12};
  if (!bool(*this))
    return ssl_context;

  // only allow tls v1.2 and up
  ssl_context.set_options(boost::asio::ssl::context::default_workarounds);
  ssl_context.set_options(boost::asio::ssl::context::no_sslv2);
  ssl_context.set_options(boost::asio::ssl::context::no_sslv3);
  ssl_context.set_options(boost::asio::ssl::context::no_tlsv1);
  ssl_context.set_options(boost::asio::ssl::context::no_tlsv1_1);

  // only allow a select handful of tls v1.3 and v1.2 ciphers to be used
  SSL_CTX_set_cipher_list(ssl_context.native_handle(), "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256");

  // set options on the SSL context for added security
  SSL_CTX *ctx = ssl_context.native_handle();
  CHECK_AND_ASSERT_THROW_MES(ctx, "Failed to get SSL context");
  SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT); // SSL_CTX_SET_OPTIONS(3)
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); // https://stackoverflow.com/questions/22378442
#ifdef SSL_OP_NO_TICKET
  SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); // https://stackoverflow.com/questions/22378442
#endif
#ifdef SSL_OP_NO_RENEGOTIATION
  SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
#endif
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
  SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
#ifdef SSL_OP_NO_COMPRESSION
  SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
  SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
#endif
  SSL_CTX_set_ecdh_auto(ctx, 1);

  switch (verification)
  {
    case ssl_verification_t::system_ca:
      ssl_context.set_default_verify_paths();
      break;
    case ssl_verification_t::user_certificates:
      ssl_context.set_verify_depth(0);
      /* fallthrough */
    case ssl_verification_t::user_ca:
      if (!ca_path.empty())
      {
        const boost::system::error_code err = load_ca_file(ssl_context, ca_path);
        if (err)
          throw boost::system::system_error{err, "Failed to load user CA file at " + ca_path};
      }
      break;
    default:
      break;
  }

  CHECK_AND_ASSERT_THROW_MES(auth.private_key_path.empty() == auth.certificate_path.empty(), "private key and certificate must be either both given or both empty");
  if (auth.private_key_path.empty())
  {
    EVP_PKEY *pkey;
    X509 *cert;
    bool ok = false;

#ifdef USE_EXTRA_EC_CERT
    CHECK_AND_ASSERT_THROW_MES(create_ec_ssl_certificate(pkey, cert, NID_secp256k1), "Failed to create certificate");
    CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
    if (!SSL_CTX_use_PrivateKey(ctx, pkey))
      MERROR("Failed to use generated EC private key for " << NID_secp256k1);
    else
      ok = true;
    X509_free(cert);
    EVP_PKEY_free(pkey);
#endif

    CHECK_AND_ASSERT_THROW_MES(create_rsa_ssl_certificate(pkey, cert), "Failed to create certificate");
    CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
    if (!SSL_CTX_use_PrivateKey(ctx, pkey))
      MERROR("Failed to use generated RSA private key for RSA");
    else
      ok = true;
    X509_free(cert);
    EVP_PKEY_free(pkey);

    CHECK_AND_ASSERT_THROW_MES(ok, "Failed to use any generated certificate");
  }
  else
    auth.use_ssl_certificate(ssl_context);

  return ssl_context;
}