This commit is contained in:
Daniel Larimer 2014-06-02 21:05:19 -04:00
commit 0cf08f124e
8 changed files with 75 additions and 14 deletions

View file

@ -305,5 +305,12 @@ if(WIN32)
endif(WIN32) endif(WIN32)
SET(POST_BUILD_STEP_COMMANDS ${POST_BUILD_STEP_COMMANDS}
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENSSL_ROOT_DIR}/ssl/openssl.cnf" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/openssl.cnf")
ADD_CUSTOM_COMMAND(TARGET fc POST_BUILD ${POST_BUILD_STEP_COMMANDS}
COMMENT "Copying OpenSSL/ssl/openssl.cnf into target directory."
)
MESSAGE(STATUS "Finished fc module configuration...") MESSAGE(STATUS "Finished fc module configuration...")

View file

@ -11,7 +11,7 @@ namespace fc {
public: public:
bigint( const std::vector<char>& bige ); bigint( const std::vector<char>& bige );
bigint( const char* bige, uint32_t l ); bigint( const char* bige, uint32_t l );
bigint( unsigned long i ); bigint(uint64_t value);
bigint( ); bigint( );
bigint( const bigint& c ); bigint( const bigint& c );
bigint( bigint&& c ); bigint( bigint&& c );

View file

@ -15,6 +15,7 @@
*/ */
namespace fc namespace fc
{ {
class path;
template <typename ssl_type> template <typename ssl_type>
struct ssl_wrapper struct ssl_wrapper
@ -55,6 +56,13 @@ namespace fc
~ssl_bignum() { BN_free(obj); } ~ssl_bignum() { BN_free(obj); }
}; };
/** Allows to explicitly specify OpenSSL configuration file path to be loaded at OpenSSL library init.
If not set OpenSSL will try to load the conf. file (openssl.cnf) from the path it was
configured with what caused serious Keyhotee startup bugs on some Win7 machines.
\warning to be effective this method should be used before any part using OpenSSL, especially
before init_openssl call
*/
void store_configuration_path(const path& filePath);
int init_openssl(); int init_openssl();
} // namespace fc } // namespace fc

View file

