4
0
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:
Justin Karneges 2003-07-09 00:31:45 +00:00
parent 1bbcc20020
commit bfbce8409f
8 changed files with 310 additions and 22 deletions

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

@ -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

@ -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

@ -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
//----------------------------------------------------------------------------

@ -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