Skip to content
Snippets Groups Projects
Select Git revision
  • c420c5b49c5613af0584f2c44e347c5d87643b70
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/windowsReleaseTest
  • release/releaseTest
  • release/releaseWindowsTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 4.0.0
  • 2.2.0
  • 2.1.0
  • 2.0.1
  • 2.0.0
  • 1.4.1
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
31 results

tls_session.h

Blame
  • Sébastien Blin's avatar
    Sébastien Blin authored
    On recent gcc, daemon fails (static assertion failed: result type
    must be destructible) cause futures must access the destructor
    since commit/71ed3c0c9a3458998bded8e2443c0a680c2eb8cd in gcc
    
    Change-Id: I1e7d35da6aeaffffcb6aa9362d335625ea370052
    c420c5b4
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    tls_session.h 4.80 KiB
    /*
     *  Copyright (C) 2004-2021 Savoir-faire Linux Inc.
     *
     *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
     *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
     *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
     *  Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 of the License, or
     *  (at your option) any later version.
     *
     *  This program 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 General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program; if not, write to the Free Software
     *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
     */
    
    #pragma once
    
    #include "noncopyable.h"
    #include "generic_io.h"
    #include "diffie-hellman.h"
    
    #include <gnutls/gnutls.h>
    
    #include <string>
    #include <functional>
    #include <memory>
    #include <future>
    #include <chrono>
    #include <vector>
    #include <array>
    
    namespace dht {
    namespace crypto {
    struct Certificate;
    struct PrivateKey;
    } // namespace crypto
    } // namespace dht
    
    namespace jami {
    namespace tls {
    
    enum class TlsSessionState {
        NONE,
        SETUP,
        COOKIE, // only used with non-initiator and non-reliable transport
        HANDSHAKE,
        MTU_DISCOVERY, // only used with non-reliable transport
        ESTABLISHED,
        SHUTDOWN
    };
    
    using clock = std::chrono::steady_clock;
    using duration = clock::duration;
    
    struct TlsParams
    {
        // User CA list for session credentials
        std::string ca_list;
    
        std::shared_ptr<dht::crypto::Certificate> peer_ca;
    
        // User identity for credential
        std::shared_ptr<dht::crypto::Certificate> cert;
        std::shared_ptr<dht::crypto::PrivateKey> cert_key;
    
        // Diffie-Hellman computed by gnutls_dh_params_init/gnutls_dh_params_generateX
        std::shared_future<DhParams> dh_params;
    
        // handshake timeout
        duration timeout;
    
        // Callback for certificate checkings
        std::function<int(unsigned status, const gnutls_datum_t* cert_list, unsigned cert_list_size)>
            cert_check;
    };
    
    /// TlsSession
    ///
    /// Manages a TLS/DTLS data transport overlayed on a given generic socket.
    ///
    /// \note API is not thread-safe.
    ///
    class TlsSession : public GenericSocket<uint8_t>
    {
    public:
        using SocketType = GenericSocket<uint8_t>;
        using OnStateChangeFunc = std::function<void(TlsSessionState)>;
        using OnRxDataFunc = std::function<void(std::vector<uint8_t>&&)>;
        using OnCertificatesUpdate
            = std::function<void(const gnutls_datum_t*, const gnutls_datum_t*, unsigned int)>;
        using VerifyCertificate = std::function<int(gnutls_session_t)>;
    
        // ===> WARNINGS <===
        // Following callbacks are called into the FSM thread context
        // Do not call blocking routines inside them.
        using TlsSessionCallbacks = struct
        {
            OnStateChangeFunc onStateChange;
            OnRxDataFunc onRxData;
            OnCertificatesUpdate onCertificatesUpdate;
            VerifyCertificate verifyCertificate;
        };
    
        TlsSession(std::unique_ptr<SocketType>&& transport,
                   const TlsParams& params,
                   const TlsSessionCallbacks& cbs,
                   bool anonymous = true);
        ~TlsSession();
    
        /// Return the name of current cipher.
        /// Can be called by onStateChange callback when state == ESTABLISHED
        /// to obtain the used cypher suite id.
        const char* currentCipherSuiteId(std::array<uint8_t, 2>& cs_id) const;
    
        /// Request TLS thread to stop and quit.
        /// \note IO operations return error after this call.
        void shutdown() override;
    
        void setOnRecv(RecvCb&& cb) override
        {
            (void) cb;
            throw std::logic_error("TlsSession::setOnRecv not implemented");
        }
    
        /// Return true if the TLS session type is a server.
        bool isInitiator() const override;
    
        bool isReliable() const override;
    
        int maxPayload() const override;
    
        void waitForReady(const duration& timeout = {});
    
        /// Synchronous writing.
        /// Return a positive number for number of bytes write, or 0 and \a ec set in case of error.
        std::size_t write(const ValueType* data, std::size_t size, std::error_code& ec) override;
    
        /// Synchronous reading.
        /// Return a positive number for number of bytes read, or 0 and \a ec set in case of error.
        std::size_t read(ValueType* data, std::size_t size, std::error_code& ec) override;
    
        int waitForData(std::chrono::milliseconds, std::error_code&) const override;
    
    private:
        class TlsSessionImpl;
        std::unique_ptr<TlsSessionImpl> pimpl_;
    };
    
    } // namespace tls
    } // namespace jami