aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ aheinecke@45: #ifndef SSLCONNECTION_H aheinecke@45: #define SSLCONNECTION_H aheinecke@45: aheinecke@45: /** aheinecke@45: * @file sslconnection.h aheinecke@45: * @brief Qt wrapper around polarssl ssl api aheinecke@45: */ aheinecke@45: aheinecke@45: #include aheinecke@45: #include aheinecke@45: #include aheinecke@45: #include aheinecke@45: aheinecke@45: #include aheinecke@45: #include aheinecke@45: #include aheinecke@45: #include aheinecke@45: #include aheinecke@45: #include aheinecke@45: aheinecke@45: class SSLConnection aheinecke@45: { aheinecke@45: public: aheinecke@45: enum ErrorCode { aheinecke@45: NoError, aheinecke@45: NoConnection, aheinecke@45: SSLHandshakeFailed, aheinecke@45: InvalidCertificate, aheinecke@45: InvalidPinnedCertificate, aheinecke@45: InvalidResponse, aheinecke@45: ConnectionLost, aheinecke@45: Timeout, aheinecke@45: ErrUnknown aheinecke@45: }; aheinecke@45: aheinecke@45: /** aheinecke@45: * @brief Construct a pinned SSL Connection aheinecke@45: * aheinecke@45: * @param[in] url the Url to connect to aheinecke@45: * @param[in] certificate optional certificate to validate https connection aheinecke@45: */ aheinecke@45: SSLConnection(const QString& url, aheinecke@45: const QByteArray& certificate = QByteArray()); aheinecke@45: aheinecke@45: ~SSLConnection(); aheinecke@45: aheinecke@45: /** @brief write */ aheinecke@45: int write(const QByteArray& request); aheinecke@45: aheinecke@45: /** aheinecke@46: * @brief read at most len bytes and reset the connection aheinecke@46: * aheinecke@46: * @param [in] len Amount of bytes to read. aheinecke@46: * aheinecke@46: * @returns a byte array containing the data or aheinecke@46: * a NULL byte array on error*/ aheinecke@45: QByteArray read(size_t len); aheinecke@45: aheinecke@45: bool initialized() { return mInitialized; } aheinecke@45: bool connected() { return mConnected; } aheinecke@45: aheinecke@45: ErrorCode getLastError() { return mErrorState; } aheinecke@45: aheinecke@45: /** @brief: Establish the connection aheinecke@45: * aheinecke@45: * @returns 0 on success otherwise a polarssl error or -1 is returned aheinecke@45: */ aheinecke@45: int connect(); aheinecke@45: aheinecke@45: private: aheinecke@45: QUrl mUrl; aheinecke@45: QByteArray mPinnedCert; aheinecke@45: x509_crt mX509PinnedCert; aheinecke@45: entropy_context mEntropy; aheinecke@45: ctr_drbg_context mCtr_drbg; aheinecke@45: ssl_context mSSL; aheinecke@46: ssl_session mSavedSession; aheinecke@45: bool mInitialized; aheinecke@46: bool mConnected; /* A connection was established */ aheinecke@46: bool mNeedsReset; /* The connection needs to be reset before the next aheinecke@46: write */ aheinecke@45: int mServerFD; aheinecke@45: SSLConnection::ErrorCode mErrorState; aheinecke@45: /* @brief: Initialize polarssl structures aheinecke@45: * aheinecke@45: * This wraps polarssl initialization functions aheinecke@45: * that can return an error. aheinecke@45: * Sets the error state accordingly. aheinecke@45: * aheinecke@45: * @returns: 0 on success a polarssl error otherwise. aheinecke@45: */ aheinecke@45: int init(); aheinecke@46: aheinecke@46: /* @brief Reset the connection. aheinecke@46: * aheinecke@46: * Resets the https connection and does another handshake. aheinecke@46: * aheinecke@46: * @returns: 0 on success a polarssl error or -1 otherwise. */ aheinecke@46: int reset(); aheinecke@46: aheinecke@46: /* @brief validates that the certificate matches the pinned one. aheinecke@46: * aheinecke@46: * Checks the peer certificate of mSSL and validates that the aheinecke@46: * certificate matches mPinnedCertificate. aheinecke@46: * aheinecke@46: * @returns: 0 on success a polarssl error or -1 otherwise. */ aheinecke@46: int validateCertificate(); aheinecke@46: aheinecke@46: /* @brief disconnects the connection */ aheinecke@46: void disconnect(); aheinecke@45: }; aheinecke@45: aheinecke@45: #endif