[31] | 1 | /*
|
---|
| 2 | * qca.h - Qt Cryptographic Architecture
|
---|
| 3 | * Copyright (C) 2003 Justin Karneges
|
---|
| 4 | *
|
---|
| 5 | * This library is free software; you can redistribute it and/or
|
---|
| 6 | * modify it under the terms of the GNU Lesser General Public
|
---|
| 7 | * License as published by the Free Software Foundation; either
|
---|
| 8 | * version 2.1 of the License, or (at your option) any later version.
|
---|
| 9 | *
|
---|
| 10 | * This library is distributed in the hope that it will be useful,
|
---|
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 13 | * Lesser General Public License for more details.
|
---|
| 14 | *
|
---|
| 15 | * You should have received a copy of the GNU Lesser General Public
|
---|
| 16 | * License along with this library; if not, write to the Free Software
|
---|
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
| 18 | *
|
---|
| 19 | */
|
---|
| 20 |
|
---|
| 21 | #ifndef QCA_H
|
---|
| 22 | #define QCA_H
|
---|
| 23 |
|
---|
| 24 | #include<qstring.h>
|
---|
| 25 | #include<qcstring.h>
|
---|
| 26 | #include<qdatetime.h>
|
---|
| 27 | #include<qmap.h>
|
---|
| 28 | #include<qptrlist.h>
|
---|
| 29 | #include<qobject.h>
|
---|
| 30 |
|
---|
| 31 | #ifdef Q_OS_WIN32
|
---|
| 32 | # ifndef QCA_STATIC
|
---|
| 33 | # ifdef QCA_MAKEDLL
|
---|
| 34 | # define QCA_EXPORT __declspec(dllexport)
|
---|
| 35 | # else
|
---|
| 36 | # define QCA_EXPORT __declspec(dllimport)
|
---|
| 37 | # endif
|
---|
| 38 | # endif
|
---|
| 39 | #endif
|
---|
| 40 | #ifndef QCA_EXPORT
|
---|
| 41 | #define QCA_EXPORT
|
---|
| 42 | #endif
|
---|
| 43 |
|
---|
[34] | 44 | #if defined(Q_OS_WIN32)
|
---|
[31] | 45 | # ifdef QCA_PLUGIN_DLL
|
---|
| 46 | # define QCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
|
---|
| 47 | # else
|
---|
| 48 | # define QCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
|
---|
| 49 | # endif
|
---|
[34] | 50 | #elif defined(Q_OS_OS2)
|
---|
| 51 | # define QCA_PLUGIN_EXPORT extern "C" _System
|
---|
[31] | 52 | #endif
|
---|
| 53 | #ifndef QCA_PLUGIN_EXPORT
|
---|
| 54 | #define QCA_PLUGIN_EXPORT extern "C"
|
---|
| 55 | #endif
|
---|
| 56 |
|
---|
| 57 | class QHostAddress;
|
---|
| 58 | class QStringList;
|
---|
| 59 |
|
---|
| 60 | class QCAProvider;
|
---|
| 61 | class QCA_HashContext;
|
---|
| 62 | class QCA_CipherContext;
|
---|
| 63 | class QCA_CertContext;
|
---|
| 64 |
|
---|
| 65 | namespace QCA
|
---|
| 66 | {
|
---|
| 67 | enum {
|
---|
| 68 | CAP_SHA1 = 0x0001,
|
---|
| 69 | CAP_SHA256 = 0x0002,
|
---|
| 70 | CAP_MD5 = 0x0004,
|
---|
| 71 | CAP_BlowFish = 0x0008,
|
---|
| 72 | CAP_TripleDES = 0x0010,
|
---|
| 73 | CAP_AES128 = 0x0020,
|
---|
| 74 | CAP_AES256 = 0x0040,
|
---|
| 75 | CAP_RSA = 0x0080,
|
---|
| 76 | CAP_X509 = 0x0100,
|
---|
| 77 | CAP_TLS = 0x0200,
|
---|
| 78 | CAP_SASL = 0x0400
|
---|
| 79 | };
|
---|
| 80 |
|
---|
| 81 | enum {
|
---|
| 82 | CBC = 0x0001,
|
---|
| 83 | CFB = 0x0002
|
---|
| 84 | };
|
---|
| 85 |
|
---|
| 86 | enum {
|
---|
| 87 | Encrypt = 0x0001,
|
---|
| 88 | Decrypt = 0x0002
|
---|
| 89 | };
|
---|
| 90 |
|
---|
| 91 | QCA_EXPORT void init();
|
---|
| 92 | QCA_EXPORT bool isSupported(int capabilities);
|
---|
| 93 | QCA_EXPORT void insertProvider(QCAProvider *);
|
---|
| 94 | QCA_EXPORT void unloadAllPlugins();
|
---|
| 95 |
|
---|
| 96 | QCA_EXPORT QString arrayToHex(const QByteArray &);
|
---|
| 97 | QCA_EXPORT QByteArray hexToArray(const QString &);
|
---|
| 98 |
|
---|
| 99 | class QCA_EXPORT Hash
|
---|
| 100 | {
|
---|
| 101 | public:
|
---|
| 102 | Hash(const Hash &);
|
---|
| 103 | Hash & operator=(const Hash &);
|
---|
| 104 | ~Hash();
|
---|
| 105 |
|
---|
| 106 | void clear();
|
---|
| 107 | void update(const QByteArray &a);
|
---|
| 108 | QByteArray final();
|
---|
| 109 |
|
---|
| 110 | protected:
|
---|
| 111 | Hash(QCA_HashContext *);
|
---|
| 112 |
|
---|
| 113 | private:
|
---|
| 114 | class Private;
|
---|
| 115 | Private *d;
|
---|
| 116 | };
|
---|
| 117 |
|
---|
| 118 | template <class T>
|
---|
| 119 | class QCA_EXPORT HashStatic
|
---|
| 120 | {
|
---|
| 121 | public:
|
---|
| 122 | HashStatic<T>() {}
|
---|
| 123 |
|
---|
| 124 | static QByteArray hash(const QByteArray &a)
|
---|
| 125 | {
|
---|
| 126 | T obj;
|
---|
| 127 | obj.update(a);
|
---|
| 128 | return obj.final();
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | static QByteArray hash(const QCString &cs)
|
---|
| 132 | {
|
---|
| 133 | QByteArray a(cs.length());
|
---|
| 134 | memcpy(a.data(), cs.data(), a.size());
|
---|
| 135 | return hash(a);
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | static QString hashToString(const QByteArray &a)
|
---|
| 139 | {
|
---|
| 140 | return arrayToHex(hash(a));
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | static QString hashToString(const QCString &cs)
|
---|
| 144 | {
|
---|
| 145 | return arrayToHex(hash(cs));
|
---|
| 146 | }
|
---|
| 147 | };
|
---|
| 148 |
|
---|
| 149 | class QCA_EXPORT Cipher
|
---|
| 150 | {
|
---|
| 151 | public:
|
---|
| 152 | Cipher(const Cipher &);
|
---|
| 153 | Cipher & operator=(const Cipher &);
|
---|
| 154 | ~Cipher();
|
---|
| 155 |
|
---|
| 156 | QByteArray dyn_generateKey(int size=-1) const;
|
---|
| 157 | QByteArray dyn_generateIV() const;
|
---|
| 158 | void reset(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad=true);
|
---|
| 159 | bool update(const QByteArray &a);
|
---|
| 160 | QByteArray final(bool *ok=0);
|
---|
| 161 |
|
---|
| 162 | protected:
|
---|
| 163 | Cipher(QCA_CipherContext *, int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad);
|
---|
| 164 |
|
---|
| 165 | private:
|
---|
| 166 | class Private;
|
---|
| 167 | Private *d;
|
---|
| 168 | };
|
---|
| 169 |
|
---|
| 170 | template <class T>
|
---|
| 171 | class QCA_EXPORT CipherStatic
|
---|
| 172 | {
|
---|
| 173 | public:
|
---|
| 174 | CipherStatic<T>() {}
|
---|
| 175 |
|
---|
| 176 | static QByteArray generateKey(int size=-1)
|
---|
| 177 | {
|
---|
| 178 | T obj;
|
---|
| 179 | return obj.dyn_generateKey(size);
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 | static QByteArray generateIV()
|
---|
| 183 | {
|
---|
| 184 | T obj;
|
---|
| 185 | return obj.dyn_generateIV();
|
---|
| 186 | }
|
---|
| 187 | };
|
---|
| 188 |
|
---|
| 189 | class QCA_EXPORT SHA1 : public Hash, public HashStatic<SHA1>
|
---|
| 190 | {
|
---|
| 191 | public:
|
---|
| 192 | SHA1();
|
---|
| 193 | };
|
---|
| 194 |
|
---|
| 195 | class QCA_EXPORT SHA256 : public Hash, public HashStatic<SHA256>
|
---|
| 196 | {
|
---|
| 197 | public:
|
---|
| 198 | SHA256();
|
---|
| 199 | };
|
---|
| 200 |
|
---|
| 201 | class QCA_EXPORT MD5 : public Hash, public HashStatic<MD5>
|
---|
| 202 | {
|
---|
| 203 | public:
|
---|
| 204 | MD5();
|
---|
| 205 | };
|
---|
| 206 |
|
---|
| 207 | class QCA_EXPORT BlowFish : public Cipher, public CipherStatic<BlowFish>
|
---|
| 208 | {
|
---|
| 209 | public:
|
---|
| 210 | BlowFish(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
|
---|
| 211 | };
|
---|
| 212 |
|
---|
| 213 | class QCA_EXPORT TripleDES : public Cipher, public CipherStatic<TripleDES>
|
---|
| 214 | {
|
---|
| 215 | public:
|
---|
| 216 | TripleDES(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
|
---|
| 217 | };
|
---|
| 218 |
|
---|
| 219 | class QCA_EXPORT AES128 : public Cipher, public CipherStatic<AES128>
|
---|
| 220 | {
|
---|
| 221 | public:
|
---|
| 222 | AES128(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
|
---|
| 223 | };
|
---|
| 224 |
|
---|
| 225 | class QCA_EXPORT AES256 : public Cipher, public CipherStatic<AES256>
|
---|
| 226 | {
|
---|
| 227 | public:
|
---|
| 228 | AES256(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
|
---|
| 229 | };
|
---|
| 230 |
|
---|
| 231 | class RSA;
|
---|
| 232 | class QCA_EXPORT RSAKey
|
---|
| 233 | {
|
---|
| 234 | public:
|
---|
| 235 | RSAKey();
|
---|
| 236 | RSAKey(const RSAKey &from);
|
---|
| 237 | RSAKey & operator=(const RSAKey &from);
|
---|
| 238 | ~RSAKey();
|
---|
| 239 |
|
---|
| 240 | bool isNull() const;
|
---|
| 241 | bool havePublic() const;
|
---|
| 242 | bool havePrivate() const;
|
---|
| 243 |
|
---|
| 244 | QByteArray toDER(bool publicOnly=false) const;
|
---|
| 245 | bool fromDER(const QByteArray &a);
|
---|
| 246 |
|
---|
| 247 | QString toPEM(bool publicOnly=false) const;
|
---|
| 248 | bool fromPEM(const QString &);
|
---|
| 249 |
|
---|
| 250 | // only call if you know what you are doing
|
---|
| 251 | bool fromNative(void *);
|
---|
| 252 |
|
---|
| 253 | private:
|
---|
| 254 | class Private;
|
---|
| 255 | Private *d;
|
---|
| 256 |
|
---|
| 257 | friend class RSA;
|
---|
| 258 | friend class TLS;
|
---|
| 259 | bool encrypt(const QByteArray &a, QByteArray *out, bool oaep) const;
|
---|
| 260 | bool decrypt(const QByteArray &a, QByteArray *out, bool oaep) const;
|
---|
| 261 | bool generate(unsigned int bits);
|
---|
| 262 | };
|
---|
| 263 |
|
---|
| 264 | class QCA_EXPORT RSA
|
---|
| 265 | {
|
---|
| 266 | public:
|
---|
| 267 | RSA();
|
---|
| 268 | ~RSA();
|
---|
| 269 |
|
---|
| 270 | RSAKey key() const;
|
---|
| 271 | void setKey(const RSAKey &);
|
---|
| 272 |
|
---|
| 273 | bool encrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const;
|
---|
| 274 | bool decrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const;
|
---|
| 275 |
|
---|
| 276 | static RSAKey generateKey(unsigned int bits);
|
---|
| 277 |
|
---|
| 278 | private:
|
---|
| 279 | RSAKey v_key;
|
---|
| 280 | };
|
---|
| 281 |
|
---|
| 282 | typedef QMap<QString, QString> CertProperties;
|
---|
| 283 | class QCA_EXPORT Cert
|
---|
| 284 | {
|
---|
| 285 | public:
|
---|
| 286 | Cert();
|
---|
| 287 | Cert(const Cert &);
|
---|
| 288 | Cert & operator=(const Cert &);
|
---|
| 289 | ~Cert();
|
---|
| 290 |
|
---|
| 291 | bool isNull() const;
|
---|
| 292 |
|
---|
| 293 | QString commonName() const;
|
---|
| 294 | QString serialNumber() const;
|
---|
| 295 | QString subjectString() const;
|
---|
| 296 | QString issuerString() const;
|
---|
| 297 | CertProperties subject() const;
|
---|
| 298 | CertProperties issuer() const;
|
---|
| 299 | QDateTime notBefore() const;
|
---|
| 300 | QDateTime notAfter() const;
|
---|
| 301 |
|
---|
| 302 | QByteArray toDER() const;
|
---|
| 303 | bool fromDER(const QByteArray &a);
|
---|
| 304 |
|
---|
| 305 | QString toPEM() const;
|
---|
| 306 | bool fromPEM(const QString &);
|
---|
| 307 |
|
---|
| 308 | private:
|
---|
| 309 | class Private;
|
---|
| 310 | Private *d;
|
---|
| 311 |
|
---|
| 312 | friend class TLS;
|
---|
| 313 | void fromContext(QCA_CertContext *);
|
---|
| 314 | };
|
---|
| 315 |
|
---|
| 316 | class QCA_EXPORT TLS : public QObject
|
---|
| 317 | {
|
---|
| 318 | Q_OBJECT
|
---|
| 319 | public:
|
---|
| 320 | enum Validity {
|
---|
| 321 | NoCert,
|
---|
| 322 | Valid,
|
---|
| 323 | HostMismatch,
|
---|
| 324 | Rejected,
|
---|
| 325 | Untrusted,
|
---|
| 326 | SignatureFailed,
|
---|
| 327 | InvalidCA,
|
---|
| 328 | InvalidPurpose,
|
---|
| 329 | SelfSigned,
|
---|
| 330 | Revoked,
|
---|
| 331 | PathLengthExceeded,
|
---|
| 332 | Expired,
|
---|
| 333 | Unknown
|
---|
| 334 | };
|
---|
| 335 | enum Error { ErrHandshake, ErrCrypt };
|
---|
| 336 |
|
---|
| 337 | TLS(QObject *parent=0);
|
---|
| 338 | ~TLS();
|
---|
| 339 |
|
---|
| 340 | void setCertificate(const Cert &cert, const RSAKey &key);
|
---|
| 341 | void setCertificateStore(const QPtrList<Cert> &store); // note: store must persist
|
---|
| 342 |
|
---|
| 343 | void reset();
|
---|
| 344 | bool startClient(const QString &host="");
|
---|
| 345 | bool startServer();
|
---|
| 346 | void close();
|
---|
| 347 | bool isHandshaken() const;
|
---|
| 348 |
|
---|
| 349 | // plain (application side)
|
---|
| 350 | void write(const QByteArray &a);
|
---|
| 351 | QByteArray read();
|
---|
| 352 |
|
---|
| 353 | // encoded (socket side)
|
---|
| 354 | void writeIncoming(const QByteArray &a);
|
---|
| 355 | QByteArray readOutgoing();
|
---|
| 356 | QByteArray readUnprocessed();
|
---|
| 357 |
|
---|
| 358 | // cert related
|
---|
| 359 | const Cert & peerCertificate() const;
|
---|
| 360 | int certificateValidityResult() const;
|
---|
| 361 |
|
---|
| 362 | signals:
|
---|
| 363 | void handshaken();
|
---|
| 364 | void readyRead();
|
---|
| 365 | void readyReadOutgoing(int plainBytes);
|
---|
| 366 | void closed();
|
---|
| 367 | void error(int);
|
---|
| 368 |
|
---|
| 369 | private slots:
|
---|
| 370 | void update();
|
---|
| 371 |
|
---|
| 372 | private:
|
---|
| 373 | class Private;
|
---|
| 374 | Private *d;
|
---|
| 375 | };
|
---|
| 376 |
|
---|
| 377 | class QCA_EXPORT SASL : public QObject
|
---|
| 378 | {
|
---|
| 379 | Q_OBJECT
|
---|
| 380 | public:
|
---|
| 381 | enum Error { ErrAuth, ErrCrypt };
|
---|
| 382 | enum ErrorCond {
|
---|
| 383 | NoMech,
|
---|
| 384 | BadProto,
|
---|
| 385 | BadServ,
|
---|
| 386 | BadAuth,
|
---|
| 387 | NoAuthzid,
|
---|
| 388 | TooWeak,
|
---|
| 389 | NeedEncrypt,
|
---|
| 390 | Expired,
|
---|
| 391 | Disabled,
|
---|
| 392 | NoUser,
|
---|
| 393 | RemoteUnavail
|
---|
| 394 | };
|
---|
| 395 | SASL(QObject *parent=0);
|
---|
| 396 | ~SASL();
|
---|
| 397 |
|
---|
| 398 | static void setAppName(const QString &name);
|
---|
| 399 |
|
---|
| 400 | void reset();
|
---|
| 401 | int errorCondition() const;
|
---|
| 402 |
|
---|
| 403 | // options
|
---|
| 404 | void setAllowPlain(bool);
|
---|
| 405 | void setAllowAnonymous(bool);
|
---|
| 406 | void setAllowActiveVulnerable(bool);
|
---|
| 407 | void setAllowDictionaryVulnerable(bool);
|
---|
| 408 | void setRequireForwardSecrecy(bool);
|
---|
| 409 | void setRequirePassCredentials(bool);
|
---|
| 410 | void setRequireMutualAuth(bool);
|
---|
| 411 |
|
---|
| 412 | void setMinimumSSF(int);
|
---|
| 413 | void setMaximumSSF(int);
|
---|
| 414 | void setExternalAuthID(const QString &authid);
|
---|
| 415 | void setExternalSSF(int);
|
---|
| 416 |
|
---|
| 417 | void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
|
---|
| 418 | void setRemoteAddr(const QHostAddress &addr, Q_UINT16 port);
|
---|
| 419 |
|
---|
| 420 | // initialize
|
---|
| 421 | bool startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst=true);
|
---|
| 422 | bool startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist);
|
---|
| 423 |
|
---|
| 424 | // authentication
|
---|
| 425 | void putStep(const QByteArray &stepData);
|
---|
| 426 | void putServerFirstStep(const QString &mech);
|
---|
| 427 | void putServerFirstStep(const QString &mech, const QByteArray &clientInit);
|
---|
| 428 | void setUsername(const QString &user);
|
---|
| 429 | void setAuthzid(const QString &auth);
|
---|
| 430 | void setPassword(const QString &pass);
|
---|
| 431 | void setRealm(const QString &realm);
|
---|
| 432 | void continueAfterParams();
|
---|
| 433 | void continueAfterAuthCheck();
|
---|
| 434 |
|
---|
| 435 | // security layer
|
---|
| 436 | int ssf() const;
|
---|
| 437 | void write(const QByteArray &a);
|
---|
| 438 | QByteArray read();
|
---|
| 439 | void writeIncoming(const QByteArray &a);
|
---|
| 440 | QByteArray readOutgoing();
|
---|
| 441 |
|
---|
| 442 | signals:
|
---|
| 443 | // for authentication
|
---|
| 444 | void clientFirstStep(const QString &mech, const QByteArray *clientInit);
|
---|
| 445 | void nextStep(const QByteArray &stepData);
|
---|
| 446 | void needParams(bool user, bool authzid, bool pass, bool realm);
|
---|
| 447 | void authCheck(const QString &user, const QString &authzid);
|
---|
| 448 | void authenticated();
|
---|
| 449 |
|
---|
| 450 | // for security layer
|
---|
| 451 | void readyRead();
|
---|
| 452 | void readyReadOutgoing(int plainBytes);
|
---|
| 453 |
|
---|
| 454 | // error
|
---|
| 455 | void error(int);
|
---|
| 456 |
|
---|
| 457 | private slots:
|
---|
| 458 | void tryAgain();
|
---|
| 459 |
|
---|
| 460 | private:
|
---|
| 461 | class Private;
|
---|
| 462 | Private *d;
|
---|
| 463 |
|
---|
| 464 | void handleServerFirstStep(int r);
|
---|
| 465 | };
|
---|
| 466 | };
|
---|
| 467 |
|
---|
| 468 | #endif
|
---|