From 01d10552f7daf4cc5fea727ecb6c997c62921277 Mon Sep 17 00:00:00 2001 From: "Fred T. Hamster" Date: Fri, 13 Mar 2026 20:05:29 -0400 Subject: [PATCH] breaking changes, not finished will not build quite yet, but nearly there... --- nucleus/library/crypto/blowfish_crypto.cpp | 73 ++-- nucleus/library/crypto/blowfish_crypto.h | 31 +- .../library/crypto/cryptical_envelopment.cpp | 367 ++++++++++++++++++ .../library/crypto/cryptical_envelopment.h | 88 +++++ nucleus/library/crypto/makefile | 2 +- ...a_crypto.cpp => old_school_rsa_crypto.cpp} | 34 +- .../{rsa_crypto.h => old_school_rsa_crypto.h} | 21 +- nucleus/library/tests_crypto/makefile | 2 +- .../tests_crypto/test_blowfish_crypto.cpp | 9 +- ...pto.cpp => test_old_school_rsa_crypto.cpp} | 8 +- octopi/library/cromp/cromp_client.cpp | 2 +- octopi/library/cromp/cromp_common.cpp | 8 +- octopi/library/cromp/cromp_common.h | 4 +- .../library/tentacles/encryption_infoton.cpp | 12 +- octopi/library/tentacles/encryption_infoton.h | 8 +- .../library/tentacles/encryption_tentacle.cpp | 8 +- .../library/tentacles/encryption_tentacle.h | 4 +- .../buildor/upgrade_hoople_to_feistymeow.sh | 2 +- 18 files changed, 579 insertions(+), 104 deletions(-) create mode 100644 nucleus/library/crypto/cryptical_envelopment.cpp create mode 100644 nucleus/library/crypto/cryptical_envelopment.h rename nucleus/library/crypto/{rsa_crypto.cpp => old_school_rsa_crypto.cpp} (91%) rename nucleus/library/crypto/{rsa_crypto.h => old_school_rsa_crypto.h} (88%) rename nucleus/library/tests_crypto/{test_rsa_crypto.cpp => test_old_school_rsa_crypto.cpp} (97%) diff --git a/nucleus/library/crypto/blowfish_crypto.cpp b/nucleus/library/crypto/blowfish_crypto.cpp index b68c7d45..3c0596d6 100644 --- a/nucleus/library/crypto/blowfish_crypto.cpp +++ b/nucleus/library/crypto/blowfish_crypto.cpp @@ -1,16 +1,14 @@ -/*****************************************************************************\ -* * -* Name : blowfish encryption * -* Author : Chris Koeritz * -* * -******************************************************************************* -* Copyright (c) 2005-$now By Author. This program is free software; you can * -* redistribute it and/or modify it under the terms of the GNU General Public * -* License as published by the Free Software Foundation; either version 2 of * -* the License or (at your option) any later version. This is online at: * -* http://www.fsf.org/copyleft/gpl.html * -* Please send any updates to: fred@gruntose.com * -\*****************************************************************************/ +/* +* Name : blowfish encryption +* Author : Chris Koeritz +***** +* Copyright (c) 2005-$now By Author. This program is free software; you can +* redistribute it and/or modify it under the terms of the GNU General Public +* License as published by the Free Software Foundation; either version 2 of +* the License or (at your option) any later version. This is online at: +* http://www.fsf.org/copyleft/gpl.html +* Please send any updates to: fred@gruntose.com +*/ #include "blowfish_crypto.h" #include "ssl_init.h" @@ -34,7 +32,7 @@ using namespace structures; namespace crypto { -const int FUDGE = 128; +////const int FUDGE = 128; // extra space for the cipher's block size. blowfish is only 8 bytes for // the cipher block size, but we ensure there will definitely be no // problems. @@ -42,9 +40,8 @@ const int FUDGE = 128; //#undef set_key // get rid of a macro we don't want. -#define DEBUG_BLOWFISH +//#define DEBUG_BLOWFISH // uncomment for noisier version. - #undef ALWAYS_LOG #define ALWAYS_LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t) #ifdef DEBUG_BLOWFISH @@ -56,9 +53,10 @@ const int FUDGE = 128; #endif // helpful macro for the error string of last failure. -#define GET_SSL_ERROR() \ - ERR_error_string(ERR_get_error(), NULL_POINTER) +//#define GET_SSL_ERROR() \ +// ERR_error_string(ERR_get_error(), NULL_POINTER) +/* #ifdef DEBUG_BLOWFISH // this macro checks on the validity of the key sizes (in bits). #define DISCUSS_KEY_SIZE(key_size) \ @@ -85,11 +83,14 @@ const int FUDGE = 128; #define DISCUSS_PROVIDED_KEY(key_size, key) #define DISCUSS_KEY_SIZE(key_size) #endif +*/ blowfish_crypto::blowfish_crypto(int key_size) -: _key_size(key_size), - _key(new byte_array) +: cryptical_envelopment(key_size, EVP_bf_cbc()) +///_key_size(key_size), +/// _key(new byte_array) { +/* FUNCDEF("ctor(int)"); static_ssl_initializer(); LOG("prior to key size discuss"); @@ -101,12 +102,15 @@ blowfish_crypto::blowfish_crypto(int key_size) LOG("prior to generate key"); generate_key(_key_size, *_key); LOG("after generate key"); +*/ } blowfish_crypto::blowfish_crypto(const byte_array &key, int key_size) -: _key_size(key_size), - _key(new byte_array(key)) +: cryptical_envelopment(key, key_size, EVP_bf_cbc()) +//: _key_size(key_size), +// _key(new byte_array(key)) { +/* FUNCDEF("ctor(byte_array,int)"); static_ssl_initializer(); // any problems with the key provided are horrid. they will yield a @@ -117,26 +121,31 @@ blowfish_crypto::blowfish_crypto(const byte_array &key, int key_size) DISCUSS_PROVIDED_KEY(key_size, key); LOG("prior to ssl static init"); LOG("after ssl static init"); +*/ } blowfish_crypto::blowfish_crypto(const blowfish_crypto &to_copy) : root_object(), - _key_size(to_copy._key_size), - _key(new byte_array(*to_copy._key)) + cryptical_envelopment(*this) +/// _key_size(to_copy._key_size), +/// _key(new byte_array(*to_copy._key)) { - FUNCDEF("copy ctor"); - static_ssl_initializer(); - LOG("after ssl static init"); +/// FUNCDEF("copy ctor"); +/// static_ssl_initializer(); +/// LOG("after ssl static init"); } blowfish_crypto::~blowfish_crypto() { +/* FUNCDEF("destructor"); LOG("prior to key whack"); WHACK(_key); LOG("after key whack"); +*/ } +/* int blowfish_crypto::key_size() const { return _key_size; } const byte_array &blowfish_crypto::get_key() const { return *_key; } @@ -144,15 +153,20 @@ const byte_array &blowfish_crypto::get_key() const { return *_key; } int blowfish_crypto::minimum_key_size() { return 64; } int blowfish_crypto::maximum_key_size() { return 448; } +*/ blowfish_crypto &blowfish_crypto::operator = (const blowfish_crypto &to_copy) { if (this == &to_copy) return *this; - _key_size = to_copy._key_size; - *_key = *to_copy._key; + *((cryptical_envelopment *)this) = *((cryptical_envelopment *)&to_copy); +//hmmm: is that the best way to do this? + +// _key_size = to_copy._key_size; +// *_key = *to_copy._key; return *this; } +/* bool blowfish_crypto::set_key(const byte_array &new_key, int key_size) { FUNCDEF("set_key"); @@ -349,6 +363,7 @@ ALWAYS_LOG(">>decrypt>>"); ALWAYS_LOG("< #include +#include "cryptical_envelopment.h" + namespace crypto { //! Provides BlowFish encryption on byte_arrays using the OpenSSL package. -class blowfish_crypto : public virtual basis::root_object +class blowfish_crypto : public cryptical_envelopment +//: public virtual basis::root_object { public: blowfish_crypto(int key_size); @@ -46,30 +49,30 @@ public: DEFINE_CLASS_NAME("blowfish_crypto"); - int key_size() const; // returns the size of our key, in bits. +/// int key_size() const; // returns the size of our key, in bits. - static int minimum_key_size(); - //!< returns the minimum key size (in bits) supported here. - static int maximum_key_size(); - //!< returns the maximum key size (in bits) supported here. +/// static int minimum_key_size(); +/// //!< returns the minimum key size (in bits) supported here. +/// static int maximum_key_size(); +/// //!< returns the maximum key size (in bits) supported here. - const basis::byte_array &get_key() const; //!< returns our current key. +/// const basis::byte_array &get_key() const; //!< returns our current key. - bool set_key(const basis::byte_array &new_key, int key_size); +/// bool set_key(const basis::byte_array &new_key, int key_size); //!< sets the encryption key to "new_key". - static void generate_key(int size, basis::byte_array &new_key); +/// static void generate_key(int size, basis::byte_array &new_key); //!< creates a "new_key" of the "size" (in bits) specified. - bool encrypt(const basis::byte_array &source, basis::byte_array &target) const; +/// bool encrypt(const basis::byte_array &source, basis::byte_array &target) const; //!< encrypts the "source" array into the "target" array. - bool decrypt(const basis::byte_array &source, basis::byte_array &target) const; +/// bool decrypt(const basis::byte_array &source, basis::byte_array &target) const; //!< decrypts the "target" array from the encrypted "source" array. // seldom-needed methods... - static const basis::byte_array &init_vector(); +/// static const basis::byte_array &init_vector(); //!< returns the initialization vector that is used by this class. /*!< decryption of chunks that were encrypted by this class will require the same init vector as this function returns. this is mainly provided @@ -80,8 +83,8 @@ public: (currently named blowfish_crypto.cpp). */ private: - int _key_size; //!< number of bits in the key. - basis::byte_array *_key; //!< our secret key. +/// int _key_size; //!< number of bits in the key. +/// basis::byte_array *_key; //!< our secret key. }; } //namespace. diff --git a/nucleus/library/crypto/cryptical_envelopment.cpp b/nucleus/library/crypto/cryptical_envelopment.cpp new file mode 100644 index 00000000..e717d1be --- /dev/null +++ b/nucleus/library/crypto/cryptical_envelopment.cpp @@ -0,0 +1,367 @@ +/*****************************************************************************\ +* * +* Name : cryptical_envelopment * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 2005-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#include "cryptical_envelopment.h" +#include "ssl_init.h" + +#include +#include +#include +#include +#include +#include +#include + +///#include +#include +#include + +using namespace basis; +using namespace loggers; +using namespace mathematics; +using namespace structures; + +namespace crypto { + +const int FUDGE = 1024; + /* extra space for the cipher's block size. blowfish, e.g., is only 8 bytes for + the cipher block size, so we'd only ever need possibly 8 bytes padding? + */ +//hmmm: guarantee the fudge space is enough for other algorithms! + +//#undef set_key + // get rid of a macro we don't want. + +#define DEBUG_CRYPTICAL_ENVELOPMENT + // uncomment for noisier version. + +// our logging via LOG is disabled unless the debugging flag above is turned on. +// but the ALWAYS_LOG macro is unfazed and will log regardless of the flag. +#undef ALWAYS_LOG +#define ALWAYS_LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t) +#ifdef DEBUG_CRYPTICAL_ENVELOPMENT + #undef LOG + #define LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t) +#else + #undef LOG + #define LOG(t) +#endif + +// helpful macro for the error string of last failure. +#define GET_SSL_ERROR() \ + ERR_error_string(ERR_get_error(), NULL_POINTER) + +#ifdef DEBUG_CRYPTICAL_ENVELOPMENT + +/// // this macro checks on the validity of the key sizes (in bits). +/// #define DISCUSS_KEY_SIZE(key_size) \ +/// if (key_size < minimum_key_size()) { \ +/// deadly_error(static_class_name(), func, \ +/// a_sprintf("key size (%d bits) is less than minimum key size %d.", \ +/// key_size, minimum_key_size())); \ +/// } \ +/// if (key_size > maximum_key_size()) { \ +/// deadly_error(static_class_name(), func, \ +/// a_sprintf("key size (%d bits) is greater than maximum key size %d.", \ +/// key_size, maximum_key_size())); \ +/// } + + // this macro checks that the key in the byte array has enough bytes for + // the key size bits. + #define DISCUSS_PROVIDED_KEY(key_size, key) \ + if (key.length() * BITS_PER_BYTE < key_size) { \ + deadly_error(static_class_name(), func, \ + a_sprintf("key array length (%d) is less than required by key size " \ + "(%d bits).", key.length(), key_size)); \ + } +#else + #define DISCUSS_PROVIDED_KEY(key_size, key) +//// #define DISCUSS_KEY_SIZE(key_size) +#endif + +cryptical_envelopment::cryptical_envelopment(int key_size, const EVP_CIPHER *cipher_type) +: _key_size(key_size), + _key(new byte_array), + _cipher_type(cipher_type) +{ + FUNCDEF("ctor(int)"); + static_ssl_initializer(); +//// LOG("prior to key size discuss"); +//// DISCUSS_KEY_SIZE(key_size); +//// if (key_size < minimum_key_size()) +//// _key_size = minimum_key_size(); +//// if (key_size > maximum_key_size()) +//// _key_size = maximum_key_size(); + LOG("prior to generate key"); + generate_key(_key_size, *_key); + LOG("after generate key"); +} + +cryptical_envelopment::cryptical_envelopment(const byte_array &key, int key_size, const EVP_CIPHER *cipher_type) +: _key_size(key_size), + _key(new byte_array(key)), + _cipher_type(cipher_type) +{ + FUNCDEF("ctor(byte_array,int)"); + static_ssl_initializer(); + // any problems with the key provided are horrid. they will yield a + // non-working blowfish object. +//// LOG("prior to key size discuss"); +//// DISCUSS_KEY_SIZE(key_size); + LOG("prior to provided key discuss"); + DISCUSS_PROVIDED_KEY(key_size, key); + LOG("prior to ssl static init"); + LOG("after ssl static init"); +} + +cryptical_envelopment::cryptical_envelopment(const cryptical_envelopment &to_copy) +: root_object(), + _key_size(to_copy._key_size), + _key(new byte_array(*to_copy._key)) +{ + FUNCDEF("copy ctor"); + static_ssl_initializer(); + LOG("after ssl static init"); +} + +cryptical_envelopment::~cryptical_envelopment() +{ + FUNCDEF("destructor"); + LOG("prior to key whack"); + WHACK(_key); + LOG("after key whack"); +} + +int cryptical_envelopment::key_size() const { return _key_size; } + +const byte_array &cryptical_envelopment::get_key() const { return *_key; } + +/////hmmm: these are not right for all encryption types. +///int cryptical_envelopment::minimum_key_size() { return 64; } +/// +///int cryptical_envelopment::maximum_key_size() { return 448; } + +cryptical_envelopment &cryptical_envelopment::operator = (const cryptical_envelopment &to_copy) +{ + if (this == &to_copy) return *this; + _key_size = to_copy._key_size; + *_key = *to_copy._key; + _cipher_type = to_copy._cipher_type; + return *this; +} + +bool cryptical_envelopment::set_key(const byte_array &new_key, int key_size) +{ + FUNCDEF("set_key"); + if (!new_key.length()) return false; +//// DISCUSS_KEY_SIZE(key_size); + DISCUSS_PROVIDED_KEY(key_size, new_key); +//// if ( (key_size < minimum_key_size()) || (key_size > maximum_key_size()) ) +//// return false; + if (new_key.length() * BITS_PER_BYTE < key_size) return false; + _key_size = key_size; + *_key = new_key; + return true; +} + +void cryptical_envelopment::generate_key(int size, byte_array &new_key) +{ + FUNCDEF("generate_key"); + static_ssl_initializer(); +//// DISCUSS_KEY_SIZE(size); +//// if (size < minimum_key_size()) +//// size = minimum_key_size(); +//// else if (size > maximum_key_size()) +//// size = maximum_key_size(); + int bytes = size / BITS_PER_BYTE; // calculate the number of bytes needed. + if (size % BITS_PER_BYTE) bytes++; // add one for non-integral portion. + new_key.reset(bytes); + for (int i = 0; i < bytes; i++) + new_key[i] = static_ssl_initializer().randomizer().inclusive(0, 255); + +//hmmm: if we leave non-zero stuff in the last byte, that's not quite right! +// also a question of endian-ness of where to zap those bits. argh! + + // clear the bits that cannot be non-zero for a key whose bits are not evenly divisible by 8. + +} + +SAFE_STATIC(mutex, __vector_init_lock, ) + +//hmmm: this seems like a bad security situation, because we are using a single process for +// creating init vectors, so it's super easy to guess these (by reading the code, for +// example). is this still secure, given that the keys are not known to an attacker? +const byte_array &cryptical_envelopment::init_vector() +{ + FUNCDEF("init_vector"); + static_ssl_initializer(); + auto_synchronizer locking(__vector_init_lock()); + static byte_array to_return(EVP_MAX_IV_LENGTH); + static bool initted = false; + if (!initted) { + LOG(">> actually creating init_vector >>"); +//hmmm: we're okay with the wrap-around on the byte type (going negative) if the init vector length is longer than 214? + for (int i = 0; i < to_return.length(); i++) + to_return[i] = abyte(214 - i); + initted = true; + LOG("<< finished init_vector creation <<"); + } + return to_return; +} + +bool cryptical_envelopment::encrypt(const byte_array &source, + byte_array &target) const +{ + FUNCDEF("encrypt"); +ALWAYS_LOG(">>encrypt>>"); + target.reset(); + if (!_key->length() || !source.length()) return false; + bool to_return = true; + +LOG(a_sprintf(" encrypting %d bytes", source.length())); + + // initialize an encoding session. + EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_init(session); + +//new rules! +//EVP_EncryptInit to set the cipher, but leave key and IV null and unset +//EVP_CIPHER_CTX_set_key_length and EVP_CTRL_AEAD_SET_IVLEN +//EVP_EncryptInit again. This time leave cipher null, because you've already set it, and set the key and IV. + + int initret = EVP_EncryptInit_ex(session, _cipher_type, NULL_POINTER, NULL_POINTER, NULL_POINTER); + if (!initret) { + // zero means a failure of the initialization. + deadly_error(class_name(), func, a_sprintf("failure in calling EVP_EncryptInit_ex, with error %s", GET_SSL_ERROR())); + } + LOG(a_sprintf(" calling set key len with key size of %d", _key_size)); + // new fancy footwork needed to keep openssl from blowing up and claiming we didn't set the key. +//hmmm: check returns on these setters? + EVP_CIPHER_CTX_set_key_length(session, _key_size); + EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN, init_vector().length(), NULL); + // and round and round we go... + initret = EVP_EncryptInit_ex(session, NULL_POINTER, NULL_POINTER, _key->observe(), init_vector().observe()); + if (!initret) { + // zero means a failure of the initialization. + deadly_error(class_name(), func, a_sprintf("second phase failure in calling EVP_EncryptInit_ex, with error %s", GET_SSL_ERROR())); + } + + // allocate temporary space for encrypted data. + byte_array encoded(source.length() + FUDGE); + + // encrypt the entire source buffer. + int encoded_len = 0; + int enc_ret = EVP_EncryptUpdate(session, encoded.access(), &encoded_len, + source.observe(), source.length()); + if (enc_ret != 1) { + deadly_error(class_name(), func, a_sprintf("encryption failed, " + "result=%d with error=%s.", enc_ret, GET_SSL_ERROR())); + to_return = false; + } else { + // chop any extra space off. + LOG(a_sprintf(" chopping extra bytes %d to %d.", encoded_len, encoded.last())); + encoded.zap(encoded_len, encoded.last()); + target = encoded; + } + + // only add padding if we succeeded with the encryption. + if (enc_ret == 1) { + // finalize the encryption. + encoded.reset(FUDGE); // reinflate for padding. + int pad_len = 0; + enc_ret = EVP_EncryptFinal_ex(session, encoded.access(), &pad_len); + if (enc_ret != 1) { + deadly_error(class_name(), func, a_sprintf("finalizing encryption " + "failed, result=%d with error=%s.", enc_ret, GET_SSL_ERROR())); + to_return = false; + } else { + LOG(a_sprintf(" encryption padding added %d bytes.", pad_len)); + encoded.zap(pad_len, encoded.last()); + target += encoded; + } + } + + EVP_CIPHER_CTX_cleanup(session); + EVP_CIPHER_CTX_free(session); +ALWAYS_LOG("<>decrypt>>"); + target.reset(); + if (!_key->length() || !source.length()) return false; + bool to_return = true; + EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_init(session); + LOG(a_sprintf(" using key size with %d bits.", _key_size)); + int initret = EVP_DecryptInit_ex(session, _cipher_type, NULL_POINTER, NULL_POINTER, NULL_POINTER); + if (!initret) { + // zero means a failure of the initialization. + deadly_error(class_name(), func, a_sprintf("failure in calling EVP_DecryptInit_ex, with error %s", GET_SSL_ERROR())); + } + // more fancy fupwork. +//hmmm: check returns on these setters? + EVP_CIPHER_CTX_set_key_length(session, _key_size); + EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN, init_vector().length(), NULL); + initret = EVP_DecryptInit_ex(session, NULL_POINTER, NULL_POINTER, _key->observe(), init_vector().observe()); + if (!initret) { + // zero means a failure of the initialization. + deadly_error(class_name(), func, a_sprintf("second phase failure in calling EVP_DecryptInit_ex, with error %s", GET_SSL_ERROR())); + } + + // allocate enough space for decoded bytes. + byte_array decoded(source.length() + FUDGE); + + int decoded_len = 0; + int dec_ret = EVP_DecryptUpdate(session, decoded.access(), &decoded_len, + source.observe(), source.length()); + if (dec_ret != 1) { + deadly_error(class_name(), func, a_sprintf("decryption failed with error=%s", GET_SSL_ERROR())); + to_return = false; + } else { + LOG(a_sprintf(" first part decrypted size in bytes is %d.", decoded_len)); + decoded.zap(decoded_len, decoded.last()); + target = decoded; + } + + // only process padding if the first part of decryption succeeded. + if (dec_ret == 1) { + decoded.reset(FUDGE); // reinflate for padding. + int pad_len = 0; + dec_ret = EVP_DecryptFinal_ex(session, decoded.access(), &pad_len); + if (dec_ret != 1) { + deadly_error(class_name(), func, a_sprintf("finalizing decryption " + "failed, result=%d, padlen=%d, target had %d bytes, error=%s.", dec_ret, + pad_len, target.length(), GET_SSL_ERROR())); + to_return = false; + } else { + LOG(a_sprintf(" decryption final had %d bytes padding.", pad_len)); + decoded.zap(pad_len, decoded.last()); + target += decoded; + } + } + + EVP_CIPHER_CTX_cleanup(session); + EVP_CIPHER_CTX_free(session); +ALWAYS_LOG("< +#include + +// forward. +struct evp_cipher_st; +typedef struct evp_cipher_st EVP_CIPHER; + +namespace crypto { + +class cryptical_envelopment : public virtual basis::root_object +{ +public: + cryptical_envelopment(int key_size, const EVP_CIPHER *cipher_type); + //!< this will create a new random key of the "key_size", in bits. + /*!< the valid sizes for keys depend on the algorithm in question. */ + + cryptical_envelopment(const basis::byte_array &key, int key_size, const EVP_CIPHER *cipher_type); + //!< uses a pre-existing "key" for encryption. + + cryptical_envelopment(const cryptical_envelopment &to_copy); //!< copy constructor. + + virtual ~cryptical_envelopment(); + + cryptical_envelopment &operator = (const cryptical_envelopment &to_copy); + + DEFINE_CLASS_NAME("cryptical_envelopment"); + + int key_size() const; // returns the size of our key, in bits. + +/// static int minimum_key_size(); +/// //!< returns the minimum key size (in bits) supported here. +/// static int maximum_key_size(); +/// //!< returns the maximum key size (in bits) supported here. + + const basis::byte_array &get_key() const; //!< returns our current key. + + bool set_key(const basis::byte_array &new_key, int key_size); + //!< sets the encryption key to "new_key" with a "key_size" in bits. + + static void generate_key(int size, basis::byte_array &new_key); + //!< creates a "new_key" of the "size" (in bits) specified. + + bool encrypt(const basis::byte_array &source, basis::byte_array &target) const; + //!< encrypts the "source" array into the "target" array. + + bool decrypt(const basis::byte_array &source, basis::byte_array &target) const; + //!< decrypts the "target" array from the encrypted "source" array. + + // seldom-needed methods... + + static const basis::byte_array &init_vector(); + //!< returns the initialization vector that is used by this class. + /*!< decryption of chunks that were encrypted by this class will require + the same init vector as this function returns. this is mainly provided + for third-party applications that want to be able to decrypt interoperably + with this class. if you are creating such an application but for some + reason cannot run this class in order to invoke this method, the vector + is created by the algorithm in this class's implementation file + (currently named cryptical_envelopment.cpp). */ + +private: + int _key_size; //!< number of bits in the key. + basis::byte_array *_key; //!< our secret key. + const EVP_CIPHER *_cipher_type; //!< what kind of encryption are we using? +}; + +} //namespace. + +#endif + diff --git a/nucleus/library/crypto/makefile b/nucleus/library/crypto/makefile index 97c7376a..06b612c4 100644 --- a/nucleus/library/crypto/makefile +++ b/nucleus/library/crypto/makefile @@ -4,7 +4,7 @@ include cpp/variables.def TYPE = library PROJECT = crypto -SOURCE = blowfish_crypto.cpp rsa_crypto.cpp ssl_init.cpp +SOURCE = blowfish_crypto.cpp cryptical_envelopment.cpp old_school_rsa_crypto.cpp ssl_init.cpp USE_SSL = t TARGETS = crypto.lib diff --git a/nucleus/library/crypto/rsa_crypto.cpp b/nucleus/library/crypto/old_school_rsa_crypto.cpp similarity index 91% rename from nucleus/library/crypto/rsa_crypto.cpp rename to nucleus/library/crypto/old_school_rsa_crypto.cpp index b96b3cdc..43a7017f 100644 --- a/nucleus/library/crypto/rsa_crypto.cpp +++ b/nucleus/library/crypto/old_school_rsa_crypto.cpp @@ -20,7 +20,7 @@ // RSA_size(rsa) - 41 for RSA_PKCS1_OAEP_PADDING and exactly RSA_size(rsa) // for RSA_NO_PADDING. -#include "rsa_crypto.h" +#include "old_school_rsa_crypto.h" #include "ssl_init.h" #include @@ -55,7 +55,7 @@ namespace crypto { SAFE_STATIC(mutex, __single_stepper, ) // protects unsafe areas of rsa crypto from access by multiple threads at once. -rsa_crypto::rsa_crypto(int key_size) +old_school_rsa_crypto::old_school_rsa_crypto(int key_size) : _key(NULL_POINTER) { FUNCDEF("ctor(int)"); @@ -64,7 +64,7 @@ rsa_crypto::rsa_crypto(int key_size) LOG("after generating key"); } -rsa_crypto::rsa_crypto(const byte_array &key) +old_school_rsa_crypto::old_school_rsa_crypto(const byte_array &key) : _key(NULL_POINTER) { FUNCDEF("ctor(byte_array)"); @@ -75,7 +75,7 @@ rsa_crypto::rsa_crypto(const byte_array &key) LOG("after set key"); } -rsa_crypto::rsa_crypto(RSA *key) +old_school_rsa_crypto::old_school_rsa_crypto(RSA *key) : _key(NULL_POINTER) { FUNCDEF("ctor(RSA)"); @@ -85,7 +85,7 @@ rsa_crypto::rsa_crypto(RSA *key) LOG("after set key"); } -rsa_crypto::rsa_crypto(const rsa_crypto &to_copy) +old_school_rsa_crypto::old_school_rsa_crypto(const old_school_rsa_crypto &to_copy) : root_object(), _key(NULL_POINTER) { @@ -96,7 +96,7 @@ rsa_crypto::rsa_crypto(const rsa_crypto &to_copy) LOG("after set key"); } -rsa_crypto::~rsa_crypto() +old_school_rsa_crypto::~old_school_rsa_crypto() { FUNCDEF("destructor"); LOG("prior to rsa free"); @@ -105,14 +105,14 @@ rsa_crypto::~rsa_crypto() LOG("after rsa free"); } -const rsa_crypto &rsa_crypto::operator = (const rsa_crypto &to_copy) +const old_school_rsa_crypto &old_school_rsa_crypto::operator = (const old_school_rsa_crypto &to_copy) { if (this == &to_copy) return *this; set_key(to_copy._key); return *this; } -RSA *rsa_crypto::generate_key(int key_size) +RSA *old_school_rsa_crypto::generate_key(int key_size) { FUNCDEF("generate_key"); if (key_size < 4) key_size = 4; // laughable lower default. @@ -136,13 +136,13 @@ RSA *rsa_crypto::generate_key(int key_size) return to_return; } -bool rsa_crypto::check_key(RSA *key) +bool old_school_rsa_crypto::check_key(RSA *key) { auto_synchronizer mutt(__single_stepper()); return RSA_check_key(key) == 1; } -bool rsa_crypto::set_key(byte_array &key) +bool old_school_rsa_crypto::set_key(byte_array &key) { FUNCDEF("set_key [byte_array]"); if (!key.length()) return false; @@ -223,7 +223,7 @@ bool rsa_crypto::set_key(byte_array &key) return true; } -bool rsa_crypto::set_key(RSA *key) +bool old_school_rsa_crypto::set_key(RSA *key) { FUNCDEF("set_key [RSA]"); if (!key) return NULL_POINTER; @@ -242,7 +242,7 @@ bool rsa_crypto::set_key(RSA *key) return true; } -bool rsa_crypto::public_key(byte_array &pubkey) const +bool old_school_rsa_crypto::public_key(byte_array &pubkey) const { FUNCDEF("public_key"); if (!_key) return false; @@ -266,7 +266,7 @@ bool rsa_crypto::public_key(byte_array &pubkey) const return true; } -bool rsa_crypto::private_key(byte_array &privkey) const +bool old_school_rsa_crypto::private_key(byte_array &privkey) const { FUNCDEF("private_key"); if (!_key) return false; @@ -310,7 +310,7 @@ bool rsa_crypto::private_key(byte_array &privkey) const return true; } -bool rsa_crypto::public_encrypt(const byte_array &source, +bool old_school_rsa_crypto::public_encrypt(const byte_array &source, byte_array &target) const { FUNCDEF("public_encrypt"); @@ -333,7 +333,7 @@ bool rsa_crypto::public_encrypt(const byte_array &source, return true; } -bool rsa_crypto::private_decrypt(const byte_array &source, +bool old_school_rsa_crypto::private_decrypt(const byte_array &source, byte_array &target) const { FUNCDEF("private_decrypt"); @@ -359,7 +359,7 @@ bool rsa_crypto::private_decrypt(const byte_array &source, return true; } -bool rsa_crypto::private_encrypt(const byte_array &source, +bool old_school_rsa_crypto::private_encrypt(const byte_array &source, byte_array &target) const { FUNCDEF("private_encrypt"); @@ -382,7 +382,7 @@ bool rsa_crypto::private_encrypt(const byte_array &source, return true; } -bool rsa_crypto::public_decrypt(const byte_array &source, +bool old_school_rsa_crypto::public_decrypt(const byte_array &source, byte_array &target) const { FUNCDEF("public_decrypt"); diff --git a/nucleus/library/crypto/rsa_crypto.h b/nucleus/library/crypto/old_school_rsa_crypto.h similarity index 88% rename from nucleus/library/crypto/rsa_crypto.h rename to nucleus/library/crypto/old_school_rsa_crypto.h index b2419309..524fb39b 100644 --- a/nucleus/library/crypto/rsa_crypto.h +++ b/nucleus/library/crypto/old_school_rsa_crypto.h @@ -1,5 +1,5 @@ -#ifndef RSA_CRYPTO_CLASS -#define RSA_CRYPTO_CLASS +#ifndef OLD_SCHOOL_RSA_CRYPTO_CLASS +#define OLD_SCHOOL_RSA_CRYPTO_CLASS /*****************************************************************************\ * * @@ -19,7 +19,6 @@ #include // forward. -//struct RSA; typedef struct rsa_st RSA; namespace crypto { @@ -29,31 +28,31 @@ namespace crypto { This class uses the OpenSSL package's support for RSA encryption. */ -class rsa_crypto : public virtual basis::nameable +class old_school_rsa_crypto : public virtual basis::nameable { public: - rsa_crypto(int key_size); + old_school_rsa_crypto(int key_size); //!< constructs using a randomized private key of the "key_size". /*!< the "key_size" must be at least 1024 bits for acceptable security. smaller keys are considered insecure. */ - rsa_crypto(const basis::byte_array &key); + old_school_rsa_crypto(const basis::byte_array &key); //!< constructs with the specified "key" as our private key. /*!< the "key" is used for encryption rather than generating a random one. the key is only valid if it was created with this class. also, if the key is a public key, then only the public_encryption and public_decryption methods will be available. */ - rsa_crypto(RSA *key); + old_school_rsa_crypto(RSA *key); //!< starts with a pre-existing "key" in the low-level form. - rsa_crypto(const rsa_crypto &to_copy); + old_school_rsa_crypto(const old_school_rsa_crypto &to_copy); - virtual ~rsa_crypto(); + virtual ~old_school_rsa_crypto(); - const rsa_crypto &operator = (const rsa_crypto &to_copy); + const old_school_rsa_crypto &operator = (const old_school_rsa_crypto &to_copy); - DEFINE_CLASS_NAME("rsa_crypto"); + DEFINE_CLASS_NAME("old_school_rsa_crypto"); bool set_key(basis::byte_array &key); //!< resets this object's key to "key". diff --git a/nucleus/library/tests_crypto/makefile b/nucleus/library/tests_crypto/makefile index d7d3f49e..e0854cbb 100644 --- a/nucleus/library/tests_crypto/makefile +++ b/nucleus/library/tests_crypto/makefile @@ -2,7 +2,7 @@ include cpp/variables.def PROJECT = tests_crypto TYPE = test -TARGETS = test_blowfish_crypto.exe test_rsa_crypto.exe +TARGETS = test_blowfish_crypto.exe test_old_school_rsa_crypto.exe LOCAL_LIBS_USED = unit_test crypto application processes loggers configuration textual timely \ filesystem structures basis USE_SSL = t diff --git a/nucleus/library/tests_crypto/test_blowfish_crypto.cpp b/nucleus/library/tests_crypto/test_blowfish_crypto.cpp index abf9f7d8..23f622c0 100644 --- a/nucleus/library/tests_crypto/test_blowfish_crypto.cpp +++ b/nucleus/library/tests_crypto/test_blowfish_crypto.cpp @@ -57,6 +57,10 @@ const int ITERATIONS = 80; // number of test runs in our testing threads. const int MAX_STRING = 20000; // largest chunk that we'll try to encrypt. +// some constants snagged from older version of blowfish_crypto class... +const int blowfish_crypto_minimum_key_size_in_bits = 64; +const int blowfish_crypto_maximum_key_size_in_bits = 448; + ////////////// class test_blowfish; // forward. @@ -137,9 +141,8 @@ void blowfish_thread::perform_activity(void *) int left = ITERATIONS; while (left--) { time_stamp key_start; - blowfish_crypto bc(_parent.randomizer().inclusive - (blowfish_crypto::minimum_key_size(), - blowfish_crypto::maximum_key_size())); + blowfish_crypto bc(_parent.randomizer().inclusive(blowfish_crypto_minimum_key_size_in_bits, + blowfish_crypto_maximum_key_size_in_bits)); #ifdef DEBUG_BLOWFISH LOG(a_sprintf("%d bit key has:", bc.key_size())); astring dumped_key = byte_formatter::text_dump(bc.get_key()); diff --git a/nucleus/library/tests_crypto/test_rsa_crypto.cpp b/nucleus/library/tests_crypto/test_old_school_rsa_crypto.cpp similarity index 97% rename from nucleus/library/tests_crypto/test_rsa_crypto.cpp rename to nucleus/library/tests_crypto/test_old_school_rsa_crypto.cpp index adc85d5a..c0dacda1 100644 --- a/nucleus/library/tests_crypto/test_rsa_crypto.cpp +++ b/nucleus/library/tests_crypto/test_old_school_rsa_crypto.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -136,7 +136,7 @@ void rsa_thread::perform_activity(void *) while (left--) { time_stamp start; - rsa_crypto rc_private_here(KEY_SIZE); + old_school_rsa_crypto rc_private_here(KEY_SIZE); int key_durat = int(time_stamp().value() - start.value()); byte_array public_key; @@ -157,13 +157,13 @@ void rsa_thread::perform_activity(void *) // with our private key, can decrypt. start.reset(); - rsa_crypto rc_pub(public_key); + old_school_rsa_crypto rc_pub(public_key); bool worked = rc_pub.public_encrypt(byte_array(ranstring.length() + 1, (abyte*)ranstring.s()), target); int pub_enc_durat = int(time_stamp().value() - start.value()); ASSERT_TRUE(worked, "phase 1 shouldn't fail to encrypt the string"); - rsa_crypto rc_priv(private_key); + old_school_rsa_crypto rc_priv(private_key); byte_array recovered; start.reset(); worked = rc_priv.private_decrypt(target, recovered); diff --git a/octopi/library/cromp/cromp_client.cpp b/octopi/library/cromp/cromp_client.cpp index 141bda78..1c58b010 100644 --- a/octopi/library/cromp/cromp_client.cpp +++ b/octopi/library/cromp/cromp_client.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/octopi/library/cromp/cromp_common.cpp b/octopi/library/cromp/cromp_common.cpp index 3a05e9ec..f732ac62 100644 --- a/octopi/library/cromp/cromp_common.cpp +++ b/octopi/library/cromp/cromp_common.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include @@ -104,9 +104,9 @@ const int cromp_common::HOSTCHOP = 6; double cromp_common::_bytes_sent_total = 0.0; double cromp_common::_bytes_received_total = 0.0; - SAFE_STATIC_CONST(rsa_crypto, _hidden_localhost_only_key, + SAFE_STATIC_CONST(old_school_rsa_crypto, _hidden_localhost_only_key, (encryption_infoton::RSA_KEY_SIZE)) - const rsa_crypto &cromp_common::localhost_only_key() { + const old_school_rsa_crypto &cromp_common::localhost_only_key() { #ifdef DEBUG_CROMP_COMMON FUNCDEF("localhost_only_key"); #endif @@ -119,7 +119,7 @@ double cromp_common::_bytes_received_total = 0.0; if (!was_initted) LOG("started creating localhost RSA key."); #endif - const rsa_crypto &to_return = _hidden_localhost_only_key(); + const old_school_rsa_crypto &to_return = _hidden_localhost_only_key(); #ifdef DEBUG_CROMP_COMMON if (!was_initted) LOG("done creating localhost RSA key."); diff --git a/octopi/library/cromp/cromp_common.h b/octopi/library/cromp/cromp_common.h index 2f5b20c1..8ac3a0fa 100644 --- a/octopi/library/cromp/cromp_common.h +++ b/octopi/library/cromp/cromp_common.h @@ -13,7 +13,7 @@ * Please send any updates to: fred@gruntose.com * \*****************************************************************************/ -#include +#include #include #include #include @@ -177,7 +177,7 @@ public: // returns our octopus support object. this should always exist when this // object is constructed properly. - static const crypto::rsa_crypto &localhost_only_key(); + static const crypto::old_school_rsa_crypto &localhost_only_key(); // this key should *only* be used for speeding up encryption on the local // host. it is generated when the first caller needs it but then is // a constant key during the program's runtime. this object can be used diff --git a/octopi/library/tentacles/encryption_infoton.cpp b/octopi/library/tentacles/encryption_infoton.cpp index b6250755..36f06985 100644 --- a/octopi/library/tentacles/encryption_infoton.cpp +++ b/octopi/library/tentacles/encryption_infoton.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -113,7 +113,7 @@ outcome encryption_infoton::prepare_blowfish_key(blowfish_crypto &new_key) return _success; } - rsa_crypto pub(_public_key); // suck in the provided key. + old_school_rsa_crypto pub(_public_key); // suck in the provided key. blowfish_crypto agreed_key(BLOWFISH_KEY_SIZE); // random blowfish key. new_key = agreed_key; @@ -125,22 +125,22 @@ outcome encryption_infoton::prepare_blowfish_key(blowfish_crypto &new_key) return _success; } -outcome encryption_infoton::prepare_both_keys(rsa_crypto &private_key) +outcome encryption_infoton::prepare_both_keys(old_school_rsa_crypto &private_key) { - rsa_crypto priv(RSA_KEY_SIZE); // generate random key. + old_school_rsa_crypto priv(RSA_KEY_SIZE); // generate random key. outcome to_return = prepare_public_key(priv); if (to_return == tentacle::OKAY) private_key = priv; return to_return; } -outcome encryption_infoton::prepare_public_key(const rsa_crypto &private_key) +outcome encryption_infoton::prepare_public_key(const old_school_rsa_crypto &private_key) { bool worked = private_key.public_key(_public_key); if (!worked) return tentacle::DISALLOWED; // why would that ever fail? return tentacle::OKAY; } -outcome encryption_infoton::extract_response(const rsa_crypto &private_key, +outcome encryption_infoton::extract_response(const old_school_rsa_crypto &private_key, blowfish_crypto &new_key) const { FUNCDEF("extract_response"); diff --git a/octopi/library/tentacles/encryption_infoton.h b/octopi/library/tentacles/encryption_infoton.h index c9a67c2c..9f02b217 100644 --- a/octopi/library/tentacles/encryption_infoton.h +++ b/octopi/library/tentacles/encryption_infoton.h @@ -16,7 +16,7 @@ \*****************************************************************************/ #include -#include +#include #include #include @@ -68,14 +68,14 @@ public: "new_key" will always be used to communicate with the client after this. */ - basis::outcome prepare_public_key(const crypto::rsa_crypto &private_key); + basis::outcome prepare_public_key(const crypto::old_school_rsa_crypto &private_key); //!< prepares the request side for a client. /*!< the rsa public key will be generated from the "private_key". */ - basis::outcome prepare_both_keys(crypto::rsa_crypto &private_key); + basis::outcome prepare_both_keys(crypto::old_school_rsa_crypto &private_key); //!< sets up both keys by randomly generating the "private_key". - basis::outcome extract_response(const crypto::rsa_crypto &private_key, + basis::outcome extract_response(const crypto::old_school_rsa_crypto &private_key, crypto::blowfish_crypto &new_key) const; //!< used by the client to extract the shared blowfish key from the server. /*!< using the private key, the server's response is decrypted and stored diff --git a/octopi/library/tentacles/encryption_tentacle.cpp b/octopi/library/tentacles/encryption_tentacle.cpp index 73789b73..7cfe5046 100644 --- a/octopi/library/tentacles/encryption_tentacle.cpp +++ b/octopi/library/tentacles/encryption_tentacle.cpp @@ -17,7 +17,7 @@ #include "key_repository.h" #include -#include +#include #include #include #include @@ -52,7 +52,7 @@ encryption_tentacle::encryption_tentacle(const byte_array &private_key) (encryption_infoton::encryption_classifier(), false), _server_side(false), _keys(new key_repository), - _rsa_private(new rsa_crypto(private_key)) + _rsa_private(new old_school_rsa_crypto(private_key)) { } @@ -61,7 +61,7 @@ encryption_tentacle::encryption_tentacle(int key_size) (encryption_infoton::encryption_classifier(), false), _server_side(false), _keys(new key_repository), - _rsa_private(new rsa_crypto(key_size)) + _rsa_private(new old_school_rsa_crypto(key_size)) { } @@ -73,7 +73,7 @@ encryption_tentacle::~encryption_tentacle() key_repository &encryption_tentacle::keys() const { return *_keys; } -const rsa_crypto &encryption_tentacle::private_key() const +const old_school_rsa_crypto &encryption_tentacle::private_key() const { return *_rsa_private; } outcome encryption_tentacle::reconstitute(const string_array &classifier, diff --git a/octopi/library/tentacles/encryption_tentacle.h b/octopi/library/tentacles/encryption_tentacle.h index 362da6e8..398e2543 100644 --- a/octopi/library/tentacles/encryption_tentacle.h +++ b/octopi/library/tentacles/encryption_tentacle.h @@ -84,14 +84,14 @@ public: /*!< this is very private info, but it's needed for encrypting items going back to the client. */ - const crypto::rsa_crypto &private_key() const; + const crypto::old_school_rsa_crypto &private_key() const; //!< provides access to the key held here. /*!< this is an important object; do not expose it externally. */ private: bool _server_side; //!< true if we're acting as a server. key_repository *_keys; //!< our table of keys that we've agreed on. - crypto::rsa_crypto *_rsa_private; //!< the private key for a client side. + crypto::old_school_rsa_crypto *_rsa_private; //!< the private key for a client side. }; } //namespace. diff --git a/scripts/buildor/upgrade_hoople_to_feistymeow.sh b/scripts/buildor/upgrade_hoople_to_feistymeow.sh index 12d31222..886f1a6c 100644 --- a/scripts/buildor/upgrade_hoople_to_feistymeow.sh +++ b/scripts/buildor/upgrade_hoople_to_feistymeow.sh @@ -142,7 +142,7 @@ standards and usages." | sed -e 's/class encryption_tentacle;/#include /g' \ | sed -e 's/class login_tentacle;/#include /g' \ | sed -e 's/class thread_cabinet;/#include /g' \ - | sed -e 's/RSA_crypto/rsa_crypto/g' \ + | sed -e 's/RSA_crypto/old_school_rsa_crypto/g' \ | sed -e 's/float_plus/double_plus/g' \ | sed -e 's/basis::obscure_/structures::obscure_/g' \ | sed -e 's/program_wide_logger()/program_wide_logger::get()/g' \ -- 2.43.0