mirror of
https://github.com/QuasarApp/qca.git
synced 2025-04-28 12:34:31 +00:00
changed plugin system to use C++
svn path=/trunk/kdesupport/qca/; revision=238159
This commit is contained in:
parent
4a286c05a1
commit
e6adfbd2b3
2
TODO
2
TODO
@ -1,3 +1,4 @@
|
||||
* rsakey: to DER
|
||||
* rsakey: to/from PEM
|
||||
* rsakey: detect for private/public capability (get rid of 'bool sec')
|
||||
* rsa: choice of pad
|
||||
@ -5,6 +6,7 @@
|
||||
* cipher: better handling of errors ('empty' arrays are not a good idea)
|
||||
* cipher: ability to disable pkcs padding
|
||||
* cipher: better entropy for keygen?
|
||||
* cipher: aes128, aes256
|
||||
* clean up openssl plugin
|
||||
|
||||
* ssl/tls/x509 (also server support)
|
||||
|
@ -9,6 +9,27 @@ int main(int argc, char **argv)
|
||||
QCA::init();
|
||||
QCString cs = (argc >= 2) ? argv[1] : "hello";
|
||||
|
||||
if(!QCA::isSupported(QCA::CAP_BlowFish))
|
||||
printf("BlowFish not supported!\n");
|
||||
else {
|
||||
// encrypt
|
||||
QByteArray key = QCA::BlowFish::generateKey();
|
||||
QByteArray iv = QCA::BlowFish::generateIV();
|
||||
printf("bfish:key:%s\n", QCA::arrayToHex(key).latin1());
|
||||
printf("bfish:iv:%s\n", QCA::arrayToHex(iv).latin1());
|
||||
QCA::BlowFish c(QCA::Encrypt, QCA::CBC, key, iv);
|
||||
c.update(cstringToArray(cs));
|
||||
QByteArray f = c.final();
|
||||
QString result = QCA::arrayToHex(f);
|
||||
printf(">bfish(\"%s\") = [%s]\n", cs.data(), result.latin1());
|
||||
|
||||
// decrypt
|
||||
QCA::BlowFish d(QCA::Decrypt, QCA::CBC, key, iv);
|
||||
d.update(f);
|
||||
QCString dec = arrayToCString(d.final());
|
||||
printf("<bfish(\"%s\") = [%s]\n", result.latin1(), dec.data());
|
||||
}
|
||||
|
||||
if(!QCA::isSupported(QCA::CAP_TripleDES))
|
||||
printf("TripleDES not supported!\n");
|
||||
else {
|
||||
@ -17,14 +38,14 @@ int main(int argc, char **argv)
|
||||
QByteArray iv = QCA::TripleDES::generateIV();
|
||||
printf("3des:key:%s\n", QCA::arrayToHex(key).latin1());
|
||||
printf("3des:iv:%s\n", QCA::arrayToHex(iv).latin1());
|
||||
QCA::TripleDES c(QCA::Encrypt, key, iv);
|
||||
QCA::TripleDES c(QCA::Encrypt, QCA::CBC, key, iv);
|
||||
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, iv);
|
||||
QCA::TripleDES d(QCA::Decrypt, QCA::CBC, key, iv);
|
||||
d.update(f);
|
||||
QCString dec = arrayToCString(d.final());
|
||||
printf("<3des(\"%s\") = [%s]\n", result.latin1(), dec.data());
|
||||
@ -36,14 +57,14 @@ int main(int argc, char **argv)
|
||||
// encrypt
|
||||
QByteArray key = QCA::AES128::generateKey();
|
||||
QByteArray iv = QCA::AES128::generateIV();
|
||||
QCA::AES128 c(QCA::Encrypt, key, iv);
|
||||
QCA::AES128 c(QCA::Encrypt, QCA::CBC, key, iv);
|
||||
c.update(cstringToArray(cs));
|
||||
QByteArray f = c.final();
|
||||
QString result = QCA::arrayToHex(f);
|
||||
printf(">aes128(\"%s\") = [%s]\n", cs.data(), result.latin1());
|
||||
|
||||
// decrypt
|
||||
QCA::AES128 d(QCA::Decrypt, key, iv);
|
||||
QCA::AES128 d(QCA::Decrypt, QCA::CBC, key, iv);
|
||||
d.update(f);
|
||||
QCString dec = arrayToCString(d.final());
|
||||
printf("<aes128(\"%s\") = [%s]\n", result.latin1(), dec.data());
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include"qcaopenssl_p.h"
|
||||
#include"qcaopenssl.h"
|
||||
|
||||
#include<qptrlist.h>
|
||||
#include<openssl/sha.h>
|
||||
@ -7,13 +7,6 @@
|
||||
#include<openssl/rsa.h>
|
||||
#include<openssl/x509.h>
|
||||
|
||||
#ifdef QCA_PLUGIN
|
||||
QCAProvider *createProvider()
|
||||
{
|
||||
return (new _QCAOpenSSL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#include<stdlib.h>
|
||||
static bool seeded = false;
|
||||
class QRandom
|
||||
@ -49,268 +42,6 @@ QByteArray QRandom::randomArray(uint size)
|
||||
return a;
|
||||
}
|
||||
|
||||
static int sha1_create();
|
||||
static void sha1_destroy(int ctx);
|
||||
static void sha1_update(int ctx, const char *in, unsigned int len);
|
||||
static void sha1_final(int ctx, char *out);
|
||||
static unsigned int sha1_finalSize(int ctx);
|
||||
|
||||
static int md5_create();
|
||||
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 unsigned int md5_finalSize(int ctx);
|
||||
|
||||
static int tdes_keySize() { return 24; }
|
||||
static int tdes_blockSize() { return 8; }
|
||||
static bool tdes_generateKey(char *out);
|
||||
static bool tdes_generateIV(char *out);
|
||||
|
||||
static int tdes_create();
|
||||
static void tdes_destroy(int ctx);
|
||||
static bool tdes_setup(int ctx, int dir, int mode, const char *key, const char *iv);
|
||||
static bool tdes_update(int ctx, const char *in, unsigned int len);
|
||||
static bool tdes_final(int ctx, char *out);
|
||||
static unsigned int tdes_finalSize(int ctx);
|
||||
|
||||
static int rsa_keyCreateFromDER(const char *in, unsigned int len, bool sec);
|
||||
static int rsa_keyCreateFromNative(void *in);
|
||||
static int rsa_keyCreateGenerate(unsigned int bits);
|
||||
static int rsa_keyClone(int ctx);
|
||||
static void rsa_keyDestroy(int ctx);
|
||||
static void rsa_keyToDER(int ctx, char **out, unsigned int *len);
|
||||
static bool rsa_encrypt(int ctx, const char *in, unsigned int len, char **out, unsigned int *outlen);
|
||||
static bool rsa_decrypt(int ctx, const char *in, unsigned int len, char **out, unsigned int *outlen);
|
||||
|
||||
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
|
||||
{
|
||||
int ctx;
|
||||
SHA_CTX c;
|
||||
};
|
||||
typedef QPtrList<pair_sha1> MAP_SHA1;
|
||||
MAP_SHA1 *map = 0;
|
||||
|
||||
struct pair_md5
|
||||
{
|
||||
int ctx;
|
||||
MD5_CTX c;
|
||||
};
|
||||
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;
|
||||
bool err;
|
||||
};
|
||||
typedef QPtrList<pair_tdes> MAP_TDES;
|
||||
MAP_TDES *map_tdes = 0;
|
||||
|
||||
struct pair_rsakey
|
||||
{
|
||||
int ctx;
|
||||
RSA *r;
|
||||
};
|
||||
typedef QPtrList<pair_rsakey> MAP_RSAKEY;
|
||||
MAP_RSAKEY *map_rsakey = 0;
|
||||
|
||||
static pair_sha1 *find(int ctx)
|
||||
{
|
||||
QPtrListIterator<pair_sha1> it(*map);
|
||||
for(pair_sha1 *p; (p = it.current()); ++it) {
|
||||
if(p->ctx == ctx)
|
||||
return p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pair_md5 *find_md5(int ctx)
|
||||
{
|
||||
QPtrListIterator<pair_md5> it(*map_md5);
|
||||
for(pair_md5 *p; (p = it.current()); ++it) {
|
||||
if(p->ctx == ctx)
|
||||
return p;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static pair_rsakey *find_rsakey(int ctx)
|
||||
{
|
||||
QPtrListIterator<pair_rsakey> it(*map_rsakey);
|
||||
for(pair_rsakey *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);
|
||||
map_rsakey = new MAP_RSAKEY;
|
||||
map_rsakey->setAutoDelete(true);
|
||||
}
|
||||
|
||||
_QCAOpenSSL::~_QCAOpenSSL()
|
||||
{
|
||||
delete map;
|
||||
map = 0;
|
||||
delete map_md5;
|
||||
map_md5 = 0;
|
||||
delete map_tdes;
|
||||
map_tdes = 0;
|
||||
delete map_rsakey;
|
||||
map_rsakey = 0;
|
||||
}
|
||||
|
||||
int _QCAOpenSSL::capabilities() const
|
||||
{
|
||||
return (QCA::CAP_SHA1 | QCA::CAP_MD5 | QCA::CAP_TripleDES | QCA::CAP_RSA);
|
||||
}
|
||||
|
||||
void *_QCAOpenSSL::functions(int cap)
|
||||
{
|
||||
if(cap == QCA::CAP_SHA1) {
|
||||
QCA_HashFunctions *f = new QCA_HashFunctions;
|
||||
f->create = sha1_create;
|
||||
f->destroy = sha1_destroy;
|
||||
f->update = sha1_update;
|
||||
f->final = sha1_final;
|
||||
f->finalSize = sha1_finalSize;
|
||||
return f;
|
||||
}
|
||||
else if(cap == QCA::CAP_MD5) {
|
||||
QCA_HashFunctions *f = new QCA_HashFunctions;
|
||||
f->create = md5_create;
|
||||
f->destroy = md5_destroy;
|
||||
f->update = md5_update;
|
||||
f->final = md5_final;
|
||||
f->finalSize = md5_finalSize;
|
||||
return f;
|
||||
}
|
||||
else if(cap == QCA::CAP_TripleDES) {
|
||||
QCA_CipherFunctions *f = new QCA_CipherFunctions;
|
||||
f->keySize = tdes_keySize;
|
||||
f->blockSize = tdes_blockSize;
|
||||
f->generateKey = tdes_generateKey;
|
||||
f->generateIV = tdes_generateIV;
|
||||
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;
|
||||
}
|
||||
else if(cap == QCA::CAP_RSA) {
|
||||
QCA_RSAFunctions *f = new QCA_RSAFunctions;
|
||||
f->keyCreateFromDER = rsa_keyCreateFromDER;
|
||||
f->keyCreateFromNative = rsa_keyCreateFromNative;
|
||||
f->keyCreateGenerate = rsa_keyCreateGenerate;
|
||||
f->keyClone = rsa_keyClone;
|
||||
f->keyDestroy = rsa_keyDestroy;
|
||||
f->keyToDER = rsa_keyToDER;
|
||||
f->encrypt = rsa_encrypt;
|
||||
f->decrypt = rsa_decrypt;
|
||||
return f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha1_create()
|
||||
{
|
||||
pair_sha1 *i = new pair_sha1;
|
||||
i->ctx = counter++;
|
||||
SHA1_Init(&i->c);
|
||||
map->append(i);
|
||||
return i->ctx;
|
||||
}
|
||||
|
||||
void sha1_destroy(int ctx)
|
||||
{
|
||||
pair_sha1 *i = find(ctx);
|
||||
map->removeRef(i);
|
||||
}
|
||||
|
||||
void sha1_update(int ctx, const char *in, unsigned int len)
|
||||
{
|
||||
pair_sha1 *i = find(ctx);
|
||||
SHA1_Update(&i->c, in, len);
|
||||
}
|
||||
|
||||
void sha1_final(int ctx, char *out)
|
||||
{
|
||||
pair_sha1 *i = find(ctx);
|
||||
SHA1_Final((unsigned char *)out, &i->c);
|
||||
}
|
||||
|
||||
unsigned int sha1_finalSize(int)
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
int md5_create()
|
||||
{
|
||||
pair_md5 *i = new pair_md5;
|
||||
i->ctx = counter++;
|
||||
MD5_Init(&i->c);
|
||||
map_md5->append(i);
|
||||
return i->ctx;
|
||||
}
|
||||
|
||||
void md5_destroy(int ctx)
|
||||
{
|
||||
pair_md5 *i = find_md5(ctx);
|
||||
map_md5->removeRef(i);
|
||||
}
|
||||
|
||||
void md5_update(int ctx, const char *in, unsigned int len)
|
||||
{
|
||||
pair_md5 *i = find_md5(ctx);
|
||||
MD5_Update(&i->c, in, len);
|
||||
}
|
||||
|
||||
void md5_final(int ctx, char *out)
|
||||
{
|
||||
pair_md5 *i = find_md5(ctx);
|
||||
MD5_Final((unsigned char *)out, &i->c);
|
||||
}
|
||||
|
||||
unsigned int md5_finalSize(int)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
static bool lib_generateKeyIV(const EVP_CIPHER *type, const QByteArray &data, const QByteArray &salt, QByteArray *key, QByteArray *iv)
|
||||
{
|
||||
QByteArray k, i;
|
||||
@ -333,246 +64,340 @@ static bool lib_generateKeyIV(const EVP_CIPHER *type, const QByteArray &data, co
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdes_generateKey(char *out)
|
||||
static void appendArray(QByteArray *a, const QByteArray &b)
|
||||
{
|
||||
const EVP_CIPHER *type = EVP_des_ede3_cbc();
|
||||
QByteArray a;
|
||||
if(!lib_generateKeyIV(type, QRandom::randomArray(128), QRandom::randomArray(2), &a, 0))
|
||||
return false;
|
||||
memcpy(out, a.data(), a.size());
|
||||
return true;
|
||||
int oldsize = a->size();
|
||||
a->resize(oldsize + b.size());
|
||||
memcpy(a->data() + oldsize, b.data(), b.size());
|
||||
}
|
||||
|
||||
bool tdes_generateIV(char *out)
|
||||
{
|
||||
const EVP_CIPHER *type = EVP_des_ede3_cbc();
|
||||
QByteArray a;
|
||||
if(!lib_generateKeyIV(type, QRandom::randomArray(128), QRandom::randomArray(2), 0, &a))
|
||||
return false;
|
||||
memcpy(out, a.data(), a.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
int tdes_create()
|
||||
class SHA1Context : public QCA_HashContext
|
||||
{
|
||||
pair_tdes *i = new pair_tdes;
|
||||
i->ctx = counter++;
|
||||
i->type = EVP_des_ede3_cbc();
|
||||
i->dir = 0;
|
||||
i->done = false;
|
||||
i->err = false;
|
||||
EVP_CIPHER_CTX_init(&i->c);
|
||||
map_tdes->append(i);
|
||||
return i->ctx;
|
||||
}
|
||||
public:
|
||||
SHA1Context()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void tdes_destroy(int ctx)
|
||||
void reset()
|
||||
{
|
||||
SHA1_Init(&c);
|
||||
}
|
||||
|
||||
void update(const char *in, unsigned int len)
|
||||
{
|
||||
SHA1_Update(&c, in, len);
|
||||
}
|
||||
|
||||
void final(char **out, unsigned int *outlen)
|
||||
{
|
||||
*outlen = 20;
|
||||
unsigned char *outbuf = (unsigned char *)malloc(*outlen);
|
||||
SHA1_Final(outbuf, &c);
|
||||
*out = (char *)outbuf;
|
||||
}
|
||||
|
||||
SHA_CTX c;
|
||||
};
|
||||
|
||||
class MD5Context : public QCA_HashContext
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
memset(&i->c, 0, sizeof(EVP_CIPHER_CTX));
|
||||
map_tdes->removeRef(i);
|
||||
}
|
||||
public:
|
||||
MD5Context()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
bool tdes_setup(int ctx, int dir, int mode, const char *key, const char *iv)
|
||||
void reset()
|
||||
{
|
||||
MD5_Init(&c);
|
||||
}
|
||||
|
||||
void update(const char *in, unsigned int len)
|
||||
{
|
||||
MD5_Update(&c, in, len);
|
||||
}
|
||||
|
||||
void final(char **out, unsigned int *outlen)
|
||||
{
|
||||
*outlen = 16;
|
||||
unsigned char *outbuf = (unsigned char *)malloc(*outlen);
|
||||
MD5_Final(outbuf, &c);
|
||||
*out = (char *)outbuf;
|
||||
}
|
||||
|
||||
MD5_CTX c;
|
||||
};
|
||||
|
||||
class EVPCipherContext : public QCA_CipherContext
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
i->dir = dir;
|
||||
public:
|
||||
EVPCipherContext()
|
||||
{
|
||||
type = 0;
|
||||
}
|
||||
|
||||
if(i->dir == 0) {
|
||||
if(!EVP_EncryptInit_ex(&i->c, i->type, NULL, (const unsigned char *)key, (const unsigned char *)iv)) {
|
||||
virtual ~EVPCipherContext()
|
||||
{
|
||||
memset(&c, 0, sizeof(EVP_CIPHER_CTX));
|
||||
}
|
||||
|
||||
virtual const EVP_CIPHER *getType(int mode) const=0;
|
||||
|
||||
int keySize() { return 24; }
|
||||
int blockSize() { return 8; }
|
||||
|
||||
bool generateKey(char *out)
|
||||
{
|
||||
QByteArray a;
|
||||
if(!lib_generateKeyIV(getType(QCA::CBC), QRandom::randomArray(128), QRandom::randomArray(2), &a, 0))
|
||||
return false;
|
||||
}
|
||||
memcpy(out, a.data(), a.size());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if(!EVP_DecryptInit_ex(&i->c, i->type, NULL, (const unsigned char *)key, (const unsigned char *)iv)) {
|
||||
|
||||
bool generateIV(char *out)
|
||||
{
|
||||
QByteArray a;
|
||||
if(!lib_generateKeyIV(getType(QCA::CBC), QRandom::randomArray(128), QRandom::randomArray(2), 0, &a))
|
||||
return false;
|
||||
}
|
||||
memcpy(out, a.data(), a.size());
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdes_update(int ctx, const char *in, unsigned int len)
|
||||
bool setup(int _dir, int mode, const char *key, const char *iv)
|
||||
{
|
||||
dir = _dir;
|
||||
type = getType(mode);
|
||||
EVP_CIPHER_CTX_init(&c);
|
||||
|
||||
if(dir == QCA::Encrypt) {
|
||||
if(!EVP_EncryptInit(&c, type, (unsigned char *)key, (unsigned char *)iv))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!EVP_DecryptInit(&c, type, (unsigned char *)key, (unsigned char *)iv))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool update(const char *in, unsigned int len)
|
||||
{
|
||||
QByteArray result(len + type->block_size);
|
||||
int olen;
|
||||
if(dir == QCA::Encrypt) {
|
||||
if(!EVP_EncryptUpdate(&c, (unsigned char *)result.data(), &olen, (const unsigned char *)in, len))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!EVP_DecryptUpdate(&c, (unsigned char *)result.data(), &olen, (const unsigned char *)in, len))
|
||||
return false;
|
||||
}
|
||||
result.resize(olen);
|
||||
appendArray(&r, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool final(char **out, unsigned int *outlen)
|
||||
{
|
||||
QByteArray result(type->block_size);
|
||||
int olen;
|
||||
if(dir == QCA::Encrypt) {
|
||||
if(!EVP_EncryptFinal(&c, (unsigned char *)result.data(), &olen))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!EVP_DecryptFinal(&c, (unsigned char *)result.data(), &olen))
|
||||
return false;
|
||||
}
|
||||
result.resize(olen);
|
||||
appendArray(&r, result);
|
||||
|
||||
*outlen = r.size();
|
||||
unsigned char *outbuf = (unsigned char *)malloc(*outlen);
|
||||
*out = (char *)outbuf;
|
||||
memcpy(outbuf, r.data(), r.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX c;
|
||||
const EVP_CIPHER *type;
|
||||
QByteArray r;
|
||||
int dir;
|
||||
};
|
||||
|
||||
class BlowFishContext : public EVPCipherContext
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
public:
|
||||
const EVP_CIPHER *getType(int mode) const
|
||||
{
|
||||
if(mode == QCA::CBC)
|
||||
return EVP_bf_cbc();
|
||||
else if(mode == QCA::CFB)
|
||||
return EVP_bf_cfb();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
i->done = false;
|
||||
i->err = false;
|
||||
QByteArray result(len + i->type->block_size);
|
||||
int olen;
|
||||
if(i->dir == 0) {
|
||||
if(!EVP_EncryptUpdate(&i->c, (unsigned char *)result.data(), &olen, (const unsigned char *)in, len))
|
||||
class TripleDESContext : public EVPCipherContext
|
||||
{
|
||||
public:
|
||||
const EVP_CIPHER *getType(int mode) const
|
||||
{
|
||||
if(mode == QCA::CBC)
|
||||
return EVP_des_ede3_cbc();
|
||||
else if(mode == QCA::CFB)
|
||||
return EVP_des_ede3_cfb();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class RSAKeyContext : public QCA_RSAKeyContext
|
||||
{
|
||||
public:
|
||||
RSAKeyContext()
|
||||
{
|
||||
r = 0;
|
||||
}
|
||||
|
||||
~RSAKeyContext()
|
||||
{
|
||||
if(r)
|
||||
RSA_free(r);
|
||||
}
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
return (r ? false: true);
|
||||
}
|
||||
|
||||
bool createFromDER(const char *in, unsigned int len, bool sec)
|
||||
{
|
||||
RSA *t;
|
||||
if(sec) {
|
||||
const unsigned char *p = (const unsigned char *)in;
|
||||
t = d2i_RSAPrivateKey(NULL, &p, len);
|
||||
}
|
||||
else {
|
||||
unsigned char *p = (unsigned char *)in;
|
||||
t = d2i_RSA_PUBKEY(NULL, &p,len);
|
||||
}
|
||||
if(!t)
|
||||
return false;
|
||||
|
||||
r = t;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if(!EVP_DecryptUpdate(&i->c, (unsigned char *)result.data(), &olen, (const unsigned char *)in, len))
|
||||
|
||||
bool createFromNative(void *in)
|
||||
{
|
||||
r = (RSA *)in;
|
||||
++(r->references);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool generate(unsigned int bits)
|
||||
{
|
||||
RSA *t = RSA_generate_key(bits, RSA_F4, NULL, NULL);
|
||||
if(!t)
|
||||
return false;
|
||||
|
||||
r = t;
|
||||
return true;
|
||||
}
|
||||
result.resize(olen);
|
||||
appendArray(&i->r, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tdes_ensureFinal(pair_tdes *i)
|
||||
{
|
||||
if(i->done)
|
||||
return;
|
||||
|
||||
QByteArray result(i->type->block_size);
|
||||
int olen;
|
||||
if(i->dir == 0) {
|
||||
if(!EVP_EncryptFinal(&i->c, (unsigned char *)result.data(), &olen)) {
|
||||
i->err = true;
|
||||
return;
|
||||
}
|
||||
QCA_RSAKeyContext *clone()
|
||||
{
|
||||
RSAKeyContext *c = new RSAKeyContext;
|
||||
if(r)
|
||||
c->createFromNative(r);
|
||||
return c;
|
||||
}
|
||||
else {
|
||||
if(!EVP_DecryptFinal(&i->c, (unsigned char *)result.data(), &olen)) {
|
||||
i->err = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void toDER(char **out, unsigned int *len)
|
||||
{
|
||||
*out = 0;
|
||||
*len = 0;
|
||||
}
|
||||
result.resize(olen);
|
||||
appendArray(&i->r, result);
|
||||
i->done = true;
|
||||
}
|
||||
|
||||
bool tdes_final(int ctx, char *out)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
if(i->err)
|
||||
return false;
|
||||
bool encrypt(const char *in, unsigned int len, char **out, unsigned int *outlen)
|
||||
{
|
||||
int size = RSA_size(r);
|
||||
int flen = len;
|
||||
if(flen >= size - 11)
|
||||
flen = size - 11;
|
||||
QByteArray result(size);
|
||||
unsigned char *from = (unsigned char *)in;
|
||||
unsigned char *to = (unsigned char *)result.data();
|
||||
int ret = RSA_public_encrypt(flen, from, to, r, RSA_PKCS1_PADDING);
|
||||
if(ret == -1)
|
||||
return false;
|
||||
result.resize(ret);
|
||||
|
||||
tdes_ensureFinal(i);
|
||||
memcpy(out, i->r.data(), i->r.size());
|
||||
return true;
|
||||
}
|
||||
*out = (char *)malloc(result.size());
|
||||
memcpy((*out), result.data(), result.size());
|
||||
*outlen = result.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int tdes_finalSize(int ctx)
|
||||
{
|
||||
pair_tdes *i = find_tdes(ctx);
|
||||
tdes_ensureFinal(i);
|
||||
return i->r.size();
|
||||
}
|
||||
bool decrypt(const char *in, unsigned int len, char **out, unsigned int *outlen)
|
||||
{
|
||||
int size = RSA_size(r);
|
||||
int flen = len;
|
||||
QByteArray result(size);
|
||||
unsigned char *from = (unsigned char *)in;
|
||||
unsigned char *to = (unsigned char *)result.data();
|
||||
int ret = RSA_private_decrypt(flen, from, to, r, RSA_PKCS1_PADDING);
|
||||
if(ret == -1)
|
||||
return false;
|
||||
result.resize(ret);
|
||||
|
||||
*out = (char *)malloc(result.size());
|
||||
memcpy((*out), result.data(), result.size());
|
||||
*outlen = result.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
int rsa_keyCreateFromDER(const char *in, unsigned int len, bool sec)
|
||||
{
|
||||
RSA *r;
|
||||
if(sec) {
|
||||
const unsigned char *p = (const unsigned char *)in;
|
||||
r = d2i_RSAPrivateKey(NULL, &p, len);
|
||||
};
|
||||
|
||||
|
||||
class QCAOpenSSL : public QCAProvider
|
||||
{
|
||||
public:
|
||||
QCAOpenSSL() {}
|
||||
~QCAOpenSSL() {}
|
||||
|
||||
int capabilities() const
|
||||
{
|
||||
return (QCA::CAP_SHA1 | QCA::CAP_MD5 | QCA::CAP_BlowFish | QCA::CAP_TripleDES | QCA::CAP_RSA);
|
||||
}
|
||||
else {
|
||||
unsigned char *p = (unsigned char *)in;
|
||||
r = d2i_RSA_PUBKEY(NULL, &p,len);
|
||||
|
||||
void *functions(int cap)
|
||||
{
|
||||
if(cap == QCA::CAP_SHA1)
|
||||
return new SHA1Context;
|
||||
else if(cap == QCA::CAP_MD5)
|
||||
return new MD5Context;
|
||||
else if(cap == QCA::CAP_BlowFish)
|
||||
return new BlowFishContext;
|
||||
else if(cap == QCA::CAP_TripleDES)
|
||||
return new TripleDESContext;
|
||||
else if(cap == QCA::CAP_RSA)
|
||||
return new RSAKeyContext;
|
||||
return 0;
|
||||
}
|
||||
if(!r)
|
||||
return -1;
|
||||
};
|
||||
|
||||
pair_rsakey *i = new pair_rsakey;
|
||||
i->ctx = counter++;
|
||||
i->r = r;
|
||||
map_rsakey->append(i);
|
||||
//printf("created %d\n", i->ctx);
|
||||
return i->ctx;
|
||||
}
|
||||
|
||||
int rsa_keyCreateFromNative(void *in)
|
||||
#ifdef QCA_PLUGIN
|
||||
QCAProvider *createProvider()
|
||||
#else
|
||||
QCAProvider *createProviderOpenSSL()
|
||||
#endif
|
||||
{
|
||||
RSA *r = (RSA *)in;
|
||||
|
||||
pair_rsakey *i = new pair_rsakey;
|
||||
i->ctx = counter++;
|
||||
i->r = r;
|
||||
map_rsakey->append(i);
|
||||
return i->ctx;
|
||||
}
|
||||
|
||||
int rsa_keyClone(int ctx)
|
||||
{
|
||||
pair_rsakey *from = find_rsakey(ctx);
|
||||
pair_rsakey *i = new pair_rsakey;
|
||||
i->ctx = counter++;
|
||||
++from->r->references;
|
||||
i->r = from->r;
|
||||
map_rsakey->append(i);
|
||||
//printf("cloned %d to %d\n", from->ctx, i->ctx);
|
||||
return i->ctx;
|
||||
}
|
||||
|
||||
void rsa_keyDestroy(int ctx)
|
||||
{
|
||||
//printf("destroying %d\n", ctx);
|
||||
pair_rsakey *i = find_rsakey(ctx);
|
||||
RSA_free(i->r);
|
||||
map_rsakey->removeRef(i);
|
||||
}
|
||||
|
||||
void rsa_keyToDER(int ctx, char **out, unsigned int *len)
|
||||
{
|
||||
ctx = -1;
|
||||
*out = 0;
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
bool rsa_encrypt(int ctx, const char *in, unsigned int len, char **out, unsigned int *outlen)
|
||||
{
|
||||
pair_rsakey *i = find_rsakey(ctx);
|
||||
|
||||
//printf("using context %d [r=%p]\n", ctx, i->r);
|
||||
int size = RSA_size(i->r);
|
||||
int flen = len;
|
||||
if(flen >= size - 11)
|
||||
flen = size - 11;
|
||||
QByteArray result(size);
|
||||
unsigned char *from = (unsigned char *)in;
|
||||
unsigned char *to = (unsigned char *)result.data();
|
||||
int r = RSA_public_encrypt(flen, from, to, i->r, RSA_PKCS1_PADDING);
|
||||
if(r == -1)
|
||||
return false;
|
||||
result.resize(r);
|
||||
|
||||
*out = (char *)malloc(result.size());
|
||||
memcpy((*out), result.data(), result.size());
|
||||
*outlen = result.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rsa_decrypt(int ctx, const char *in, unsigned int len, char **out, unsigned int *outlen)
|
||||
{
|
||||
pair_rsakey *i = find_rsakey(ctx);
|
||||
if(!i) {
|
||||
//printf("no key!!\n");
|
||||
return false;
|
||||
}
|
||||
//printf("using context %d [r=%p]\n", ctx, i->r);
|
||||
|
||||
int size = RSA_size(i->r);
|
||||
int flen = len;
|
||||
QByteArray result(size);
|
||||
unsigned char *from = (unsigned char *)in;
|
||||
unsigned char *to = (unsigned char *)result.data();
|
||||
//printf("about to decrypt\n");
|
||||
int r = RSA_private_decrypt(flen, from, to, i->r, RSA_PKCS1_PADDING);
|
||||
//printf("done decrypt\n");
|
||||
if(r == -1)
|
||||
return false;
|
||||
result.resize(r);
|
||||
|
||||
*out = (char *)malloc(result.size());
|
||||
memcpy((*out), result.data(), result.size());
|
||||
*outlen = result.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
int rsa_keyCreateGenerate(unsigned int bits)
|
||||
{
|
||||
RSA *r = RSA_generate_key(bits, RSA_F4, NULL, NULL);
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
pair_rsakey *i = new pair_rsakey;
|
||||
i->ctx = counter++;
|
||||
i->r = r;
|
||||
map_rsakey->append(i);
|
||||
return i->ctx;
|
||||
return (new QCAOpenSSL);
|
||||
}
|
||||
|
@ -5,12 +5,8 @@
|
||||
|
||||
#ifdef QCA_PLUGIN
|
||||
QCA_EXPORT QCAProvider *createProvider();
|
||||
#else
|
||||
QCAProvider *createProviderOpenSSL();
|
||||
#endif
|
||||
|
||||
class QCAOpenSSL : public QCAProvider
|
||||
{
|
||||
public:
|
||||
QCAOpenSSL() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -9,7 +9,7 @@ INCLUDEPATH += ../src
|
||||
# RH 9
|
||||
INCLUDEPATH += /usr/kerberos/include
|
||||
|
||||
HEADERS = qcaopenssl.h qcaopenssl_p.h
|
||||
HEADERS = qcaopenssl.h
|
||||
SOURCES = qcaopenssl.cpp
|
||||
DEFINES += QCA_PLUGIN
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
#ifndef QCAOPENSSL_P_H
|
||||
#define QCAOPENSSL_P_H
|
||||
|
||||
#include"qcaopenssl.h"
|
||||
|
||||
class _QCAOpenSSL : public QCAOpenSSL
|
||||
{
|
||||
public:
|
||||
_QCAOpenSSL();
|
||||
~_QCAOpenSSL();
|
||||
|
||||
int capabilities() const;
|
||||
void *functions(int cap);
|
||||
};
|
||||
|
||||
#endif
|
15
rsatest.cpp
15
rsatest.cpp
@ -2,7 +2,7 @@
|
||||
#include"qca.h"
|
||||
#include<stdio.h>
|
||||
|
||||
static QCA::RSAKey readKeyFile(const QString &name, bool sec=false)
|
||||
QCA::RSAKey readKeyFile(const QString &name, bool sec=false)
|
||||
{
|
||||
QCA::RSAKey k;
|
||||
QFile f(name);
|
||||
@ -30,12 +30,13 @@ int main(int argc, char **argv)
|
||||
if(!QCA::isSupported(QCA::CAP_RSA))
|
||||
printf("RSA not supported!\n");
|
||||
else {
|
||||
/*QCA::RSAKey pubkey = readKeyFile("keypublic.der");
|
||||
if(pubkey.isNull())
|
||||
return 1;
|
||||
QCA::RSAKey seckey = readKeyFile("keyprivate.der", true);
|
||||
if(seckey.isNull())
|
||||
return 1;*/
|
||||
//QCA::RSAKey pubkey = readKeyFile("keypublic.der");
|
||||
//if(pubkey.isNull())
|
||||
// return 1;
|
||||
//QCA::RSAKey seckey = readKeyFile("keyprivate.der", true);
|
||||
//if(seckey.isNull())
|
||||
// return 1;
|
||||
|
||||
QCA::RSAKey seckey = QCA::RSA::generateKey(1024);
|
||||
if(seckey.isNull())
|
||||
return 1;
|
||||
|
185
src/qca.cpp
185
src/qca.cpp
@ -9,7 +9,7 @@
|
||||
#include<stdio.h>
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include"qcaopenssl_p.h"
|
||||
#include"qcaopenssl.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
@ -52,7 +52,7 @@ void QCA::init()
|
||||
{
|
||||
providerList.clear();
|
||||
#ifdef USE_OPENSSL
|
||||
providerList.append(new _QCAOpenSSL);
|
||||
providerList.append(createProviderOpenSSL());
|
||||
#endif
|
||||
|
||||
// load plugins
|
||||
@ -71,6 +71,7 @@ void QCA::init()
|
||||
}
|
||||
void *s = lib->resolve("createProvider");
|
||||
if(!s) {
|
||||
printf("can't resolve\n");
|
||||
delete lib;
|
||||
continue;
|
||||
}
|
||||
@ -113,35 +114,32 @@ static void *getFunctions(int cap)
|
||||
class Hash::Private
|
||||
{
|
||||
public:
|
||||
Private(QCA_HashFunctions *_f)
|
||||
Private(QCA_HashContext *_c)
|
||||
{
|
||||
f = _f;
|
||||
ctx = f->create();
|
||||
c = _c;
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
f->destroy(ctx);
|
||||
delete c;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
f->destroy(ctx);
|
||||
ctx = f->create();
|
||||
c->reset();
|
||||
}
|
||||
|
||||
QCA_HashFunctions *f;
|
||||
int ctx;
|
||||
QCA_HashContext *c;
|
||||
};
|
||||
|
||||
Hash::Hash(QCA_HashFunctions *f)
|
||||
Hash::Hash(QCA_HashContext *c)
|
||||
{
|
||||
d = new Private(f);
|
||||
d = new Private(c);
|
||||
}
|
||||
|
||||
Hash::Hash(const Hash &from)
|
||||
{
|
||||
d = new Private(from.d->f);
|
||||
d = new Private(from.d->c);
|
||||
*this = from;
|
||||
}
|
||||
|
||||
@ -163,13 +161,17 @@ void Hash::clear()
|
||||
|
||||
void Hash::update(const QByteArray &a)
|
||||
{
|
||||
d->f->update(d->ctx, a.data(), a.size());
|
||||
d->c->update(a.data(), a.size());
|
||||
}
|
||||
|
||||
QByteArray Hash::final()
|
||||
{
|
||||
QByteArray buf(d->f->finalSize(d->ctx));
|
||||
d->f->final(d->ctx, buf.data());
|
||||
char *out;
|
||||
unsigned int len;
|
||||
d->c->final(&out, &len);
|
||||
QByteArray buf(len);
|
||||
memcpy(buf.data(), out, len);
|
||||
free(out);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -180,50 +182,48 @@ QByteArray Hash::final()
|
||||
class Cipher::Private
|
||||
{
|
||||
public:
|
||||
Private(QCA_CipherFunctions *_f)
|
||||
Private(QCA_CipherContext *_c)
|
||||
{
|
||||
f = _f;
|
||||
ctx = f->create();
|
||||
c = _c;
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
f->destroy(ctx);
|
||||
delete c;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
f->destroy(ctx);
|
||||
ctx = f->create();
|
||||
//c->reset();
|
||||
|
||||
dir = Encrypt;
|
||||
key.resize(0);
|
||||
iv.resize(0);
|
||||
err = false;
|
||||
}
|
||||
|
||||
QCA_CipherFunctions *f;
|
||||
int ctx;
|
||||
QCA_CipherContext *c;
|
||||
int dir;
|
||||
int mode;
|
||||
QByteArray key, iv;
|
||||
bool err;
|
||||
};
|
||||
|
||||
Cipher::Cipher(QCA_CipherFunctions *f, int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
Cipher::Cipher(QCA_CipherContext *c, int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
{
|
||||
d = new Private(f);
|
||||
d = new Private(c);
|
||||
reset(dir, mode, key, iv);
|
||||
}
|
||||
|
||||
Cipher::Cipher(const Cipher &from)
|
||||
{
|
||||
d = new Private(from.d->f);
|
||||
d = new Private(from.d->c);
|
||||
*this = from;
|
||||
}
|
||||
|
||||
Cipher & Cipher::operator=(const Cipher &from)
|
||||
{
|
||||
reset(from.d->dir, from.d->key, from.d->iv);
|
||||
reset(from.d->dir, from.d->mode, from.d->key, from.d->iv);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -234,16 +234,16 @@ Cipher::~Cipher()
|
||||
|
||||
QByteArray Cipher::dyn_generateKey() const
|
||||
{
|
||||
QByteArray buf(d->f->keySize());
|
||||
if(!d->f->generateKey(buf.data()))
|
||||
QByteArray buf(d->c->keySize());
|
||||
if(!d->c->generateKey(buf.data()))
|
||||
return QByteArray();
|
||||
return buf;
|
||||
}
|
||||
|
||||
QByteArray Cipher::dyn_generateIV() const
|
||||
{
|
||||
QByteArray buf(d->f->blockSize());
|
||||
if(!d->f->generateIV(buf.data()))
|
||||
QByteArray buf(d->c->blockSize());
|
||||
if(!d->c->generateIV(buf.data()))
|
||||
return QByteArray();
|
||||
return buf;
|
||||
}
|
||||
@ -255,7 +255,7 @@ void Cipher::reset(int dir, int mode, const QByteArray &key, const QByteArray &i
|
||||
d->mode = mode;
|
||||
d->key = key.copy();
|
||||
d->iv = iv.copy();
|
||||
if(!d->f->setup(d->ctx, d->dir, d->mode, d->key.data(), d->iv.isEmpty() ? 0 : d->iv.data())) {
|
||||
if(!d->c->setup(d->dir, d->mode, d->key.data(), d->iv.isEmpty() ? 0 : d->iv.data())) {
|
||||
d->err = true;
|
||||
return;
|
||||
}
|
||||
@ -266,7 +266,7 @@ bool Cipher::update(const QByteArray &a)
|
||||
if(d->err)
|
||||
return false;
|
||||
|
||||
if(!d->f->update(d->ctx, a.data(), a.size())) {
|
||||
if(!d->c->update(a.data(), a.size())) {
|
||||
d->err = true;
|
||||
return false;
|
||||
}
|
||||
@ -278,12 +278,15 @@ QByteArray Cipher::final()
|
||||
if(d->err)
|
||||
return QByteArray();
|
||||
|
||||
QByteArray buf(d->f->finalSize(d->ctx));
|
||||
if(!d->f->final(d->ctx, buf.data())) {
|
||||
char *out;
|
||||
unsigned int len;
|
||||
if(!d->c->final(&out, &len)) {
|
||||
d->err = true;
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray buf(len);
|
||||
memcpy(buf.data(), out, len);
|
||||
free(out);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -292,7 +295,7 @@ QByteArray Cipher::final()
|
||||
// SHA1
|
||||
//----------------------------------------------------------------------------
|
||||
SHA1::SHA1()
|
||||
:Hash((QCA_HashFunctions *)getFunctions(CAP_SHA1))
|
||||
:Hash((QCA_HashContext *)getFunctions(CAP_SHA1))
|
||||
{
|
||||
}
|
||||
|
||||
@ -301,7 +304,7 @@ SHA1::SHA1()
|
||||
// SHA256
|
||||
//----------------------------------------------------------------------------
|
||||
SHA256::SHA256()
|
||||
:Hash((QCA_HashFunctions *)getFunctions(CAP_SHA256))
|
||||
:Hash((QCA_HashContext *)getFunctions(CAP_SHA256))
|
||||
{
|
||||
}
|
||||
|
||||
@ -310,7 +313,7 @@ SHA256::SHA256()
|
||||
// MD5
|
||||
//----------------------------------------------------------------------------
|
||||
MD5::MD5()
|
||||
:Hash((QCA_HashFunctions *)getFunctions(CAP_MD5))
|
||||
:Hash((QCA_HashContext *)getFunctions(CAP_MD5))
|
||||
{
|
||||
}
|
||||
|
||||
@ -319,7 +322,7 @@ MD5::MD5()
|
||||
// BlowFish
|
||||
//----------------------------------------------------------------------------
|
||||
BlowFish::BlowFish(int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
:Cipher((QCA_CipherFunctions *)getFunctions(CAP_BlowFish), dir, mode, key, iv)
|
||||
:Cipher((QCA_CipherContext *)getFunctions(CAP_BlowFish), dir, mode, key, iv)
|
||||
{
|
||||
}
|
||||
|
||||
@ -328,7 +331,7 @@ BlowFish::BlowFish(int dir, int mode, const QByteArray &key, const QByteArray &i
|
||||
// TripleDES
|
||||
//----------------------------------------------------------------------------
|
||||
TripleDES::TripleDES(int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
:Cipher((QCA_CipherFunctions *)getFunctions(CAP_TripleDES), dir, mode, key, iv)
|
||||
:Cipher((QCA_CipherContext *)getFunctions(CAP_TripleDES), dir, mode, key, iv)
|
||||
{
|
||||
}
|
||||
|
||||
@ -337,7 +340,7 @@ TripleDES::TripleDES(int dir, int mode, const QByteArray &key, const QByteArray
|
||||
// AES128
|
||||
//----------------------------------------------------------------------------
|
||||
AES128::AES128(int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
:Cipher((QCA_CipherFunctions *)getFunctions(CAP_AES128), dir, mode, key, iv)
|
||||
:Cipher((QCA_CipherContext *)getFunctions(CAP_AES128), dir, mode, key, iv)
|
||||
{
|
||||
}
|
||||
|
||||
@ -346,7 +349,7 @@ AES128::AES128(int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
// AES256
|
||||
//----------------------------------------------------------------------------
|
||||
AES256::AES256(int dir, int mode, const QByteArray &key, const QByteArray &iv)
|
||||
:Cipher((QCA_CipherFunctions *)getFunctions(CAP_AES256), dir, mode, key, iv)
|
||||
:Cipher((QCA_CipherContext *)getFunctions(CAP_AES256), dir, mode, key, iv)
|
||||
{
|
||||
}
|
||||
|
||||
@ -359,25 +362,15 @@ class RSAKey::Private
|
||||
public:
|
||||
Private()
|
||||
{
|
||||
f = (QCA_RSAFunctions *)getFunctions(CAP_RSA);
|
||||
ctx = -1;
|
||||
c = (QCA_RSAKeyContext *)getFunctions(CAP_RSA);
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
reset();
|
||||
delete c;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if(ctx != -1) {
|
||||
f->keyDestroy(ctx);
|
||||
ctx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
QCA_RSAFunctions *f;
|
||||
int ctx;
|
||||
QCA_RSAKeyContext *c;
|
||||
};
|
||||
|
||||
RSAKey::RSAKey()
|
||||
@ -393,10 +386,11 @@ RSAKey::RSAKey(const RSAKey &from)
|
||||
|
||||
RSAKey & RSAKey::operator=(const RSAKey &from)
|
||||
{
|
||||
d->reset();
|
||||
if(d->c)
|
||||
delete d->c;
|
||||
*d = *from.d;
|
||||
if(d->ctx != -1)
|
||||
d->ctx = d->f->keyClone(d->ctx);
|
||||
d->c = d->c->clone();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -407,14 +401,14 @@ RSAKey::~RSAKey()
|
||||
|
||||
bool RSAKey::isNull() const
|
||||
{
|
||||
return (d->ctx == -1 ? true: false);
|
||||
return d->c->isNull();
|
||||
}
|
||||
|
||||
QByteArray RSAKey::toDER() const
|
||||
{
|
||||
char *out;
|
||||
unsigned int len;
|
||||
d->f->keyToDER(d->ctx, &out, &len);
|
||||
d->c->toDER(&out, &len);
|
||||
QByteArray buf(len);
|
||||
memcpy(buf.data(), out, len);
|
||||
free(out);
|
||||
@ -423,34 +417,41 @@ QByteArray RSAKey::toDER() const
|
||||
|
||||
bool RSAKey::fromDER(const QByteArray &a, bool sec)
|
||||
{
|
||||
int ctx = d->f->keyCreateFromDER(a.data(), a.size(), sec);
|
||||
if(ctx == -1)
|
||||
return false;
|
||||
d->ctx = ctx;
|
||||
return true;
|
||||
return d->c->createFromDER(a.data(), a.size(), sec);
|
||||
}
|
||||
|
||||
bool RSAKey::fromNative(void *p)
|
||||
{
|
||||
int ctx = d->f->keyCreateFromNative(p);
|
||||
if(ctx == -1)
|
||||
return d->c->createFromNative(p);
|
||||
}
|
||||
|
||||
bool RSAKey::encrypt(const QByteArray &a, QByteArray *b) const
|
||||
{
|
||||
char *out;
|
||||
unsigned int len;
|
||||
if(!d->c->encrypt(a.data(), a.size(), &out, &len))
|
||||
return false;
|
||||
d->ctx = ctx;
|
||||
b->resize(len);
|
||||
memcpy(b->data(), out, len);
|
||||
free(out);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RSAKey::decrypt(const QByteArray &a, QByteArray *b) const
|
||||
{
|
||||
char *out;
|
||||
unsigned int len;
|
||||
if(!d->c->decrypt(a.data(), a.size(), &out, &len))
|
||||
return false;
|
||||
b->resize(len);
|
||||
memcpy(b->data(), out, len);
|
||||
free(out);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RSAKey::generate(unsigned int bits)
|
||||
{
|
||||
int ctx = d->f->keyCreateGenerate(bits);
|
||||
if(ctx == -1)
|
||||
return false;
|
||||
d->ctx = ctx;
|
||||
return true;
|
||||
}
|
||||
|
||||
int RSAKey::internalContext() const
|
||||
{
|
||||
return d->ctx;
|
||||
return d->c->generate(bits);
|
||||
}
|
||||
|
||||
|
||||
@ -479,34 +480,14 @@ bool RSA::encrypt(const QByteArray &a, QByteArray *b) const
|
||||
{
|
||||
if(v_key.isNull())
|
||||
return false;
|
||||
|
||||
QCA_RSAFunctions *f = (QCA_RSAFunctions *)getFunctions(CAP_RSA);
|
||||
char *out;
|
||||
unsigned int len;
|
||||
if(!f->encrypt(v_key.internalContext(), a.data(), a.size(), &out, &len))
|
||||
return false;
|
||||
|
||||
b->resize(len);
|
||||
memcpy(b->data(), out, len);
|
||||
free(out);
|
||||
return true;
|
||||
return v_key.encrypt(a, b);
|
||||
}
|
||||
|
||||
bool RSA::decrypt(const QByteArray &a, QByteArray *b) const
|
||||
{
|
||||
if(v_key.isNull())
|
||||
return false;
|
||||
|
||||
QCA_RSAFunctions *f = (QCA_RSAFunctions *)getFunctions(CAP_RSA);
|
||||
char *out;
|
||||
unsigned int len;
|
||||
if(!f->decrypt(v_key.internalContext(), a.data(), a.size(), &out, &len))
|
||||
return false;
|
||||
|
||||
b->resize(len);
|
||||
memcpy(b->data(), out, len);
|
||||
free(out);
|
||||
return true;
|
||||
return v_key.decrypt(a, b);
|
||||
}
|
||||
|
||||
RSAKey RSA::generateKey(unsigned int bits)
|
||||
|
11
src/qca.h
11
src/qca.h
@ -4,8 +4,8 @@
|
||||
#include<qstring.h>
|
||||
#include<qcstring.h>
|
||||
|
||||
struct QCA_HashFunctions;
|
||||
struct QCA_CipherFunctions;
|
||||
class QCA_HashContext;
|
||||
class QCA_CipherContext;
|
||||
|
||||
namespace QCA
|
||||
{
|
||||
@ -52,7 +52,7 @@ namespace QCA
|
||||
QByteArray final();
|
||||
|
||||
protected:
|
||||
Hash(QCA_HashFunctions *);
|
||||
Hash(QCA_HashContext *);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
@ -104,7 +104,7 @@ namespace QCA
|
||||
QByteArray final();
|
||||
|
||||
protected:
|
||||
Cipher(QCA_CipherFunctions *, int dir, int mode, const QByteArray &key, const QByteArray &iv);
|
||||
Cipher(QCA_CipherContext *, int dir, int mode, const QByteArray &key, const QByteArray &iv);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
@ -194,7 +194,8 @@ namespace QCA
|
||||
Private *d;
|
||||
|
||||
friend class RSA;
|
||||
int internalContext() const;
|
||||
bool encrypt(const QByteArray &a, QByteArray *out) const;
|
||||
bool decrypt(const QByteArray &a, QByteArray *out) const;
|
||||
bool generate(unsigned int bits);
|
||||
};
|
||||
|
||||
|
@ -20,41 +20,45 @@ public:
|
||||
virtual void *functions(int cap)=0;
|
||||
};
|
||||
|
||||
struct QCA_HashFunctions
|
||||
class QCA_HashContext
|
||||
{
|
||||
int (*create)();
|
||||
void (*destroy)(int ctx);
|
||||
void (*update)(int ctx, const char *in, unsigned int len);
|
||||
void (*final)(int ctx, char *out);
|
||||
unsigned int (*finalSize)(int ctx);
|
||||
public:
|
||||
virtual ~QCA_HashContext() {}
|
||||
|
||||
virtual void reset()=0;
|
||||
virtual void update(const char *in, unsigned int len)=0;
|
||||
virtual void final(char **out, unsigned int *outlen)=0;
|
||||
};
|
||||
|
||||
struct QCA_CipherFunctions
|
||||
class QCA_CipherContext
|
||||
{
|
||||
int (*keySize)();
|
||||
int (*blockSize)();
|
||||
bool (*generateKey)(char *out);
|
||||
bool (*generateIV)(char *out);
|
||||
public:
|
||||
virtual ~QCA_CipherContext() {}
|
||||
|
||||
int (*create)();
|
||||
void (*destroy)(int ctx);
|
||||
bool (*setup)(int ctx, int dir, int mode, const char *key, const char *iv);
|
||||
bool (*update)(int ctx, const char *in, unsigned int len);
|
||||
bool (*final)(int ctx, char *out);
|
||||
unsigned int (*finalSize)(int ctx);
|
||||
virtual int keySize()=0;
|
||||
virtual int blockSize()=0;
|
||||
virtual bool generateKey(char *out)=0;
|
||||
virtual bool generateIV(char *out)=0;
|
||||
|
||||
virtual bool setup(int dir, int mode, const char *key, const char *iv)=0;
|
||||
virtual bool update(const char *in, unsigned int len)=0;
|
||||
virtual bool final(char **out, unsigned int *outlen)=0;
|
||||
};
|
||||
|
||||
struct QCA_RSAFunctions
|
||||
class QCA_RSAKeyContext
|
||||
{
|
||||
int (*keyCreateFromDER)(const char *in, unsigned int len, bool sec);
|
||||
int (*keyCreateFromNative)(void *in);
|
||||
int (*keyCreateGenerate)(unsigned int bits);
|
||||
int (*keyClone)(int ctx);
|
||||
void (*keyDestroy)(int ctx);
|
||||
void (*keyToDER)(int ctx, char **out, unsigned int *len);
|
||||
public:
|
||||
virtual ~QCA_RSAKeyContext() {}
|
||||
|
||||
bool (*encrypt)(int ctx, const char *in, unsigned int len, char **out, unsigned int *outlen);
|
||||
bool (*decrypt)(int ctx, const char *in, unsigned int len, char **out, unsigned int *outlen);
|
||||
virtual bool isNull() const=0;
|
||||
virtual bool createFromDER(const char *in, unsigned int len, bool sec)=0;
|
||||
virtual bool createFromNative(void *in)=0;
|
||||
virtual bool generate(unsigned int bits)=0;
|
||||
virtual QCA_RSAKeyContext *clone()=0;
|
||||
virtual void toDER(char **out, unsigned int *len)=0;
|
||||
|
||||
virtual bool encrypt(const char *in, unsigned int len, char **out, unsigned int *outlen)=0;
|
||||
virtual bool decrypt(const char *in, unsigned int len, char **out, unsigned int *outlen)=0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user