@ -10,17 +10,20 @@
namespace fc { namespace fc {
static int init = init_openssl();
struct aes_encoder::impl struct aes_encoder::impl
{ {
evp_cipher_ctx ctx; evp_cipher_ctx ctx;
}; };
aes_encoder::aes_encoder(){} aes_encoder::aes_encoder()
{
static int init = init_openssl();
}
aes_encoder::~aes_encoder() aes_encoder::~aes_encoder()
{ {
} }
void aes_encoder::init( const fc::sha256& key, const fc::uint128& init_value ) void aes_encoder::init( const fc::sha256& key, const fc::uint128& init_value )
{ {
my->ctx.obj = EVP_CIPHER_CTX_new(); my->ctx.obj = EVP_CIPHER_CTX_new();
@ -80,7 +83,11 @@ struct aes_decoder::impl
evp_cipher_ctx ctx; evp_cipher_ctx ctx;
}; };
aes_decoder::aes_decoder(){} aes_decoder::aes_decoder()
{
static int init = init_openssl();
}
void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value ) void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value )
{ {
my->ctx.obj = EVP_CIPHER_CTX_new(); my->ctx.obj = EVP_CIPHER_CTX_new();

View file

@ -6,6 +6,16 @@
#include <fc/exception/exception.hpp> #include <fc/exception/exception.hpp>
#ifdef _MSC_VER
# include <stdlib.h>
# define bswap_64(x) _byteswap_uint64(x)
#elif defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# define bswap_64(x) OSSwapInt64(x)
#else
# include <byteswap.h>
#endif
namespace fc { namespace fc {
bigint::bigint( const char* bige, uint32_t l ) { bigint::bigint( const char* bige, uint32_t l ) {
n = BN_bin2bn( (const unsigned char*)bige, l, NULL ); n = BN_bin2bn( (const unsigned char*)bige, l, NULL );
@ -28,9 +38,10 @@ namespace fc {
return BN_dup( n ); return BN_dup( n );
} }
bigint::bigint( unsigned long i ) bigint::bigint(uint64_t value)
:n(BN_new()) { {
BN_set_word( n, i ); uint64_t big_endian_value = bswap_64(value);
n = BN_bin2bn((const unsigned char*)&big_endian_value, sizeof(big_endian_value), NULL);
} }
bigint::bigint( const bigint& c ) { bigint::bigint( const bigint& c ) {
@ -47,7 +58,15 @@ namespace fc {
} }
bool bigint::is_negative()const { return BN_is_negative(n); } bool bigint::is_negative()const { return BN_is_negative(n); }
int64_t bigint::to_int64()const { return BN_get_word(n); }
int64_t bigint::to_int64() const
{
FC_ASSERT(BN_num_bits(n) <= 63);
size_t size = BN_num_bytes(n);
uint64_t abs_value = 0;
BN_bn2bin(n, (unsigned char*)&abs_value + (sizeof(uint64_t) - size));
return BN_is_negative(n) ? -(int64_t)bswap_64(abs_value) : bswap_64(abs_value);
}
int64_t bigint::log2()const { return BN_num_bits(n); } int64_t bigint::log2()const { return BN_num_bits(n); }
bool bigint::operator < ( const bigint& c )const { bool bigint::operator < ( const bigint& c )const {

View file

@ -10,8 +10,6 @@
#include <assert.h> #include <assert.h>
namespace fc { namespace ecc { namespace fc { namespace ecc {
static int init = init_openssl();
namespace detail namespace detail
{ {
class public_key_impl class public_key_impl
@ -20,7 +18,9 @@ namespace fc { namespace ecc {
public_key_impl() public_key_impl()
:_key(nullptr) :_key(nullptr)
{ {
static int init = init_openssl();
} }
~public_key_impl() ~public_key_impl()
{ {
if( _key != nullptr ) if( _key != nullptr )
@ -40,6 +40,7 @@ namespace fc { namespace ecc {
private_key_impl() private_key_impl()
:_key(nullptr) :_key(nullptr)
{ {
static int init = init_openssl();
} }
~private_key_impl() ~private_key_impl()
{ {

View file

@ -1,20 +1,37 @@
#include <fc/crypto/openssl.hpp> #include <fc/crypto/openssl.hpp>
#include <fc/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <string>
namespace fc namespace fc
{ {
struct openssl_scope struct openssl_scope
{ {
static path _configurationFilePath;
openssl_scope() openssl_scope()
{ {
ERR_load_crypto_strings(); ERR_load_crypto_strings();
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
OPENSSL_config(NULL); const boost::filesystem::path& boostPath = _configurationFilePath;
OPENSSL_config(boostPath.empty() ? nullptr : _configurationFilePath.to_native_ansi_path().c_str());
} }
~openssl_scope() ~openssl_scope()
{ {
EVP_cleanup(); EVP_cleanup();
ERR_free_strings(); ERR_free_strings();
} }
}; };
path openssl_scope::_configurationFilePath;
void store_configuration_path(const path& filePath)
{
openssl_scope::_configurationFilePath = filePath;
}
int init_openssl() int init_openssl()
{ {

View file

@ -6,10 +6,10 @@
namespace fc { namespace fc {
static int init = init_openssl();
void rand_bytes(char* buf, int count) void rand_bytes(char* buf, int count)
{ {
static int init = init_openssl();
int result = RAND_bytes((unsigned char*)buf, count); int result = RAND_bytes((unsigned char*)buf, count);
if (result != 1) if (result != 1)
FC_THROW("Error calling OpenSSL's RAND_bytes(): ${code}", ("code", (uint32_t)ERR_get_error())); FC_THROW("Error calling OpenSSL's RAND_bytes(): ${code}", ("code", (uint32_t)ERR_get_error()));
@ -17,6 +17,8 @@ void rand_bytes(char* buf, int count)
void rand_pseudo_bytes(char* buf, int count) void rand_pseudo_bytes(char* buf, int count)
{ {
static int init = init_openssl();
int result = RAND_pseudo_bytes((unsigned char*)buf, count); int result = RAND_pseudo_bytes((unsigned char*)buf, count);
if (result == -1) if (result == -1)
FC_THROW("Error calling OpenSSL's RAND_pseudo_bytes(): ${code}", ("code", (uint32_t)ERR_get_error())); FC_THROW("Error calling OpenSSL's RAND_pseudo_bytes(): ${code}", ("code", (uint32_t)ERR_get_error()));