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

keystore API for accessing system stores, smart cards, and pgp

svn path=/trunk/kdesupport/qca/; revision=401186
This commit is contained in:
Justin Karneges 2005-03-28 07:11:58 +00:00
parent 7033275a3a
commit ab508f9893
18 changed files with 966 additions and 265 deletions

6
TODO

@ -22,9 +22,12 @@
give all classes non-default ctors/dtors/copy/op=, and dpointers?
* finish API:
make systemstore work via keystore
pkey: ability to get the bitsize of a key
cert: subject/issuer key ids?
cert: use info as a multi-map?
pgp: get key types and bits?
dlgroup, symmetric key -> make these into provider objects, for smartcards?
qcaprovider.h
* build system:
@ -36,6 +39,7 @@
* finish code for APIs:
cert: rfc 2818 hostname validation
keystore
tls
sasl
securemessagesystem (consider thread issues)
@ -56,10 +60,8 @@
figure out why Valgrind reports so many memory leaks
* possibilities for the future:
smart cards (pkcs11/15)
xmldsig
xmlenc (sort of done already in cutestuff/xmlsec, but need to qca-ify)
advanced pgp functionality (full key info and ability to manipulate keyrings)
Key wrapping - RFC3217 and RFC3394
dtls (secure UDP)
quoted-printable TextFilter

@ -27,6 +27,7 @@
#include "qca_basic.h"
#include "qca_publickey.h"
#include "qca_cert.h"
#include "qca_keystore.h"
#include "qca_securelayer.h"
#include "qca_securemessage.h"
#include "qcaprovider.h"

@ -29,6 +29,8 @@
namespace QCA
{
class CertificateCollection;
/**
Certificate Request Format
*/
@ -78,6 +80,20 @@ namespace QCA
OCSPSigning
};
/**
Specify the intended usage of a certificate
*/
enum UsageMode
{
UsageAny = 0x00, ///< Any application, or unspecified
UsageTLSServer = 0x01, ///< server side of a TLS or SSL connection
UsageTLSClient = 0x02, ///< client side of a TLS or SSL connection
UsageCodeSigning = 0x04, ///< code signing certificate
UsageEmailProtection = 0x08, ///< email (S/MIME) certificate
UsageTimeStamping = 0x10, ///< time stamping certificate
UsageCRLSigning = 0x20 ///< certificate revocation list signing certificate
};
/**
The validity (or otherwise) of a certificate
*/
@ -164,6 +180,8 @@ namespace QCA
QSecureArray signature() const;
SignatureAlgorithm signatureAlgorithm() const;
Validity validate(const CertificateCollection &trusted, const CertificateCollection &untrusted, UsageMode u = UsageAny) const;
// import / export
QSecureArray toDER() const;
QString toPEM() const;
@ -279,48 +297,35 @@ namespace QCA
static CRL fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString());
};
class QCA_EXPORT Store : public Algorithm
// a bundle of Certificates and CRLs
class CertificateCollection
{
public:
enum TrustMode
{
Trusted,
Untrusted
};
CertificateCollection();
CertificateCollection(const CertificateCollection &from);
~CertificateCollection();
CertificateCollection & operator=(const CertificateCollection &from);
/**
Specify the intended usage of a certificate
*/
enum UsageMode
{
UsageAny = 0x00, ///< Any application, or unspecified
UsageTLSServer = 0x01, ///< server side of a TLS or SSL connection
UsageTLSClient = 0x02, ///< client side of a TLS or SSL connection
UsageCodeSigning = 0x04, ///< code signing certificate
UsageEmailProtection = 0x08, ///< email (S/MIME) certificate
UsageTimeStamping = 0x10, ///< time stamping certificate
UsageCRLSigning = 0x20 ///< certificate revocation list signing certificate
};
Store(const QString &provider = QString());
void addCertificate(const Certificate &cert, TrustMode t = Untrusted);
void addCertificate(const Certificate &cert);
void addCRL(const CRL &crl);
Validity validate(const Certificate &cert, UsageMode u = UsageAny) const;
QList<Certificate> certificates() const;
QList<CRL> crls() const;
void append(const CertificateCollection &other);
CertificateCollection operator+(const CertificateCollection &other) const;
CertificateCollection & operator+=(const CertificateCollection &other);
// import / export
static bool canUsePKCS7(const QString &provider = QString());
bool toPKCS7File(const QString &fileName) const;
bool toFlatTextFile(const QString &fileName) const;
static Store fromPKCS7File(const QString &fileName, TrustMode t = Untrusted, ConvertResult *result = 0, const QString &provider = QString());
static Store fromFlatTextFile(const QString &fileName, TrustMode t = Untrusted, ConvertResult *result = 0, const QString &provider = QString());
bool toFlatTextFile(const QString &fileName);
bool toPKCS7File(const QString &fileName, const QString &provider = QString());
static CertificateCollection fromFlatTextFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString());
static CertificateCollection fromPKCS7File(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString());
void append(const Store &a);
Store operator+(const Store &a) const;
Store & operator+=(const Store &a);
private:
class Private;
QSharedDataPointer<Private> d;
};
class QCA_EXPORT CertificateAuthority : public Algorithm
@ -336,14 +341,15 @@ namespace QCA
CRL updateCRL(const CRL &crl, const QList<CRLEntry> &entries, const QDateTime &nextUpdate) const;
};
class QCA_EXPORT PersonalBundle
// holds a certificate chain and an associated private key
class QCA_EXPORT KeyBundle
{
public:
PersonalBundle();
PersonalBundle(const QString &fileName, const QSecureArray &passphrase);
PersonalBundle(const PersonalBundle &from);
~PersonalBundle();
PersonalBundle & operator=(const PersonalBundle &from);
KeyBundle();
KeyBundle(const QString &fileName, const QSecureArray &passphrase);
KeyBundle(const KeyBundle &from);
~KeyBundle();
KeyBundle & operator=(const KeyBundle &from);
bool isNull() const;
@ -356,12 +362,49 @@ namespace QCA
// import / export
QByteArray toArray(const QSecureArray &passphrase, const QString &provider = QString()) const;
bool toFile(const QString &fileName, const QSecureArray &passphrase, const QString &provider = QString()) const;
static PersonalBundle fromArray(const QByteArray &a, const QSecureArray &passphrase, ConvertResult *result = 0, const QString &provider = QString());
static PersonalBundle fromFile(const QString &fileName, const QSecureArray &passphrase, ConvertResult *result = 0, const QString &provider = QString());
static KeyBundle fromArray(const QByteArray &a, const QSecureArray &passphrase, ConvertResult *result = 0, const QString &provider = QString());
static KeyBundle fromFile(const QString &fileName, const QSecureArray &passphrase, ConvertResult *result = 0, const QString &provider = QString());
private:
class Private;
Private *d;
QSharedDataPointer<Private> d;
};
// PGPKey can either reference an item in a real PGP keyring or can
// be made by calling a "from" function. Note that with the latter
// method, the key is of no use besides being informational. The
// key must be in a keyring (inKeyring() == true) to actually do
// crypto with it.
class QCA_EXPORT PGPKey : public Algorithm
{
public:
PGPKey();
PGPKey(const QString &fileName);
PGPKey(const PGPKey &from);
~PGPKey();
PGPKey & operator=(const PGPKey &from);
bool isNull() const;
QString keyId() const;
QString primaryUserId() const;
QStringList userIds() const;
bool havePrivate() const;
QDateTime creationDate() const;
QDateTime expirationDate() const;
QString fingerprint() const;
bool inKeyring() const;
bool isTrusted() const;
// import / export
QSecureArray toArray() const;
QString toString() const;
bool toFile(const QString &fileName) const;
static PGPKey fromArray(const QSecureArray &a, ConvertResult *result = 0, const QString &provider = QString());
static PGPKey fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString());
static PGPKey fromFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString());
};
}

