00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "encrypteddevice.h"
00025
00026 #include <openssl/err.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029
00030 #include "SignOn/signonplugincommon.h"
00031
00032 using namespace SignOn;
00033
00034 EncryptedDevice::EncryptedDevice(QIODevice *actualDevice,
00035 const unsigned char *encryptionKey,
00036 unsigned int keySize,
00037 const unsigned char *ivIn,
00038 const unsigned char *ivOut):
00039 m_actualDevice(actualDevice),
00040 m_currentPosOut(0),
00041 m_currentPosIn(0),
00042 m_tempByteArray(NULL),
00043 m_tempByteArrayPos(0),
00044 m_valid(true)
00045 {
00046 setOpenMode(actualDevice->openMode());
00047
00048 if (AES_set_encrypt_key(encryptionKey, keySize * 8,
00049 &m_encryptionKey) != 0) {
00050 BLAME() << "AES_set_encrypt_key failed:" << ERR_get_error();
00051 m_valid = false;
00052 return;
00053 }
00054
00055 AES_ecb_encrypt(ivOut, m_keyStreamOut, &m_encryptionKey, AES_ENCRYPT);
00056 AES_ecb_encrypt(ivIn, m_keyStreamIn, &m_encryptionKey, AES_ENCRYPT);
00057 }
00058
00059 bool EncryptedDevice::open(OpenMode mode)
00060 {
00061 if (!m_valid)
00062 return false;
00063 if (!m_actualDevice->open(mode))
00064 return false;
00065 return QIODevice::open(mode);
00066 }
00067
00068 void EncryptedDevice::close()
00069 {
00070 m_actualDevice->close();
00071 QIODevice::close();
00072 }
00073
00074 qint64 EncryptedDevice::bytesAvailable() const
00075 {
00076 if (m_tempByteArray != NULL)
00077 return m_tempByteArray->size() - m_tempByteArrayPos;
00078 return m_actualDevice->bytesAvailable();
00079 }
00080
00081 qint64 EncryptedDevice::bytesToWrite() const
00082 {
00083 return m_actualDevice->bytesToWrite();
00084 }
00085
00086 qint64 EncryptedDevice::readData(char *data, qint64 maxLen)
00087 {
00088 qint64 bytesRead = 0;
00089 if (m_tempByteArray != NULL) {
00090 if (m_tempByteArrayPos < m_tempByteArray->size()) {
00091 int bytesToRead = m_tempByteArray->size() - m_tempByteArrayPos;
00092 if (bytesToRead > maxLen)
00093 bytesToRead = (int)maxLen;
00094 memcpy(data, m_tempByteArray->constData(), bytesToRead);
00095 bytesRead = bytesToRead;
00096 m_tempByteArrayPos += bytesToRead;
00097 }
00098 } else {
00099 bytesRead = m_actualDevice->read(data, maxLen);
00100 }
00101
00102 for (qint64 i = 0; i < bytesRead; ++i) {
00103 if (m_currentPosIn == AES_BLOCK_SIZE) {
00104 AES_ecb_encrypt(m_keyStreamIn, m_keyStreamIn,
00105 &m_encryptionKey, AES_ENCRYPT);
00106 m_currentPosIn = 0;
00107 }
00108 data[i] = data[i] ^ m_keyStreamIn[m_currentPosIn];
00109 ++m_currentPosIn;
00110 }
00111
00112 return bytesRead;
00113 }
00114
00115 qint64 EncryptedDevice::writeData(const char *data, qint64 len)
00116 {
00117 if (len <= 0)
00118 return 0;
00119
00120 char *encryptedData = (char *)malloc(len);
00121 if (encryptedData == NULL)
00122 return -1;
00123
00124 for (qint64 i = 0; i < len; ++i) {
00125 if (m_currentPosOut == AES_BLOCK_SIZE) {
00126 AES_ecb_encrypt(m_keyStreamOut, m_keyStreamOut,
00127 &m_encryptionKey, AES_ENCRYPT);
00128 m_currentPosOut = 0;
00129 }
00130 encryptedData[i] = data[i] ^ m_keyStreamOut[m_currentPosOut];
00131 ++m_currentPosOut;
00132 }
00133
00134 qint64 totalBytesWritten = 0;
00135 while (totalBytesWritten < len) {
00136 qint64 bytesWritten =
00137 m_actualDevice->write(encryptedData + totalBytesWritten,
00138 len - totalBytesWritten);
00139 if (bytesWritten < 0)
00140 break;
00141 totalBytesWritten += bytesWritten;
00142 }
00143 free(encryptedData);
00144
00145 return totalBytesWritten;
00146 }