qca/include/QtCrypto/qcaprovider.h

651 lines
20 KiB
C
Raw Normal View History

/*
* qcaprovider.h - QCA Plugin API
* 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
*
*/
// WARNING!
//
// Do not use the Plugin interface in applications! This interface is
// for plugin developers ONLY. It may change between QCA versions.
#ifndef QCAPROVIDER_H
#define QCAPROVIDER_H
#include <QtCore>
#include "qca_core.h"
#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 <limits>
#define QCA_PLUGIN_VERSION 2
/** \page providers Providers
QCA works on the concept of a "provider". There is a limited
internal provider (named "default"), but most of the work is
done in plugin modules.
The logic to selection of a provider is fairly simple. The user can
specify a provider name - if that name exists, and the provider supports
the requested feature, then the named provider is used. If that
didn't work, then the available plugins are searched (based on a
priority order) for the requested feature. If that doesn't work,
then the default provider is searched for the requested feature.
So the only way to get the default provider is to either have no other support
whatsoever, or to specify the default provider directly (this goes for the
algorithm constructors as well as setGlobalRNG()).
*/
class QCA_EXPORT QCAPlugin : public QObject
{
Q_OBJECT
public:
virtual int version() const = 0;
virtual QCA::Provider *createProvider() = 0;
};
namespace QCA {
class QCA_EXPORT RandomContext : public Provider::Context
{
public:
RandomContext(Provider *p) : Provider::Context(p, "random") {}
virtual QSecureArray nextBytes(int size, Random::Quality q) = 0;
};
class QCA_EXPORT HashContext : public Provider::Context
{
public:
HashContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual void clear() = 0;
virtual void update(const QSecureArray &a) = 0;
virtual QSecureArray final() = 0;
};
class QCA_EXPORT CipherContext : public Provider::Context
{
public:
//enum Mode { CBC, CFB, ECB };
CipherContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv) = 0;
virtual KeyLength keyLength() const = 0;
virtual unsigned int blockSize() const = 0;
virtual bool update(const QSecureArray &in, QSecureArray *out) = 0;
virtual bool final(QSecureArray *out) = 0;
};
class QCA_EXPORT MACContext : public Provider::Context
{
public:
MACContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual void setup(const SymmetricKey &key) = 0;
virtual KeyLength keyLength() const = 0;
virtual void update(const QSecureArray &in) = 0;
virtual void final(QSecureArray *out) = 0;
protected:
KeyLength anyKeyLength() const
{
// this is used instead of a default implementation to make sure that
// provider authors think about it, at least a bit.
// See Meyers, Effective C++, Effective C++ (2nd Ed), Item 36
return KeyLength( 0, INT_MAX, 1 );
}
};
class QCA_EXPORT KDFContext : public Provider::Context
{
public:
KDFContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual SymmetricKey makeKey(const QSecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount) = 0;
};
class QCA_EXPORT DLGroupContext : public QObject, public Provider::Context
{
Q_OBJECT
public:
DLGroupContext(Provider *p) : Provider::Context(p, "dlgroup") {}
virtual QList<DLGroupSet> supportedGroupSets() const = 0;
virtual bool isNull() const = 0;
virtual void fetchGroup(DLGroupSet set, bool block) = 0;
virtual void getResult(QBigInteger *p, QBigInteger *q, QBigInteger *g) const = 0;
signals:
void finished();
};
class QCA_EXPORT PKeyBase : public QObject, public Provider::Context
{
Q_OBJECT
public:
PKeyBase(Provider *p, const QString &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;
// encrypt/decrypt
virtual int maximumEncryptSize(EncryptionAlgorithm alg) const;
virtual QSecureArray encrypt(const QSecureArray &in, EncryptionAlgorithm alg) const;
virtual bool decrypt(const QSecureArray &in, QSecureArray *out, EncryptionAlgorithm alg) const;
// sign / verify
virtual void startSign(SignatureAlgorithm alg, SignatureFormat format);
virtual void startVerify(SignatureAlgorithm alg, SignatureFormat format);
virtual void update(const QSecureArray &in);
virtual QSecureArray endSign();
virtual bool endVerify(const QSecureArray &sig);
// key agreement
virtual SymmetricKey deriveKey(const PKeyBase &theirs) const;
signals:
void finished();
};
class QCA_EXPORT RSAContext : public PKeyBase
{
Q_OBJECT
public:
RSAContext(Provider *p) : PKeyBase(p, "rsa") {}
virtual void createPrivate(int bits, int exp, bool block) = 0;
virtual void createPrivate(const QBigInteger &n, const QBigInteger &e, const QBigInteger &p, const QBigInteger &q, const QBigInteger &d) = 0;
virtual void createPublic(const QBigInteger &n, const QBigInteger &e) = 0;
virtual QBigInteger n() const = 0;
virtual QBigInteger e() const = 0;
virtual QBigInteger p() const = 0;
virtual QBigInteger q() const = 0;
virtual QBigInteger d() const = 0;
};
class QCA_EXPORT DSAContext : public PKeyBase
{
Q_OBJECT
public:
DSAContext(Provider *p) : PKeyBase(p, "dsa") {}
virtual void createPrivate(const DLGroup &domain, bool block) = 0;
virtual void createPrivate(const DLGroup &domain, const QBigInteger &y, const QBigInteger &x) = 0;
virtual void createPublic(const DLGroup &domain, const QBigInteger &y) = 0;
virtual DLGroup domain() const = 0;
virtual QBigInteger y() const = 0;
virtual QBigInteger x() const = 0;
};
class QCA_EXPORT DHContext : public PKeyBase
{
Q_OBJECT
public:
DHContext(Provider *p) : PKeyBase(p, "dh") {}
virtual void createPrivate(const DLGroup &domain, bool block) = 0;
virtual void createPrivate(const DLGroup &domain, const QBigInteger &y, const QBigInteger &x) = 0;
virtual void createPublic(const DLGroup &domain, const QBigInteger &y) = 0;
virtual DLGroup domain() const = 0;
virtual QBigInteger y() const = 0;
virtual QBigInteger x() const = 0;
};
class QCA_EXPORT PKeyContext : public Provider::Context
{
public:
PKeyContext(Provider *p) : Provider::Context(p, "pkey") {}
virtual QList<PKey::Type> supportedTypes() const = 0;
virtual QList<PKey::Type> supportedIOTypes() const = 0;
virtual QList<PBEAlgorithm> supportedPBEAlgorithms() const = 0;
virtual PKeyBase *key() = 0;
virtual const PKeyBase *key() const = 0;
virtual void setKey(PKeyBase *key) = 0;
virtual bool importKey(const PKeyBase *key) = 0;
// import / export
virtual QSecureArray publicToDER() const = 0;
virtual QString publicToPEM() const = 0;
virtual ConvertResult publicFromDER(const QSecureArray &a) = 0;
virtual ConvertResult publicFromPEM(const QString &s) = 0;
virtual QSecureArray privateToDER(const QSecureArray &passphrase, PBEAlgorithm pbe) const = 0;
virtual QString privateToPEM(const QSecureArray &passphrase, PBEAlgorithm pbe) const = 0;
virtual ConvertResult privateFromDER(const QSecureArray &a, const QSecureArray &passphrase) = 0;
virtual ConvertResult privateFromPEM(const QString &s, const QSecureArray &passphrase) = 0;
};
class QCA_EXPORT CertBase : public Provider::Context
{
public:
CertBase(Provider *p, const QString &type) : Provider::Context(p, type) {}
// import / export
virtual QSecureArray toDER() const = 0;
virtual QString toPEM() const = 0;
virtual ConvertResult fromDER(const QSecureArray &a) = 0;
virtual ConvertResult fromPEM(const QString &s) = 0;
};
class QCA_EXPORT CertContextProps
{
public:
int version; // cert only
QDateTime start, end; // cert only
CertificateInfo subject;
CertificateInfo issuer; // cert only
Constraints constraints;
QStringList policies;
QBigInteger serial; // cert only
bool isCA;
bool isSelfSigned; // cert only
int pathLimit;
QSecureArray sig;
SignatureAlgorithm sigalgo;
QByteArray subjectId, issuerId; // cert only
QString challenge; // csr only
CertificateRequestFormat format; // csr only
};
class QCA_EXPORT CRLContextProps
{
public:
CertificateInfo issuer;
int number;
QDateTime thisUpdate, nextUpdate;
QList<CRLEntry> revoked;
QSecureArray sig;
SignatureAlgorithm sigalgo;
QByteArray issuerId;
};
class CRLContext;
class QCA_EXPORT CertContext : public CertBase
{
public:
CertContext(Provider *p) : CertBase(p, "cert") {}
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 QCA_EXPORT CSRContext : public CertBase
{
public:
CSRContext(Provider *p) : CertBase(p, "csr") {}
virtual bool canUseFormat(CertificateRequestFormat f) const = 0;
virtual bool createRequest(const CertificateOptions &opts, const PKeyContext &priv) = 0;
virtual const CertContextProps *props() const = 0;
virtual PKeyContext *subjectPublicKey() const = 0; // caller must delete
virtual QString toSPKAC() const = 0;
virtual ConvertResult fromSPKAC(const QString &s) = 0;
};
class QCA_EXPORT CRLContext : public CertBase
{
public:
CRLContext(Provider *p) : CertBase(p, "crl") {}
virtual const CRLContextProps *props() const = 0;
};
class QCA_EXPORT CertCollectionContext : public Provider::Context
{
public:
CertCollectionContext(Provider *p) : Provider::Context(p, "certcollection") {}
// ownership of items IS NOT passed
virtual QByteArray toPKCS7(const QList<CertContext*> &certs, const QList<CRLContext*> &crls) const = 0;
// ownership of items IS passed
virtual ConvertResult fromPKCS7(const QByteArray &a, QList<CertContext*> *certs, QList<CRLContext*> *crls) const = 0;
};
class QCA_EXPORT CAContext : public Provider::Context
{
public:
CAContext(Provider *p) : Provider::Context(p, "ca") {}
virtual void setup(const CertContext &cert, const PKeyContext &priv) = 0;
// caller must delete all return values here
virtual CertContext *certificate() const = 0;
virtual CertContext *signRequest(const CSRContext &req, const QDateTime &notValidAfter) const = 0;
virtual CertContext *createCertificate(const PKeyContext &pub, const CertificateOptions &opts) const = 0;
virtual CRLContext *createCRL(const QDateTime &nextUpdate) const = 0;
virtual CRLContext *updateCRL(const CRLContext &crl, const QList<CRLEntry> &entries, const QDateTime &nextUpdate) const = 0;
};
class QCA_EXPORT PIXContext : public Provider::Context
{
public:
PIXContext(Provider *p) : Provider::Context(p, "pix") {}
virtual QByteArray toPKCS12(const QString &name, const QList<const CertContext*> &chain, const PKeyContext &priv, const QSecureArray &passphrase) const = 0;
// caller must delete
virtual ConvertResult fromPKCS12(const QByteArray &in, const QSecureArray &passphrase, QString *name, QList<CertContext*> *chain, PKeyContext **priv) const = 0;
};
class QCA_EXPORT PGPKeyContextProps
{
public:
QString keyId;
QStringList userIds;
bool isSecret;
QDateTime creationDate, expirationDate;
QString fingerprint;
bool inKeyring;
bool isTrusted;
};
class QCA_EXPORT PGPKeyContext : public Provider::Context
{
public:
PGPKeyContext(Provider *p) : Provider::Context(p, "pgpkey") {}
virtual const PGPKeyContextProps *props() const = 0;
virtual QSecureArray toBinary() const = 0;
virtual QString toAscii() const = 0;
virtual ConvertResult fromBinary(const QSecureArray &a) = 0;
virtual ConvertResult fromAscii(const QString &s) = 0;
};
class QCA_EXPORT KeyStoreEntryContext : public Provider::Context
{
public:
KeyStoreEntryContext(Provider *p) : Provider::Context(p, "keystoreentry") {}
virtual KeyStoreEntry::Type type() const = 0;
virtual QString id() const = 0;
virtual QString name() const = 0;
virtual KeyBundle keyBundle() const;
virtual Certificate certificate() const;
virtual CRL crl() const;
virtual PGPKey pgpSecretKey() const;
virtual PGPKey pgpPublicKey() const;
};
class QCA_EXPORT KeyStoreListContext : public QObject, public Provider::Context
{
Q_OBJECT
public:
KeyStoreListContext(Provider *p) : Provider::Context(p, "keystorelist") {}
virtual void start() = 0;
// returns a list of integer context ids (for keystores)
virtual QList<int> keyStores() const = 0;
// null/empty return values mean the context id is gone
virtual KeyStore::Type type(int id) const = 0;
virtual QString storeId(int id) const = 0;
virtual QString name(int id) const = 0;
virtual bool isReadOnly(int id) const;
virtual QList<KeyStoreEntry::Type> entryTypes(int id) const = 0;
// caller must delete
virtual QList<KeyStoreEntryContext*> entryList(int id) const = 0;
virtual bool writeEntry(int id, const KeyBundle &kb);
virtual bool writeEntry(int id, const Certificate &cert);
virtual bool writeEntry(int id, const CRL &crl);
virtual PGPKey writeEntry(int id, const PGPKey &key);
virtual bool removeEntry(int id, const QString &entryId);
virtual void submitPassphrase(int id, const QSecureArray &passphrase);
signals:
// note: busyStart is assumed after calling start(), no need to emit
void busyStart();
void busyEnd();
void updated(KeyStoreListContext *sender);
void diagnosticText(KeyStoreListContext *sender, const QString &str);
void storeUpdated(KeyStoreListContext *sender, int contextId);
// emit this from the thread that caused it
void storeNeedPassphrase(KeyStoreListContext *sender, int contextId);
};
class QCA_EXPORT TLSContext : public QObject, public Provider::Context
{
Q_OBJECT
public:
class SessionInfo
{
public:
bool isCompressed;
TLS::Version version;
QString cipherSuite;
int cipherBits, cipherMaxBits;
};
enum Result
{
Success,
Error,
Continue
};
TLSContext(Provider *p) : Provider::Context(p, "tls") {}
virtual void reset() = 0;
virtual QStringList supportedCipherSuites() const = 0;
virtual bool canCompress() const = 0;
virtual bool canUseDTLS() const;
virtual int maxSSF() const = 0;
virtual void setConstraints(int minSSF, int maxSSF) = 0;
virtual void setConstraints(const QStringList &cipherSuiteList) = 0;
virtual void setup(const CertificateCollection &trusted, const CertificateChain &cert, const PrivateKey &key, bool server, bool compress, bool dtls) = 0;
virtual void shutdown() = 0; // flag for shutdown, call update next
virtual void setMTU(int size); // for dtls
// start() results:
// result (Success or Error)
virtual void start() = 0;
// update() results:
// during handshake:
// result
// to_net
// during shutdown:
// result
// to_net
// else
// result (Success or Error)
// to_net
// encoded
// to_app
// eof
// note: for dtls, this function only operates with single
// packets. perform the operation repeatedly to send/recv
// multiple packets.
virtual void update(const QByteArray &from_net, const QByteArray &from_app) = 0;
virtual void waitForResultsReady(int msecs) = 0;
// results
virtual Result result() const = 0;
virtual QByteArray to_net() = 0;
virtual int encoded() const = 0;
virtual QByteArray to_app() = 0;
virtual bool eof() const = 0;
// call after successful handshake
virtual Validity peerCertificateValidity() const = 0;
virtual CertificateChain peerCertificateChain() const = 0;
virtual SessionInfo sessionInfo() const = 0;
// call after shutdown
virtual QByteArray unprocessed() = 0;
signals:
void resultsReady();
void dtlsTimeout(); // call update, even with empty args
};
class QCA_EXPORT SASLContext : public Provider::Context
{
public:
class HostPort
{
public:
QString addr;
quint16 port;
};
class AuthParams
{
public:
bool user, authzid, pass, realm;
};
enum Result
{
Success,
Error,
NeedParams,
AuthCheck,
Continue
};
enum AuthError
{
NoMech,
BadProto,
BadServ,
BadAuth,
NoAuthzid,
TooWeak,
NeedEncrypt,
Expired,
Disabled,
NoUser,
RemoteUnavail
};
SASLContext(Provider *p) : Provider::Context(p, "sasl") {}
// common
virtual void reset() = 0;
virtual void setCoreProps(const QString &service, const QString &host, HostPort *local, HostPort *remote) = 0;
virtual void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax, const QString &_ext_authid, int _ext_ssf) = 0;
virtual int security() const = 0;
virtual AuthError authError() const = 0;
// init / first step
virtual bool clientStart(const QStringList &mechlist) = 0;
virtual int clientFirstStep(bool allowClientSendFirst) = 0;
virtual bool serverStart(const QString &realm, QStringList *mechlist, const QString &name) = 0;
virtual int serverFirstStep(const QString &mech, const QByteArray *in) = 0;
// get / set params
virtual AuthParams clientParamsNeeded() const = 0;
virtual void setClientParams(const QString *user, const QString *authzid, const QSecureArray *pass, const QString *realm) = 0;
virtual QString username() const = 0;
virtual QString authzid() const = 0;
// continue steps
virtual int nextStep(const QByteArray &in) = 0;
virtual int tryAgain() = 0;
// results
virtual QString mech() const = 0;
virtual const QByteArray *clientInit() const = 0;
virtual QByteArray result() const = 0;
// security layer
virtual bool encode(const QByteArray &in, QByteArray *out) = 0;
virtual bool decode(const QByteArray &in, QByteArray *out) = 0;
};
class QCA_EXPORT MessageContext : public QObject, public Provider::Context
{
Q_OBJECT
public:
enum Operation
{
Encrypt,
Decrypt,
Sign,
Verify,
SignAndEncrypt
};
MessageContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual bool canSignMultiple() const = 0;
virtual SecureMessage::Type type() const = 0;
virtual void reset() = 0;
virtual void setupEncrypt(const SecureMessageKeyList &keys) = 0;
virtual void setupSign(const SecureMessageKeyList &keys, SecureMessage::SignMode m, bool bundleSigner, bool smime) = 0;
virtual void setupVerify(const QByteArray &detachedSig) = 0;
virtual void start(SecureMessage::Format f, Operation op) = 0;
virtual void update(const QByteArray &in) = 0;
virtual QByteArray read() = 0;
virtual void end() = 0;
virtual bool finished() const = 0;
virtual void waitForFinished(int msecs) = 0; // -1 means wait forever
virtual bool success() const = 0;
virtual SecureMessage::Error errorCode() const = 0;
virtual QByteArray signature() const = 0;
virtual QString hashName() const = 0;
virtual SecureMessageSignatureList signers() const = 0;
signals:
void updated();
};
class QCA_EXPORT SMSContext : public Provider::Context
{
public:
SMSContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
virtual void setTrustedCertificates(const CertificateCollection &trusted);
virtual void setPrivateKeys(const QList<SecureMessageKey> &keys);
virtual MessageContext *createMessage() = 0;
};
}
#endif