SilentEye 0.4.1

modules/secryptoaes/secryptoaes.cpp

Go to the documentation of this file.
00001 //  This file is part of SilentEye.
00002 //
00003 //  SilentEye is free software: you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation, either version 3 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  SilentEye is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with SilentEye.  If not, see <http://www.gnu.org/licenses/>.
00015 
00016 #include "secryptoaes.h"
00017 #include "math.h"
00018 
00019 namespace SECryptoAES {
00020 
00021     SECryptoAES::SECryptoAES()
00022     {
00023         this->setObjectName("SECryptoAES128");
00024         m_logger = new Logger(this);
00025         m_init = NULL;
00026         m_isQcaCompatible = false;
00027     }
00028 
00029     SECryptoAES::~SECryptoAES()
00030     {
00031         if (m_init != NULL)
00032             delete m_init;
00033         delete m_logger;
00034     }
00035 
00036     void SECryptoAES::init()
00037     {
00038         if (m_init != NULL)
00039             return;
00040         m_init = new QCA::Initializer;
00041         m_isQcaCompatible = QCA::isSupported("aes128-cbc-pkcs7");
00042 
00043         if( m_isQcaCompatible )
00044         {
00045             m_logger->info(name() + ": aes128-cbc-pkcs7 supported by system [OK]");
00046             m_key = QCA::SymmetricKey( QString(name()+"%/.?!:;]{[}&").toUtf8() );
00047         }
00048         else
00049         {
00050             m_logger->warning(name() + ": aes128-cbc-pkcs7 supported by system [KO]");
00051             QList<QCA::Provider*> prov = QCA::providers();
00052             m_logger->debug("> QCA2: " + QString::number(prov.size()) + " providers found");
00053             for(int i = 0; i<prov.size(); i++)
00054                 m_logger->debug(prov.at(i)->name());
00055 
00056             m_logger->debug(QCA::pluginDiagnosticText());
00057         }
00058 
00059     }
00060 
00061 
00062     QString SECryptoAES::name() const
00063     {
00064         return QString("Silent Eye Encryption "+typeSupported());
00065     }
00066 
00067     QString SECryptoAES::version() const
00068     {
00069         return QString("1.1");
00070     }
00071 
00072     QString SECryptoAES::status()
00073     {
00074         init();
00075         if(m_isQcaCompatible)
00076             return "OK|aes128-cbc-pkcs7 supported by system";
00077         else
00078             return "KO|'aes128-cbc-pkcs7' not supported by system.\nPlease check your 'libqca2-plugin-ossl' installation.";
00079     }
00080 
00081     QString SECryptoAES::typeSupported() const
00082     {
00083         return QString("AES128");
00084     }
00085 
00086     QCA::SecureArray SECryptoAES::initializationVector(QString key)
00087     {
00088         QByteArray hash = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Md5);
00089         QString md5 = hash.toHex();
00090         QString value;
00091         for (int i=0; i<floor(128 / md5.size()); i++)
00092         {
00093             value += md5;
00094         }
00095         m_logger->debug("encrypted key: " + value);
00096         return QCA::InitializationVector( QCA::SecureArray(value.toUtf8()) );
00097     }
00098 
00099     QPointer<EncodedData> SECryptoAES::encode(QString key, QPointer<EncodedData> msg)
00100     {
00101         init();
00102         if(!m_isQcaCompatible){
00103             throw ModuleException("aes128-cbc-pkcs7 is not supported by the system.");
00104         }
00105 
00106         QCA::InitializationVector iv = initializationVector(key);
00107 
00108         // create a 128 bit AES cipher object using Cipher Block Chaining (CBC) mode
00109         QCA::Cipher cipher(QString("aes128"),QCA::Cipher::CBC,
00110                            // use Default padding, which is equivalent to PKCS7 for CBC
00111                            QCA::Cipher::DefaultPadding,
00112                            // this object will encrypt
00113                            QCA::Encode,
00114                            m_key, iv);
00115 
00116         // we use the cipher object to encrypt the argument we passed in
00117         // the result of that is returned - note that if there is less than
00118         // 1 block, then nothing will be returned - it is buffered
00119         // update() can be called as many times as required.
00120         QCA::SecureArray u = cipher.update( QCA::SecureArray(msg->bytes()) );
00121 
00122         if (!cipher.ok())
00123             throw ModuleException("An error occured during the encryption process.",
00124                                   "An error occured during the cipher update !");
00125 
00126         if(msg->format() != Data::FILE)
00127             m_logger->debug("AES128 non-final encryption of " + QCA::arrayToHex(msg->bytes()) + " is " + QCA::arrayToHex(u.toByteArray()) );
00128 
00129         // Because we are using PKCS7 padding, we need to output the final (padded) block
00130         // Note that we should always call final() even with no padding, to clean up
00131         QCA::SecureArray f = cipher.final();
00132 
00133         if (!cipher.ok())
00134             throw ModuleException("An error occured during the encryption process.",
00135                                   "An error occured during the finalization of the cipher !");
00136 
00137         return new EncodedData(u.append(f).toByteArray(), Data::BYTES, false);
00138     }
00139 
00140     QPointer<EncodedData> SECryptoAES::decode(QString key, QPointer<EncodedData> data)
00141     {
00142         init();
00143         if(!m_isQcaCompatible){
00144             throw ModuleException("aes128-cbc-pkcs7 is not supported by the system.");
00145         }
00146 
00147         QCA::InitializationVector iv = initializationVector(key);
00148 
00149         // create a 128 bit AES cipher object using Cipher Block Chaining (CBC) mode
00150         QCA::Cipher cipher(QString("aes128"),QCA::Cipher::CBC,
00151                            // use Default padding, which is equivalent to PKCS7 for CBC
00152                            QCA::Cipher::DefaultPadding,
00153                            // this object will encrypt
00154                            QCA::Decode,
00155                            m_key, iv);
00156 
00157         // take that cipher text, and decrypt it
00158         QCA::SecureArray plainText = cipher.update( QCA::SecureArray(data->toData()->data()) );
00159 
00160         // check if the update() call worked
00161         if (!cipher.ok())
00162             throw ModuleException("An error occured during the decryption process. (wrong password key?)",
00163                                   "An error occured during the cipher update !");
00164 
00165         // Again we need to call final(), to get the last block (with its padding removed)
00166         plainText += cipher.final();
00167 
00168         // check if the final() call worked
00169         if (!cipher.ok())
00170             throw ModuleException("An error occured during the decryption process. (wrong password key?)",
00171                                   "An error occured during the finalization of the cipher !");
00172 
00173         QPointer<EncodedData> result = new EncodedData(plainText.toByteArray(), Data::F_UNDEF, false);
00174         if(result->format() != Data::FILE)
00175             m_logger->debug("AES128 decryption of " + QCA::arrayToHex(data->toData()->data()) + " is "  + result->toString());
00176 
00177         return result;
00178     }
00179 
00180 }
00181 
00182 Q_EXPORT_PLUGIN2(secryptoaes, SECryptoAES::SECryptoAES)