/* * qca.h - TQt Cryptographic Architecture * Copyright (C) 2003 Justin Karneges * * 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 TQCA_H #define TQCA_H #include #include #include #include #include #include #ifdef Q_OS_WIN32 # ifndef TQCA_STATIC # ifdef TQCA_MAKEDLL # define TQCA_EXPORT __declspec(dllexport) # else # define TQCA_EXPORT __declspec(dllimport) # endif # endif #endif #ifndef TQCA_EXPORT #define TQCA_EXPORT #endif #ifdef Q_OS_WIN32 # ifdef TQCA_PLUGIN_DLL # define TQCA_PLUGIN_EXPORT extern "C" __declspec(dllexport) # else # define TQCA_PLUGIN_EXPORT extern "C" __declspec(dllimport) # endif #endif #ifndef TQCA_PLUGIN_EXPORT #define TQCA_PLUGIN_EXPORT extern "C" __attribute__ ((visibility ("default"))) #endif class TQHostAddress; class TQStringList; class TQCAProvider; class TQCA_HashContext; class TQCA_CipherContext; class TQCA_CertContext; namespace TQCA { enum { CAP_SHA1 = 0x0001, CAP_SHA256 = 0x0002, CAP_MD5 = 0x0004, CAP_BlowFish = 0x0008, CAP_TripleDES = 0x0010, CAP_AES128 = 0x0020, CAP_AES256 = 0x0040, CAP_RSA = 0x0080, CAP_X509 = 0x0100, CAP_TLS = 0x0200, CAP_SASL = 0x0400 }; enum { CBC = 0x0001, CFB = 0x0002 }; enum { Encrypt = 0x0001, Decrypt = 0x0002 }; TQCA_EXPORT void init(); TQCA_EXPORT bool isSupported(int capabilities); TQCA_EXPORT void insertProvider(TQCAProvider *); TQCA_EXPORT void unloadAllPlugins(); TQCA_EXPORT TQString arrayToHex(const TQByteArray &); TQCA_EXPORT TQByteArray hexToArray(const TQString &); class TQCA_EXPORT Hash { public: Hash(const Hash &); Hash & operator=(const Hash &); ~Hash(); void clear(); void update(const TQByteArray &a); TQByteArray final(); protected: Hash(TQCA_HashContext *); private: class Private; Private *d; }; template class TQCA_EXPORT HashStatic { public: HashStatic() {} static TQByteArray hash(const TQByteArray &a) { T obj; obj.update(a); return obj.final(); } static TQByteArray hash(const TQCString &cs) { TQByteArray a(cs.length()); memcpy(a.data(), cs.data(), a.size()); return hash(a); } static TQString hashToString(const TQByteArray &a) { return arrayToHex(hash(a)); } static TQString hashToString(const TQCString &cs) { return arrayToHex(hash(cs)); } }; class TQCA_EXPORT Cipher { public: Cipher(const Cipher &); Cipher & operator=(const Cipher &); ~Cipher(); TQByteArray dyn_generateKey(int size=-1) const; TQByteArray dyn_generateIV() const; void reset(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad=true); bool update(const TQByteArray &a); TQByteArray final(bool *ok=0); protected: Cipher(TQCA_CipherContext *, int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad); private: class Private; Private *d; }; template class TQCA_EXPORT CipherStatic { public: CipherStatic() {} static TQByteArray generateKey(int size=-1) { T obj; return obj.dyn_generateKey(size); } static TQByteArray generateIV() { T obj; return obj.dyn_generateIV(); } }; class TQCA_EXPORT SHA1 : public Hash, public HashStatic { public: SHA1(); }; class TQCA_EXPORT SHA256 : public Hash, public HashStatic { public: SHA256(); }; class TQCA_EXPORT MD5 : public Hash, public HashStatic { public: MD5(); }; class TQCA_EXPORT BlowFish : public Cipher, public CipherStatic { public: BlowFish(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true); }; class TQCA_EXPORT TripleDES : public Cipher, public CipherStatic { public: TripleDES(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true); }; class TQCA_EXPORT AES128 : public Cipher, public CipherStatic { public: AES128(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true); }; class TQCA_EXPORT AES256 : public Cipher, public CipherStatic { public: AES256(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true); }; class RSA; class TQCA_EXPORT RSAKey { public: RSAKey(); RSAKey(const RSAKey &from); RSAKey & operator=(const RSAKey &from); ~RSAKey(); bool isNull() const; bool havePublic() const; bool havePrivate() const; TQByteArray toDER(bool publicOnly=false) const; bool fromDER(const TQByteArray &a); TQString toPEM(bool publicOnly=false) const; bool fromPEM(const TQString &); // only call if you know what you are doing bool fromNative(void *); private: class Private; Private *d; friend class RSA; friend class TLS; bool encrypt(const TQByteArray &a, TQByteArray *out, bool oaep) const; bool decrypt(const TQByteArray &a, TQByteArray *out, bool oaep) const; bool generate(unsigned int bits); }; class TQCA_EXPORT RSA { public: RSA(); ~RSA(); RSAKey key() const; void setKey(const RSAKey &); bool encrypt(const TQByteArray &a, TQByteArray *out, bool oaep=false) const; bool decrypt(const TQByteArray &a, TQByteArray *out, bool oaep=false) const; static RSAKey generateKey(unsigned int bits); private: RSAKey v_key; }; typedef TQMap CertProperties; class TQCA_EXPORT Cert { public: Cert(); Cert(const Cert &); Cert & operator=(const Cert &); ~Cert(); bool isNull() const; TQString commonName() const; TQString serialNumber() const; TQString subjectString() const; TQString issuerString() const; CertProperties subject() const; CertProperties issuer() const; TQDateTime notBefore() const; TQDateTime notAfter() const; TQByteArray toDER() const; bool fromDER(const TQByteArray &a); TQString toPEM() const; bool fromPEM(const TQString &); private: class Private; Private *d; friend class TLS; void fromContext(TQCA_CertContext *); }; class TQCA_EXPORT TLS : public TQObject { Q_OBJECT public: enum Validity { NoCert, Valid, HostMismatch, Rejected, Untrusted, SignatureFailed, InvalidCA, InvalidPurpose, SelfSigned, Revoked, PathLengthExceeded, Expired, Unknown }; enum Error { ErrHandshake, ErrCrypt }; TLS(TQObject *parent=0); ~TLS(); void setCertificate(const Cert &cert, const RSAKey &key); void setCertificateStore(const TQPtrList &store); // note: store must persist void reset(); bool startClient(const TQString &host=""); bool startServer(); void close(); bool isHandshaken() const; // plain (application side) void write(const TQByteArray &a); TQByteArray read(); // encoded (socket side) void writeIncoming(const TQByteArray &a); TQByteArray readOutgoing(); TQByteArray readUnprocessed(); // cert related const Cert & peerCertificate() const; int certificateValidityResult() const; signals: void handshaken(); void readyRead(); void readyReadOutgoing(int plainBytes); void closed(); void error(int); private slots: void update(); private: class Private; Private *d; }; class TQCA_EXPORT SASL : public TQObject { Q_OBJECT public: enum Error { ErrAuth, ErrCrypt }; enum ErrorCond { NoMech, BadProto, BadServ, BadAuth, NoAuthzid, TooWeak, NeedEncrypt, Expired, Disabled, NoUser, RemoteUnavail }; SASL(TQObject *parent=0); ~SASL(); static void setAppName(const TQString &name); void reset(); int errorCondition() const; // options void setAllowPlain(bool); void setAllowAnonymous(bool); void setAllowActiveVulnerable(bool); void setAllowDictionaryVulnerable(bool); void setRequireForwardSecrecy(bool); void setRequirePassCredentials(bool); void setRequireMutualAuth(bool); void setMinimumSSF(int); void setMaximumSSF(int); void setExternalAuthID(const TQString &authid); void setExternalSSF(int); void setLocalAddr(const TQHostAddress &addr, TQ_UINT16 port); void setRemoteAddr(const TQHostAddress &addr, TQ_UINT16 port); // initialize bool startClient(const TQString &service, const TQString &host, const TQStringList &mechlist, bool allowClientSendFirst=true); bool startServer(const TQString &service, const TQString &host, const TQString &realm, TQStringList *mechlist); // authentication void putStep(const TQByteArray &stepData); void putServerFirstStep(const TQString &mech); void putServerFirstStep(const TQString &mech, const TQByteArray &clientInit); void setUsername(const TQString &user); void setAuthzid(const TQString &auth); void setPassword(const TQString &pass); void setRealm(const TQString &realm); void continueAfterParams(); void continueAfterAuthCheck(); // security layer int ssf() const; void write(const TQByteArray &a); TQByteArray read(); void writeIncoming(const TQByteArray &a); TQByteArray readOutgoing(); signals: // for authentication void clientFirstStep(const TQString &mech, const TQByteArray *clientInit); void nextStep(const TQByteArray &stepData); void needParams(bool user, bool authzid, bool pass, bool realm); void authCheck(const TQString &user, const TQString &authzid); void authenticated(); // for security layer void readyRead(); void readyReadOutgoing(int plainBytes); // error void error(int); private slots: void tryAgain(); private: class Private; Private *d; void handleServerFirstStep(int r); }; }; #endif