4
0
mirror of https://github.com/QuasarApp/qca.git synced 2025-05-10 17:59:33 +00:00

smart provider handling for pkey

svn path=/trunk/kdesupport/qca/; revision=405023
This commit is contained in:
Justin Karneges 2005-04-12 10:25:35 +00:00
parent d814e960c9
commit beb5736f05
5 changed files with 407 additions and 64 deletions

3
TODO

@ -19,8 +19,7 @@
give all classes non-default ctors/dtors/copy/op=, and dpointers?
* finish API:
dlgroup: make it a provider object? (for smartcards)
symmetrickey: make it a provider object? (for smartcards)
ability to set arbitrary properties in a provider (string+variant pairs?)
finish qcaprovider.h
* build system:

@ -246,6 +246,12 @@ namespace QCA
*/
bool isPrivate() const;
/**
Test if the key data can be exported. If the key resides on a smart
card or other such device, this will likely return false.
*/
bool canExport() const;
/**
Test if the key can be used for key agreement
*/
@ -519,7 +525,7 @@ namespace QCA
analysis.
\param bits the length of key that is required
\param exp the exponent - typicall 3, 17 or 65537
\param exp the exponent - typically 3, 17 or 65537
\param provider the name of the provider to use
*/
PrivateKey createRSA(int bits, int exp = 65537, const QString &provider = QString());

