SilentEye 0.4.1
|
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)