@ -39,7 +39,8 @@ namespace QCA
{
class Provider;
class Random;
class Store;
class CertificateCollection;
class KeyStoreManager;
/**
* Convenience representation for the plugin providers
@ -323,11 +324,16 @@ namespace QCA
*/
QCA_EXPORT void setGlobalRNG(const QString &provider);
/**
Return a reference to the KeyStoreManager, which is used to interface with
system storage, PGP keyrings, and smart cards.
*/
QCA_EXPORT KeyStoreManager *keyStoreManager();
/**
Test if QCA can access the root CA certificates
QCA supports the concept of a Store, containing certificates.
If those certificates are available, this function returns true,
If root certificates are available, this function returns true,
otherwise it returns false.
\sa systemStore
@ -337,11 +343,11 @@ namespace QCA
/**
Get system-wide root CA certificates
\param provider a specific provider to generate the Store, if required
\param provider a specific provider to generate the CertificateCollection, if required
\sa haveSystemStore
*/
QCA_EXPORT Store systemStore(const QString &provider = QString());
QCA_EXPORT CertificateCollection systemStore(const QString &provider = QString());
/**
* Get the application name that will be used by SASL server mode

@ -0,0 +1,124 @@
/*
* qca_keystore.h - Qt Cryptographic Architecture
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef QCA_KEYSTORE_H
#define QCA_KEYSTORE_H
#include "qca_core.h"
#include "qca_cert.h"
namespace QCA
{
// container for any kind of object in a keystore
class QCA_EXPORT KeyStoreEntry : public Algorithm
{
public:
enum Type
{
TypeKeyBundle,
TypeCertificate,
TypeCRL,
TypePGPSecretKey,
TypePGPPublicKey
};
KeyStoreEntry();
KeyStoreEntry(const KeyStoreEntry &from);
~KeyStoreEntry();
KeyStoreEntry & operator=(const KeyStoreEntry &from);
bool isNull() const;
Type type() const;
QString name() const;
QString id() const;
KeyBundle keyBundle() const;
Certificate certificate() const;
CRL crl() const;
PGPKey pgpSecretKey() const;
PGPKey pgpPublicKey() const;
};
/*
systemstore: System TrustedCertificates
accepted self-signed: Application TrustedCertificates
apple keychain: User Identities
smartcard: SmartCard Identities
gnupg: PGPKeyring Identities,PGPPublicKeys
*/
class QCA_EXPORT KeyStore : public Algorithm
{
public:
enum Type
{
System, // root certs
User, // Apple Keychain, KDE Wallet, and others
Application, // for caching accepted self-signed certs
SmartCard, // smartcards
PGPKeyring // pgp keyring
};
KeyStore();
KeyStore(const KeyStore &from);
~KeyStore();
KeyStore & operator=(const KeyStore &from);
bool isNull() const;
Type type() const;
QString name() const;
QString id() const;
bool isReadOnly() const;
QList<KeyStoreEntry> entryList() const;
bool containsTrustedCertificates() const; // Certificate and CRL
bool containsIdentities() const; // KeyBundle and PGPSecretKey
bool containsPGPPublicKeys() const; // PGPPublicKey
bool writeEntry(const KeyBundle &kb);
bool writeEntry(const Certificate &cert);
bool writeEntry(const CRL &crl);
PGPKey writeEntry(const PGPKey &key); // returns a ref to the key in the keyring
bool removeEntry(const QString &id);
};
// use this to get access to keystores and monitor for their activity
class QCA_EXPORT KeyStoreManager : public QObject
{
Q_OBJECT
public:
KeyStore keyStore(const QString &id) const;
QList<KeyStore> keyStores() const;
int count() const;
signals:
void keyStoreAvailable(const QString &id);
void keyStoreUnavailable(const QString &id);
void keyStoreUpdated(const QString &id);
private:
KeyStoreManager();
~KeyStoreManager();
};
}
#endif

@ -129,7 +129,7 @@ namespace QCA
static QStringList supportedCipherSuites(const QString &provider = QString());
void setCertificate(const CertificateChain &cert, const PrivateKey &key);
void setStore(const Store &store);
void setTrustedCertificates(const CertificateCollection &trusted);
void setConstraints(SecurityLevel s);
void setConstraints(int minSSF, int maxSSF);
void setConstraints(const QStringList &cipherSuiteList);

@ -219,7 +219,7 @@ namespace QCA
SMIME(QObject *parent = 0, const QString &provider = QString());
~SMIME();
void setStore(const Store &store);
void setTrustedCertificates(const CertificateCollection &trusted); // todo: untrusted?
void setPrivateKeys(const QList<PrivateKey> &keys);
};
}

