/* net6 - Library providing IPv4/IPv6 network access * Copyright (C) 2005, 2006 Armin Burgmeier / 0x539 dev group * * 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _NET6_ENCRYPT_HPP_ #define _NET6_ENCRYPT_HPP_ #include #include #include "socket.hpp" //#include namespace net6 { // Newer versions of GNUTLS use types suffixed with _t. typedef gnutls_session gnutls_session_t; typedef gnutls_anon_client_credentials gnutls_anon_client_credentials_t; typedef gnutls_anon_server_credentials gnutls_anon_server_credentials_t; typedef gnutls_transport_ptr gnutls_transport_ptr_t; typedef gnutls_dh_params gnutls_dh_params_t; typedef gnutls_connection_end gnutls_connection_end_t; class dh_params: private net6::non_copyable { public: /** @brief Generates new params. */ dh_params(); /** @brief Takes ownership of given dh params. */ dh_params(gnutls_dh_params_t initial_params); ~dh_params(); gnutls_dh_params_t cobj(); const gnutls_dh_params_t cobj() const; protected: gnutls_dh_params_t params; }; class tcp_encrypted_socket_base: public tcp_client_socket { public: enum handshake_state { DEFAULT, HANDSHAKING, HANDSHAKED }; virtual ~tcp_encrypted_socket_base(); /** @brief Initiates a TLS handshake. * * Returns TRUE when the handshake has been completed and FALSE when * further data needs to be transmitted. You may then select and call * this function again when data is availabe to send and/or receive * (see tcp_encrypted_socket_base::get_dir()). * * TODO: Possibility to make this blocking */ bool handshake(); /** Returns true when GNUTLS tried to send data, but failed. * and false when GNUTLS tried to receive. */ bool get_dir() const; /** @brief Returns the amount of bytes remaining in the GnuTLS buffers. * * If a socket is selected for IO_INCOMING, the selector would not * return for this socket even if there is still data to be read when * GnuTLS already read that data and keeps it in its internal buffer. */ size_type get_pending() const; /** @brief Tries to send len bytes of data starting at * buf. * * The function returns the amount of bytes actually sent that may * be less than len. * * A handshake must have been performed before using this function. */ virtual size_type send(const void* buf, size_type len) const; /** @brief Tries to read len bytes of data into the buffer * starting at buf. * * The function returns the amount of bytes actually read that may * be less than len. * * A handshake must have been performed before using this function. */ virtual size_type recv(void* buf, size_type len) const; protected: /** Ownership of session is given to tcp_encrypted_socket_base. */ tcp_encrypted_socket_base(socket_type cobj, gnutls_session_t sess); template< typename buffer_type, ssize_t(*iofunc)(gnutls_session_t, buffer_type, size_t) > size_type io_impl(buffer_type buf, size_type len) const; gnutls_session_t session; handshake_state state; bool was_blocking; }; class tcp_encrypted_socket_client: public tcp_encrypted_socket_base { public: tcp_encrypted_socket_client(tcp_client_socket& sock); virtual ~tcp_encrypted_socket_client(); private: typedef gnutls_anon_client_credentials_t credentials_type; credentials_type anoncred; }; class tcp_encrypted_socket_server: public tcp_encrypted_socket_base { public: /** @brief Constructor creating its own dh_params. */ tcp_encrypted_socket_server(tcp_client_socket& sock); /** @brief Constructor using the given dh_params. */ tcp_encrypted_socket_server(tcp_client_socket& sock, dh_params& params); virtual ~tcp_encrypted_socket_server(); private: typedef gnutls_anon_server_credentials_t credentials_type; credentials_type anoncred; std::auto_ptr own_params; }; } // namespace net6 #endif // _NET6_ENCRYPT_HPP_