1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
.. _tls_api:
Transport Layer Security (TLS)
========================================
.. versionadded:: 1.10.2
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).
The implementation uses ``std::tr1::function`` for callbacks, so it
may not have been compiled into the version you are using; you can
test for the feature macro ``BOTAN_HAS_TLS`` to check.
General TLS Interface
----------------------------------------
TLS servers and clients share most of an interface, called
`TLS_Channel`. The primary difference is in terms of how the objects
are constructed. 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.
.. 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:: bool is_active()
Returns true if and only if a handshake has been completed on this
connection.
.. cpp:function:: bool is_closed()
Returns true if and only if a close notification has been sent or
received, or if a fatal alert of any kind was received from the
counterparty.
.. 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_complete* callback will be called again.
.. cpp:function:: std::vector<X509_Certificate> peer_cert_chain()
Returns the certificate chain of the server
TLS Clients
----------------------------------------
.. cpp:class:: TLS_Client
.. cpp:function:: TLS_Client( \
std::tr1::function<void, const byte*, size_t> socket_output_fn, \
std::tr1::function<void, const byte*, size_t, u16bit> proc_fn, \
std::tr1::function<bool, const TLS_Session&> handshake_complete, \
TLS_Session_Manager& session_manager, \
Credentials_Manager& credendials_manager, \
const TLS_Policy& policy, \
RandomNumberGenerator& rng, \
const std::string& servername = "", \
std::tr1::function<std::string, std::vector<std::string> > next_protocol)
Initialize a new TLS client. The constructor will immediately
initiate a new session. The *socket_output_fn* callback will be
called with output that should be sent to the counterparty.
The *proc_fn* will be called with data sent by the counterparty
after it has been processed. The byte array and size_t represent
the plaintext; the u16bit value provides notification if the
counterparty sent an alert via the TLS alert system. Possible values
of alert data are included in the Alert_Type enum. Particularly
relevant is the CLOSE_NOTIFY value.
The *handshake_complete* 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 *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
`TLS_Session_Manager_In_Memory` which caches connections for the
lifetime of a single process.
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 <credentials_manager>` for more
information.
Use *servername* to specify the DNS name of the server you are
attempting to connect to, if you know it.
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.
A simple TLS client example:
.. literalinclude:: examples/tls_client.cpp
TLS Servers
----------------------------------------
.. cpp:class:: TLS_Server
.. cpp:function:: TLS_Server(std::tr1::function<void, const byte*, size_t> socket_output_fn, \
std::tr1::function<void, const byte*, size_t, u16bit> proc_fn, \
std::tr1::function<bool, const TLS_Session&> handshake_complete, \
TLS_Session_Manager& session_manager, \
Credentials_Manager& creds, \
const TLS_Policy& policy, \
RandomNumberGenerator& rng, \
const std::vector<std::string>& protocols)
The first 7 arguments are treated similiarly to `TLS_Client`. The
final (optional) argument, protocols, specifies the protocols the
server is willing to advertise it supports.
A TLS server that can handle concurrent connections using asio:
.. literalinclude:: examples/asio_tls_server.cpp
|