diff options
| author | 2009-11-27 12:19:24 +0000 | |
|---|---|---|
| committer | 2009-11-27 12:19:24 +0000 | |
| commit | 40bd837739879d27a8a574b5d38a85f3d8635d02 (patch) | |
| tree | cc747eff9d551b5673fa1ef7c82f0d252337b446 /src/modules | |
| parent | win32: fixed uninstaller (diff) | |
| download | KVIrc-40bd837739879d27a8a574b5d38a85f3d8635d02.tar.gz KVIrc-40bd837739879d27a8a574b5d38a85f3d8635d02.tar.bz2 KVIrc-40bd837739879d27a8a574b5d38a85f3d8635d02.zip | |
[KVIrc] (trunk) Merge the remaining changes from the no_embedded branch back.
This commit allows to build an encryption module (Blowfish and AES)
completely based on Crypto++, no embedded code needed anymore.
pbuilder testbuild for r3632 + this commit was successfull.
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@3633 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/rijndael/CMakeLists.txt | 30 | ||||
| -rw-r--r-- | src/modules/rijndael/libkvirijndael_cryptopp.cpp | 637 | ||||
| -rw-r--r-- | src/modules/rijndael/libkvirijndael_cryptopp.h | 145 |
3 files changed, 804 insertions, 8 deletions
diff --git a/src/modules/rijndael/CMakeLists.txt b/src/modules/rijndael/CMakeLists.txt index 148a953e2..cd794f080 100644 --- a/src/modules/rijndael/CMakeLists.txt +++ b/src/modules/rijndael/CMakeLists.txt @@ -1,16 +1,29 @@ # CMakeLists for src/modules/rijndael +IF(WANT_NO_EMBEDDED_CODE OR WANT_OPENSSL) SUBDIRS(caps) -SET(kvirijndael_MOC_HDRS - libkvirijndael.h -) +IF(WANT_NO_EMBEDDED_CODE) + ADD_DEFINITIONS("-fexceptions") -SET(kvirijndael_SRCS - libkvirijndael.cpp - rijndael.cpp - ablowfish.cpp -) + SET(kvirijndael_SRCS + libkvirijndael_cryptopp.cpp + ) + + SET(kvirijndael_MOC_HDRS + libkvirijndael_cryptopp.h + ) +ELSEIF(WANT_NO_EMBEDDED_CODE) + SET(kvirijndael_SRCS + libkvirijndael.cpp + rijndael.cpp + ablowfish.cpp + ) + + SET(kvirijndael_MOC_HDRS + libkvirijndael.h + ) +ENDIF(WANT_NO_EMBEDDED_CODE) # After this call, files will be moc'ed to moc_kvi_*.cpp QT4_WRAP_CPP(kvirijndael_MOC_SRCS ${kvirijndael_MOC_HDRS}) @@ -19,3 +32,4 @@ SET(ADDITIONAL_LINK_FLAGS "${ADDITIONAL_LINK_FLAGS} -fno-strict-aliasing") SET(kvi_module_name kvirijndael) INCLUDE(${CMAKE_SOURCE_DIR}/cmake/module.rules.txt) +ENDIF(WANT_NO_EMBEDDED_CODE OR WANT_OPENSSL) diff --git a/src/modules/rijndael/libkvirijndael_cryptopp.cpp b/src/modules/rijndael/libkvirijndael_cryptopp.cpp new file mode 100644 index 000000000..91dece084 --- /dev/null +++ b/src/modules/rijndael/libkvirijndael_cryptopp.cpp @@ -0,0 +1,637 @@ +//============================================================================= +// +// File : libkvirijndael_cryptopp.cpp +// Creation date : Fri, 17 Jul 2009 22:04:54 +0200 by Kai Wasserbäch +// based on libkvirijndael.cpp as this aims to be a drop-in replacement +// +// This file is part of the KVirc irc client distribution +// Copyright © 2009 Kai Wasserbäch <debian@carbon-project.org> +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "libkvirijndael_cryptopp.h" + +#include <crypto++/aes.h> +#include <crypto++/blowfish.h> +#include <crypto++/modes.h> +#include <crypto++/base64.h> +#include <crypto++/hex.h> +#include <crypto++/osrng.h> +#include <string> + +#include "kvi_module.h" +#include "kvi_debug.h" +#include "kvi_locale.h" +#include "kvi_mirccntrl.h" +#include "kvi_time.h" + +/* +@doc: rijndael +@type: +module +@short: +The Rijndael cryptographic engines +@title: +The rijndael module +@body: +The rijndael module exports six [doc:crypt_engines]cryptographic engines[/doc] based +on the Advanced Encryptiong Standard algorithm called Rijndael. Rijndael was +originally written by Joan Daemen and Vincent Rijmen. The original Rijndael +description is available at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/.[br] +It is a private key block cipher that has been designed to replace +the widely used DES, and it should provide at least a decent security against +common attacks. Theoretically the best attack that one can perform on this cipher +is the "brute force" attack that requires a really massive parallel computation: +actually out of the possibilities of a common "hacker".[br] +My implementation allows the usage of 128, 192 and 256 bit keys +on 128 bit data blocks. The encrypted binary data buffer is then converted +into an ascii-string by using the base64 conversion or hex-digit-string rappresentation. +The six engines are the six possible combinations of the key lengths and ascii-string +conversions. +*/ + + + +#include "kvi_pointerlist.h" + +static KviPointerList<KviCryptEngine> * g_pEngineList = 0; + +// The following lines contain a compatible (to the embedded version) +// implementation of the KviCryptEngine for Rijndael. Therefore the output +// gets encoded the same way (Hex or ASCII) as with the embedded version. +KviRijndaelEngine::KviRijndaelEngine() +: KviCryptEngine() +{ + g_pEngineList->append(this); + m_szEncKey.clear(); + m_szDecKey.clear(); +} + +KviRijndaelEngine::~KviRijndaelEngine() +{ + g_pEngineList->removeRef(this); + m_szEncKey.clear(); + m_szDecKey.clear(); +} + +bool KviRijndaelEngine::init(const char *encKey, int encKeyLen, const char *decKey, int decKeyLen) +{ + if(encKey && (encKeyLen > 0)) + { + if(!(decKey && (decKeyLen > 0))) + { + decKey = encKey; + decKeyLen = encKeyLen; + } // else all + } else { + // no encrypt key specified... + if(decKey && decKeyLen) + { + encKey = decKey; + encKeyLen = decKeyLen; + } else { + // both keys missing + setLastError(__tr("Missing both encrypt and decrypt key: at least one is needed")); + return false; + } + } + + m_szEncKey = encKey; + m_szDecKey = decKey; + + if(encKeyLen > getKeyLen()) { + m_szEncKey = m_szEncKey.substr(0,getKeyLen()); + } + + if(encKeyLen < getKeyLen()) { + m_szEncKey.resize(getKeyLen()); + } + + if(decKeyLen > getKeyLen()) { + m_szDecKey = m_szDecKey.substr(0,getKeyLen()); + } + + if(decKeyLen < getKeyLen()) { + m_szDecKey.resize(getKeyLen()); + } + + if(m_szEncKey.empty() || m_szDecKey.empty()) { + return false; + } + else { + return true; + } +} + +KviCryptEngine::EncryptResult KviRijndaelEngine::encrypt(const char * plainText,KviStr &outBuffer) +{ + std::string cipher; + // byte is a typedef by Crypto++ for unsigned char. + byte key[m_szEncKey.size()],iv[CryptoPP::AES::BLOCKSIZE]; + + for(unsigned int i=0;i<m_szEncKey.size();i++) { + key[i] = m_szEncKey[i]; + } + + // The following is absolute shit, but the module we replace does it like + // that, so we hardcode the IV to 0 in the required length... + for(unsigned int i=0;i<sizeof(iv);i++) { + iv[i] = 0x00; + } + + // We hardcode CBC mode here, as the embedded code is always called in + // CBC mode too (see above, line 148), no need to use the external + // cipher object. + // The padding mode is enforced to be + // CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING, as the embedded code + // does only that. + try { + CryptoPP::CBC_Mode< CryptoPP::AES >::Encryption encryptor( key, sizeof(key), iv ); + + if(getEncoding() == KVI_RIJNDAEL_HEX) { + CryptoPP::StringSource(static_cast<std::string>(plainText), true, + new CryptoPP::StreamTransformationFilter( + encryptor, new CryptoPP::HexEncoder( + new CryptoPP::StringSink( cipher ) + ), CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING + ) + ); + } + else if(getEncoding() == KVI_RIJNDAEL_B64) { + CryptoPP::StringSource(static_cast<std::string>(plainText), true, + new CryptoPP::StreamTransformationFilter( + encryptor, new CryptoPP::Base64Encoder( + new CryptoPP::StringSink( cipher ) + ), CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING + ) + ); + } + else { + setLastError(__tr("Unable to determine output encoding (Hex or Base64).")); + return KviCryptEngine::EncryptError; + } + } + catch(CryptoPP::Exception e) { + QString staticErrTxt = + __tr("Crypto++ threw the following exception: "); + setLastError(staticErrTxt.append(QString(e.what()))); + return KviCryptEngine::EncryptError; + } + + outBuffer = cipher.c_str(); + outBuffer.prepend(KVI_TEXT_CRYPTESCAPE); + return KviCryptEngine::Encrypted; +} + +KviCryptEngine::DecryptResult KviRijndaelEngine::decrypt(const char * inBuffer,KviStr &plainText) +{ + std::string plain; + byte key[m_szDecKey.size()],iv[CryptoPP::AES::BLOCKSIZE]; + std::string szIn = inBuffer; + + for(unsigned int i=0;i<m_szDecKey.size();i++) { + key[i] = m_szDecKey[i]; + } + + // The following is absolute shit, but the module we replace does it like + // that, so we hardcode the IV to 0 in the required length... + for(unsigned int i=0;i<sizeof(iv);i++) { + iv[i] = 0x00; + } + + if(static_cast<int>(szIn[0]) != KVI_TEXT_CRYPTESCAPE) + { + plainText = inBuffer; + return KviCryptEngine::DecryptOkWasPlainText; + } + + szIn = szIn.erase(0,1); + + if(szIn.empty()) + { + plainText = inBuffer; + return KviCryptEngine::DecryptOkWasPlainText; // empty buffer + } + + try { + CryptoPP::CBC_Mode< CryptoPP::AES >::Decryption decryptor( key, sizeof(key), iv ); + + if(getEncoding() == KVI_RIJNDAEL_HEX) { + CryptoPP::StringSource(szIn, true, + new CryptoPP::HexDecoder( + new CryptoPP::StreamTransformationFilter( + decryptor, new CryptoPP::StringSink( plain ), + CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING ) + ) + ); + } + else if(getEncoding() == KVI_RIJNDAEL_B64) { + CryptoPP::StringSource(szIn, true, + new CryptoPP::Base64Decoder( + new CryptoPP::StreamTransformationFilter( + decryptor, new CryptoPP::StringSink( plain ), + CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING ) + ) + ); + } + else { + setLastError(__tr("Unable to determine input encoding (Hex or Base64).")); + return KviCryptEngine::DecryptError; + } + } + catch(CryptoPP::Exception e) { + QString staticErrTxt = + __tr("Crypto++ threw the following exception: "); + setLastError(staticErrTxt.append(QString(e.what()))); + return KviCryptEngine::DecryptError; + } + + plainText = plain.c_str(); + return KviCryptEngine::DecryptOkWasEncrypted; +} + +// The following is needed in either case +static KviCryptEngine * allocRijndael128HexEngine() +{ + return new KviRijndael128HexEngine(); +} + +static KviCryptEngine * allocRijndael192HexEngine() +{ + return new KviRijndael192HexEngine(); +} + +static KviCryptEngine * allocRijndael256HexEngine() +{ + return new KviRijndael256HexEngine(); +} + +static KviCryptEngine * allocRijndael128Base64Engine() +{ + return new KviRijndael128Base64Engine(); +} + +static KviCryptEngine * allocRijndael192Base64Engine() +{ + return new KviRijndael192Base64Engine(); +} + +static KviCryptEngine * allocRijndael256Base64Engine() +{ + return new KviRijndael256Base64Engine(); +} + +static void deallocRijndaelCryptEngine(KviCryptEngine * e) +{ + delete e; +} + +// Again a compatible (to the embedded version) implementation of the +// KviCryptEngine, this time for Blowfish. +KviMircryptionEngine::KviMircryptionEngine() +: KviCryptEngine() +{ + g_pEngineList->append(this); + m_szEncKey.clear(); + m_szDecKey.clear(); +} + +KviMircryptionEngine::~KviMircryptionEngine() +{ + g_pEngineList->removeRef(this); + m_szEncKey.clear(); + m_szDecKey.clear(); +} + +bool KviMircryptionEngine::init(const char * encKey,int encKeyLen,const char * decKey,int decKeyLen) +{ + if(encKey && (encKeyLen > 0)) + { + if(!(decKey && (decKeyLen > 0))) + { + decKey = encKey; + decKeyLen = encKeyLen; + } // else all + } else { + // no encrypt key specified... + if(decKey && decKeyLen) + { + encKey = decKey; + encKeyLen = decKeyLen; + } else { + // both keys missing + setLastError(__tr("Missing both encrypt and decrypt key: at least one is needed")); + return false; + } + } + + m_szEncKey = std::string(encKey,encKeyLen); + m_szDecKey = std::string(decKey,decKeyLen); + if((m_szEncKey.find("cbc:",0,4) != std::string::npos) && (m_szEncKey.size() > 4)) { + m_szEncKey = m_szEncKey.substr(4); + m_bEncryptCBC = true; + } + else { + m_bEncryptCBC = false; + } + + if((m_szDecKey.find("cbc:",0,4) != std::string::npos) && (m_szDecKey.size() > 4)) { + m_szDecKey = m_szDecKey.substr(4); + m_bDecryptCBC = true; + } + else { + m_bDecryptCBC = false; + } + + return true; +} + +KviCryptEngine::EncryptResult KviMircryptionEngine::encrypt(const char * plainText,KviStr &outBuffer) +{ + std::string cipher; + byte key[m_szEncKey.size()], iv[CryptoPP::Blowfish::BLOCKSIZE]; + + for(unsigned int i=0;i<m_szEncKey.size();i++) { + key[i] = m_szEncKey.at(i); + } + + if(m_bEncryptCBC) + { + try { + for(unsigned int i=0;i<sizeof(iv);i++) { + iv[i] = 0x00; + } + + CryptoPP::CBC_Mode< CryptoPP::Blowfish >::Encryption encryptor( key, sizeof(key), iv ); + CryptoPP::StringSource(static_cast<std::string>(plainText), true, + new CryptoPP::StreamTransformationFilter( + encryptor, new CryptoPP::Base64Encoder( + new CryptoPP::StringSink( cipher ) + ), CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING + ) + ); + } + catch(CryptoPP::Exception e) { + QString staticErrTxt = + __tr("Crypto++ threw the following exception: "); + setLastError(staticErrTxt.append(QString(e.what()))); + return KviCryptEngine::EncryptError; + } + } else { + try { + CryptoPP::ECB_Mode< CryptoPP::Blowfish >::Encryption encryptor( key, sizeof(key) ); + CryptoPP::StringSource(static_cast<std::string>(plainText), true, + new CryptoPP::StreamTransformationFilter( + encryptor, new CryptoPP::Base64Encoder( + new CryptoPP::StringSink( cipher ) + ), CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING + ) + ); + } + catch(CryptoPP::Exception e) { + QString staticErrTxt = + __tr("Crypto++ threw the following exception: "); + setLastError(staticErrTxt.append(QString(e.what()))); + return KviCryptEngine::EncryptError; + } + } + + outBuffer = "+OK "; + outBuffer.append(cipher.c_str()); + + return KviCryptEngine::Encrypted; +} + +KviCryptEngine::DecryptResult KviMircryptionEngine::decrypt(const char * inBuffer,KviStr &plainText) +{ + std::string plain; + std::string szIn = inBuffer; + byte key[m_szDecKey.size()], iv[CryptoPP::Blowfish::BLOCKSIZE]; + + // various old versions + if(szIn.find("mcps ",0,5) != std::string::npos) { + szIn = szIn.substr(5); + } + else if(szIn.find("+OK ",0,4) != std::string::npos) { + szIn = szIn.substr(4); + } + // some servers seem to strip the + at the beginning... + else if(szIn.find("OK ",0,3) != std::string::npos) { + szIn = szIn.substr(3); + } + else { + plainText = szIn.c_str(); + return KviCryptEngine::DecryptOkWasPlainText; + } + + for(unsigned int i=0;i<m_szDecKey.size();i++) { + key[i] = m_szDecKey.at(i); + } + + if(m_bDecryptCBC) + { + try { + for(unsigned int i=0;i<sizeof(iv);i++) { + iv[i] = 0x00; + } + + CryptoPP::CBC_Mode< CryptoPP::Blowfish >::Decryption decryptor( key, sizeof(key), iv ); + CryptoPP::StringSource(szIn, true, + new CryptoPP::Base64Decoder( + new CryptoPP::StreamTransformationFilter( + decryptor, + new CryptoPP::StringSink( plain ), + CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING + ) + ) + ); + } + catch(CryptoPP::Exception e) { + QString staticErrTxt = + __tr("Crypto++ threw the following exception: "); + setLastError(staticErrTxt.append(QString(e.what()))); + return KviCryptEngine::DecryptError; + } + } else { + try { + CryptoPP::ECB_Mode< CryptoPP::Blowfish >::Decryption decryptor( key, sizeof(key) ); + CryptoPP::StringSource(szIn, true, + new CryptoPP::Base64Decoder( + new CryptoPP::StreamTransformationFilter( + decryptor, new CryptoPP::StringSink( plain ), + CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING ) + ) + ); + } + catch(CryptoPP::Exception e) { + QString staticErrTxt = + __tr("Crypto++ threw the following exception: "); + setLastError(staticErrTxt.append(QString(e.what()))); + return KviCryptEngine::DecryptError; + } + } + + plainText = plain.c_str(); + return KviCryptEngine::DecryptOkWasEncrypted; +} + +static KviCryptEngine * allocMircryptionEngine() +{ + return new KviMircryptionEngine(); +} + +// ======================================= +// module routines +// ======================================= +static bool rijndael_module_init(KviModule * m) +{ + g_pEngineList = new KviPointerList<KviCryptEngine>; + g_pEngineList->setAutoDelete(false); + + KviStr format = __tr("Cryptographic engine based on the\n" \ + "Advanced Encryption Standard (AES)\n" \ + "algorithm called Rijndael.\n" \ + "The text is first encrypted with Rijndael\n" \ + "and then converted to %s notation.\n" \ + "The keys used are %d bit long and will be padded\n" \ + "with zeros if you provide shorter ones.\n" \ + "If only one key is provided, this engine\n" \ + "will use it for both encrypting and decrypting.\n" \ + "This is the Crypto++ implementation which could do\n" \ + "a lot more than the current default engine, but as\n" \ + "this should be a drop-in replacement, it acts just\n" \ + "like that one.\n" \ + "Information about the algorithm can be found at\n" \ + "<http://www.cryptolounge.org/wiki/AES>\n"); + + // FIXME: Maybe convert this repeated code to a function eh ? + + KviCryptEngineDescription * d = new KviCryptEngineDescription; + d->szName = "Rijndael128Hex"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),128); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocRijndael128HexEngine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + d = new KviCryptEngineDescription; + d->szName = "Rijndael192Hex"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),192); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocRijndael192HexEngine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + d = new KviCryptEngineDescription; + d->szName = "Rijndael256Hex"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),256); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocRijndael256HexEngine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + d = new KviCryptEngineDescription; + d->szName = "Rijndael128Base64"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription.sprintf(format.ptr(),__tr("base64"),128); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocRijndael128Base64Engine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + d = new KviCryptEngineDescription; + d->szName = "Rijndael192Base64"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription.sprintf(format.ptr(),__tr("base64"),192); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocRijndael192Base64Engine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + d = new KviCryptEngineDescription; + d->szName = "Rijndael256Base64"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription.sprintf(format.ptr(),__tr("base64"),256); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocRijndael256Base64Engine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + + d = new KviCryptEngineDescription; + d->szName = "Mircryption"; + d->szAuthor = "Kai Wasserbäch"; + d->szDescription = __tr("Popular cryptographic engine based on the\n" \ + "old Blowfish encryption algorithm.\n" \ + "The text is first encrypted with Blowfish \n" \ + "and then converted to base64 notation.\n" \ + "The keys used have variable length and\n" \ + "are specified as character strings.\n" \ + "You can specify keys long up to 56 bytes (448 bits).\n" \ + "If only one key is provided, this engine\n" \ + "will use it for both encrypting and decrypting.\n" \ + "This engine works in ECB mode by default:\n" \ + "if you want to use CBC mode you must prefix\n" \ + "your key(s) with \"cbc:\".\n\n" \ + "This is the Crypto++ based version, not relying on embedded code\n"); + d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT | + KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY; + d->allocFunc = allocMircryptionEngine; + d->deallocFunc = deallocRijndaelCryptEngine; + m->registerCryptEngine(d); + + + return true; +} + +static bool rijndael_module_cleanup(KviModule *m) +{ + while(g_pEngineList->first())delete g_pEngineList->first(); + delete g_pEngineList; + g_pEngineList = 0; + m->unregisterCryptEngines(); + return true; +} + +static bool rijndael_module_can_unload(KviModule *) +{ + return g_pEngineList->isEmpty(); +} + +// ======================================= +// plugin definition structure +// ======================================= +KVIRC_MODULE( +"Rijndael crypt engine", + "4.0.1", + "Copyright © 2009 Kai Wasserbäch <debian@carbon-project.org>" \ + " © 2000-2008 Szymon Stefanek <pragma at kvirc dot net>" , + "Exports the rijndael crypt engine", + rijndael_module_init , + rijndael_module_can_unload, + 0, + rijndael_module_cleanup + ) diff --git a/src/modules/rijndael/libkvirijndael_cryptopp.h b/src/modules/rijndael/libkvirijndael_cryptopp.h new file mode 100644 index 000000000..6a296aaf3 --- /dev/null +++ b/src/modules/rijndael/libkvirijndael_cryptopp.h @@ -0,0 +1,145 @@ +#ifndef _LIBKVIRIJNDAEL_H_ +#define _LIBKVIRIJNDAEL_H_ +//============================================================================= +// +// File : libkvirijndael_cryptopp.h +// Creation date : Fri, 17 Jul 2009 22:04:54 +0200 by Kai Wasserbäch +// based on libkvirjndael.h as this is aimed as drop-in replacement. +// +// This file is part of the KVirc irc client distribution +// Copyright © 2009 Kai Wasserbäch <debian@carbon-project.org> +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +//base class +#include "kvi_crypt.h" + +// class definitions for the libcrypto++ case +#include <crypto++/aes.h> +#include <crypto++/blowfish.h> +#include <string> + +// The following two defines are to indicate the in-/output encoding (hex +// or Base64). +#define KVI_RIJNDAEL_HEX 0 +#define KVI_RIJNDAEL_B64 1 + +// AES/Rijndael +class KviRijndaelEngine : public KviCryptEngine +{ + Q_OBJECT + public: + KviRijndaelEngine(); + virtual ~KviRijndaelEngine(); + protected: + virtual int getKeyLen(){ return CryptoPP::AES::DEFAULT_KEYLENGTH; }; + virtual int getEncoding(){ return KVI_RIJNDAEL_HEX; }; + private: + std::string m_szEncKey; + std::string m_szDecKey; + public: + virtual bool init(const char *encKey,int encKeyLen,const char *decKey,int decKeyLen); + virtual KviCryptEngine::EncryptResult encrypt(const char * plainText,KviStr &outBuffer); + virtual KviCryptEngine::DecryptResult decrypt(const char * inBuffer,KviStr &plainText); +}; + +class KviRijndael128HexEngine : public KviRijndaelEngine +{ + Q_OBJECT + public: + KviRijndael128HexEngine() : KviRijndaelEngine() {}; + virtual ~KviRijndael128HexEngine(){}; + protected: + virtual int getKeyLen(){ return CryptoPP::AES::MIN_KEYLENGTH; }; + virtual int getEncoding(){ return KVI_RIJNDAEL_HEX; }; +}; + +class KviRijndael192HexEngine : public KviRijndaelEngine +{ + Q_OBJECT + public: + KviRijndael192HexEngine() : KviRijndaelEngine() {}; + virtual ~KviRijndael192HexEngine(){}; + protected: + virtual int getKeyLen(){ return (CryptoPP::AES::MIN_KEYLENGTH + CryptoPP::AES::KEYLENGTH_MULTIPLE); }; + virtual int getEncoding() { return KVI_RIJNDAEL_HEX; }; +}; + +class KviRijndael256HexEngine : public KviRijndaelEngine +{ + Q_OBJECT + public: + KviRijndael256HexEngine() : KviRijndaelEngine() {}; + virtual ~KviRijndael256HexEngine(){}; + protected: + virtual int getKeyLen(){ return CryptoPP::AES::MAX_KEYLENGTH; }; + virtual int getEncoding() { return KVI_RIJNDAEL_HEX; }; +}; + +class KviRijndael128Base64Engine : public KviRijndaelEngine +{ + Q_OBJECT + public: + KviRijndael128Base64Engine() : KviRijndaelEngine() {}; + virtual ~KviRijndael128Base64Engine(){}; + protected: + virtual int getKeyLen(){ return CryptoPP::AES::MIN_KEYLENGTH; }; + virtual int getEncoding() { return KVI_RIJNDAEL_B64; }; +}; + +class KviRijndael192Base64Engine : public KviRijndaelEngine +{ + Q_OBJECT + public: + KviRijndael192Base64Engine() : KviRijndaelEngine() {}; + virtual ~KviRijndael192Base64Engine(){}; + protected: + virtual int getKeyLen(){ return (CryptoPP::AES::MIN_KEYLENGTH + CryptoPP::AES::KEYLENGTH_MULTIPLE); }; + virtual int getEncoding() { return KVI_RIJNDAEL_B64; }; +}; + +class KviRijndael256Base64Engine : public KviRijndaelEngine +{ + Q_OBJECT + public: + KviRijndael256Base64Engine() : KviRijndaelEngine() {}; + virtual ~KviRijndael256Base64Engine(){}; + protected: + virtual int getKeyLen(){ return CryptoPP::AES::MAX_KEYLENGTH; }; + virtual int getEncoding() { return KVI_RIJNDAEL_B64; }; +}; + +// Blowfish (named »Mircryption« to be a real drop in replacement, hopefully) +class KviMircryptionEngine : public KviCryptEngine +{ + Q_OBJECT + public: + KviMircryptionEngine(); + ~KviMircryptionEngine(); + + virtual bool init(const char *encKey,int encKeyLen,const char *decKey,int decKeyLen); + virtual KviCryptEngine::EncryptResult encrypt(const char * plainText,KviStr &outBuffer); + virtual KviCryptEngine::DecryptResult decrypt(const char * inBuffer,KviStr &plainText); + private: + std::string m_szEncKey; + std::string m_szDecKey; + bool m_bEncryptCBC; + bool m_bDecryptCBC; +}; +#endif // _LIBKVIRIJNDAEL_H_ |
