mirror of
https://github.com/QuasarApp/qca.git
synced 2025-04-28 12:34:31 +00:00
RSA support
svn path=/trunk/kdesupport/qca/; revision=236591
This commit is contained in:
parent
89c32cf384
commit
413fb04eb5
11
TODO
11
TODO
@ -1,8 +1,13 @@
|
||||
* clean up plugin system
|
||||
* flesh out rsa and rsakey
|
||||
* rsa: choice of pad
|
||||
* make 'cipherkey' class?
|
||||
* better handling of errors ('empty' arrays are not a good idea)
|
||||
* ability to disable pkcs padding on ciphers
|
||||
* better entropy?
|
||||
* clean up plugin system
|
||||
|
||||
* ssl/tls/x509
|
||||
* sasl
|
||||
* ssl/tls/x509 (also server support)
|
||||
* sasl (also server support)
|
||||
|
||||
* figure out where to install the lib and plugins. maybe Qt plugin path?
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include<openssl/sha.h>
|
||||
#include<openssl/md5.h>
|
||||
#include<openssl/evp.h>
|
||||
#include<openssl/rsa.h>
|
||||
#include<openssl/x509.h>
|
||||
|
||||
#ifdef QCA_PLUGIN
|
||||
QCAProvider *createProvider()
|
||||
@ -71,6 +73,13 @@ 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_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();
|
||||
@ -109,6 +118,14 @@ struct pair_tdes
|
||||
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);
|
||||
@ -139,6 +156,16 @@ static pair_tdes *find_tdes(int ctx)
|
||||
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;
|
||||
@ -147,6 +174,8 @@ _QCAOpenSSL::_QCAOpenSSL()
|
||||
map_md5->setAutoDelete(true);
|
||||
map_tdes = new MAP_TDES;
|
||||
map_tdes->setAutoDelete(true);
|
||||
map_rsakey = new MAP_RSAKEY;
|
||||
map_rsakey->setAutoDelete(true);
|
||||
}
|
||||
|
||||
_QCAOpenSSL::~_QCAOpenSSL()
|
||||
@ -157,11 +186,13 @@ _QCAOpenSSL::~_QCAOpenSSL()
|
||||
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);
|
||||
return (QCA::CAP_SHA1 | QCA::CAP_MD5 | QCA::CAP_TripleDES | QCA::CAP_RSA);
|
||||
}
|
||||
|
||||
void *_QCAOpenSSL::functions(int cap)
|
||||
@ -198,6 +229,17 @@ void *_QCAOpenSSL::functions(int cap)
|
||||
f->finalSize = tdes_finalSize;
|
||||
return f;
|
||||
}
|
||||
else if(cap == QCA::CAP_RSA) {
|
||||
QCA_RSAFunctions *f = new QCA_RSAFunctions;
|
||||
f->keyCreateFromDER = rsa_keyCreateFromDER;
|
||||
f->keyClone = rsa_keyClone;
|
||||
f->keyDestroy = rsa_keyDestroy;
|
||||
f->keyToDER = rsa_keyToDER;
|
||||
f->encrypt = rsa_encrypt;
|
||||
f->decrypt = rsa_decrypt;
|
||||
return f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -408,3 +450,110 @@ unsigned int tdes_finalSize(int ctx)
|
||||
return i->r.size();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
unsigned char *p = (unsigned char *)in;
|
||||
r = d2i_RSA_PUBKEY(NULL, &p,len);
|
||||
}
|
||||
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_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;
|
||||
}
|
||||
|
||||
/*bool RSAKey::generateKey(int bits)
|
||||
{
|
||||
RSA *r = RSA_generate_key(bits, RSA_F4, NULL, NULL);
|
||||
if(!r)
|
||||
return false;
|
||||
d->r = r;
|
||||
return true;
|
||||
}*/
|
||||
|
146
src/qca.cpp
146
src/qca.cpp
@ -338,3 +338,149 @@ AES256::AES256(int dir, const QByteArray &key, const QByteArray &iv)
|
||||
:Cipher((QCA_CipherFunctions *)getFunctions(CAP_AES256), dir, key, iv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// RSAKey
|
||||
//----------------------------------------------------------------------------
|
||||
class RSAKey::Private
|
||||
{
|
||||
public:
|
||||
Private()
|
||||
{
|
||||
f = (QCA_RSAFunctions *)getFunctions(CAP_RSA);
|
||||
ctx = -1;
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if(ctx != -1) {
|
||||
f->keyDestroy(ctx);
|
||||
ctx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
QCA_RSAFunctions *f;
|
||||
int ctx;
|
||||
};
|
||||
|
||||
RSAKey::RSAKey()
|
||||
{
|
||||
d = new Private;
|
||||
}
|
||||
|
||||
RSAKey::RSAKey(const RSAKey &from)
|
||||
{
|
||||
d = new Private;
|
||||
*this = from;
|
||||
}
|
||||
|
||||
RSAKey & RSAKey::operator=(const RSAKey &from)
|
||||
{
|
||||
d->reset();
|
||||
*d = *from.d;
|
||||
if(d->ctx != -1)
|
||||
d->ctx = d->f->keyClone(d->ctx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
RSAKey::~RSAKey()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool RSAKey::isNull() const
|
||||
{
|
||||
return (d->ctx == -1 ? true: false);
|
||||
}
|
||||
|
||||
QByteArray RSAKey::toDER() const
|
||||
{
|
||||
char *out;
|
||||
unsigned int len;
|
||||
d->f->keyToDER(d->ctx, &out, &len);
|
||||
QByteArray buf(len);
|
||||
memcpy(buf.data(), out, len);
|
||||
free(out);
|
||||
return buf;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int RSAKey::internalContext() const
|
||||
{
|
||||
return d->ctx;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// RSA
|
||||
//----------------------------------------------------------------------------
|
||||
RSA::RSA()
|
||||
{
|
||||
}
|
||||
|
||||
RSA::~RSA()
|
||||
{
|
||||
}
|
||||
|
||||
RSAKey RSA::key() const
|
||||
{
|
||||
return v_key;
|
||||
}
|
||||
|
||||
void RSA::setKey(const RSAKey &k)
|
||||
{
|
||||
v_key = k;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
RSAKey RSA::generateKey(int bits)
|
||||
{
|
||||
return RSAKey();
|
||||
}
|
||||
|
41
src/qca.h
41
src/qca.h
@ -16,6 +16,7 @@ namespace QCA
|
||||
CAP_TripleDES = 0x0008,
|
||||
CAP_AES128 = 0x0010,
|
||||
CAP_AES256 = 0x0020,
|
||||
CAP_RSA = 0x0040,
|
||||
|
||||
//CAP_X509 = 0x0040,
|
||||
//CAP_TLS = 0x0080,
|
||||
@ -155,6 +156,46 @@ namespace QCA
|
||||
public:
|
||||
AES256(int dir=Encrypt, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray());
|
||||
};
|
||||
|
||||
class RSA;
|
||||
class RSAKey
|
||||
{
|
||||
public:
|
||||
RSAKey();
|
||||
RSAKey(const RSAKey &from);
|
||||
RSAKey & operator=(const RSAKey &from);
|
||||
~RSAKey();
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
QByteArray toDER() const;
|
||||
bool fromDER(const QByteArray &a, bool sec=false);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
friend class RSA;
|
||||
int internalContext() const;
|
||||
};
|
||||
|
||||
class RSA
|
||||
{
|
||||
public:
|
||||
RSA();
|
||||
~RSA();
|
||||
|
||||
RSAKey key() const;
|
||||
void setKey(const RSAKey &);
|
||||
|
||||
bool encrypt(const QByteArray &a, QByteArray *out) const;
|
||||
bool decrypt(const QByteArray &a, QByteArray *out) const;
|
||||
|
||||
static RSAKey generateKey(int bits);
|
||||
|
||||
private:
|
||||
RSAKey v_key;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -44,4 +44,15 @@ struct QCA_CipherFunctions
|
||||
unsigned int (*finalSize)(int ctx);
|
||||
};
|
||||
|
||||
struct QCA_RSAFunctions
|
||||
{
|
||||
int (*keyCreateFromDER)(const char *in, unsigned int len, bool sec);
|
||||
int (*keyClone)(int ctx);
|
||||
void (*keyDestroy)(int ctx);
|
||||
void (*keyToDER)(int ctx, char **out, unsigned int *len);
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user