aboutsummaryrefslogtreecommitdiffstats
path: root/doc/manual/tls.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/tls.rst')
-rw-r--r--doc/manual/tls.rst753
1 files changed, 753 insertions, 0 deletions
diff --git a/doc/manual/tls.rst b/doc/manual/tls.rst
new file mode 100644
index 000000000..805bca823
--- /dev/null
+++ b/doc/manual/tls.rst
@@ -0,0 +1,753 @@
+
+Transport Layer Security (TLS)
+========================================
+
+.. versionadded:: 1.11.0
+
+Botan supports both client and server implementations of the SSL/TLS
+protocols, including SSL v3, TLS v1.0, TLS v1.1, and TLS v1.2 (the
+insecure and obsolete SSL v2 protocol is not supported, beyond
+processing SSL v2 client hellos which some clients still send for
+backwards compatability with ancient servers). There is also some
+initial support for DTLS (v1.0 and v1.2), a variant of TLS adapted for
+operation on datagram transports such as UDP and SCTP, though as of
+1.11.6 DTLS handshaking does not support timeouts or retransmissions,
+so it can only be used over reliable datagrams (such as SCTP with
+reliable transmission turned on for DTLS handshake packets). DTLS
+support should be considered as beta quality and further testing is
+invited.
+
+The TLS implementation does not know anything about sockets or the
+network layer. Instead, it calls a user provided callback (hereafter
+``output_fn``) whenever it has data that it would want to send to the
+other party (for instance, by writing it to a network socket), and
+whenever the application receives some data from the counterparty (for
+instance, by reading from a network socket) it passes that information
+to TLS using :cpp:func:`TLS::Channel::received_data`. If the data
+passed in results in some change in the state, such as a handshake
+completing, or some data or an alert being received from the other
+side, then a user provided callback will be invoked. If the reader is
+familiar with OpenSSL's BIO layer, it might be analagous to saying the
+only way of interacting with Botan's TLS is via a `BIO_mem` I/O
+abstraction. This makes the library completely agnostic to how you
+write your network layer, be it blocking sockets, libevent, asio, a
+message queue, etc.
+
+The callbacks that TLS calls have the signatures
+
+ .. cpp:function:: void output_fn(const byte data[], size_t data_len)
+
+ TLS requests that all bytes of *data* be queued up to send to the
+ counterparty. After this function returns, *data* will be
+ overwritten, so a copy of the input must be made if the callback
+ cannot send the data immediately.
+
+ .. cpp:function:: void data_cb(const byte data[], size_t data_len)
+
+ Called whenever application data is received from the other side
+ of the connection, in which case *data* and *data_len* specify
+ the data received. This array will be overwritten sometime after
+ the callback returns, so again a copy should be made if need be.
+
+ .. cpp:function:: void alert_cb(Alert alert, const byte data[], size_t data_len)
+
+ Called when an alert is received. Normally, data is null and
+ data_len is 0, as most alerts have no associated data. However,
+ if TLS heartbeats (see :rfc:`6520`) were negotiated, and we
+ initiated a heartbeat, then if/when the other party responds,
+ ``alert_cb`` will be called with whatever data was included in
+ the heartbeat response (if any) along with a psuedo-alert value
+ of ``HEARTBEAT_PAYLOAD``.
+
+ .. cpp:function:: bool handshake_cb(const TLS::Session& session)
+
+ Called whenever a negotiation completes. This can happen more
+ than once on any connection. The *session* parameter provides
+ information about the session which was established.
+
+ If this function returns false, the session will not be cached
+ for later resumption.
+
+ If this function wishes to cancel the handshake, it can throw an
+ exception which will send a close message to the counterparty and
+ reset the connection state.
+
+You can of course use tools like ``std::bind`` to bind additional
+parameters to your callback functions.
+
+TLS Channels
+----------------------------------------
+
+TLS servers and clients share an interface called `TLS::Channel`. A
+TLS channel (either client or server object) has these methods
+available:
+
+.. cpp:class:: TLS::Channel
+
+ .. cpp:function:: size_t received_data(const byte buf[], size_t buf_size)
+
+ This function is used to provide data sent by the counterparty
+ (eg data that you read off the socket layer). Depending on the
+ current protocol state and the amount of data provided this may
+ result in one or more callback functions that were provided to
+ the constructor being called.
+
+ The return value of ``received_data`` specifies how many more
+ bytes of input are needed to make any progress, unless the end of
+ the data fell exactly on a message boundary, in which case it
+ will return 0 instead.
+
+ .. cpp:function:: void send(const byte buf[], size_t buf_size)
+
+ If the connection has completed the initial handshake process,
+ the data provided is sent to the counterparty as TLS
+ traffic. Otherwise, an exception is thrown.
+
+ .. cpp:function:: void close()
+
+ A close notification is sent to the counterparty, and the
+ internal state is cleared.
+
+ .. cpp:function:: void send_alert(const Alert& alert)
+
+ Some other alert is sent to the counterparty. If the alert is
+ fatal, the internal state is cleared.
+
+ .. cpp:function:: bool is_active()
+
+ Returns true if and only if a handshake has been completed on
+ this connection and the connection has not been subsequently
+ closed.
+
+ .. cpp:function:: bool is_closed()
+
+ Returns true if and only if either a close notification or a
+ fatal alert message have been either sent or received.
+
+ .. cpp:function:: void renegotiate(bool force_full_renegotiation = false)
+
+ Initiates a renegotiation. The counterparty is allowed by the
+ protocol to ignore this request. If a successful renegotiation
+ occurs, the *handshake_cb* callback will be called again.
+
+ If *force_full_renegotiation* is false, then the client will
+ attempt to simply renew the current session - this will refresh
+ the symmetric keys but will not change the session master
+ secret. Otherwise it will initiate a completely new session.
+
+ For a server, if *force_full_renegotiation* is false, then a
+ session resumption will be allowed if the client attempts
+ it. Otherwise the server will prevent resumption and force the
+ creation of a new session.
+
+ .. cpp:function:: std::vector<X509_Certificate> peer_cert_chain()
+
+ Returns the certificate chain of the counterparty. When acting
+ as a client, this value will be non-empty unless the client's
+ policy allowed anonymous connections and the server then chose
+ an anonymous ciphersuite. Acting as a server, this value will
+ ordinarily be empty, unless the server requested a certificate
+ and the client responded with one.
+
+ .. cpp:function:: SymmetricKey key_material_export( \
+ const std::string& label, \
+ const std::string& context, \
+ size_t length)
+
+ Returns an exported key of *length* bytes derived from *label*,
+ *context*, and the session's master secret and client and server
+ random values. This key will be unique to this connection, and
+ as long as the session master secret remains secure an attacker
+ should not be able to guess the key.
+
+ Per :rfc:`5705`, *label* should begin with "EXPERIMENTAL" unless
+ the label has been standardized in an RFC.
+
+
+.. _tls_client:
+
+TLS Clients
+----------------------------------------
+
+.. cpp:class:: TLS::Client
+
+ .. cpp:function:: TLS::Client( \
+ std::function<void, const byte*, size_t> output_fn, \
+ std::function<void, const byte*, size_t> data_cb, \
+ std::function<TLS::Alert, const byte*, size_t> alert_cb,
+ std::function<bool, const TLS::Session&> handshake_cb, \
+ TLS::Session_Manager& session_manager, \
+ Credentials_Manager& credendials_manager, \
+ const TLS::Policy& policy, \
+ RandomNumberGenerator& rng, \
+ const Server_Information& server_info, \
+ const Protocol_Version offer_version, \
+ std::function<std::string, std::vector<std::string> > next_protocol, \
+ size_t reserved_io_buffer_size)
+
+ Initialize a new TLS client. The constructor will immediately
+ initiate a new session.
+
+ The *output_fn* callback will be called with output that
+ should be sent to the counterparty. For instance this will be
+ called immediately from the constructor after the client hello
+ message is constructed. An implementation of *output_fn* is
+ allowed to defer the write (for instance if writing when the
+ callback occurs would block), but should eventually write the data
+ to the counterparty *in order*.
+
+ The *data_cb* will be called with data sent by the counterparty
+ after it has been processed. The byte array and size_t represent
+ the plaintext value and size.
+
+ The *alert_cb* will be called when a protocol alert is received,
+ commonly with a close alert during connection teardown.
+
+ The *handshake_cb* function is called when a handshake
+ (either initial or renegotiation) is completed. The return value of
+ the callback specifies if the session should be cached for later
+ resumption. If the function for some reason desires to prevent the
+ connection from completing, it should throw an exception
+ (preferably a TLS::Exception, which can provide more specific alert
+ information to the counterparty). The :cpp:class:`TLS::Session`
+ provides information about the session that was just established.
+
+ The *session_manager* is an interface for storing TLS sessions,
+ which allows for session resumption upon reconnecting to a server.
+ In the absence of a need for persistent sessions, use
+ :cpp:class:`TLS::Session_Manager_In_Memory` which caches
+ connections for the lifetime of a single process. See
+ :ref:`tls_session_managers` for more about session managers.
+
+ The *credentials_manager* is an interface that will be called to
+ retrieve any certificates, secret keys, pre-shared keys, or SRP
+ intformation; see :doc:`credentials_manager` for more information.
+
+ Use *server_info* to specify the DNS name of the server you are
+ attempting to connect to, if you know it. This helps the server
+ select what certificate to use and helps the client validate the
+ connection.
+
+ Use *offer_version* to control the version of TLS you wish the
+ client to offer. Normally, you'll want to offer the most recent
+ version of TLS that is available, however some broken servers are
+ intolerant of certain versions being offered, and for classes of
+ applications that have to deal with such servers (typically web
+ browsers) it may be necessary to implement a version backdown
+ strategy if the initial attempt fails.
+
+ Setting *offer_version* is also used to offer DTLS instead of TLS;
+ use :cpp:func:`TLS::Protocol_Version::latest_dtls_version`.
+
+ .. warning::
+
+ Implementing such a backdown strategy allows an attacker to
+ downgrade your connection to the weakest protocol that both you
+ and the server support.
+
+ The optional *next_protocol* callback is called if the server
+ indicates it supports the next protocol notification extension.
+ The callback wlil be called with a list of protocol names that the
+ server advertises, and the client can select from them or return an
+ unadvertised protocol.
+
+ The optional *reserved_io_buffer_size* specifies how many bytes to
+ pre-allocate in the I/O buffers. Use this if you want to control
+ how much memory the channel uses initially (the buffers will be
+ resized as needed to process inputs). Otherwise some reasonable
+ default is used.
+
+A simple TLS client example:
+
+.. literalinclude:: ../../src/cmd/tls_client.cpp
+
+TLS Servers
+----------------------------------------
+
+.. cpp:class:: TLS::Server
+
+ .. cpp:function:: TLS::Server( \
+ std::function<void, const byte*, size_t> output_fn, \
+ std::function<void, const byte*, size_t> data_cb, \
+ std::function<TLS::Alert, const byte*, size_t> alert_cb,
+ TLS::Session_Manager& session_manager, \
+ Credentials_Manager& creds, \
+ const TLS::Policy& policy, \
+ RandomNumberGenerator& rng, \
+ const std::vector<std::string>& protocols, \
+ bool reserved_io_buffer_size)
+
+The first 7 arguments as well as the final argument
+*reserved_io_buffer_size*, are treated similiarly to the :ref:`client
+<tls_client>`. The (optional) argument, *protocols*, specifies the
+protocols the server is willing to advertise it supports.
+
+.. cpp:function:: std::string TLS::Server::next_protocol() const
+
+ If a handshake has completed, and if the client indicated a next
+ protocol (ie, the protocol that it intends to run over this TLS
+ session) this return value will specify it. The next protocol
+ extension is somewhat unusual in that it applies to the connection
+ rather than the session. The next protocol can not change during a
+ renegotiation, but might change across different connections using
+ that session.
+
+A TLS server that can handle concurrent connections using asio:
+
+.. literalinclude:: ../../src/cmd/tls_server_asio.cpp
+
+.. _tls_sessions:
+
+TLS Sessions
+----------------------------------------
+
+TLS allows clients and servers to support *session resumption*, where
+the end point retains some information about an established session
+and then reuse that information to bootstrap a new session in way that
+is much cheaper computationally than a full handshake.
+
+Every time your handshake callback is called, a new session has been
+established, and a ``TLS::Session`` is included that provides
+information about that session:
+
+.. cpp:class:: TLS::Session
+
+ .. cpp:function:: Protocol_Version version() const
+
+ Returns the :cpp:class:`protocol version <TLS::Protocol_Version>`
+ that was negotiated
+
+ .. cpp:function:: Ciphersuite ciphersite() const
+
+ Returns the :cpp:class:`ciphersuite <TLS::Ciphersuite>` that
+ was negotiated.
+
+ .. cpp:function:: Server_Information server_info() const
+
+ Returns information that identifies the server side of the
+ connection. This is useful for the client in that it
+ identifies what was originally passed to the constructor. For
+ the server, it includes the name the client specified in the
+ server name indicator extension.
+
+ .. cpp:function:: std::vector<X509_Certificate> peer_certs() const
+
+ Returns the certificate chain of the peer
+
+ .. cpp:function:: std::string srp_identifier() const
+
+ If an SRP ciphersuite was used, then this is the identifier
+ that was used for authentication.
+
+ .. cpp:function:: bool secure_renegotiation() const
+
+ Returns ``true`` if the connection was negotiated with the
+ correct extensions to prevent the renegotiation attack.
+
+There are also functions for serialization and deserializing sessions:
+
+.. cpp:class:: TLS::Session
+
+ .. cpp:function:: std::vector<byte> encrypt(const SymmetricKey& key, \
+ RandomNumberGenerator& rng)
+
+ Encrypts a session using a symmetric key *key* and returns a raw
+ binary value that can later be passed to ``decrypt``. The key
+ may be of any length.
+
+ Currently the implementation uses AES-256 in CBC mode with a
+ SHA-256 HMAC. The keys for these are derived from *key* using
+ KDF2(SHA-256).
+
+ .. cpp:function:: static Session decrypt(const byte ciphertext[], \
+ size_t length, \
+ const SymmetricKey& key)
+
+ Decrypts a session that was encrypted previously with
+ ``encrypt`` and *key*, or throws an exception if decryption
+ fails.
+
+ .. cpp:function:: secure_vector<byte> DER_encode() const
+
+ Returns a serialized version of the session.
+
+ .. warning:: The return value contains the master secret for
+ the session, and an attacker who recovers it could
+ recover plaintext of previous sessions or
+ impersonate one side to the other.
+
+.. _tls_session_managers:
+
+TLS Session Managers
+----------------------------------------
+
+You may want sessions stored in a specific format or storage type. To
+do so, implement the ``TLS::Session_Manager`` interface and pass your
+implementation to the ``TLS::Client`` or ``TLS::Server`` constructor.
+
+.. cpp:class:: TLS::Session_Mananger
+
+ .. cpp:function:: void save(const Session& session)
+
+ Save a new *session*. It is possible that this sessions session
+ ID will replicate a session ID already stored, in which case the
+ new session information should overwrite the previous information.
+
+ .. cpp:function:: void remove_entry(const std::vector<byte>& session_id)
+
+ Remove the session identified by *session_id*. Future attempts
+ at resumption should fail for this session.
+
+ .. cpp:function:: bool load_from_session_id(const std::vector<byte>& session_id, \
+ Session& session)
+
+ Attempt to resume a session identified by *session_id*. If
+ located, *session* is set to the session data previously passed
+ to *save*, and ``true`` is returned. Otherwise *session* is not
+ modified and ``false`` is returned.
+
+ .. cpp:function:: bool load_from_server_info(const Server_Information& server, \
+ Session& session)
+
+ Attempt to resume a session with a known server.
+
+ .. cpp:function:: std::chrono::seconds session_lifetime() const
+
+ Returns the expected maximum lifetime of a session when using
+ this session manager. Will return 0 if the lifetime is unknown
+ or has no explicit expiration policy.
+
+.. _tls_session_manager_inmem:
+
+In Memory Session Manager
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``TLS::Session_Manager_In_Memory`` implementation saves sessions
+in memory, with an upper bound on the maximum number of sessions and
+the lifetime of a session.
+
+It is safe to share a single object across many threads as it uses a
+lock internally.
+
+.. cpp:class:: TLS::Session_Managers_In_Memory
+
+ .. cpp:function:: Session_Manager_In_Memory(RandomNumberGenerator& rng, \
+ size_t max_sessions = 1000, \
+ std::chrono::seconds session_lifetime = 7200)
+
+ Limits the maximum number of saved sessions to *max_sessions*, and
+ expires all sessions older than *session_lifetime*.
+
+Noop Session Mananger
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``TLS::Session_Manager_Noop`` implementation does not save
+sessions at all, and thus session resumption always fails. Its
+constructor has no arguments.
+
+SQLite3 Session Manager
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This session manager is only available if support for SQLite3 was
+enabled at build time. If the macro
+``BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER`` is defined, then
+``botan/tls_session_manager_sqlite.h`` contains
+``TLS::Session_Manager_SQLite`` which stores sessions persistently to
+a sqlite3 database. The session data is encrypted using a passphrase,
+and stored in two tables, named ``tls_sessions`` (which holds the
+actual session information) and ``tls_sessions_metadata`` (which holds
+the PBKDF information).
+
+.. warning:: The hostnames associated with the saved sessions are
+ stored in the database in plaintext. This may be a
+ serious privacy risk in some applications.
+
+.. cpp:class:: TLS::Session_Manager_SQLite
+
+ .. cpp:function:: Session_Manager_SQLite( \
+ const std::string& passphrase, \
+ RandomNumberGenerator& rng, \
+ const std::string& db_filename, \
+ size_t max_sessions = 1000, \
+ std::chrono::seconds session_lifetime = 7200)
+
+ Uses the sqlite3 database named by *db_filename*.
+
+TLS Policies
+----------------------------------------
+
+``TLS::Policy`` is how an application can control details of what will
+be negotiated during a handshake.
+
+.. cpp:class:: TLS::Policy
+
+ .. cpp:function:: std::vector<std::string> allowed_ciphers() const
+
+ Returns the list of ciphers we are willing to negotiate, in order
+ of preference.
+
+ Default: "AES-256/GCM", "AES-128/GCM",
+ "AES-256/CCM", "AES-128/CCM", "AES-256/CCM-8", "AES-128/CCM-8",
+ "AES-256", "AES-128"
+
+ Also allowed: "Camellia-256/GCM", "Camellia-128/GCM",
+ "Camellia-256", "Camellia-128", "SEED", "3DES", "RC4"
+
+ .. note::
+
+ RC4 will never be negotiated in DTLS due to protocol limitations
+
+ .. cpp:function:: std::vector<std::string> allowed_macs() const
+
+ Returns the list of algorithms we are willing to use for
+ message authentication, in order of preference.
+
+ Default: "AEAD", "SHA-384", "SHA-256", "SHA-1"
+
+ Also allowed: "MD5"
+
+ .. cpp:function:: std::vector<std::string> allowed_key_exchange_methods() const
+
+ Returns the list of key exchange methods we are willing to use,
+ in order of preference.
+
+ Default: "ECDH", "DH", "RSA"
+
+ Also allowed: "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK"
+
+ .. cpp:function:: std::vector<std::string> allowed_signature_hashes() const
+
+ Returns the list of algorithms we are willing to use for
+ public key signatures, in order of preference.
+
+ Default: "SHA-512", "SHA-384", "SHA-256", "SHA-224"
+
+ Also allowed (although **not recommended**): "MD5", "SHA-1"
+
+ .. note::
+
+ This is only used with TLS v1.2. In earlier versions of the
+ protocol, signatures are fixed to using only SHA-1 (for
+ DSA/ECDSA) or a MD5/SHA-1 pair (for RSA).
+
+ .. cpp:function:: std::vector<std::string> allowed_signature_methods() const
+
+ Default: "ECDSA", "RSA", "DSA"
+
+ Also allowed: "" (meaning anonymous)
+
+ .. cpp:function:: std::vector<std::string> allowed_ecc_curves() const
+
+ Return a list of ECC curves we are willing to use, in order of preference.
+
+ Default: "brainpool512r1", "brainpool384r1", "brainpool256r1",
+ "secp521r1", "secp384r1", "secp256r1",
+ "secp256k1"
+
+ Also allowed: "secp224r1", "secp224k1", "secp192r1", "secp192k1",
+ "secp160r2", "secp160r1", "secp160k1"
+
+ .. cpp:function:: std::vector<byte> compression() const
+
+ Return the list of compression methods we are willing to use, in order of
+ preference. Default is null compression only.
+
+ .. note::
+
+ TLS compression is not currently supported.
+
+ .. cpp:function:: bool acceptable_protocol_version(Protocol_Version version)
+
+ Return true if this version of the protocol is one that we are
+ willing to negotiate.
+
+ Default: True if a known TLS version. DTLS is not accepted by default;
+ to enable DTLS (or combined TLS/DTLS) in your application, override this
+ function.
+
+ .. cpp:function:: bool server_uses_own_ciphersuite_preferences() const
+
+ If this returns true, a server will pick the cipher it prefers the
+ most out of the client's list. Otherwise, it will negotiate the
+ first cipher in the client's ciphersuite list that it supports.
+
+ .. cpp:function:: bool negotiate_heartbeat_support() const
+
+ If this function returns true, clients will offer the heartbeat
+ support extension, and servers will respond to clients offering
+ the extension. Otherwise, clients will not offer heartbeat
+ support and servers will ignore clients offering heartbeat
+ support.
+
+ If this returns true, callers should expect to handle heartbeat
+ data in their ``alert_cb``.
+
+ Default: false
+
+ .. cpp:function:: bool allow_server_initiated_renegotiation() const
+
+ If this function returns true, a client will accept a
+ server-initiated renegotiation attempt. Otherwise it will send
+ the server a non-fatal ``no_renegotiation`` alert.
+
+ Default: true
+
+ .. cpp:function:: bool allow_insecure_renegotiation() const
+
+ If this function returns true, we will allow renegotiation attempts
+ even if the counterparty does not support the RFC 5746 extensions.
+
+ .. warning:: Returning true here could expose you to attacks
+
+ Default: false
+
+ .. cpp:function:: DL_Group dh_group() const
+
+ For ephemeral Diffie-Hellman key exchange, the server sends a
+ group parameter. Return the group parameter a server should
+ use.
+
+ Default: 2048 bit IETF IPsec group ("modp/ietf/2048")
+
+ .. cpp:function:: size_t minimum_dh_group_size() const
+
+ Return the minimum size in bits for a Diffie-Hellman group that a
+ client will accept. Due to the design of the protocol the client
+ has only two options - accept the group, or reject it with a
+ fatal alert then attempt to reconnect after disabling ephemeral
+ Diffie-Hellman.
+
+ Default: 1024 bits
+
+ .. cpp:function:: bool hide_unknown_users() const
+
+ The SRP and PSK suites work using an identifier along with a
+ shared secret. If this function returns true, when an identifier
+ that the server does not recognize is provided by a client, a
+ random shared secret will be generated in such a way that a
+ client should not be able to tell the difference between the
+ identifier not being known and the secret being wrong. This can
+ help protect against some username probing attacks. If it
+ returns false, the server will instead send an
+ ``unknown_psk_identity`` alert when an unknown identifier is
+ used.
+
+ Default: false
+
+ .. cpp:function:: u32bit session_ticket_lifetime() const
+
+ Return the lifetime of session tickets. Each session includes the
+ start time. Sessions resumptions using tickets older than
+ ``session_ticket_lifetime`` seconds will fail, forcing a full
+ renegotiation.
+
+ Default: 86400 seconds (1 day)
+
+TLS Ciphersuites
+----------------------------------------
+
+.. cpp:class:: TLS::Ciphersuite
+
+ .. cpp:function:: u16bit ciphersuite_code() const
+
+ Return the numerical code for this ciphersuite
+
+ .. cpp:function:: std::string to_string() const
+
+ Return the ful name of ciphersuite (for example
+ "RSA_WITH_RC4_128_SHA" or "ECDHE_RSA_WITH_AES_128_GCM_SHA256")
+
+ .. cpp:function:: std::string kex_algo() const
+
+ Return the key exchange algorithm of this ciphersuite
+
+ .. cpp:function:: std::string sig_algo() const
+
+ Return the signature algorithm of this ciphersuite
+
+ .. cpp:function:: std::string cipher_algo() const
+
+ Return the cipher algorithm of this ciphersuite
+
+ .. cpp:function:: std::string mac_algo() const
+
+ Return the authentication algorithm of this ciphersuite
+
+.. _tls_alerts:
+
+TLS Alerts
+----------------------------------------
+
+A ``TLS::Alert`` is passed to every invocation of a channel's *alert_cb*.
+
+.. cpp:class:: TLS::Alert
+
+ .. cpp:function:: is_valid() const
+
+ Return true if this alert is not a null alert
+
+ .. cpp:function:: is_fatal() const
+
+ Return true if this alert is fatal. A fatal alert causes the
+ connection to be immediately disconnected. Otherwise, the alert
+ is a warning and the connection remains valid.
+
+ .. cpp:function:: Type type() const
+
+ Returns the type of the alert as an enum
+
+ .. cpp:function:: std::string type_string()
+
+ Returns the type of the alert as a string
+
+TLS Protocol Version
+----------------------------------------
+
+TLS has several different versions with slightly different behaviors.
+The ``TLS::Protocol_Version`` class represents a specific version:
+
+.. cpp:class:: TLS::Protocol_Version
+
+ .. cpp:type:: enum Version_Code
+
+ ``SSL_V3``, ``TLS_V10``, ``TLS_V11``, ``TLS_V12``, ``DTLS_V10``,
+ ``DTLS_V12``
+
+ .. cpp:function:: static Protocol_Version latest_tls_version()
+
+ Returns the latest version of TLS supported by this implementation
+ (currently TLS v1.2)
+
+ .. cpp:function:: static Protocol_Version latest_dtls_version()
+
+ Returns the latest version of DTLS supported by this implementation
+ (currently DTLS v1.2)
+
+ .. cpp:function:: Protocol_Version(Version_Code named_version)
+
+ Create a specific version
+
+ .. cpp:function:: byte major_version() const
+
+ Returns major number of the protocol version
+
+ .. cpp:function:: byte minor_version() const
+
+ Returns minor number of the protocol version
+
+ .. cpp:function:: std::string to_string() const
+
+ Returns string description of the version, for instance "SSL v3",
+ "TLS v1.1", or "DTLS v1.0".
+
+ .. cpp:function:: static Protocol_Version latest_tls_version()
+
+ Returns the latest version of the TLS protocol known the the library
+ (currently TLS v1.2)
+
+ .. cpp:function:: static Protocol_Version latest_dtls_version()
+
+ Returns the latest version of the DTLS protocol known the the
+ library (currently DTLS v1.2)
+
+