@ -266,6 +266,8 @@ public:
SignatureAlgorithm sigalgo;
};
class CRLContext;
class CertContext : public CertBase
{
public:
@ -274,6 +276,9 @@ public:
virtual bool createSelfSigned(const CertificateOptions &opts, const PKeyContext &priv) = 0;
virtual const CertContextProps *props() const = 0;
virtual PKeyContext *subjectPublicKey() const = 0; // caller must delete
// ownership of items IS NOT passed
virtual Validity validate(const QList<CertContext*> &trusted, const QList<CertContext*> &untrusted, const QList<CRLContext *> &crls, UsageMode u) const = 0;
};
class CSRContext : public CertBase
@ -297,22 +302,16 @@ public:
virtual const CRLContextProps *props() const = 0;
};
class StoreContext : public Provider::Context
class CertCollectionContext : public Provider::Context
{
public:
StoreContext(Provider *p) : Provider::Context(p, "store") {}
CertCollectionContext(Provider *p) : Provider::Context(p, "certcollection") {}
virtual void addCertificate(const CertContext &cert, Store::TrustMode t) = 0;
virtual void addCRL(const CRLContext &crl) = 0;
virtual Validity validate(const CertContext &cert, Store::UsageMode u) const = 0;
virtual QList<CertContext*> certificates() const = 0; // caller must delete
virtual QList<CRLContext*> crls() const = 0; // caller must delete
virtual void append(const StoreContext &s) = 0;
// ownership of items IS NOT passed
virtual QByteArray toPKCS7(const QList<CertContext*> &certs, const QList<CRLContext*> &crls) const = 0;
// import / export
virtual bool canUsePKCS7() const = 0;
virtual QByteArray toPKCS7() const = 0;
virtual ConvertResult fromPKCS7(const QByteArray &a, Store::TrustMode t) = 0;
// ownership of items IS passed
virtual ConvertResult fromPKCS7(const QByteArray &a, QList<CertContext*> *certs, QList<CRLContext*> *crls) const = 0;
};
class CAContext : public Provider::Context
@ -341,6 +340,18 @@ public:
virtual ConvertResult fromPKCS12(const QByteArray &in, const QSecureArray &passphrase, QString *name, QList<CertContext*> *chain, PKeyContext **priv) const = 0;
};
class KeyStoreContext : public Provider::Context
{
public:
KeyStoreContext(Provider *p) : Provider::Context(p, "keystore") {}
};
class KeyStoreListContext : public Provider::Context
{
public:
KeyStoreListContext(Provider *p) : Provider::Context(p, "keystorelist") {}
};
class TLSContext : public Provider::Context
{
public:
@ -348,8 +359,8 @@ public:
TLSContext(Provider *p) : Provider::Context(p, "tls") {}
virtual void reset() = 0;
virtual bool startClient(const StoreContext &store, const CertContext &cert, const PKeyContext &key) = 0;
virtual bool startServer(const StoreContext &store, const CertContext &cert, const PKeyContext &key) = 0;
virtual bool startClient(const QList<CertContext*> &trusted, const QList<CRLContext*> &crls, const CertContext &cert, const PKeyContext &key) = 0;
virtual bool startServer(const QList<CertContext*> &trusted, const QList<CRLContext*> &crls, const CertContext &cert, const PKeyContext &key) = 0;
virtual int handshake(const QByteArray &in, QByteArray *out) = 0;
virtual int shutdown(const QByteArray &in, QByteArray *out) = 0;

@ -2723,6 +2723,9 @@ public:
return kc;
}
// implemented later because it depends on MyCRLContext
virtual QCA::Validity validate(const QList<QCA::CertContext*> &trusted, const QList<QCA::CertContext*> &untrusted, const QList<QCA::CRLContext *> &crls, QCA::UsageMode u) const;
void make_props()
{
X509 *x = item.cert;
@ -3074,10 +3077,88 @@ public:
}
};
static bool usage_check(const MyCertContext &cc, QCA::UsageMode u)
{
// TODO: check usage
Q_UNUSED(cc);
Q_UNUSED(u);
return true;
}
QCA::Validity MyCertContext::validate(const QList<QCA::CertContext*> &trusted, const QList<QCA::CertContext*> &untrusted, const QList<QCA::CRLContext *> &crls, QCA::UsageMode u) const
{
STACK_OF(X509) *trusted_list = sk_X509_new_null();
STACK_OF(X509) *untrusted_list = sk_X509_new_null();
QList<X509_CRL*> crl_list;
int n;
for(n = 0; n < trusted.count(); ++n)
{
const MyCertContext *cc = static_cast<const MyCertContext *>(trusted[n]);
X509 *x = cc->item.cert;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
sk_X509_push(trusted_list, x);
}
for(n = 0; n < untrusted.count(); ++n)
{
const MyCertContext *cc = static_cast<const MyCertContext *>(untrusted[n]);
X509 *x = cc->item.cert;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
sk_X509_push(untrusted_list, x);
}
for(n = 0; n < crls.count(); ++n)
{
const MyCRLContext *cc = static_cast<const MyCRLContext *>(crls[n]);
X509_CRL *x = cc->item.crl;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
crl_list.append(x);
}
const MyCertContext *cc = this;
X509 *x = cc->item.cert;
// verification happens through a store "context"
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
// make a store of crls
X509_STORE *store = X509_STORE_new();
for(int n = 0; n < crl_list.count(); ++n)
X509_STORE_add_crl(store, crl_list[n]);
// the first initialization handles untrusted certs, crls, and target cert
X509_STORE_CTX_init(ctx, store, x, untrusted_list);
// this initializes the trusted certs
X509_STORE_CTX_trusted_stack(ctx, trusted_list);
// verify!
int ret = X509_verify_cert(ctx);
int err = -1;
if(!ret)
err = ctx->error;
// cleanup
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
sk_X509_pop_free(trusted_list, X509_free);
sk_X509_pop_free(untrusted_list, X509_free);
for(int n = 0; n < crl_list.count(); ++n)
X509_CRL_free(crl_list[n]);
if(!ret)
return convert_verify_error(err);
if(!usage_check(*cc, u))
return QCA::ErrorInvalidPurpose;
return QCA::ValidityGood;
}
//----------------------------------------------------------------------------
// MyStoreContext
//----------------------------------------------------------------------------
class MyStoreContext : public QCA::StoreContext
/*class MyStoreContext : public QCA::StoreContext
{
public:
STACK_OF(X509) *trusted, *untrusted;
@ -3282,7 +3363,7 @@ public:
Q_UNUSED(u);
return true;
}
};
};*/
class opensslCipherContext : public QCA::CipherContext
{
@ -3547,8 +3628,8 @@ public:
return new MyCSRContext( this );
else if ( type == "crl" )
return new MyCRLContext( this );
else if ( type == "store" )
return new MyStoreContext( this );
//else if ( type == "store" )
// return new MyStoreContext( this );
return 0;
}
};

