File indexing completed on 2024-04-28 04:43:41

0001 /*
0002  * qca_securelayer.h - Qt Cryptographic Architecture
0003  * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
0004  * Copyright (C) 2004-2006  Brad Hards <bradh@frogmouth.net>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Lesser General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2.1 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Lesser General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Lesser General Public
0017  * License along with this library; if not, write to the Free Software
0018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0019  * 02110-1301  USA
0020  *
0021  */
0022 
0023 /**
0024    \file qca_securelayer.h
0025 
0026    Header file for SecureLayer and its subclasses
0027 
0028    \note You should not use this header directly from an
0029    application. You should just use <tt> \#include \<QtCrypto>
0030    </tt> instead.
0031 */
0032 #ifndef QCA_SECURELAYER_H
0033 #define QCA_SECURELAYER_H
0034 
0035 #include "qca_cert.h"
0036 #include "qca_core.h"
0037 #include "qca_publickey.h"
0038 #include <QObject>
0039 
0040 namespace QCA {
0041 
0042 /**
0043    Specify the lower-bound for acceptable TLS/SASL security layers
0044 
0045    For TLS, the interpretation of these levels is:
0046    - Any cipher suite that provides non-authenticated communications
0047    (usually anonymous Diffie-Hellman) is SL_Integrity.
0048    - Any cipher suite that is limited to 40 bits (export-version
0049    crippled forms of RC2, RC4 or DES) is SL_Export. Standard
0050    DES (56 bits) and some forms of RC4 (64 bits) are also SL_Export.
0051    - Any normal cipher (AES, Camellia, RC4 or similar) with 128 bits, or
0052    Elliptic Curve Ciphers with 283 bits, is SL_Baseline
0053    - AES or Camellia at least 192 bits, triple-DES and similar
0054    ciphers are SL_High.  ECC with 409 or more bits is also SL_High.
0055    - Highest does not have an equivalent strength. It
0056    indicates that the provider should use the strongest
0057    ciphers available (but not less than SL_High).
0058  */
0059 enum SecurityLevel
0060 {
0061     SL_None,      ///< indicates that no security is ok
0062     SL_Integrity, ///< must at least get integrity protection
0063     SL_Export,    ///< must be export level bits or more
0064     SL_Baseline,  ///< must be 128 bit or more
0065     SL_High,      ///< must be more than 128 bit
0066     SL_Highest    ///< SL_High or max possible, whichever is greater
0067 };
0068 
0069 /**
0070    \class SecureLayer qca_securelayer.h QtCrypto
0071 
0072    Abstract interface to a security layer
0073 
0074    SecureLayer is normally used between an application and a
0075    potentially insecure network. It provides secure
0076    communications over that network.
0077 
0078    The concept is that (after some initial setup), the
0079    application can write() some data to the SecureLayer
0080    implementation, and that data is encrypted (or otherwise
0081    protected, depending on the setup). The SecureLayer
0082    implementation then emits the readyReadOutgoing() signal,
0083    and the application uses readOutgoing() to retrieve the
0084    encrypted data from the SecureLayer implementation.  The
0085    encrypted data is then sent out on the network.
0086 
0087    When some encrypted data comes back from the network, the
0088    application does a writeIncoming() to the SecureLayer
0089    implementation. Some time later, the SecureLayer
0090    implementation may emit readyRead() to the application,
0091    which then read()s the decrypted data from the SecureLayer
0092    implementation.
0093 
0094    Note that sometimes data is sent or received between the
0095    SecureLayer implementation and the network without any data
0096    being sent between the application and the SecureLayer
0097    implementation. This is a result of the initial negotiation
0098    activities (which require network traffic to agree a
0099    configuration to use) and other overheads associated with
0100    the secure link.
0101 
0102    \ingroup UserAPI
0103 */
0104 class QCA_EXPORT SecureLayer : public QObject
0105 {
0106     Q_OBJECT
0107 public:
0108     /**
0109        Constructor for an abstract secure communications
0110        layer
0111 
0112        \param parent the parent object for this object
0113     */
0114     SecureLayer(QObject *parent = nullptr);
0115 
0116     /**
0117        Returns true if the layer has a meaningful "close".
0118     */
0119     virtual bool isClosable() const;
0120 
0121     /**
0122        Returns the number of bytes available to be read()
0123        on the application side.
0124     */
0125     virtual int bytesAvailable() const = 0;
0126 
0127     /**
0128        Returns the number of bytes available to be
0129        readOutgoing() on the network side.
0130     */
0131     virtual int bytesOutgoingAvailable() const = 0;
0132 
0133     /**
0134        Close the link. Note that this may not be
0135        meaningful / possible for all implementations.
0136 
0137        \sa isClosable() for a test that verifies if the
0138        link can be %closed.
0139     */
0140     virtual void close();
0141 
0142     /**
0143        This method writes unencrypted (plain) data to
0144        the SecureLayer implementation. You normally
0145        call this function on the application side.
0146 
0147        \param a the source of the application-side data
0148     */
0149     virtual void write(const QByteArray &a) = 0;
0150 
0151     /**
0152        This method reads decrypted (plain) data from
0153        the SecureLayer implementation. You normally call
0154        this function on the application side after receiving
0155        the readyRead() signal.
0156     */
0157     virtual QByteArray read() = 0;
0158 
0159     /**
0160        This method accepts encoded (typically encrypted) data
0161        for processing. You normally call this function using
0162        data read from the network socket (e.g. using
0163        QTcpSocket::readAll()) after receiving a signal that
0164        indicates that the socket has data to read.
0165 
0166        \param a the ByteArray to take network-side data from
0167     */
0168     virtual void writeIncoming(const QByteArray &a) = 0;
0169 
0170     /**
0171        This method provides encoded (typically encrypted)
0172        data. You normally call this function to get data
0173        to write out to the network socket (e.g. using
0174        QTcpSocket::write()) after receiving the
0175        readyReadOutgoing() signal.
0176 
0177        \param plainBytes the number of bytes that were read.
0178     */
0179     virtual QByteArray readOutgoing(int *plainBytes = nullptr) = 0;
0180 
0181     /**
0182        This allows you to read data without having it
0183        decrypted first. This is intended to be used for
0184        protocols that close off the connection and return
0185        to plain text transfer. You do not normally need to
0186        use this function.
0187     */
0188     virtual QByteArray readUnprocessed();
0189 
0190     /**
0191        Convert encrypted bytes written to plain text bytes written
0192 
0193        \param encryptedBytes the number of bytes to convert
0194     */
0195     virtual int convertBytesWritten(qint64 encryptedBytes) = 0;
0196 
0197 Q_SIGNALS:
0198     /**
0199        This signal is emitted when SecureLayer has
0200        decrypted (application side) data ready to be
0201        read. Typically you will connect this signal to a
0202        slot that reads the data (using read()).
0203     */
0204     void readyRead();
0205 
0206     /**
0207        This signal is emitted when SecureLayer has encrypted
0208        (network side) data ready to be read. Typically you
0209        will connect this signal to a slot that reads the data
0210        (using readOutgoing()) and writes it to a network socket.
0211     */
0212     void readyReadOutgoing();
0213 
0214     /**
0215        This signal is emitted when the SecureLayer connection
0216        is %closed.
0217     */
0218     void closed();
0219 
0220     /**
0221        This signal is emitted when an error is detected. You
0222        can determine the error type using errorCode().
0223     */
0224     void error();
0225 
0226 private:
0227     Q_DISABLE_COPY(SecureLayer)
0228 };
0229 
0230 /**
0231    \class TLSSession qca_securelayer.h QtCrypto
0232 
0233    Session token, used for TLS resuming
0234 
0235    \ingroup UserAPI
0236 
0237 */
0238 class QCA_EXPORT TLSSession : public Algorithm
0239 {
0240 public:
0241     TLSSession();
0242 
0243     /**
0244        Copy constructor
0245 
0246        \param from the session token to copy from
0247     */
0248     TLSSession(const TLSSession &from);
0249 
0250     ~TLSSession() override;
0251 
0252     /**
0253        Assignment operator
0254 
0255        \param from the session token to assign from
0256     */
0257     TLSSession &operator=(const TLSSession &from);
0258 
0259     /**
0260        Test if the session token is valid
0261     */
0262     bool isNull() const;
0263 };
0264 
0265 /**
0266    \class TLS qca_securelayer.h QtCrypto
0267 
0268    Transport Layer Security / Secure Socket Layer
0269 
0270    Transport Layer Security (%TLS) is the current
0271    state-of-the-art in secure transport mechanisms over the
0272    internet. It can be used in a way where only one side of
0273    the link needs to authenticate to the other. This makes it
0274    very useful for servers to provide their identity to
0275    clients. Note that is is possible to use %TLS to
0276    authenticate both client and server.
0277 
0278    %TLS is a IETF standard (<a
0279    href="http://www.ietf.org/rfc/rfc2712.txt">RFC2712</a> for
0280    TLS version 1.0, and <a
0281    href="http://www.ietf.org/rfc/rfc4346.txt">RFC4346</a> for
0282    TLS version 1.1) based on earlier Netscape work on Secure
0283    Socket Layer (SSL version 2 and SSL version 3). New
0284    applications should use at least TLS 1.0, and SSL version 2
0285    should be avoided due to known security problems.
0286 
0287    \ingroup UserAPI
0288 */
0289 class QCA_EXPORT TLS : public SecureLayer, public Algorithm
0290 {
0291     Q_OBJECT
0292 public:
0293     /**
0294        Operating mode
0295     */
0296     enum Mode
0297     {
0298         Stream,  ///< stream mode
0299         Datagram ///< datagram mode
0300     };
0301 
0302     /**
0303        Version of %TLS or SSL
0304     */
0305     enum Version
0306     {
0307         TLS_v1, ///< Transport Layer Security, version 1
0308         SSL_v3, ///< Secure Socket Layer, version 3
0309         SSL_v2, ///< Secure Socket Layer, version 2
0310         DTLS_v1 ///< Datagram Transport Layer Security, version 1
0311     };
0312 
0313     /**
0314        Type of error
0315     */
0316     enum Error
0317     {
0318         ErrorSignerExpired,   ///< local certificate is expired
0319         ErrorSignerInvalid,   ///< local certificate is invalid in some way
0320         ErrorCertKeyMismatch, ///< certificate and private key don't match
0321         ErrorInit,            ///< problem starting up %TLS
0322         ErrorHandshake,       ///< problem during the negotiation
0323         ErrorCrypt            ///< problem at anytime after
0324     };
0325 
0326     /**
0327        Type of identity
0328     */
0329     enum IdentityResult
0330     {
0331         Valid,              ///< identity is verified
0332         HostMismatch,       ///< valid cert provided, but wrong owner
0333         InvalidCertificate, ///< invalid cert
0334         NoCertificate       ///< identity unknown
0335     };
0336 
0337     /**
0338         Constructor for Transport Layer Security connection
0339 
0340         This produces a Stream (normal %TLS) rather than Datagram (DTLS)
0341         object.
0342         If you want to do DTLS, see below.
0343 
0344         \param parent the parent object for this object
0345         \param provider the name of the provider, if a specific provider
0346         is required
0347     */
0348     explicit TLS(QObject *parent = nullptr, const QString &provider = QString());
0349 
0350     /**
0351        Constructor for Transport Layer Security connection.
0352 
0353        This constructor can be used for both normal %TLS (set mode to TLS::Stream)
0354        or DTLS (set mode to TLS::Datagram).
0355 
0356        \param mode the connection Mode
0357        \param parent the parent object for this object
0358        \param provider the name of the provider, if a specific provider is
0359        required
0360     */
0361     explicit TLS(Mode mode, QObject *parent = nullptr, const QString &provider = QString());
0362 
0363     /**
0364        Destructor
0365     */
0366     ~TLS() override;
0367 
0368     /**
0369        Reset the connection
0370     */
0371     void reset();
0372 
0373     /**
0374        Get the list of cipher suites that are available for use.
0375 
0376        A cipher suite is a combination of key exchange,
0377        encryption and hashing algorithms that are agreed
0378        during the initial handshake between client and
0379        server.
0380 
0381        \param version the protocol Version that the cipher
0382        suites are required for
0383 
0384        \return list of the names of the cipher suites
0385        supported.
0386     */
0387     QStringList supportedCipherSuites(const Version &version = TLS_v1) const;
0388 
0389     /**
0390        The local certificate to use. This is the
0391        certificate that will be provided to the peer. This
0392        is almost always required on the server side
0393        (because the server has to provide a certificate to
0394        the client), and may be used on the client side.
0395 
0396        \param cert a chain of certificates that
0397        link the host certificate to a trusted root
0398        certificate.
0399        \param key the private key for the certificate
0400        chain
0401     */
0402     void setCertificate(const CertificateChain &cert, const PrivateKey &key);
0403 
0404     /**
0405        \overload
0406 
0407        Allows setting a certificate from a KeyBundle.
0408 
0409        \param kb key bundle containing the local certificate
0410        and associated private key.
0411     */
0412     void setCertificate(const KeyBundle &kb);
0413 
0414     /**
0415        Return the trusted certificates set for this object
0416     */
0417     CertificateCollection trustedCertificates() const;
0418 
0419     /**
0420        Set up the set of trusted certificates that will be used to verify
0421        that the certificate provided is valid.
0422 
0423        Typically, this will be the collection of root certificates from
0424        the system, which you can get using QCA::systemStore(), however you
0425        may choose to pass whatever certificates match your assurance
0426        needs.
0427 
0428        \param trusted a bundle of trusted certificates.
0429     */
0430     void setTrustedCertificates(const CertificateCollection &trusted);
0431 
0432     /**
0433        The security level required for this link
0434 
0435        \param s the level required for this link.
0436     */
0437     void setConstraints(SecurityLevel s);
0438 
0439     /**
0440        \overload
0441 
0442        \param minSSF the minimum Security Strength Factor
0443        required for this link.
0444        \param maxSSF the maximum Security Strength Factor
0445        required for this link.
0446     */
0447     void setConstraints(int minSSF, int maxSSF);
0448 
0449     /**
0450        \overload
0451 
0452        \param cipherSuiteList a list of the names of
0453        cipher suites that can be used for this link.
0454 
0455        \note the names are the same as the names in the
0456        applicable IETF RFCs (or Internet Drafts if there
0457        is no applicable RFC).
0458     */
0459     void setConstraints(const QStringList &cipherSuiteList);
0460 
0461     /**
0462        Retrieve the list of allowed issuers by the server,
0463        if the server has provided them.  Only DN types will
0464        be present.
0465 
0466        \code
0467 Certificate someCert = ...
0468 PrivateKey someKey = ...
0469 
0470 // see if the server will take our cert
0471 CertificateInfoOrdered issuerInfo = someCert.issuerInfoOrdered().dnOnly();
0472 foreach(const CertificateInfoOrdered &info, tls->issuerList())
0473 {
0474     if(info == issuerInfo)
0475     {
0476         // server will accept someCert, let's present it
0477         tls->setCertificate(someCert, someKey);
0478         break;
0479     }
0480 }
0481        \endcode
0482     */
0483     QList<CertificateInfoOrdered> issuerList() const;
0484 
0485     /**
0486        Sets the issuer list to present to the client.  For
0487        use with servers only.  Only DN types are allowed.
0488 
0489        \param issuers the list of valid issuers to be used.
0490     */
0491     void setIssuerList(const QList<CertificateInfoOrdered> &issuers);
0492 
0493     /**
0494        Resume a %TLS session using the given session object
0495 
0496        \param session the session state to use for resumption.
0497     */
0498     void setSession(const TLSSession &session);
0499 
0500     /**
0501        Test if the link can use compression
0502 
0503        \return true if the link can use compression
0504     */
0505     bool canCompress() const;
0506 
0507     /**
0508        Test if the link can specify a hostname (Server Name
0509        Indication)
0510 
0511        \return true if the link can specify a hostname
0512     */
0513     bool canSetHostName() const;
0514 
0515     /**
0516        Returns true if compression is enabled
0517 
0518        This only indicates whether or not the object is configured to use
0519        compression, not whether or not the link is actually compressed.
0520        Use isCompressed() for that.
0521     */
0522     bool compressionEnabled() const;
0523 
0524     /**
0525        Set the link to use compression
0526 
0527        \param b true if the link should use compression, or false to
0528        disable compression
0529     */
0530     void setCompressionEnabled(bool b);
0531 
0532     /**
0533        Returns the host name specified or an empty string if no host
0534        name is specified.
0535     */
0536     QString hostName() const;
0537 
0538     /**
0539        Start the %TLS/SSL connection as a client
0540 
0541        Typically, you'll want to perform RFC 2818 validation on the
0542        server's certificate, based on the hostname you're intending
0543        to connect to.  Pass a value for \a host in order to have the
0544        validation for you.  If you want to bypass this behavior and
0545        do the validation yourself, pass an empty string for \a host.
0546 
0547        If the host is an internationalized domain name, then it must be
0548        provided in unicode format, not in IDNA ACE/punycode format.
0549 
0550        \param host the hostname that you want to connect to
0551 
0552        \note The hostname will be used for Server Name Indication
0553        extension (see
0554        <a href="http://www.ietf.org/rfc/rfc3546.txt">RFC 3546</a> Section
0555        3.1) if supported by the backend provider.
0556     */
0557     void startClient(const QString &host = QString());
0558 
0559     /**
0560        Start the %TLS/SSL connection as a server.
0561     */
0562     void startServer();
0563 
0564     /**
0565        Resumes %TLS processing.
0566 
0567        Call this function after hostNameReceived(), certificateRequested()
0568        peerCertificateAvailable() or handshaken() is emitted.  By
0569        requiring this function to be called in order to proceed,
0570        applications are given a chance to perform user interaction between
0571        steps in the %TLS process.
0572     */
0573     void continueAfterStep();
0574 
0575     /**
0576        test if the handshake is complete
0577 
0578        \return true if the handshake is complete
0579 
0580        \sa handshaken
0581     */
0582     bool isHandshaken() const;
0583 
0584     /**
0585        test if the link is compressed
0586 
0587        \return true if the link is compressed
0588     */
0589     bool isCompressed() const;
0590 
0591     /**
0592        The protocol version that is in use for this connection.
0593     */
0594     Version version() const;
0595 
0596     /**
0597        The cipher suite that has been negotiated for this connection.
0598 
0599        The name returned here is the name used in the applicable RFC
0600        (or Internet Draft, where there is no RFC).
0601     */
0602     QString cipherSuite() const;
0603 
0604     /**
0605        The number of effective bits of security being used for this
0606        connection.
0607 
0608        This can differ from the actual number of bits in
0609        the cipher for certain
0610        older "export ciphers" that are deliberately crippled. If you
0611        want that information, use cipherMaxBits().
0612     */
0613     int cipherBits() const;
0614 
0615     /**
0616        The number of bits of security that the cipher could use.
0617 
0618        This is normally the same as cipherBits(), but can be greater
0619        for older "export ciphers".
0620     */
0621     int cipherMaxBits() const;
0622 
0623     /**
0624        The session object of the %TLS connection, which can be used
0625        for resuming.
0626     */
0627     TLSSession session() const;
0628 
0629     /**
0630        This method returns the type of error that has
0631        occurred. You should only need to check this if the
0632        error() signal is emitted.
0633     */
0634     Error errorCode() const;
0635 
0636     /**
0637        After the SSL/%TLS handshake is complete, this
0638        method allows you to determine if the other end
0639        of the connection (if the application is a client,
0640        this is the server; if the application is a server,
0641        this is the client) has a valid identity.
0642 
0643        Note that the security of %TLS/SSL depends on
0644        checking this. It is not enough to check that the
0645        certificate is valid - you must check that the
0646        certificate is valid for the entity that you are
0647        trying to communicate with.
0648 
0649        \note If this returns QCA::TLS::InvalidCertificate,
0650        you may wish to use peerCertificateValidity() to
0651        determine whether to proceed or not.
0652     */
0653     IdentityResult peerIdentityResult() const;
0654 
0655     /**
0656        After the SSL/%TLS handshake is valid, this method
0657        allows you to check if the received certificate
0658        from the other end is valid. As noted in
0659        peerIdentityResult(), you also need to check that
0660        the certificate matches the entity you are trying
0661        to communicate with.
0662     */
0663     Validity peerCertificateValidity() const;
0664 
0665     /**
0666        The CertificateChain for the local host
0667        certificate.
0668     */
0669     CertificateChain localCertificateChain() const;
0670 
0671     /**
0672        The PrivateKey for the local host
0673        certificate.
0674     */
0675     PrivateKey localPrivateKey() const;
0676 
0677     /**
0678        The CertificateChain from the peer (other end of
0679        the connection to the trusted root certificate).
0680     */
0681     CertificateChain peerCertificateChain() const;
0682 
0683     // reimplemented
0684     bool       isClosable() const override;
0685     int        bytesAvailable() const override;
0686     int        bytesOutgoingAvailable() const override;
0687     void       close() override;
0688     void       write(const QByteArray &a) override;
0689     QByteArray read() override;
0690     void       writeIncoming(const QByteArray &a) override;
0691     QByteArray readOutgoing(int *plainBytes = nullptr) override;
0692     QByteArray readUnprocessed() override;
0693     int        convertBytesWritten(qint64 encryptedBytes) override;
0694 
0695     /**
0696        Determine the number of packets available to be
0697        read on the application side.
0698 
0699        \note this is only used with DTLS.
0700     */
0701     int packetsAvailable() const;
0702 
0703     /**
0704        Determine the number of packets available to be
0705        read on the network side.
0706 
0707        \note this is only used with DTLS.
0708     */
0709     int packetsOutgoingAvailable() const;
0710 
0711     /**
0712        Return the currently configured maximum packet size
0713 
0714        \note this is only used with DTLS
0715     */
0716     int packetMTU() const;
0717 
0718     /**
0719        Set the maximum packet size to use.
0720 
0721        \param size the number of bytes to set as the MTU.
0722 
0723        \note this is only used with DTLS.
0724     */
0725     void setPacketMTU(int size) const;
0726 
0727 Q_SIGNALS:
0728     /**
0729        Emitted if a host name is set by the client.  At
0730        this time, the server can inspect the hostName().
0731 
0732        You must call continueAfterStep() in order for %TLS
0733        processing to resume after this signal is emitted.
0734 
0735        This signal is only emitted in server mode.
0736 
0737        \sa continueAfterStep
0738     */
0739     void hostNameReceived();
0740 
0741     /**
0742        Emitted when the server requests a certificate.  At
0743        this time, the client can inspect the issuerList().
0744 
0745        You must call continueAfterStep() in order for %TLS
0746        processing to resume after this signal is emitted.
0747 
0748        This signal is only emitted in client mode.
0749 
0750        \sa continueAfterStep
0751     */
0752     void certificateRequested();
0753 
0754     /**
0755        Emitted when a certificate is received from the peer.
0756        At this time, you may inspect peerIdentityResult(),
0757        peerCertificateValidity(), and peerCertificateChain().
0758 
0759        You must call continueAfterStep() in order for %TLS
0760        processing to resume after this signal is emitted.
0761 
0762        \sa continueAfterStep
0763     */
0764     void peerCertificateAvailable();
0765 
0766     /**
0767        Emitted when the protocol handshake is complete.  At
0768        this time, all available information about the %TLS
0769        session can be inspected.
0770 
0771        You must call continueAfterStep() in order for %TLS
0772        processing to resume after this signal is emitted.
0773 
0774        \sa continueAfterStep
0775        \sa isHandshaken
0776     */
0777     void handshaken();
0778 
0779 protected:
0780     /**
0781        Called when a connection is made to a particular signal
0782 
0783        \param signal the name of the signal that has been
0784        connected to.
0785     */
0786     void connectNotify(const QMetaMethod &signal) override;
0787 
0788     /**
0789        Called when a connection is removed from a particular signal
0790 
0791        \param signal the name of the signal that has been
0792        disconnected from.
0793     */
0794     void disconnectNotify(const QMetaMethod &signal) override;
0795 
0796 private:
0797     Q_DISABLE_COPY(TLS)
0798 
0799     class Private;
0800     friend class Private;
0801     Private *d;
0802 };
0803 
0804 /**
0805    \class SASL qca_securelayer.h QtCrypto
0806 
0807    Simple Authentication and Security Layer protocol implementation
0808 
0809    This class implements the Simple Authenication and Security Layer protocol,
0810    which is described in RFC2222 - see
0811    <a href="http://www.ietf.org/rfc/rfc2222.txt">http://www.ietf.org/rfc/rfc2222.txt</a>.
0812 
0813    As the name suggests, %SASL provides authentication (eg, a "login" of some
0814    form), for a connection oriented protocol, and can also provide protection
0815    for the subsequent connection.
0816 
0817    The %SASL protocol is designed to be extensible, through a range of
0818    "mechanisms", where a mechanism is the actual authentication method.
0819    Example mechanisms include Anonymous, LOGIN, Kerberos V4, and GSSAPI.
0820    Mechanisms can be added (potentially without restarting the server
0821    application) by the system administrator.
0822 
0823    It is important to understand that %SASL is neither "network aware" nor
0824    "protocol aware".  That means that %SASL does not understand how the client
0825    connects to the server, and %SASL does not understand the actual
0826    application protocol.
0827 
0828    \ingroup UserAPI
0829 
0830 */
0831 class QCA_EXPORT SASL : public SecureLayer, public Algorithm
0832 {
0833     Q_OBJECT
0834 public:
0835     /**
0836        Possible errors that may occur when using %SASL
0837     */
0838     enum Error
0839     {
0840         ErrorInit,      ///< problem starting up %SASL
0841         ErrorHandshake, ///< problem during the authentication process
0842         ErrorCrypt      ///< problem at anytime after
0843     };
0844 
0845     /**
0846        Possible authentication error states
0847     */
0848     enum AuthCondition
0849     {
0850         AuthFail,         ///< Generic authentication failure
0851         NoMechanism,      ///< No compatible/appropriate authentication mechanism
0852         BadProtocol,      ///< Bad protocol or cancelled
0853         BadServer,        ///< Server failed mutual authentication (client side only)
0854         BadAuth,          ///< Authentication failure (server side only)
0855         NoAuthzid,        ///< Authorization failure (server side only)
0856         TooWeak,          ///< Mechanism too weak for this user (server side only)
0857         NeedEncrypt,      ///< Encryption is needed in order to use mechanism (server side only)
0858         Expired,          ///< Passphrase expired, has to be reset (server side only)
0859         Disabled,         ///< Account is disabled (server side only)
0860         NoUser,           ///< User not found (server side only)
0861         RemoteUnavailable ///< Remote service needed for auth is gone (server side only)
0862     };
0863 
0864     /**
0865        Authentication requirement flag values
0866     */
0867     enum AuthFlags
0868     {
0869         AuthFlagsNone          = 0x00,
0870         AllowPlain             = 0x01,
0871         AllowAnonymous         = 0x02,
0872         RequireForwardSecrecy  = 0x04,
0873         RequirePassCredentials = 0x08,
0874         RequireMutualAuth      = 0x10,
0875         RequireAuthzidSupport  = 0x20 // server-only
0876     };
0877 
0878     /**
0879        Mode options for client side sending
0880     */
0881     enum ClientSendMode
0882     {
0883         AllowClientSendFirst,
0884         DisableClientSendFirst
0885     };
0886 
0887     /**
0888        Mode options for server side sending
0889     */
0890     enum ServerSendMode
0891     {
0892         AllowServerSendLast,
0893         DisableServerSendLast
0894     };
0895 
0896     /**
0897        \class Params qca_securelayer.h QtCrypto
0898 
0899        Parameter flags for the %SASL authentication
0900 
0901        This is used to indicate which parameters are needed by %SASL
0902        in order to complete the authentication process.
0903 
0904        \ingroup UserAPI
0905     */
0906     class QCA_EXPORT Params
0907     {
0908     public:
0909         Params();
0910 
0911         /**
0912            Standard constructor.
0913 
0914            The concept behind this is that you set each of the
0915            flags depending on which parameters are needed.
0916 
0917            \param user the username is required
0918            \param authzid the authorization identity is required
0919            \param pass the password is required
0920            \param realm the realm is required
0921         */
0922         Params(bool user, bool authzid, bool pass, bool realm);
0923 
0924         /**
0925            Standard copy constructor
0926 
0927            \param from the Params object to copy
0928         */
0929         Params(const Params &from);
0930         ~Params();
0931 
0932         /**
0933            Standard assignment operator
0934 
0935            \param from the Params object to assign from
0936         */
0937         Params &operator=(const Params &from);
0938 
0939         /**
0940            User is needed
0941         */
0942         bool needUsername() const;
0943 
0944         /**
0945            An Authorization ID can be sent if desired
0946         */
0947         bool canSendAuthzid() const;
0948 
0949         /**
0950            Password is needed
0951         */
0952         bool needPassword() const;
0953 
0954         /**
0955            A Realm can be sent if desired
0956         */
0957         bool canSendRealm() const;
0958 
0959     private:
0960         class Private;
0961         Private *d;
0962     };
0963 
0964     /**
0965        Standard constructor
0966 
0967        \param parent the parent object for this %SASL connection
0968        \param provider if specified, the provider to use. If not
0969        specified, or specified as empty, then any provider is
0970        acceptable.
0971     */
0972     explicit SASL(QObject *parent = nullptr, const QString &provider = QString());
0973 
0974     ~SASL() override;
0975 
0976     /**
0977        Reset the %SASL mechanism
0978     */
0979     void reset();
0980 
0981     /**
0982        Specify connection constraints
0983 
0984        %SASL supports a range of authentication requirements, and
0985        a range of security levels. This method allows you to
0986        specify the requirements for your connection.
0987 
0988        \param f the authentication requirements, which you typically
0989        build using a binary OR function (eg AllowPlain | AllowAnonymous)
0990        \param s the security level of the encryption, if used. See
0991        SecurityLevel for details of what each level provides.
0992     */
0993     void setConstraints(AuthFlags f, SecurityLevel s = SL_None);
0994 
0995     /**
0996        \overload
0997 
0998        Unless you have a specific reason for directly specifying a
0999        strength factor, you probably should use the method above.
1000 
1001        \param f the authentication requirements, which you typically
1002        build using a binary OR function (eg AllowPlain | AllowAnonymous)
1003        \param minSSF the minimum security strength factor that is required
1004        \param maxSSF the maximum security strength factor that is required
1005 
1006        \note Security strength factors are a rough approximation to key
1007        length in the encryption function (eg if you are securing with
1008        plain DES, the security strength factor would be 56).
1009     */
1010     void setConstraints(AuthFlags f, int minSSF, int maxSSF);
1011 
1012     /**
1013        Specify the local address.
1014 
1015        \param addr the address of the local part of the connection
1016        \param port the port number of the local part of the connection
1017     */
1018     void setLocalAddress(const QString &addr, quint16 port);
1019 
1020     /**
1021        Specify the peer address.
1022 
1023        \param addr the address of the peer side of the connection
1024        \param port the port number of the peer side of the connection
1025     */
1026     void setRemoteAddress(const QString &addr, quint16 port);
1027 
1028     /**
1029        Specify the id of the externally secured connection
1030 
1031        \param authid the id of the connection
1032     */
1033     void setExternalAuthId(const QString &authid);
1034 
1035     /**
1036        Specify a security strength factor for an externally secured
1037        connection
1038 
1039        \param strength the security strength factor of the connection
1040     */
1041     void setExternalSSF(int strength);
1042 
1043     /**
1044        Initialise the client side of the connection
1045 
1046        startClient must be called on the client side of the connection.
1047        clientStarted will be emitted when the operation is completed.
1048 
1049        \param service the name of the service
1050        \param host the client side host name
1051        \param mechlist the list of mechanisms which can be used
1052        \param mode the mode to use on the client side
1053     */
1054     void startClient(const QString     &service,
1055                      const QString     &host,
1056                      const QStringList &mechlist,
1057                      ClientSendMode     mode = AllowClientSendFirst);
1058 
1059     /**
1060        Initialise the server side of the connection
1061 
1062        startServer must be called on the server side of the connection.
1063        serverStarted will be emitted when the operation is completed.
1064 
1065        \param service the name of the service
1066        \param host the server side host name
1067        \param realm the realm to use
1068        \param mode which mode to use on the server side
1069     */
1070     void startServer(const QString &service,
1071                      const QString &host,
1072                      const QString &realm,
1073                      ServerSendMode mode = DisableServerSendLast);
1074 
1075     /**
1076        Process the first step in server mode (server)
1077 
1078        Call this with the mechanism selected by the client.  If there
1079        is initial client data, call the other version of this function
1080        instead.
1081 
1082        \param mech the mechanism to be used.
1083     */
1084     void putServerFirstStep(const QString &mech);
1085 
1086     /**
1087        Process the first step in server mode (server)
1088 
1089        Call this with the mechanism selected by the client, and initial
1090        client data.  If there is no initial client data, call the other
1091        version of this function instead.
1092 
1093        \param mech the mechanism to be used
1094        \param clientInit the initial data provided by the client side
1095     */
1096     void putServerFirstStep(const QString &mech, const QByteArray &clientInit);
1097 
1098     /**
1099        Process an authentication step
1100 
1101        Call this with authentication data received from the network.
1102        The only exception is the first step in server mode, in which
1103        case putServerFirstStep must be called.
1104 
1105        \param stepData the authentication data from the network
1106     */
1107     void putStep(const QByteArray &stepData);
1108 
1109     /**
1110        Return the mechanism selected (client)
1111     */
1112     QString mechanism() const;
1113 
1114     /**
1115        Return the mechanism list (server)
1116     */
1117     QStringList mechanismList() const;
1118 
1119     /**
1120        Return the realm list, if available (client)
1121     */
1122     QStringList realmList() const;
1123 
1124     /**
1125        Return the security strength factor of the connection
1126     */
1127     int ssf() const;
1128 
1129     /**
1130        Return the error code
1131     */
1132     Error errorCode() const;
1133 
1134     /**
1135        Return the reason for authentication failure
1136     */
1137     AuthCondition authCondition() const;
1138 
1139     /**
1140        Specify the username to use in authentication
1141 
1142        \param user the username to use
1143     */
1144     void setUsername(const QString &user);
1145 
1146     /**
1147        Specify the authorization identity to use in authentication
1148 
1149        \param auth the authorization identity to use
1150     */
1151     void setAuthzid(const QString &auth);
1152 
1153     /**
1154        Specify the password to use in authentication
1155 
1156        \param pass the password to use
1157     */
1158     void setPassword(const SecureArray &pass);
1159 
1160     /**
1161        Specify the realm to use in authentication
1162 
1163        \param realm the realm to use
1164     */
1165     void setRealm(const QString &realm);
1166 
1167     /**
1168        Continue negotiation after parameters have been set (client)
1169     */
1170     void continueAfterParams();
1171 
1172     /**
1173        Continue negotiation after auth ids have been checked (server)
1174     */
1175     void continueAfterAuthCheck();
1176 
1177     // reimplemented
1178     int        bytesAvailable() const override;
1179     int        bytesOutgoingAvailable() const override;
1180     void       write(const QByteArray &a) override;
1181     QByteArray read() override;
1182     void       writeIncoming(const QByteArray &a) override;
1183     QByteArray readOutgoing(int *plainBytes = nullptr) override;
1184     int        convertBytesWritten(qint64 encryptedBytes) override;
1185 
1186 Q_SIGNALS:
1187     /**
1188        This signal is emitted when the client has been successfully
1189        started
1190 
1191        \param clientInit true if the client should send an initial
1192        response to the server
1193        \param clientInitData the initial response to send to the server.
1194        Do note that there is a difference in SASL between an empty initial
1195        response and no initial response, and so even if clientInitData is
1196        an empty array, you still need to send an initial response if
1197        clientInit is true.
1198     */
1199     void clientStarted(bool clientInit, const QByteArray &clientInitData);
1200 
1201     /**
1202        This signal is emitted after the server has been
1203        successfully started
1204     */
1205     void serverStarted();
1206 
1207     /**
1208        This signal is emitted when there is data required
1209        to be sent over the network to complete the next
1210        step in the authentication process.
1211 
1212        \param stepData the data to send over the network
1213     */
1214     void nextStep(const QByteArray &stepData);
1215 
1216     /**
1217        This signal is emitted when the client needs
1218        additional parameters
1219 
1220        After receiving this signal, the application should set
1221        the required parameter values appropriately and then call
1222        continueAfterParams().
1223 
1224        \param params the parameters that are required by the client
1225     */
1226     void needParams(const QCA::SASL::Params &params);
1227 
1228     /**
1229        This signal is emitted when the server needs to
1230        perform the authentication check
1231 
1232        If the user and authzid are valid, call continueAfterAuthCheck().
1233 
1234        \param user the user identification name
1235        \param authzid the user authorization name
1236     */
1237     void authCheck(const QString &user, const QString &authzid);
1238 
1239     /**
1240        This signal is emitted when authentication is complete.
1241     */
1242     void authenticated();
1243 
1244 private:
1245     Q_DISABLE_COPY(SASL)
1246 
1247     class Private;
1248     friend class Private;
1249     Private *d;
1250 };
1251 
1252 }
1253 
1254 #endif