@ -137,7 +137,9 @@ class PKeyBase : public QObject, public Provider::Context
public:
PKeyBase(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual bool isNull() const = 0;
virtual PKey::Type type() const = 0;
virtual bool isPrivate() const = 0;
virtual bool canExport() const = 0;
virtual void convertToPublic() = 0;
virtual int bits() const = 0;
@ -212,8 +214,8 @@ public:
virtual PKeyBase *key() = 0;
virtual const PKeyBase *key() const = 0;
virtual PKey::Type type() const = 0;
virtual void setKey(PKeyBase *key) = 0;
virtual bool importKey(const PKeyBase *key) = 0;
// import / export
virtual QSecureArray publicToDER() const = 0;

@ -175,13 +175,13 @@ static QCA::Constraints find_constraints(const QCA::PKeyContext &key, const QCA:
{
QCA::Constraints constraints;
if(key.type() == QCA::PKey::RSA)
if(key.key()->type() == QCA::PKey::RSA)
constraints += QCA::KeyEncipherment;
if(key.type() == QCA::PKey::DH)
if(key.key()->type() == QCA::PKey::DH)
constraints += QCA::KeyAgreement;
if(key.type() == QCA::PKey::RSA || key.type() == QCA::PKey::DSA)
if(key.key()->type() == QCA::PKey::RSA || key.key()->type() == QCA::PKey::DSA)
{
constraints += QCA::DigitalSignature;
constraints += QCA::NonRepudiation;
@ -1507,11 +1507,21 @@ public:
return (evp.pkey ? false: true);
}
virtual QCA::PKey::Type type() const
{
return QCA::PKey::RSA;
}
virtual bool isPrivate() const
{
return sec;
}
virtual bool canExport() const
{
return true;
}
virtual void convertToPublic()
{
if(!sec)
@ -1826,11 +1836,21 @@ public:
return (evp.pkey ? false: true);
}
virtual QCA::PKey::Type type() const
{
return QCA::PKey::DSA;
}
virtual bool isPrivate() const
{
return sec;
}
virtual bool canExport() const
{
return true;
}
virtual void convertToPublic()
{
if(!sec)
@ -2083,11 +2103,21 @@ public:
return (evp.pkey ? false: true);
}
virtual QCA::PKey::Type type() const
{
return QCA::PKey::DH;
}
virtual bool isPrivate() const
{
return sec;
}
virtual bool canExport() const
{
return true;
}
virtual void convertToPublic()
{
if(!sec)
@ -2279,25 +2309,21 @@ public:
return k;
}
virtual QCA::PKey::Type type() const
{
QString str = k->type();
if(str == "rsa")
return QCA::PKey::RSA;
else if(str == "dsa")
return QCA::PKey::DSA;
else
return QCA::PKey::DH;
}
virtual void setKey(QCA::PKeyBase *key)
{
k = key;
}
virtual bool importKey(const QCA::PKeyBase *key)
{
Q_UNUSED(key);
printf("import key\n");
return false;
}
EVP_PKEY *get_pkey() const
{
QCA::PKey::Type t = type();
QCA::PKey::Type t = k->type();
if(t == QCA::PKey::RSA)
return static_cast<RSAKey *>(k)->evp.pkey;
else if(t == QCA::PKey::DSA)
@ -3657,6 +3683,7 @@ class opensslProvider : public QCA::Provider
public:
void init()
{
printf("init\n");
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();

@ -27,6 +27,7 @@
namespace QCA {
Provider::Context *getContext(const QString &type, const QString &provider);
Provider::Context *getContext(const QString &type, Provider *p);
bool stringToFile(const QString &fileName, const QString &content)
{
@ -66,6 +67,218 @@ bool arrayFromFile(const QString &fileName, QByteArray *a)
return true;
}
ProviderList allProviders()
{
ProviderList pl = providers();
pl += defaultProvider();
return pl;
}
Provider *providerForName(const QString &name)
{
ProviderList pl = allProviders();
for(int n = 0; n < pl.count(); ++n)
{
if(pl[n]->name() == name)
return pl[n];
}
return 0;
}
class Getter_GroupSet
{
public:
static QList<DLGroupSet> getList(Provider *p)
{
QList<DLGroupSet> list;
const DLGroupContext *c = static_cast<const DLGroupContext *>(getContext("dlgroup", p));
if(!c)
return list;
list = c->supportedGroupSets();
delete c;
return list;
}
};
class Getter_PBE
{
public:
static QList<PBEAlgorithm> getList(Provider *p)
{
QList<PBEAlgorithm> list;
const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", p));
if(!c)
return list;
list = c->supportedPBEAlgorithms();
delete c;
return list;
}
};
class Getter_Type
{
public:
static QList<PKey::Type> getList(Provider *p)
{
QList<PKey::Type> list;
const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", p));
if(!c)
return list;
list = c->supportedTypes();
delete c;
return list;
}
};
class Getter_IOType
{
public:
static QList<PKey::Type> getList(Provider *p)
{
QList<PKey::Type> list;
const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", p));
if(!c)
return list;
list = c->supportedIOTypes();
delete c;
return list;
}
};
template <typename I>
class Getter_PublicKey
{
public:
// DER
static ConvertResult fromData(PKeyContext *c, const QSecureArray &in)
{
return c->publicFromDER(in);
}
// PEM
static ConvertResult fromData(PKeyContext *c, const QString &in)
{
return c->publicFromPEM(in);
}
static PublicKey getKey(Provider *p, const I &in, const QSecureArray &, ConvertResult *result)
{
PublicKey k;
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", p));
if(!c)
return k;
ConvertResult r = fromData(c, in);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
return k;
}
};
template <typename I>
class Getter_PrivateKey
{
public:
// DER
static ConvertResult fromData(PKeyContext *c, const QSecureArray &in, const QSecureArray &passphrase)
{
return c->privateFromDER(in, passphrase);
}
// PEM
static ConvertResult fromData(PKeyContext *c, const QString &in, const QSecureArray &passphrase)
{
return c->privateFromPEM(in, passphrase);
}
static PrivateKey getKey(Provider *p, const I &in, const QSecureArray &passphrase, ConvertResult *result)
{
PrivateKey k;
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", p));
if(!c)
return k;
ConvertResult r = fromData(c, in, passphrase);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
return k;
}
};
Provider *providerForPBE(PBEAlgorithm alg)
{
ProviderList pl = allProviders();
for(int n = 0; n < pl.count(); ++n)
{
if(Getter_PBE::getList(pl[n]).contains(alg))
return pl[n];
}
return 0;
}
template <typename T, typename G>
QList<T> getList(const QString &provider)
{
QList<T> list;
// single
if(!provider.isEmpty())
{
Provider *p = providerForName(provider);
if(p)
list = G::getList(p);
}
// all
else
{
ProviderList pl = allProviders();
for(int n = 0; n < pl.count(); ++n)
list += G::getList(pl[n]);
}
return list;
}
template <typename T, typename G, typename I>
T getKey(const QString &provider, const I &in, const QSecureArray &passphrase, ConvertResult *result)
{
T k;
// single
if(!provider.isEmpty())
{
Provider *p = providerForName(provider);
if(!p)
return k;
k = G::getKey(p, in, passphrase, result);
}
// all
else
{
ProviderList pl = allProviders();
for(int n = 0; n < pl.count(); ++n)
{
ConvertResult r;
k = G::getKey(pl[n], in, passphrase, &r);
if(result)
*result = r;
if(!k.isNull())
break;
if(r == ErrorPassphrase) // don't loop if we get this
break;
}
}
return k;
}
PBEAlgorithm get_pbe_default()
{
return PBES2_TripleDES_SHA1;
}
//----------------------------------------------------------------------------
// DLGroup
//----------------------------------------------------------------------------
@ -119,10 +332,11 @@ DLGroup & DLGroup::operator=(const DLGroup &from)
QList<DLGroupSet> DLGroup::supportedGroupSets(const QString &provider)
{
DLGroupContext *c = static_cast<DLGroupContext *>(getContext("dlgroup", provider));
QList<DLGroupSet> list = c->supportedGroupSets();
delete c;
return list;
return getList<DLGroupSet, Getter_GroupSet>(provider);
//DLGroupContext *c = static_cast<DLGroupContext *>(getContext("dlgroup", provider));
//QList<DLGroupSet> list = c->supportedGroupSets();
//delete c;
//return list;
}
bool DLGroup::isNull() const
@ -205,18 +419,20 @@ void PKey::assignToPrivate(PKey *dest) const
QList<PKey::Type> PKey::supportedTypes(const QString &provider)
{
const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", provider));
QList<Type> list = c->supportedTypes();
delete c;
return list;
return getList<Type, Getter_Type>(provider);
//const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", provider));
//QList<Type> list = c->supportedTypes();
//delete c;
//return list;
}
QList<PKey::Type> PKey::supportedIOTypes(const QString &provider)
{
const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", provider));
QList<Type> list = c->supportedIOTypes();
delete c;
return list;
return getList<Type, Getter_IOType>(provider);
//const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", provider));
//QList<Type> list = c->supportedIOTypes();
//delete c;
//return list;
}
bool PKey::isNull() const
@ -228,14 +444,12 @@ PKey::Type PKey::type() const
{
if(isNull())
return RSA; // some default so we don't explode
return static_cast<const PKeyContext *>(context())->type();
return static_cast<const PKeyContext *>(context())->key()->type();
}
int PKey::bitSize() const
{
const PKeyContext *kc = static_cast<const PKeyContext *>(context());
const PKeyBase *kb = static_cast<const PKeyBase *>(kc->key());
return kb->bits();
return static_cast<const PKeyContext *>(context())->key()->bits();
}
bool PKey::isRSA() const
@ -267,6 +481,11 @@ bool PKey::isPrivate() const
return static_cast<const PKeyContext *>(context())->key()->isPrivate();
}
bool PKey::canExport() const
{
return static_cast<const PKeyContext *>(context())->key()->canExport();
}
bool PKey::canKeyAgree() const
{
return isDH();
@ -450,26 +669,30 @@ bool PublicKey::toPEMFile(const QString &fileName) const
PublicKey PublicKey::fromDER(const QSecureArray &a, ConvertResult *result, const QString &provider)
{
PublicKey k;
return getKey<PublicKey, Getter_PublicKey<QSecureArray>, QSecureArray>(provider, a, QSecureArray(), result);
/*PublicKey k;
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", provider));
ConvertResult r = c->publicFromDER(a);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
return k;
return k;*/
}
PublicKey PublicKey::fromPEM(const QString &s, ConvertResult *result, const QString &provider)
{
PublicKey k;
return getKey<PublicKey, Getter_PublicKey<QString>, QString>(provider, s, QSecureArray(), result);
/*PublicKey k;
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", provider));
ConvertResult r = c->publicFromPEM(s);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
return k;
return k;*/
}
PublicKey PublicKey::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider)
@ -563,20 +786,74 @@ SymmetricKey PrivateKey::deriveKey(const PublicKey &theirs) const
QList<PBEAlgorithm> PrivateKey::supportedPBEAlgorithms(const QString &provider)
{
const PKeyContext *c = static_cast<const PKeyContext *>(getContext("pkey", provider));
QList<PBEAlgorithm> list = c->supportedPBEAlgorithms();
delete c;
return list;
return getList<PBEAlgorithm, Getter_PBE>(provider);
//QList<PBEAlgorithm> list = getList<PBEAlgorithm, Getter_PBE>(provider);
// single
/*if(!provider.isEmpty())
{
Provider *p = providerForName(provider);
if(p)
list = getPBEList(p);
}
// all
else
{
ProviderList pl = allProviders();
for(int n = 0; n < pl.count(); ++n)
list += getPBEList(pl[n]);
}*/
//return list;
}
QSecureArray PrivateKey::toDER(const QSecureArray &passphrase, PBEAlgorithm pbe) const
{
return static_cast<const PKeyContext *>(context())->privateToDER(passphrase, pbe);
QSecureArray out;
if(pbe == PBEDefault)
pbe = get_pbe_default();
Provider *p = providerForPBE(pbe);
if(!p)
return out;
const PKeyContext *cur = static_cast<const PKeyContext *>(context());
if(cur->provider() == p)
{
out = cur->privateToDER(passphrase, pbe);
}
else
{
PKeyContext *pk = static_cast<const PKeyContext *>(getContext("pkey", p));
if(pk->importKey(cur->key()))
out = pk->privateToDER(passphrase, pbe);
delete pk;
}
return out;
}
QString PrivateKey::toPEM(const QSecureArray &passphrase, PBEAlgorithm pbe) const
{
return static_cast<const PKeyContext *>(context())->privateToPEM(passphrase, pbe);
//return static_cast<const PKeyContext *>(context())->privateToPEM(passphrase, pbe);
QString out;
if(pbe == PBEDefault)
pbe = get_pbe_default();
Provider *p = providerForPBE(pbe);
if(!p)
return out;
const PKeyContext *cur = static_cast<const PKeyContext *>(context());
if(cur->provider() == p)
{
out = cur->privateToPEM(passphrase, pbe);
}
else
{
PKeyContext *pk = static_cast<const PKeyContext *>(getContext("pkey", p));
if(pk->importKey(cur->key()))
out = pk->privateToPEM(passphrase, pbe);
delete pk;
}
return out;
}
bool PrivateKey::toPEMFile(const QString &fileName, const QSecureArray &passphrase, PBEAlgorithm pbe) const
@ -586,26 +863,58 @@ bool PrivateKey::toPEMFile(const QString &fileName, const QSecureArray &passphra
PrivateKey PrivateKey::fromDER(const QSecureArray &a, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
{
PrivateKey k;
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", provider));
ConvertResult r = c->privateFromDER(a, passphrase);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
return k;
return getKey<PrivateKey, Getter_PrivateKey<QSecureArray>, QSecureArray>(provider, a, passphrase, result);
/*PrivateKey k;
// single
if(!provider.isEmpty())
{
Provider *p = providerForName(provider);
if(!p)
return k;
PKeyContext *c = static_cast<PKeyContext *>(p->createContext("pkey"));
if(!c)
return k;
ConvertResult r = c->privateFromDER(a, passphrase);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
}
// all
else
{
ProviderList pl = allProviders();
for(int n = 0; n < pl.count(); ++n)
{
PKeyContext *c = static_cast<PKeyContext *>(pl[n]->createContext("pkey"));
if(!c)
continue;
ConvertResult r = c->privateFromDER(a, passphrase);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
if(!k.isNull())
break;
}
}
return k;*/
}
PrivateKey PrivateKey::fromPEM(const QString &s, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
{
PrivateKey k;
return getKey<PrivateKey, Getter_PrivateKey<QString>, QString>(provider, s, passphrase, result);
/*PrivateKey k;
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", provider));
ConvertResult r = c->privateFromPEM(s, passphrase);
if(result)
*result = r;
if(r == ConvertGood)
k.change(c);
return k;
return k;*/
}
PrivateKey PrivateKey::fromPEMFile(const QString &fileName, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
@ -725,7 +1034,7 @@ PrivateKey KeyGenerator::createRSA(int bits, int exp, const QString &provider)
d->key = PrivateKey();
d->wasBlocking = d->blocking;
d->k = static_cast<RSAContext *>(getContext("rsa", provider));
d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()->name()));
d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()));
if(!d->blocking)
{
@ -749,7 +1058,7 @@ PrivateKey KeyGenerator::createDSA(const DLGroup &domain, const QString &provide
d->key = PrivateKey();
d->wasBlocking = d->blocking;
d->k = static_cast<DSAContext *>(getContext("dsa", provider));
d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()->name()));
d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()));
if(!d->blocking)
{
@ -773,7 +1082,7 @@ PrivateKey KeyGenerator::createDH(const DLGroup &domain, const QString &provider
d->key = PrivateKey();
d->wasBlocking = d->blocking;
d->k = static_cast<DHContext *>(getContext("dh", provider));
d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()->name()));
d->dest = static_cast<PKeyContext *>(getContext("pkey", d->k->provider()));
if(!d->blocking)
{
@ -833,7 +1142,7 @@ RSAPublicKey::RSAPublicKey(const QBigInteger &n, const QBigInteger &e, const QSt
{
RSAContext *k = static_cast<RSAContext *>(getContext("rsa", provider));
k->createPublic(n, e);
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()->name()));
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
c->setKey(k);
change(c);
}
@ -864,7 +1173,7 @@ RSAPrivateKey::RSAPrivateKey(const QBigInteger &n, const QBigInteger &e, const Q
{
RSAContext *k = static_cast<RSAContext *>(getContext("rsa", provider));
k->createPrivate(n, e, p, q, d);
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()->name()));
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
c->setKey(k);
change(c);
}
@ -905,7 +1214,7 @@ DSAPublicKey::DSAPublicKey(const DLGroup &domain, const QBigInteger &y, const QS
{
DSAContext *k = static_cast<DSAContext *>(getContext("dsa", provider));
k->createPublic(domain, y);
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()->name()));
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
c->setKey(k);
change(c);
}
@ -936,7 +1245,7 @@ DSAPrivateKey::DSAPrivateKey(const DLGroup &domain, const QBigInteger &y, const
{
DSAContext *k = static_cast<DSAContext *>(getContext("dsa", provider));
k->createPrivate(domain, y, x);
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()->name()));
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
c->setKey(k);
change(c);
}
@ -967,7 +1276,7 @@ DHPublicKey::DHPublicKey(const DLGroup &domain, const QBigInteger &y, const QStr
{
DHContext *k = static_cast<DHContext *>(getContext("dh", provider));
k->createPublic(domain, y);
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()->name()));
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
c->setKey(k);
change(c);
}
@ -998,7 +1307,7 @@ DHPrivateKey::DHPrivateKey(const DLGroup &domain, const QBigInteger &y, const QB
{
DHContext *k = static_cast<DHContext *>(getContext("dh", provider));
k->createPrivate(domain, y, x);
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()->name()));
PKeyContext *c = static_cast<PKeyContext *>(getContext("pkey", k->provider()));
c->setKey(k);
change(c);
}