@ -36,6 +36,7 @@ PUBLIC_HEADERS += \
$$QCA_INC/qca_basic.h \
$$QCA_INC/qca_publickey.h \
$$QCA_INC/qca_cert.h \
$$QCA_INC/qca_keystore.h \
$$QCA_INC/qca_securelayer.h \
$$QCA_INC/qca_securemessage.h \
$$QCA_INC/qcaprovider.h \
@ -50,6 +51,7 @@ SOURCES += \
$$QCA_CPP/qca_basic.cpp \
$$QCA_CPP/qca_publickey.cpp \
$$QCA_CPP/qca_cert.cpp \
$$QCA_CPP/qca_keystore.cpp \
$$QCA_CPP/qca_securelayer.cpp \
$$QCA_CPP/qca_securemessage.cpp \
$$QCA_CPP/qca_default.cpp

@ -343,6 +343,36 @@ SignatureAlgorithm Certificate::signatureAlgorithm() const
return static_cast<const CertContext *>(context())->props()->sigalgo;
}
Validity Certificate::validate(const CertificateCollection &trusted, const CertificateCollection &untrusted, UsageMode u) const
{
QList<CertContext*> trusted_list;
QList<CertContext*> untrusted_list;
QList<CRLContext*> crl_list;
QList<Certificate> trusted_certs = trusted.certificates();
QList<Certificate> untrusted_certs = untrusted.certificates();
QList<CRL> crls = trusted.crls() + untrusted.crls();
int n;
for(n = 0; n < trusted_certs.count(); ++n)
{
CertContext *c = static_cast<CertContext *>(trusted_certs[n].context());
trusted_list += c;
}
for(n = 0; n < untrusted_certs.count(); ++n)
{
CertContext *c = static_cast<CertContext *>(untrusted_certs[n].context());
untrusted_list += c;
}
for(n = 0; n < crls.count(); ++n)
{
CRLContext *c = static_cast<CRLContext *>(crls[n].context());
crl_list += c;
}
return static_cast<const CertContext *>(context())->validate(trusted_list, untrusted_list, crl_list, u);
}
QSecureArray Certificate::toDER() const
{
return static_cast<const CertContext *>(context())->toDER();
@ -717,11 +747,15 @@ CRL CRL::fromPEM(const QString &s, ConvertResult *result, const QString &provide
//----------------------------------------------------------------------------
// Store
//----------------------------------------------------------------------------
static QString readNextPem(QTextStream *ts)
// TODO: support CRLs
// CRL / X509 CRL
// CERTIFICATE / X509 CERTIFICATE
static QString readNextPem(QTextStream *ts, bool *isCRL)
{
QString pem;
bool found = false;
bool done = false;
*isCRL = false;
while(!ts->atEnd())
{
QString line = ts->readLine();
@ -748,139 +782,190 @@ static QString readNextPem(QTextStream *ts)
return pem;
}
Store::Store(const QString &provider)
:Algorithm("store", provider)
class CertificateCollection::Private : public QSharedData
{
public:
QList<Certificate> certs;
QList<CRL> crls;
};
CertificateCollection::CertificateCollection()
:d(new Private)
{
}
void Store::addCertificate(const Certificate &cert, TrustMode t)
CertificateCollection::CertificateCollection(const CertificateCollection &from)
:d(from.d)
{
static_cast<StoreContext *>(context())->addCertificate(*(static_cast<const CertContext *>(cert.context())), t);
}
void Store::addCRL(const CRL &crl)
CertificateCollection::~CertificateCollection()
{
static_cast<StoreContext *>(context())->addCRL(*(static_cast<const CRLContext *>(crl.context())));
}
Validity Store::validate(const Certificate &cert, UsageMode u) const
CertificateCollection & CertificateCollection::operator=(const CertificateCollection &from)
{
return static_cast<const StoreContext *>(context())->validate(*(static_cast<const CertContext *>(cert.context())), u);
d = from.d;
return *this;
}
QList<Certificate> Store::certificates() const
void CertificateCollection::addCertificate(const Certificate &cert)
{
QList<CertContext *> in = static_cast<const StoreContext *>(context())->certificates();
QList<Certificate> out;
for(int n = 0; n < in.count(); ++n)
{
Certificate cert;
cert.change(in[n]);
out.append(cert);
}
return out;
d->certs.append(cert);
}
QList<CRL> Store::crls() const
void CertificateCollection::addCRL(const CRL &crl)
{
QList<CRLContext *> in = static_cast<const StoreContext *>(context())->crls();
QList<CRL> out;
for(int n = 0; n < in.count(); ++n)
{
CRL crl;
crl.change(in[n]);
out.append(crl);
}
return out;
d->crls.append(crl);
}
bool Store::canUsePKCS7(const QString &provider)
QList<Certificate> CertificateCollection::certificates() const
{
StoreContext *c = static_cast<StoreContext *>(getContext("store", provider));
bool ok = c->canUsePKCS7();
return d->certs;
}
QList<CRL> CertificateCollection::crls() const
{
return d->crls;
}
void CertificateCollection::append(const CertificateCollection &other)
{
d->certs += other.d->certs;
d->crls += other.d->crls;
}
CertificateCollection CertificateCollection::operator+(const CertificateCollection &other) const
{
CertificateCollection c = *this;
c.append(other);
return c;
}
CertificateCollection & CertificateCollection::operator+=(const CertificateCollection &other)
{
append(other);
return *this;
}
bool CertificateCollection::canUsePKCS7(const QString &provider)
{
CertCollectionContext *c = static_cast<CertCollectionContext *>(getContext("certcollection", provider));
bool ok = c ? true : false;
delete c;
return ok;
}
bool Store::toPKCS7File(const QString &fileName) const
{
return arrayToFile(fileName, static_cast<const StoreContext *>(context())->toPKCS7());
}
bool Store::toFlatTextFile(const QString &fileName) const
bool CertificateCollection::toFlatTextFile(const QString &fileName)
{
QFile f(fileName);
if(!f.open(QFile::WriteOnly))
return false;
QList<CertContext *> in = static_cast<const StoreContext *>(context())->certificates();
QTextStream ts(&f);
for(int n = 0; n < in.count(); ++n)
ts << in[n]->toPEM();
qDeleteAll(in);
int n;
for(n = 0; n < d->certs.count(); ++n)
ts << d->certs[n].toPEM();
for(n = 0; n < d->crls.count(); ++n)
ts << d->crls[n].toPEM();
return true;
}
Store Store::fromPKCS7File(const QString &fileName, TrustMode t, ConvertResult *result, const QString &provider)
bool CertificateCollection::toPKCS7File(const QString &fileName, const QString &provider)
{
QByteArray der;
if(!arrayFromFile(fileName, &der))
CertCollectionContext *col = static_cast<CertCollectionContext *>(getContext("certcollection", provider));
QList<CertContext*> cert_list;
QList<CRLContext*> crl_list;
int n;
for(n = 0; n < d->certs.count(); ++n)
{
if(result)
*result = ErrorFile;
return Store();
CertContext *c = static_cast<CertContext *>(d->certs[n].context());
cert_list += c;
}
for(n = 0; n < d->crls.count(); ++n)
{
CRLContext *c = static_cast<CRLContext *>(d->crls[n].context());
crl_list += c;
}
Store store;
StoreContext *c = static_cast<StoreContext *>(getContext("store", provider));
ConvertResult r = c->fromPKCS7(der, t);
if(result)
*result = r;
if(r == ConvertGood)
store.change(c);
return store;
QByteArray result = col->toPKCS7(cert_list, crl_list);
delete col;
return arrayToFile(fileName, result);
}
Store Store::fromFlatTextFile(const QString &fileName, TrustMode t, ConvertResult *result, const QString &provider)
CertificateCollection CertificateCollection::fromFlatTextFile(const QString &fileName, ConvertResult *result, const QString &provider)
{
QFile f(fileName);
if(!f.open(QFile::ReadOnly))
{
if(result)
*result = ErrorFile;
return Store();
return CertificateCollection();
}
Store store(provider);
CertificateCollection certs;
QTextStream ts(&f);
while(1)
{
QString pem = readNextPem(&ts);
bool isCRL;
QString pem = readNextPem(&ts, &isCRL);
if(pem.isNull())
break;
Certificate cert = Certificate::fromPEM(pem, 0, store.provider()->name());
if(!cert.isNull())
store.addCertificate(cert, t);
if(isCRL)
{
CRL c = CRL::fromPEM(pem, 0, provider);
if(!c.isNull())
certs.addCRL(c);
}
else
{
Certificate c = Certificate::fromPEM(pem, 0, provider);
if(!c.isNull())
certs.addCertificate(c);
}
}
return store;
return certs;
}
void Store::append(const Store &a)
CertificateCollection CertificateCollection::fromPKCS7File(const QString &fileName, ConvertResult *result, const QString &provider)
{
static_cast<StoreContext *>(context())->append(*(static_cast<const StoreContext *>(a.context())));
}
QByteArray der;
if(!arrayFromFile(fileName, &der))
{
if(result)
*result = ErrorFile;
return CertificateCollection();
}
Store Store::operator+(const Store &a) const
{
Store s = *this;
s.append(a);
return s;
}
CertificateCollection certs;
Store & Store::operator+=(const Store &a)
{
append(a);
return *this;
QList<CertContext*> cert_list;
QList<CRLContext*> crl_list;
CertCollectionContext *col = static_cast<CertCollectionContext *>(getContext("certcollection", provider));
ConvertResult r = col->fromPKCS7(der, &cert_list, &crl_list);
delete col;
if(result)
*result = r;
if(r == ConvertGood)
{
int n;
for(n = 0; n < cert_list.count(); ++n)
{
Certificate c;
c.change(cert_list[n]);
certs.addCertificate(c);
}
for(n = 0; n < crl_list.count(); ++n)
{
CRL c;
c.change(crl_list[n]);
certs.addCRL(c);
}
}
return certs;
}
//----------------------------------------------------------------------------
@ -927,9 +1012,9 @@ CRL CertificateAuthority::updateCRL(const CRL &crl, const QList<CRLEntry> &entri
}
//----------------------------------------------------------------------------
// PersonalBundle
// KeyBundle
//----------------------------------------------------------------------------
class PersonalBundle::Private
class KeyBundle::Private : public QSharedData
{
public:
QString name;
@ -937,65 +1022,64 @@ public:
PrivateKey key;
};
PersonalBundle::PersonalBundle()
KeyBundle::KeyBundle()
:d(new Private)
{
d = new Private;
}
PersonalBundle::PersonalBundle(const QString &fileName, const QSecureArray &passphrase)
KeyBundle::KeyBundle(const QString &fileName, const QSecureArray &passphrase)
:d(new Private)
{
d = new Private;
*this = fromFile(fileName, passphrase, 0, QString());
}
PersonalBundle::PersonalBundle(const PersonalBundle &from)
KeyBundle::KeyBundle(const KeyBundle &from)
:d(from.d)
{
d = new Private(*from.d);
}
PersonalBundle::~PersonalBundle()
KeyBundle::~KeyBundle()
{
delete d;
}
PersonalBundle & PersonalBundle::operator=(const PersonalBundle &from)
KeyBundle & KeyBundle::operator=(const KeyBundle &from)
{
*d = *from.d;
d = from.d;
return *this;
}
bool PersonalBundle::isNull() const
bool KeyBundle::isNull() const
{
return d->chain.isEmpty();
}
QString PersonalBundle::name() const
QString KeyBundle::name() const
{
return d->name;
}
CertificateChain PersonalBundle::certificateChain() const
CertificateChain KeyBundle::certificateChain() const
{
return d->chain;
}
PrivateKey PersonalBundle::privateKey() const
PrivateKey KeyBundle::privateKey() const
{
return d->key;
}
void PersonalBundle::setName(const QString &s)
void KeyBundle::setName(const QString &s)
{
d->name = s;
}
void PersonalBundle::setCertificateChainAndKey(const CertificateChain &c, const PrivateKey &key)
void KeyBundle::setCertificateChainAndKey(const CertificateChain &c, const PrivateKey &key)
{
d->chain = c;
d->key = key;
}
QByteArray PersonalBundle::toArray(const QSecureArray &passphrase, const QString &provider) const
QByteArray KeyBundle::toArray(const QSecureArray &passphrase, const QString &provider) const
{
PIXContext *pix = static_cast<PIXContext *>(getContext("pix", provider));
@ -1008,18 +1092,18 @@ QByteArray PersonalBundle::toArray(const QSecureArray &passphrase, const QString
return buf;
}
bool PersonalBundle::toFile(const QString &fileName, const QSecureArray &passphrase, const QString &provider) const
bool KeyBundle::toFile(const QString &fileName, const QSecureArray &passphrase, const QString &provider) const
{
return arrayToFile(fileName, toArray(passphrase, provider));
}
PersonalBundle PersonalBundle::fromArray(const QByteArray &a, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
KeyBundle KeyBundle::fromArray(const QByteArray &a, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
{
QString name;
QList<CertContext *> list;
PKeyContext *kc = 0;
PersonalBundle bundle;
KeyBundle bundle;
PIXContext *pix = static_cast<PIXContext *>(getContext("pix", provider));
ConvertResult r = pix->fromPKCS12(a, passphrase, &name, &list, &kc);
if(result)
@ -1038,16 +1122,134 @@ PersonalBundle PersonalBundle::fromArray(const QByteArray &a, const QSecureArray
return bundle;
}
PersonalBundle PersonalBundle::fromFile(const QString &fileName, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
KeyBundle KeyBundle::fromFile(const QString &fileName, const QSecureArray &passphrase, ConvertResult *result, const QString &provider)
{
QByteArray der;
if(!arrayFromFile(fileName, &der))
{
if(result)
*result = ErrorFile;
return PersonalBundle();
return KeyBundle();
}
return fromArray(der, passphrase, result, provider);
}
//----------------------------------------------------------------------------
// PGPKey
//----------------------------------------------------------------------------
// TODO
PGPKey::PGPKey()
{
}
PGPKey::PGPKey(const QString &fileName)
{
Q_UNUSED(fileName);
}
PGPKey::PGPKey(const PGPKey &from)
:Algorithm(from)
{
}
PGPKey::~PGPKey()
{
}
PGPKey & PGPKey::operator=(const PGPKey &from)
{
Algorithm::operator=(from);
return *this;
}
bool PGPKey::isNull() const
{
return false;
}
QString PGPKey::keyId() const
{
return QString();
}
QString PGPKey::primaryUserId() const
{
return QString();
}
QStringList PGPKey::userIds() const
{
return QStringList();
}
bool PGPKey::havePrivate() const
{
return false;
}
QDateTime PGPKey::creationDate() const
{
return QDateTime();
}
QDateTime PGPKey::expirationDate() const
{
return QDateTime();
}
QString PGPKey::fingerprint() const
{
return QString();
}
bool PGPKey::inKeyring() const
{
return false;
}
bool PGPKey::isTrusted() const
{
return false;
}
QSecureArray PGPKey::toArray() const
{
return QSecureArray();
}
QString PGPKey::toString() const
{
return QString();
}
bool PGPKey::toFile(const QString &fileName) const
{
Q_UNUSED(fileName);
return false;
}
PGPKey PGPKey::fromArray(const QSecureArray &a, ConvertResult *result, const QString &provider)
{
Q_UNUSED(a);
Q_UNUSED(result);
Q_UNUSED(provider);
return PGPKey();
}
PGPKey PGPKey::fromString(const QString &s, ConvertResult *result, const QString &provider)
{
Q_UNUSED(s);
Q_UNUSED(result);
Q_UNUSED(provider);
return PGPKey();
}
PGPKey PGPKey::fromFile(const QString &fileName, ConvertResult *result, const QString &provider)
{
Q_UNUSED(fileName);
Q_UNUSED(result);
Q_UNUSED(provider);
return PGPKey();
}
}

@ -25,6 +25,7 @@
#include "qca_plugin.h"
#include "qca_textfilter.h"
#include "qca_cert.h"
#include "qca_keystore.h"
#include "qcaprovider.h"
#ifndef QCA_NO_SYSTEMSTORE
@ -43,12 +44,30 @@ Provider *create_default_provider();
//----------------------------------------------------------------------------
// Global
//----------------------------------------------------------------------------
static QMutex *manager_mutex = 0;
static QString *app_name = 0;
static QCA::ProviderManager *manager = 0;
static QCA::Random *global_rng = 0;
static bool qca_init = false;
static bool qca_secmem = false;
class Global
{
public:
bool secmem;
QString app_name;
QMutex manager_mutex;
ProviderManager manager;
Random *rng;
KeyStoreManager *ksm;
Global()
{
rng = 0;
ksm = 0;
secmem = false;
}
~Global()
{
delete rng;
}
};
static Global *global = 0;
static bool features_have(const QStringList &have, const QStringList &want)
{
@ -62,7 +81,7 @@ static bool features_have(const QStringList &have, const QStringList &want)
void init()
{
if(qca_init)
if(global)
return;
init(Practical, 64);
@ -70,11 +89,9 @@ void init()
void init(MemoryMode mode, int prealloc)
{
if(qca_init)
if(global)
return;
qca_init = true;
bool allow_mmap_fallback = false;
bool drop_root = false;
if(mode == Practical)
@ -85,7 +102,7 @@ void init(MemoryMode mode, int prealloc)
else if(mode == Locking)
drop_root = true;
qca_secmem = botan_init(prealloc, allow_mmap_fallback);
bool secmem = botan_init(prealloc, allow_mmap_fallback);
if(drop_root)
{
@ -94,55 +111,43 @@ void init(MemoryMode mode, int prealloc)
#endif
}
manager_mutex = new QMutex;
manager = new ProviderManager;
manager->setDefault(create_default_provider()); // manager owns it
app_name = new QString;
global = new Global;
global->secmem = secmem;
global->manager.setDefault(create_default_provider()); // manager owns it
}
void deinit()
{
if(!qca_init)
if(!global)
return;
delete global_rng;
global_rng = 0;
delete app_name;
app_name = 0;
delete manager;
manager = 0;
delete manager_mutex;
manager_mutex = 0;
delete global;
global = 0;
botan_deinit();
qca_secmem = false;
qca_init = false;
}
bool haveSecureMemory()
{
return qca_secmem;
if(!global)
return false;
return global->secmem;
}
bool isSupported(const QStringList &features)
{
if(!qca_init)
if(!global)
return false;
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
if(features_have(manager->allFeatures(), features))
if(features_have(global->manager.allFeatures(), features))
return true;
// ok, try scanning for new stuff
manager->scan();
global->manager.scan();
if(features_have(manager->allFeatures(), features))
if(features_have(global->manager.allFeatures(), features))
return true;
return false;
@ -157,95 +162,100 @@ QStringList supportedFeatures()
{
init();
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
// query all features
manager->scan();
return manager->allFeatures();
global->manager.scan();
return global->manager.allFeatures();
}
QStringList defaultFeatures()
{
init();
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
return manager->find("default")->features();
return global->manager.find("default")->features();
}
bool insertProvider(Provider *p, int priority)
{
init();
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
return manager->add(p, priority);
return global->manager.add(p, priority);
}
void setProviderPriority(const QString &name, int priority)
{
if(!qca_init)
if(!global)
return;
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
manager->changePriority(name, priority);
global->manager.changePriority(name, priority);
}
int providerPriority(const QString &name)
{
if(!qca_init)
if(!global)
return -1;
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
return manager->getPriority(name);
return global->manager.getPriority(name);
}
const ProviderList & providers()
{
init();
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
return manager->providers();
return global->manager.providers();
}
void scanForPlugins()
{
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
manager->scan();
global->manager.scan();
}
void unloadAllPlugins()
{
if(!qca_init)
if(!global)
return;
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
// if the global_rng was owned by a plugin, then delete it
if(global_rng && (global_rng->provider() != manager->find("default")))
if(global->rng && (global->rng->provider() != global->manager.find("default")))
{
delete global_rng;
global_rng = 0;
delete global->rng;
global->rng = 0;
}
manager->unloadAll();
global->manager.unloadAll();
}
Random & globalRNG()
{
if(!global_rng)
global_rng = new Random;
return *global_rng;
if(!global->rng)
global->rng = new Random;
return *global->rng;
}
void setGlobalRNG(const QString &provider)
{
delete global_rng;
global_rng = new Random(provider);
delete global->rng;
global->rng = new Random(provider);
}
KeyStoreManager *keyStoreManager()
{
return global->ksm;
}
bool haveSystemStore()
@ -257,27 +267,27 @@ bool haveSystemStore()
#endif
}
Store systemStore(const QString &provider)
CertificateCollection systemStore(const QString &provider)
{
#ifndef QCA_NO_SYSTEMSTORE
return qca_get_systemstore(provider);
#else
return Store(provider);
return CertificateCollection();
#endif
}
QString appName()
{
if(!qca_init)
if(!global)
return QString();
return *app_name;
return global->app_name;
}
void setAppName(const QString &s)
{
if(!qca_init)
if(!global)
return;
*app_name = s;
global->app_name = s;
}
QString arrayToHex(const QSecureArray &a)
@ -292,33 +302,33 @@ QByteArray hexToArray(const QString &str)
static Provider *getProviderForType(const QString &type, const QString &provider)
{
QMutexLocker lock(manager_mutex);
QMutexLocker lock(&global->manager_mutex);
Provider *p = 0;
bool scanned = false;
if(!provider.isEmpty())
{
// try using specific provider
p = manager->findFor(provider, type);
p = global->manager.findFor(provider, type);
if(!p)
{
// maybe this provider is new, so scan and try again
manager->scan();
global->manager.scan();
scanned = true;
p = manager->findFor(provider, type);
p = global->manager.findFor(provider, type);
}
}
if(!p)
{
// try using some other provider
p = manager->findFor(QString(), type);
p = global->manager.findFor(QString(), type);
if((!p || p->name() == "default") && !scanned)
{
// maybe there are new providers, so scan and try again
// before giving up or using default
manager->scan();
global->manager.scan();
scanned = true;
p = manager->findFor(QString::null, type);
p = global->manager.findFor(QString(), type);
}
}

217
src/qca_keystore.cpp Normal file

@ -0,0 +1,217 @@
/*
* qca_keystore.cpp - Qt Cryptographic Architecture
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "qca_keystore.h"
namespace QCA {
//----------------------------------------------------------------------------
// KeyStoreEntry
//----------------------------------------------------------------------------
KeyStoreEntry::KeyStoreEntry()
{
}
KeyStoreEntry::KeyStoreEntry(const KeyStoreEntry &from)
:Algorithm(from)
{
}
KeyStoreEntry::~KeyStoreEntry()
{
}
KeyStoreEntry & KeyStoreEntry::operator=(const KeyStoreEntry &from)
{
Algorithm::operator=(from);
return *this;
}
bool KeyStoreEntry::isNull() const
{
return false;
}
KeyStoreEntry::Type KeyStoreEntry::type() const
{
return TypeCertificate;
}
QString KeyStoreEntry::name() const
{
return QString();
}
QString KeyStoreEntry::id() const
{
return QString();
}
KeyBundle KeyStoreEntry::keyBundle() const
{
return KeyBundle();
}
Certificate KeyStoreEntry::certificate() const
{
return Certificate();
}
CRL KeyStoreEntry::crl() const
{
return CRL();
}
PGPKey KeyStoreEntry::pgpSecretKey() const
{
return PGPKey();
}
PGPKey KeyStoreEntry::pgpPublicKey() const
{
return PGPKey();
}
//----------------------------------------------------------------------------
// KeyStore
//----------------------------------------------------------------------------
KeyStore::KeyStore()
{
}
KeyStore::KeyStore(const KeyStore &from)
:Algorithm(from)
{
}
KeyStore::~KeyStore()
{
}
KeyStore & KeyStore::operator=(const KeyStore &from)
{
Algorithm::operator=(from);
return *this;
}
bool KeyStore::isNull() const
{
return false;
}
KeyStore::Type KeyStore::type() const
{
return System;
}
QString KeyStore::name() const
{
return QString();
}
QString KeyStore::id() const
{
return QString();
}
bool KeyStore::isReadOnly() const
{
return false;
}
QList<KeyStoreEntry> KeyStore::entryList() const
{
return QList<KeyStoreEntry>();
}
bool KeyStore::containsTrustedCertificates() const
{
return false;
}
bool KeyStore::containsIdentities() const
{
return false;
}
bool KeyStore::containsPGPPublicKeys() const
{
return false;
}
bool KeyStore::writeEntry(const KeyBundle &kb)
{
Q_UNUSED(kb);
return false;
}
bool KeyStore::writeEntry(const Certificate &cert)
{
Q_UNUSED(cert);
return false;
}
bool KeyStore::writeEntry(const CRL &crl)
{
Q_UNUSED(crl);
return false;
}
PGPKey KeyStore::writeEntry(const PGPKey &key)
{
Q_UNUSED(key);
return PGPKey();
}
bool KeyStore::removeEntry(const QString &id)
{
Q_UNUSED(id);
return false;
}
//----------------------------------------------------------------------------
// KeyStoreManager
//----------------------------------------------------------------------------
KeyStoreManager::KeyStoreManager()
{
}
KeyStoreManager::~KeyStoreManager()
{
}
KeyStore KeyStoreManager::keyStore(const QString &id) const
{
Q_UNUSED(id);
return KeyStore();
}
QList<KeyStore> KeyStoreManager::keyStores() const
{
return QList<KeyStore>();
}
int KeyStoreManager::count() const
{
return 0;
}
}

@ -98,7 +98,7 @@ class TLS::Private
public:
Private()
{
store = 0;
//store = 0;
}
void reset()
@ -137,7 +137,7 @@ public:
Certificate ourCert;
PrivateKey ourKey;
Store *store;
//Store *store;
};
TLS::TLS(QObject *parent, const QString &provider)
@ -171,9 +171,10 @@ void TLS::setCertificate(const CertificateChain &cert, const PrivateKey &key)
d->ourKey = key;
}
void TLS::setStore(const Store &store)
void TLS::setTrustedCertificates(const CertificateCollection &trusted)
{
d->store = new Store(store);
Q_UNUSED(trusted);
//d->store = new Store(store);
}
void TLS::setConstraints(SecurityLevel s)
@ -206,9 +207,9 @@ bool TLS::startClient(const QString &host)
d->reset();
d->host = host;
if(!d->c->startClient(*((StoreContext *)d->store->context()), *((CertContext *)d->ourCert.context()), *((PKeyContext *)d->ourKey.context())))
/*if(!d->c->startClient(*((StoreContext *)d->store->context()), *((CertContext *)d->ourCert.context()), *((PKeyContext *)d->ourKey.context())))
return false;
QTimer::singleShot(0, this, SLOT(update()));
QTimer::singleShot(0, this, SLOT(update()));*/
return true;
}
@ -216,9 +217,9 @@ bool TLS::startServer()
{
d->reset();
if(!d->c->startServer(*((StoreContext *)d->store->context()), *((CertContext *)d->ourCert.context()), *((PKeyContext *)d->ourKey.context())))
/*if(!d->c->startServer(*((StoreContext *)d->store->context()), *((CertContext *)d->ourCert.context()), *((PKeyContext *)d->ourKey.context())))
return false;
QTimer::singleShot(0, this, SLOT(update()));
QTimer::singleShot(0, this, SLOT(update()));*/
return true;
}

@ -340,9 +340,9 @@ SMIME::~SMIME()
{
}
void SMIME::setStore(const Store &store)
void SMIME::setTrustedCertificates(const CertificateCollection &trusted)
{
Q_UNUSED(store);
Q_UNUSED(trusted);
}
void SMIME::setPrivateKeys(const QList<PrivateKey> &keys)

@ -28,7 +28,7 @@
namespace QCA
{
bool qca_have_systemstore();
Store qca_get_systemstore(const QString &provider);
CertificateCollection qca_get_systemstore(const QString &provider);
}
#endif

@ -34,12 +34,12 @@ bool qca_have_systemstore()
#endif
}
Store qca_get_systemstore(const QString &provider)
CertificateCollection qca_get_systemstore(const QString &provider)
{
#ifndef QCA_NO_SYSTEMSTORE
return Store::fromFlatTextFile(QCA_SYSTEMSTORE_PATH, Store::Trusted, 0, provider);
return CertificateCollection::fromFlatTextFile(QCA_SYSTEMSTORE_PATH, 0, provider);
#else
return Store(provider);
return CertificateCollection();
#endif
}

@ -289,7 +289,7 @@ static void usage()
printf(" --makereq [priv.pem] (passphrase)\n");
printf(" --showcert [cert.pem]\n");
printf(" --showreq [certreq.pem]\n");
printf(" --validate [cert.pem] (nonrootstore.pem)\n");
printf(" --validate [cert.pem] (nonroots.pem)\n");
printf("\n");
}
@ -968,13 +968,14 @@ int main(int argc, char **argv)
}
// get roots
QCA::Store store = QCA::systemStore();
QCA::CertificateCollection roots = QCA::systemStore();
// get nonroots
QCA::CertificateCollection nonroots;
if(args.count() >= 3)
store += QCA::Store::fromFlatTextFile(args[2]);
nonroots = QCA::CertificateCollection::fromFlatTextFile(args[2]);
QCA::Validity v = store.validate(target);
QCA::Validity v = target.validate(roots, nonroots);
if(v == QCA::ValidityGood)
printf("Certificate is valid\n");
else