adding aes encryption and openssl wrapper cleanup
This commit is contained in:
parent
6c3b31873c
commit
e19c3327a0
6 changed files with 231 additions and 54 deletions
|
|
@ -93,6 +93,8 @@ set( fc_sources
|
|||
src/log/console_appender.cpp
|
||||
src/log/file_appender.cpp
|
||||
src/log/logger_config.cpp
|
||||
src/crypto/openssl.cpp
|
||||
src/crypto/aes.cpp
|
||||
src/crypto/crc.cpp
|
||||
src/crypto/city.cpp
|
||||
src/crypto/base32.cpp
|
||||
|
|
@ -116,6 +118,7 @@ set( fc_sources
|
|||
src/network/ip.cpp
|
||||
src/network/resolve.cpp
|
||||
src/network/url.cpp
|
||||
src/compress/smaz.cpp
|
||||
vendor/cyoencode-1.0.2/src/CyoDecode.c
|
||||
vendor/cyoencode-1.0.2/src/CyoEncode.c
|
||||
)
|
||||
|
|
@ -126,4 +129,8 @@ set( sources
|
|||
|
||||
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC )
|
||||
|
||||
set( BOOST_LIBRARIES ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_CHRONO_LIBRARY} ${ALL_OPENSSL_LIBRARIES} ${Boost_COROUTINE_LIBRARY} ${Boost_CONTEXT_LIBRARY} )
|
||||
|
||||
#add_executable( test_compress tests/compress.cpp )
|
||||
#target_link_libraries( test_compress fc ${BOOST_LIBRARIES} )
|
||||
|
||||
|
|
|
|||
9
include/fc/crypto/aes.hpp
Normal file
9
include/fc/crypto/aes.hpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
#include <fc/sha512.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
std::vector<char> aes_encrypt( const fc::sha512& key, const std::vector<char>& plain_text );
|
||||
std::vector<char> aes_decrypt( const fc::sha512& key, const std::vector<char>& cipher_text );
|
||||
|
||||
}
|
||||
59
include/fc/crypto/openssl.hpp
Normal file
59
include/fc/crypto/openssl.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
/**
|
||||
* @file openssl.hpp
|
||||
* Provides common utility calls for wrapping openssl c api.
|
||||
*/
|
||||
namespace fc
|
||||
{
|
||||
|
||||
template <typename ssl_type>
|
||||
struct ssl_wrapper
|
||||
{
|
||||
ssl_wrapper(ssl_type* obj):obj(obj) {}
|
||||
|
||||
operator ssl_type*()
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
ssl_type* operator->() { return obj; }
|
||||
|
||||
ssl_type* obj;
|
||||
};
|
||||
|
||||
#define SSL_TYPE(name, ssl_type, free_func) \
|
||||
struct name : public ssl_wrapper<ssl_type> \
|
||||
{ \
|
||||
name(ssl_type* obj) \
|
||||
: ssl_wrapper(obj) {} \
|
||||
~name() \
|
||||
{ \
|
||||
free_func(obj); \
|
||||
} \
|
||||
};
|
||||
|
||||
SSL_TYPE(ec_group, EC_GROUP, EC_GROUP_free)
|
||||
SSL_TYPE(ec_point, EC_POINT, EC_POINT_free)
|
||||
SSL_TYPE(ecdsa_sig, ECDSA_SIG, ECDSA_SIG_free)
|
||||
SSL_TYPE(bn_ctx, BN_CTX, BN_CTX_free)
|
||||
SSL_TYPE(evp_cipher_ctx, EVP_CIPHER_CTX, EVP_CIPHER_CTX_free )
|
||||
|
||||
/** allocates a bignum by default.. */
|
||||
struct ssl_bignum : public ssl_wrapper<BIGNUM>
|
||||
{
|
||||
ssl_bignum() : ssl_wrapper(BN_new()) {}
|
||||
~ssl_bignum() { BN_free(obj); }
|
||||
};
|
||||
|
||||
int init_openssl();
|
||||
|
||||
} // namespace fc
|
||||
130
src/crypto/aes.cpp
Normal file
130
src/crypto/aes.cpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#include <fc/crypto/sha512.hpp>
|
||||
#include <fc/crypto/openssl.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
static int init = init_openssl();
|
||||
|
||||
/** example method from wiki.opensslfoundation.com */
|
||||
int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
|
||||
unsigned char *iv, unsigned char *ciphertext)
|
||||
{
|
||||
evp_cipher_ctx ctx( EVP_CIPHER_CTX_new() );
|
||||
|
||||
int len = 0;
|
||||
int ciphertext_len = 0;
|
||||
|
||||
/* Create and initialise the context */
|
||||
if(!ctx)
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error allocating evp cipher context",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
|
||||
/* Initialise the encryption operation. IMPORTANT - ensure you use a key
|
||||
* * and IV size appropriate for your cipher
|
||||
* * In this example we are using 256 bit AES (i.e. a 256 bit key). The
|
||||
* * IV size for *most* modes is the same as the block size. For AES this
|
||||
* * is 128 bits */
|
||||
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption init",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
|
||||
/* Provide the message to be encrypted, and obtain the encrypted output.
|
||||
* * EVP_EncryptUpdate can be called multiple times if necessary
|
||||
* */
|
||||
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption update",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
ciphertext_len = len;
|
||||
|
||||
/* Finalise the encryption. Further ciphertext bytes may be written at
|
||||
* * this stage.
|
||||
* */
|
||||
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption final",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
ciphertext_len += len;
|
||||
|
||||
return ciphertext_len;
|
||||
}
|
||||
|
||||
int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
|
||||
unsigned char *iv, unsigned char *plaintext)
|
||||
{
|
||||
evp_cipher_ctx ctx( EVP_CIPHER_CTX_new() );
|
||||
int len = 0;
|
||||
int plaintext_len = 0;
|
||||
|
||||
/* Create and initialise the context */
|
||||
if(!ctx)
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error allocating evp cipher context",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
|
||||
/* Initialise the decryption operation. IMPORTANT - ensure you use a key
|
||||
* * and IV size appropriate for your cipher
|
||||
* * In this example we are using 256 bit AES (i.e. a 256 bit key). The
|
||||
* * IV size for *most* modes is the same as the block size. For AES this
|
||||
* * is 128 bits */
|
||||
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt init",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
|
||||
/* Provide the message to be decrypted, and obtain the plaintext output.
|
||||
* * EVP_DecryptUpdate can be called multiple times if necessary
|
||||
* */
|
||||
if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt update",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
|
||||
plaintext_len = len;
|
||||
|
||||
/* Finalise the decryption. Further plaintext bytes may be written at
|
||||
* * this stage.
|
||||
* */
|
||||
if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt final",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
plaintext_len += len;
|
||||
|
||||
return plaintext_len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<char> aes_encrypt( const fc::sha512& key, const std::vector<char>& plain_text )
|
||||
{
|
||||
std::vector<char> cipher_text(plain_text.size()+16);
|
||||
auto cipher_len = aes_encrypt( (unsigned char*)plain_text.data(), plain_text.size(),
|
||||
(unsigned char*)&key, ((unsigned char*)&key)+32,
|
||||
(unsigned char*)cipher_text.data() );
|
||||
cipher_text.resize(cipher_len);
|
||||
return cipher_text;
|
||||
|
||||
}
|
||||
std::vector<char> aes_decrypt( const fc::sha512& key, const std::vector<char>& cipher_text )
|
||||
{
|
||||
std::vector<char> plain_text( cipher_text.size() );
|
||||
auto plain_len = aes_decrypt( (unsigned char*)cipher_text.data(), cipher_text.size(),
|
||||
(unsigned char*)&key, ((unsigned char*)&key)+32,
|
||||
(unsigned char*)plain_text.data() );
|
||||
plain_text.resize(plain_len);
|
||||
return plain_text;
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -2,61 +2,11 @@
|
|||
#include <fc/fwd_impl.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <fc/crypto/openssl.hpp>
|
||||
#include <assert.h>
|
||||
|
||||
namespace fc { namespace ecc {
|
||||
|
||||
template <typename ssl_type>
|
||||
struct ssl_wrapper
|
||||
{
|
||||
ssl_wrapper(ssl_type* obj)
|
||||
: obj(obj) {}
|
||||
virtual ~ssl_wrapper()
|
||||
{
|
||||
}
|
||||
operator ssl_type*()
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
ssl_type* operator->() { return obj; }
|
||||
|
||||
ssl_type* obj;
|
||||
};
|
||||
|
||||
struct ssl_bignum
|
||||
: public ssl_wrapper<BIGNUM>
|
||||
{
|
||||
ssl_bignum()
|
||||
: ssl_wrapper(BN_new()) {}
|
||||
~ssl_bignum()
|
||||
{
|
||||
BN_free(obj);
|
||||
}
|
||||
};
|
||||
|
||||
#define SSL_TYPE(name, ssl_type, free_func) \
|
||||
struct name \
|
||||
: public ssl_wrapper<ssl_type> \
|
||||
{ \
|
||||
name(ssl_type* obj) \
|
||||
: ssl_wrapper(obj) {} \
|
||||
~name() \
|
||||
{ \
|
||||
free_func(obj); \
|
||||
} \
|
||||
};
|
||||
|
||||
SSL_TYPE(ec_group, EC_GROUP, EC_GROUP_free)
|
||||
SSL_TYPE(ec_point, EC_POINT, EC_POINT_free)
|
||||
SSL_TYPE(ecdsa_sig, ECDSA_SIG, ECDSA_SIG_free)
|
||||
SSL_TYPE(bn_ctx, BN_CTX, BN_CTX_free)
|
||||
static int init = init_openssl();
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
|
@ -414,8 +364,6 @@ struct ssl_bignum
|
|||
return 1 == ECDSA_verify( 0, (unsigned char*)&digest, sizeof(digest), (unsigned char*)&sig, sizeof(sig), my->_key );
|
||||
}
|
||||
|
||||
static int load_ssl_error = [=](){ ERR_load_crypto_strings(); return 1; }();
|
||||
|
||||
public_key_data public_key::serialize()const
|
||||
{
|
||||
public_key_data dat;
|
||||
|
|
|
|||
24
src/crypto/openssl.cpp
Normal file
24
src/crypto/openssl.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <fc/crypto/openssl.hpp>
|
||||
namespace fc
|
||||
{
|
||||
struct openssl_scope
|
||||
{
|
||||
openssl_scope()
|
||||
{
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
OPENSSL_config(NULL);
|
||||
}
|
||||
~openssl_scope()
|
||||
{
|
||||
EVP_cleanup();
|
||||
ERR_free_strings();
|
||||
}
|
||||
};
|
||||
|
||||
int init_openssl()
|
||||
{
|
||||
static openssl_scope ossl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue