mirror of
https://github.com/QuasarApp/qca.git
synced 2025-05-11 18:29:33 +00:00
initial cipher support
svn path=/trunk/kdesupport/qca/; revision=236209
This commit is contained in:
parent
1bbcc20020
commit
bfbce8409f
9
TODO
9
TODO
@ -1,10 +1,13 @@
|
||||
Qt Cryptographic Architecture
|
||||
-----------------------------
|
||||
|
||||
Hashing
|
||||
Ciphers
|
||||
Hashing (SHA1, MD5)
|
||||
Ciphers (3DES, AES)
|
||||
X509
|
||||
SSL/TLS
|
||||
SASL
|
||||
OpenPGP
|
||||
|
||||
* deal with cipher errors
|
||||
* make static cipher functions for quick access?
|
||||
* clean up plugin system
|
||||
|
||||
|
50
ciphertest.cpp
Normal file
50
ciphertest.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include"qca.h"
|
||||
#include<stdio.h>
|
||||
|
||||
static QCString arrayToCString(const QByteArray &);
|
||||
static QByteArray cstringToArray(const QCString &);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCA::init();
|
||||
QCString cs = (argc >= 2) ? argv[1] : "hello";
|
||||
|
||||
if(!QCA::isSupported(QCA::CAP_TripleDES))
|
||||
printf("TripleDES not supported!\n");
|
||||
else {
|
||||
// encrypt
|
||||
QCA::TripleDES c(QCA::Encrypt);
|
||||
QByteArray key(c.keySize());
|
||||
for(uint n = 0; n < key.size(); ++n)
|
||||
key[n] = (uchar)n;
|
||||
c.setKey(key);
|
||||
c.update(cstringToArray(cs));
|
||||
QByteArray f = c.final();
|
||||
QString result = QCA::arrayToHex(f);
|
||||
printf(">3des(\"%s\") = [%s]\n", cs.data(), result.latin1());
|
||||
|
||||
// decrypt
|
||||
QCA::TripleDES d(QCA::Decrypt, key);
|
||||
d.update(f);
|
||||
QCString dec = arrayToCString(d.final());
|
||||
printf("<3des(\"%s\") = [%s]\n", result.latin1(), dec.data());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QCString arrayToCString(const QByteArray &a)
|
||||
{
|
||||
QCString cs;
|
||||
cs.resize(a.size()+1);
|
||||
memcpy(cs.data(), a.data(), a.size());
|
||||
return cs;
|
||||
}
|
||||
|
||||
QByteArray cstringToArray(const QCString &cs)
|
||||
{
|
||||
QByteArray a(cs.length());
|
||||
memcpy(a.data(), cs.data(), a.size());
|
||||
return a;
|
||||
}
|
||||
|
13
ciphertest.pro
Normal file
13
ciphertest.pro
Normal file
@ -0,0 +1,13 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += thread
|
||||
TARGET = ciphertest
|
||||
|
||||
MOC_DIR = .moc
|
||||
OBJECTS_DIR = .obj
|
||||
UI_DIR = .ui
|
||||
|
||||
INCLUDEPATH += src
|
||||
INCLUDEPATH += plugins
|
||||
HEADERS += src/qca.h
|
||||
SOURCES += ciphertest.cpp src/qca.cpp
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include<qptrlist.h>
|
||||
#include<openssl/sha.h>
|
||||
#include<openssl/md5.h>
|
||||
#include<openssl/evp.h>
|
||||
|
||||
#ifdef QCA_PLUGIN
|
||||
QCAProvider *createProvider()
|
||||
@ -21,6 +22,20 @@ static void md5_destroy(int ctx);
|
||||
static void md5_update(int ctx, const char *in, unsigned int len);
|
||||
static void md5_final(int ctx, char *out);
|
||||
|
||||
static int tdes_create();
|
||||
static void tdes_destroy(int ctx);
|
||||
static void tdes_setup(int ctx, int dir, const char *key, const char *iv);
|
||||
static void tdes_update(int ctx, const char *in, unsigned int len);
|
||||
static void tdes_final(int ctx, char *out);
|
||||
static unsigned int tdes_finalSize(int ctx);
|
||||
|
||||
static void appendArray(QByteArray *a, const QByteArray &b)
|
||||
{
|
||||
int oldsize = a->size();
|
||||
a->resize(oldsize + b.size());
|
||||
memcpy(a->data() + oldsize, b.data(), b.size());
|
||||
}
|
||||
|
||||
static int counter = 0;
|
||||
|
||||
struct pair_sha1
|
||||
@ -39,6 +54,18 @@ struct pair_md5
|
||||
typedef QPtrList<pair_md5> MAP_MD5;
|
||||
MAP_MD5 *map_md5 = 0;
|
||||
|
||||
struct pair_tdes
|
||||
{
|
||||
int ctx;
|
||||
EVP_CIPHER_CTX c;
|
||||
const EVP_CIPHER *type;
|
||||
QByteArray r;
|
||||
int dir;
|
||||
bool done;
|
||||
};
|
||||
typedef QPtrList<pair_tdes> MAP_TDES;
|
||||
MAP_TDES *map_tdes = 0;
|
||||
|
||||
static pair_sha1 *find(int ctx)
|
||||
{
|
||||
QPtrListIterator<pair_sha1> it(*map);
|
||||
@ -59,12 +86,24 @@ static pair_md5 *find_md5(int ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pair_tdes *find_tdes(int ctx)
|
||||
{
|
||||
QPtrListIterator<pair_tdes> it(*map_tdes);
|
||||
for(pair_tdes *p; (p = it.current()); ++it) {
|
||||
if(p->ctx == ctx)
|
||||
return p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
_QCAOpenSSL::_QCAOpenSSL()
|
||||
{
|
||||
map = new MAP_SHA1;
|
||||
map->setAutoDelete(true);
|
||||
map_md5 = new MAP_MD5;
|
||||
map_md5->setAutoDelete(true);
|
||||
map_tdes = new MAP_TDES;
|
||||
map_tdes->setAutoDelete(true);
|
||||
}
|
||||
|
||||
_QCAOpenSSL::~_QCAOpenSSL()
|
||||
@ -73,11 +112,13 @@ _QCAOpenSSL::~_QCAOpenSSL()
|
||||
map = 0;
|
||||
delete map_md5;
|
||||
map_md5 = 0;
|
||||
delete map_tdes;
|
||||
map_tdes = 0;
|
||||
}
|
||||
|
||||
int _QCAOpenSSL::capabilities() const
|
||||
{
|
||||
return (QCA::CAP_SHA1 | QCA::CAP_MD5);
|
||||
return (QCA::CAP_SHA1 | QCA::CAP_MD5 | QCA::CAP_TripleDES);
|
||||
}
|
||||
|
||||
void *_QCAOpenSSL::functions(int cap)
|
||||
@ -98,6 +139,16 @@ void *_QCAOpenSSL::functions(int cap)
|
||||
f->final = md5_final;
|
||||
return f;
|
||||
}
|
||||
else if(cap == QCA::CAP_TripleDES) {
|
||||
QCA_TripleDESFunctions *f = new QCA_TripleDESFunctions;
|
||||
f->create = tdes_create;
|
||||
f->destroy = tdes_destroy;
|
||||
f->setup = tdes_setup;
|
||||
f->update = tdes_update;
|
||||
f->final = tdes_final;
|
||||
f->finalSize = tdes_finalSize;
|
||||
return f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -155,3 +206,78 @@ void md5_final(int ctx, char *out)
|
||||
MD5_Final((unsigned char *)out, &i->c);
|
||||
}
|
||||
|
||||
int tdes_create()
|
||||
{
|
||||
pair_tdes *i = new pair_tdes;
|
||||
i->ctx = counter++;
|
||||
i->type = EVP_des_ede3_cbc();
|
||||
i->dir = 0;
|
||||
i->done = false;
|
||||
EVP_CIPHER_CTX_init(&i->c);
|
||||
map_tdes->append(i);
|
||||
return i->ctx;
|
||||
}
|
||||
|
||||
void tdes_destroy(int ctx)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
memset(&i->c, 0, sizeof(EVP_CIPHER_CTX));
|
||||
map_tdes->removeRef(i);
|
||||
}
|
||||
|
||||
void tdes_setup(int ctx, int dir, const char *key, const char *iv)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
i->dir = dir;
|
||||
|
||||
if(i->dir == 0)
|
||||
EVP_EncryptInit_ex(&i->c, i->type, NULL, (const unsigned char *)key, (const unsigned char *)iv);
|
||||
else
|
||||
EVP_DecryptInit_ex(&i->c, i->type, NULL, (const unsigned char *)key, (const unsigned char *)iv);
|
||||
}
|
||||
|
||||
void tdes_update(int ctx, const char *in, unsigned int len)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
|
||||
i->done = false;
|
||||
QByteArray result(len + i->type->block_size);
|
||||
int olen;
|
||||
if(i->dir == 0)
|
||||
EVP_EncryptUpdate(&i->c, (unsigned char *)result.data(), &olen, (const unsigned char *)in, len);
|
||||
else
|
||||
EVP_DecryptUpdate(&i->c, (unsigned char *)result.data(), &olen, (const unsigned char *)in, len);
|
||||
result.resize(olen);
|
||||
appendArray(&i->r, result);
|
||||
}
|
||||
|
||||
static void tdes_ensureFinal(pair_tdes *i)
|
||||
{
|
||||
if(i->done)
|
||||
return;
|
||||
|
||||
QByteArray result(i->type->block_size);
|
||||
int olen;
|
||||
if(i->dir == 0)
|
||||
EVP_EncryptFinal(&i->c, (unsigned char *)result.data(), &olen);
|
||||
else
|
||||
EVP_DecryptFinal(&i->c, (unsigned char *)result.data(), &olen);
|
||||
result.resize(olen);
|
||||
appendArray(&i->r, result);
|
||||
i->done = true;
|
||||
}
|
||||
|
||||
void tdes_final(int ctx, char *out)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
tdes_ensureFinal(i);
|
||||
memcpy(out, i->r.data(), i->r.size());
|
||||
}
|
||||
|
||||
unsigned int tdes_finalSize(int ctx)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
tdes_ensureFinal(i);
|
||||
return i->r.size();
|
||||
}
|
||||
|
||||
|
@ -14,5 +14,5 @@ SOURCES = qcaopenssl.cpp
|
||||
DEFINES += QCA_PLUGIN
|
||||
|
||||
# link with OpenSSL
|
||||
LIBS += -lssl -lcrypto
|
||||
LIBS += -L/usr/local/lib -lcrypto
|
||||
|
||||
|
77
src/qca.cpp
77
src/qca.cpp
@ -32,7 +32,19 @@ QString QCA::arrayToHex(const QByteArray &a)
|
||||
str.sprintf("%02x", (uchar)a[n]);
|
||||
out.append(str);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QByteArray QCA::hexToArray(const QString &str)
|
||||
{
|
||||
QByteArray out(str.length() / 2);
|
||||
int at = 0;
|
||||
for(int n = 0; n + 1 < (int)str.length(); n += 2) {
|
||||
uchar a = str[n];
|
||||
uchar b = str[n+1];
|
||||
uchar c = ((a & 0x0f) << 4) + (b & 0x0f);
|
||||
out[at++] = c;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -138,6 +150,16 @@ void Cipher::setIV(const QByteArray &a)
|
||||
v_iv = a.copy();
|
||||
}
|
||||
|
||||
/*bool Cipher::encrypt(const QByteArray &in, QByteArray *out)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Cipher::decrypt(const QByteArray &in, QByteArray *out)
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SHA1
|
||||
@ -229,29 +251,72 @@ QByteArray MD5::final()
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TripleDES
|
||||
//----------------------------------------------------------------------------
|
||||
TripleDES::TripleDES()
|
||||
TripleDES::TripleDES(int dir, const QByteArray &key)
|
||||
{
|
||||
f = (QCA_TripleDESFunctions *)getFunctions(CAP_TripleDES);
|
||||
ctx = f->create();
|
||||
v_dir = dir;
|
||||
if(!key.isEmpty())
|
||||
setKey(key);
|
||||
}
|
||||
|
||||
TripleDES::~TripleDES()
|
||||
{
|
||||
f->destroy(ctx);
|
||||
}
|
||||
|
||||
bool TripleDES::encrypt(const QByteArray &in, QByteArray *out, bool pad)
|
||||
uint TripleDES::blockSize() const
|
||||
{
|
||||
return false;
|
||||
return 8;
|
||||
}
|
||||
|
||||
bool TripleDES::decrypt(const QByteArray &in, QByteArray *out, bool pad)
|
||||
uint TripleDES::keySize() const
|
||||
{
|
||||
return false;
|
||||
return 24;
|
||||
}
|
||||
|
||||
void TripleDES::clear()
|
||||
{
|
||||
f->destroy(ctx);
|
||||
setKey(QByteArray(0));
|
||||
setIV(QByteArray(0));
|
||||
ctx = f->create();
|
||||
}
|
||||
|
||||
void TripleDES::update(const QByteArray &a)
|
||||
{
|
||||
QByteArray i = iv();
|
||||
f->setup(ctx, v_dir, key().data(), i.isEmpty() ? 0 : i.data());
|
||||
f->update(ctx, a.data(), a.size());
|
||||
}
|
||||
|
||||
QByteArray TripleDES::final()
|
||||
{
|
||||
QByteArray buf(f->finalSize(ctx));
|
||||
f->final(ctx, buf.data());
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*QByteArray TripleDES::encryptBlock(const QByteArray &in)
|
||||
{
|
||||
QByteArray result(blockSize());
|
||||
f->encryptBlock(in.data(), result.data());
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray TripleDES::decryptBlock(const QByteArray &in)
|
||||
{
|
||||
QByteArray result(blockSize());
|
||||
f->decryptBlock(in.data(), result.data());
|
||||
return result;
|
||||
}*/
|
||||
|
||||
|
||||
/*
|
||||
//----------------------------------------------------------------------------
|
||||
// AES128
|
||||
//----------------------------------------------------------------------------
|
||||
|
43
src/qca.h
43
src/qca.h
@ -4,8 +4,9 @@
|
||||
#include<qstring.h>
|
||||
#include<qcstring.h>
|
||||
|
||||
class QCA_SHA1Functions;
|
||||
class QCA_MD5Functions;
|
||||
struct QCA_SHA1Functions;
|
||||
struct QCA_MD5Functions;
|
||||
struct QCA_TripleDESFunctions;
|
||||
|
||||
namespace QCA
|
||||
{
|
||||
@ -22,10 +23,13 @@ namespace QCA
|
||||
CAP_PGP = 0x0200,
|
||||
};
|
||||
|
||||
enum { Encrypt, Decrypt };
|
||||
|
||||
void init();
|
||||
bool isSupported(int capabilities);
|
||||
|
||||
QString arrayToHex(const QByteArray &);
|
||||
QByteArray hexToArray(const QString &);
|
||||
|
||||
class Hash
|
||||
{
|
||||
@ -80,8 +84,17 @@ namespace QCA
|
||||
void setKey(const QByteArray &a);
|
||||
void setIV(const QByteArray &a);
|
||||
|
||||
virtual bool encrypt(const QByteArray &in, QByteArray *out, bool pad=true)=0;
|
||||
virtual bool decrypt(const QByteArray &in, QByteArray *out, bool pad=true)=0;
|
||||
virtual uint blockSize() const=0;
|
||||
virtual uint keySize() const=0;
|
||||
virtual void clear()=0;
|
||||
virtual void update(const QByteArray &a)=0;
|
||||
virtual QByteArray final()=0;
|
||||
|
||||
//virtual QByteArray encrypt(const QByteArray &in, const QByteArray &iv=QByteArray())=0;
|
||||
//virtual QByteArray decrypt(const QByteArray &in, const QByteArray &iv=QByteArray())=0;
|
||||
|
||||
//bool encrypt(const QByteArray &in, QByteArray *out);
|
||||
//bool decrypt(const QByteArray &in, QByteArray *out);
|
||||
|
||||
private:
|
||||
QByteArray v_key, v_iv;
|
||||
@ -102,7 +115,7 @@ namespace QCA
|
||||
int ctx;
|
||||
};
|
||||
|
||||
/*class SHA256 : public Hash, public HashStatic<SHA256>
|
||||
class SHA256 : public Hash, public HashStatic<SHA256>
|
||||
{
|
||||
public:
|
||||
SHA256();
|
||||
@ -111,7 +124,7 @@ namespace QCA
|
||||
void clear();
|
||||
void update(const QByteArray &a);
|
||||
QByteArray final();
|
||||
};*/
|
||||
};
|
||||
|
||||
class MD5 : public Hash, public HashStatic<MD5>
|
||||
{
|
||||
@ -128,17 +141,25 @@ namespace QCA
|
||||
int ctx;
|
||||
};
|
||||
|
||||
/*class TripleDES : public Cipher
|
||||
class TripleDES : public Cipher
|
||||
{
|
||||
public:
|
||||
TripleDES();
|
||||
TripleDES(int dir, const QByteArray &key=QByteArray());
|
||||
~TripleDES();
|
||||
|
||||
bool encrypt(const QByteArray &in, QByteArray *out, bool pad=true);
|
||||
bool decrypt(const QByteArray &in, QByteArray *out, bool pad=true);
|
||||
uint blockSize() const;
|
||||
uint keySize() const;
|
||||
void clear();
|
||||
void update(const QByteArray &a);
|
||||
QByteArray final();
|
||||
|
||||
private:
|
||||
struct QCA_TripleDESFunctions *f;
|
||||
int ctx;
|
||||
int v_dir;
|
||||
};
|
||||
|
||||
class AES128 : public Cipher
|
||||
/*class AES128 : public Cipher
|
||||
{
|
||||
public:
|
||||
AES128();
|
||||
|
@ -36,4 +36,14 @@ struct QCA_MD5Functions
|
||||
void (*final)(int ctx, char *out); // 16 bytes output
|
||||
};
|
||||
|
||||
struct QCA_TripleDESFunctions
|
||||
{
|
||||
int (*create)();
|
||||
void (*destroy)(int ctx);
|
||||
void (*setup)(int ctx, int dir, const char *key, const char *iv);
|
||||
void (*update)(int ctx, const char *in, unsigned int len);
|
||||
void (*final)(int ctx, char *out);
|
||||
unsigned int (*finalSize)(int ctx);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user