1Transport Layer Security (TLS) 2======================================== 3 4.. versionadded:: 1.11.0 5 6Botan has client and server implementations of various versions of the 7TLS protocol, including TLS v1.0, TLS v1.1, and TLS v1.2. As of 8version 1.11.13, support for the insecure SSLv3 protocol has been 9removed. 10 11There is also support for DTLS (v1.0 and v1.2), a variant of TLS 12adapted for operation on datagram transports such as UDP and 13SCTP. DTLS support should be considered as beta quality and further 14testing is invited. 15 16The TLS implementation does not know anything about sockets or the 17network layer. Instead, it calls a user provided callback (hereafter 18``output_fn``) whenever it has data that it would want to send to the 19other party (for instance, by writing it to a network socket), and 20whenever the application receives some data from the counterparty (for 21instance, by reading from a network socket) it passes that information 22to TLS using :cpp:func:`TLS::Channel::received_data`. If the data 23passed in results in some change in the state, such as a handshake 24completing, or some data or an alert being received from the other 25side, then the appropriate user provided callback will be invoked. 26 27If the reader is familiar with OpenSSL's BIO layer, it might be analogous 28to saying the only way of interacting with Botan's TLS is via a `BIO_mem` I/O 29abstraction. This makes the library completely agnostic to how you 30write your network layer, be it blocking sockets, libevent, asio, a 31message queue, lwIP on RTOS, some carrier pigeons, etc. 32 33Starting in 1.11.31, the application callbacks are encapsulated as the class 34``TLS::Callbacks`` with the following members. The first four (``tls_emit_data``, 35``tls_record_received``, ``tls_alert``, and ``tls_session_established``) are 36mandatory for using TLS, all others are optional and provide additional 37information about the connection. 38 39 .. cpp:function:: void tls_emit_data(const uint8_t data[], size_t data_len) 40 41 Mandatory. The TLS stack requests that all bytes of *data* be queued up to send to the 42 counterparty. After this function returns, the buffer containing *data* will 43 be overwritten, so a copy of the input must be made if the callback 44 cannot send the data immediately. 45 46 As an example you could ``send`` to perform a blocking write on a socket, 47 or append the data to a queue managed by your application, and initiate 48 an asynchronous write. 49 50 For TLS all writes must occur *in the order requested*. 51 For DTLS this ordering is not strictly required, but is still recommended. 52 53 .. cpp:function:: void tls_record_received(uint64_t rec_no, const uint8_t data[], size_t data_len) 54 55 Mandatory. Called once for each application_data record which is received, with the 56 matching (TLS level) record sequence number. 57 58 Currently empty records are ignored and do not instigate a callback, 59 but this may change in a future release. 60 61 As with ``tls_emit_data``, the array will be overwritten sometime after 62 the callback returns, so a copy should be made if needed. 63 64 For TLS the record number will always increase. 65 66 For DTLS, it is possible to receive records with the `rec_no` field out of 67 order, or with gaps, corresponding to reordered or lost datagrams. 68 69 .. cpp:function:: void tls_alert(Alert alert) 70 71 Mandatory. Called when an alert is received from the peer. Note that alerts 72 received before the handshake is complete are not authenticated and 73 could have been inserted by a MITM attacker. 74 75 .. cpp:function:: bool tls_session_established(const TLS::Session& session) 76 77 Mandatory. Called whenever a negotiation completes. This can happen more 78 than once on any connection, if renegotiation occurs. The *session* parameter 79 provides information about the session which was just established. 80 81 If this function returns false, the session will not be cached 82 for later resumption. 83 84 If this function wishes to cancel the handshake, it can throw an 85 exception which will send a close message to the counterparty and 86 reset the connection state. 87 88 .. cpp:function:: void tls_verify_cert_chain(const std::vector<X509_Certificate>& cert_chain, \ 89 const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, \ 90 const std::vector<Certificate_Store*>& trusted_roots, \ 91 Usage_Type usage, \ 92 const std::string& hostname, \ 93 const Policy& policy) 94 95 Optional - default implementation should work for many users. 96 It can be overridden for implementing extra validation routines 97 such as public key pinning. 98 99 Verifies the certificate chain in *cert_chain*, assuming the leaf 100 certificate is the first element. Throws an exception if any 101 error makes this certificate chain unacceptable. 102 103 If usage is `Usage_Type::TLS_SERVER_AUTH`, then *hostname* should 104 match the information in the server certificate. If usage is 105 `TLS_CLIENT_AUTH`, then *hostname* specifies the host the client 106 is authenticating against (from SNI); the callback can use this for 107 any special site specific auth logic. 108 109 The `ocsp_responses` is a possibly empty list of OCSP responses provided by 110 the server. In the current implementation of TLS OCSP stapling, only a 111 single OCSP response can be returned. A existing TLS extension allows the 112 server to send multiple OCSP responses, this extension may be supported in 113 the future in which case more than one OCSP response may be given during 114 this callback. 115 116 The `trusted_roots` parameter was returned by a call from the associated 117 `Credentials_Manager`. 118 119 The `policy` provided is the policy for the TLS session which is 120 being authenticated using this certificate chain. It can be consulted 121 for values such as allowable signature methods and key sizes. 122 123 .. cpp:function:: std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const 124 125 Called by default `tls_verify_cert_chain` to set timeout for online OCSP requests 126 on the certificate chain. Return 0 to disable OCSP. Current default is 0. 127 128 .. cpp:function:: std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos) 129 130 Optional. Called by the server when a client includes a list of protocols in the ALPN extension. 131 The server then choose which protocol to use, or "" to disable sending any ALPN response. 132 The default implementation returns the empty string all of the time, effectively disabling 133 ALPN responses. 134 135 .. cpp:function:: void tls_session_activated() 136 137 Optional. By default does nothing. This is called when the session is 138 activated, that is once it is possible to send or receive data on the 139 channel. In particular it is possible for an implementation of this 140 function to perform an initial write on the channel. 141 142 .. cpp:function:: std::vector<uint8_t> tls_provide_cert_status(const std::vector<X509_Certificate>& chain, \ 143 const Certificate_Status_Request& csr) 144 145 Optional. This can return a cached OCSP response. This is only 146 used on the server side, and only if the client requests OCSP 147 stapling. 148 149 .. cpp:function:: std::string tls_peer_network_identity() 150 151 Optional. Return a string that identifies the peer in some unique way 152 (for example, by formatting the remote IP and port into a string). 153 This is currently used to bind DTLS cookies to the network identity. 154 155 .. cpp:function:: void tls_inspect_handshake_msg(const Handshake_Message&) 156 157 This callback is optional, and can be used to inspect all handshake messages 158 while the session establishment occurs. 159 160 .. cpp:function:: void tls_modify_extensions(Extensions& extn, Connection_Side which_side) 161 162 This callback is optional, and can be used to modify extensions before they 163 are sent to the peer. For example this enables adding a custom extension, 164 or replacing or removing an extension set by the library. 165 166 .. cpp:function:: void tls_examine_extensions(const Extensions& extn, Connection_Side which_side) 167 168 This callback is optional, and can be used to examine extensions sent by 169 the peer. 170 171 .. cpp:function:: void tls_log_error(const char* msg) 172 173 Optional logging for an error message. (Not currently used) 174 175 .. cpp:function:: void tls_log_debug(const char* msg) 176 177 Optional logging for an debug message. (Not currently used) 178 179 .. cpp:function:: void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t len) 180 181 Optional logging for an debug value. (Not currently used) 182 183 .. cpp:function:: std::string tls_decode_group_param(TLS::Group_Params group_param) 184 185 Optional. Called by the server when a client hello includes a list of supported groups in the 186 supported_groups extension and by the client when decoding the server key exchange including the selected curve identifier. 187 The function should return the name of the DH group or elliptic curve the passed 188 TLS group identifier should be mapped to. Therefore this callback enables the use of custom 189 elliptic curves or DH groups in TLS, if both client and server map the custom identifiers correctly. 190 Please note that it is required to allow the group TLS identifier in 191 in the used :cpp:class:`TLS::Policy`. 192 193Versions from 1.11.0 to 1.11.30 did not have ``TLS::Callbacks`` and instead 194used independent std::functions to pass the various callback functions. 195This interface is currently still included but is deprecated and will be removed 196in a future release. For the documentation for this interface, please check 197the docs for 1.11.30. This version of the manual only documents the new interface 198added in 1.11.31. 199 200TLS Channels 201---------------------------------------- 202 203TLS servers and clients share an interface called `TLS::Channel`. A 204TLS channel (either client or server object) has these methods 205available: 206 207.. cpp:class:: TLS::Channel 208 209 .. cpp:function:: size_t received_data(const uint8_t buf[], size_t buf_size) 210 .. cpp:function:: size_t received_data(const std::vector<uint8_t>& buf) 211 212 This function is used to provide data sent by the counterparty 213 (eg data that you read off the socket layer). Depending on the 214 current protocol state and the amount of data provided this may 215 result in one or more callback functions that were provided to 216 the constructor being called. 217 218 The return value of ``received_data`` specifies how many more 219 bytes of input are needed to make any progress, unless the end of 220 the data fell exactly on a message boundary, in which case it 221 will return 0 instead. 222 223 .. cpp:function:: void send(const uint8_t buf[], size_t buf_size) 224 .. cpp:function:: void send(const std::string& str) 225 .. cpp:function:: void send(const std::vector<uint8_t>& vec) 226 227 Create one or more new TLS application records containing the 228 provided data and send them. This will eventually result in at 229 least one call to the ``output_fn`` callback before ``send`` 230 returns. 231 232 If the current TLS connection state is unable to transmit new 233 application records (for example because a handshake has not 234 yet completed or the connection has already ended due to an 235 error) an exception will be thrown. 236 237 .. cpp:function:: void close() 238 239 A close notification is sent to the counterparty, and the 240 internal state is cleared. 241 242 .. cpp:function:: void send_alert(const Alert& alert) 243 244 Some other alert is sent to the counterparty. If the alert is 245 fatal, the internal state is cleared. 246 247 .. cpp:function:: bool is_active() 248 249 Returns true if and only if a handshake has been completed on 250 this connection and the connection has not been subsequently 251 closed. 252 253 .. cpp:function:: bool is_closed() 254 255 Returns true if and only if either a close notification or a 256 fatal alert message have been either sent or received. 257 258 .. cpp:function:: bool timeout_check() 259 260 This function does nothing unless the channel represents a DTLS 261 connection and a handshake is actively in progress. In this case 262 it will check the current timeout state and potentially initiate 263 retransmission of handshake packets. Returns true if a timeout 264 condition occurred. 265 266 .. cpp:function:: void renegotiate(bool force_full_renegotiation = false) 267 268 Initiates a renegotiation. The counterparty is allowed by the 269 protocol to ignore this request. If a successful renegotiation 270 occurs, the *handshake_cb* callback will be called again. 271 272 If *force_full_renegotiation* is false, then the client will 273 attempt to simply renew the current session - this will refresh 274 the symmetric keys but will not change the session master 275 secret. Otherwise it will initiate a completely new session. 276 277 For a server, if *force_full_renegotiation* is false, then a 278 session resumption will be allowed if the client attempts 279 it. Otherwise the server will prevent resumption and force the 280 creation of a new session. 281 282 .. cpp:function:: std::vector<X509_Certificate> peer_cert_chain() 283 284 Returns the certificate chain of the counterparty. When acting 285 as a client, this value will be non-empty unless the client's 286 policy allowed anonymous connections and the server then chose 287 an anonymous ciphersuite. Acting as a server, this value will 288 ordinarily be empty, unless the server requested a certificate 289 and the client responded with one. 290 291 .. cpp:function:: SymmetricKey key_material_export( \ 292 const std::string& label, \ 293 const std::string& context, \ 294 size_t length) 295 296 Returns an exported key of *length* bytes derived from *label*, 297 *context*, and the session's master secret and client and server 298 random values. This key will be unique to this connection, and 299 as long as the session master secret remains secure an attacker 300 should not be able to guess the key. 301 302 Per :rfc:`5705`, *label* should begin with "EXPERIMENTAL" unless 303 the label has been standardized in an RFC. 304 305.. _tls_client: 306 307TLS Clients 308---------------------------------------- 309 310.. cpp:class:: TLS::Client 311 312 .. cpp:function:: Client( \ 313 Callbacks& callbacks, \ 314 Session_Manager& session_manager, \ 315 Credentials_Manager& creds, \ 316 const Policy& policy, \ 317 RandomNumberGenerator& rng, \ 318 const Server_Information& server_info = Server_Information(), \ 319 const Protocol_Version offer_version = Protocol_Version::latest_tls_version(), \ 320 const std::vector<std::string>& next_protocols = std::vector<std::string>(), \ 321 size_t reserved_io_buffer_size = 16*1024 \ 322 ) 323 324 Initialize a new TLS client. The constructor will immediately 325 initiate a new session. 326 327 The *callbacks* parameter specifies the various application callbacks 328 which pertain to this particular client connection. 329 330 The *session_manager* is an interface for storing TLS sessions, 331 which allows for session resumption upon reconnecting to a server. 332 In the absence of a need for persistent sessions, use 333 :cpp:class:`TLS::Session_Manager_In_Memory` which caches 334 connections for the lifetime of a single process. See 335 :ref:`tls_session_managers` for more about session managers. 336 337 The *credentials_manager* is an interface that will be called to 338 retrieve any certificates, secret keys, pre-shared keys, or SRP 339 information; see :doc:`credentials_manager` for more information. 340 341 Use the optional *server_info* to specify the DNS name of the 342 server you are attempting to connect to, if you know it. This helps 343 the server select what certificate to use and helps the client 344 validate the connection. 345 346 Note that the server name indicator name must be a FQDN. IP 347 addresses are not allowed by RFC 6066 and may lead to interoperability 348 problems. 349 350 Use the optional *offer_version* to control the version of TLS you 351 wish the client to offer. Normally, you'll want to offer the most 352 recent version of (D)TLS that is available, however some broken 353 servers are intolerant of certain versions being offered, and for 354 classes of applications that have to deal with such servers 355 (typically web browsers) it may be necessary to implement a version 356 backdown strategy if the initial attempt fails. 357 358 .. warning:: 359 360 Implementing such a backdown strategy allows an attacker to 361 downgrade your connection to the weakest protocol that both you 362 and the server support. 363 364 Setting *offer_version* is also used to offer DTLS instead of TLS; 365 use :cpp:func:`TLS::Protocol_Version::latest_dtls_version`. 366 367 Optionally, the client will advertise *app_protocols* to the 368 server using the ALPN extension. 369 370 The optional *reserved_io_buffer_size* specifies how many bytes to 371 pre-allocate in the I/O buffers. Use this if you want to control 372 how much memory the channel uses initially (the buffers will be 373 resized as needed to process inputs). Otherwise some reasonable 374 default is used. 375 376Code Example 377^^^^^^^^^^^^ 378A minimal example of a TLS client is provided below. 379The full code for a TLS client using BSD sockets is in `src/cli/tls_client.cpp` 380 381.. code-block:: cpp 382 383 #include <botan/tls_client.h> 384 #include <botan/tls_callbacks.h> 385 #include <botan/tls_session_manager.h> 386 #include <botan/tls_policy.h> 387 #include <botan/auto_rng.h> 388 #include <botan/certstor.h> 389 390 /** 391 * @brief Callbacks invoked by TLS::Channel. 392 * 393 * Botan::TLS::Callbacks is an abstract class. 394 * For improved readability, only the functions that are mandatory 395 * to implement are listed here. See src/lib/tls/tls_callbacks.h. 396 */ 397 class Callbacks : public Botan::TLS::Callbacks 398 { 399 public: 400 void tls_emit_data(const uint8_t data[], size_t size) override 401 { 402 // send data to tls server, e.g., using BSD sockets or boost asio 403 } 404 405 void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override 406 { 407 // process full TLS record received by tls server, e.g., 408 // by passing it to the application 409 } 410 411 void tls_alert(Botan::TLS::Alert alert) override 412 { 413 // handle a tls alert received from the tls server 414 } 415 416 bool tls_session_established(const Botan::TLS::Session& session) override 417 { 418 // the session with the tls server was established 419 // return false to prevent the session from being cached, true to 420 // cache the session in the configured session manager 421 return false; 422 } 423 }; 424 425 /** 426 * @brief Credentials storage for the tls client. 427 * 428 * It returns a list of trusted CA certificates from a local directory. 429 * TLS client authentication is disabled. See src/lib/tls/credentials_manager.h. 430 */ 431 class Client_Credentials : public Botan::Credentials_Manager 432 { 433 public: 434 Client_Credentials() 435 { 436 // Here we base trust on the system managed trusted CA list 437 m_stores.push_back(new Botan::System_Certificate_Store); 438 } 439 440 std::vector<Botan::Certificate_Store*> trusted_certificate_authorities( 441 const std::string& type, 442 const std::string& context) override 443 { 444 // return a list of certificates of CAs we trust for tls server certificates 445 // ownership of the pointers remains with Credentials_Manager 446 return m_stores; 447 } 448 449 std::vector<Botan::X509_Certificate> cert_chain( 450 const std::vector<std::string>& cert_key_types, 451 const std::string& type, 452 const std::string& context) override 453 { 454 // when using tls client authentication (optional), return 455 // a certificate chain being sent to the tls server, 456 // else an empty list 457 return std::vector<Botan::X509_Certificate>(); 458 } 459 460 Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert, 461 const std::string& type, 462 const std::string& context) override 463 { 464 // when returning a chain in cert_chain(), return the private key 465 // associated with the leaf certificate here 466 return nullptr; 467 } 468 469 private: 470 std::vector<Botan::Certificate_Store*> m_stores; 471 }; 472 473 int main() 474 { 475 // prepare all the parameters 476 Callbacks callbacks; 477 Botan::AutoSeeded_RNG rng; 478 Botan::TLS::Session_Manager_In_Memory session_mgr(rng); 479 Client_Credentials creds; 480 Botan::TLS::Strict_Policy policy; 481 482 // open the tls connection 483 Botan::TLS::Client client(callbacks, 484 session_mgr, 485 creds, 486 policy, 487 rng, 488 Botan::TLS::Server_Information("botan.randombit.net", 443), 489 Botan::TLS::Protocol_Version::TLS_V12); 490 491 while(!client.is_closed()) 492 { 493 // read data received from the tls server, e.g., using BSD sockets or boost asio 494 // ... 495 496 // send data to the tls server using client.send_data() 497 } 498 } 499 500.. _tls_server: 501 502TLS Servers 503---------------------------------------- 504 505.. cpp:class:: TLS::Server 506 507 .. cpp:function:: Server( \ 508 Callbacks& callbacks, \ 509 Session_Manager& session_manager, \ 510 Credentials_Manager& creds, \ 511 const Policy& policy, \ 512 RandomNumberGenerator& rng, \ 513 bool is_datagram = false, \ 514 size_t reserved_io_buffer_size = 16*1024 \ 515 ) 516 517The first 5 arguments as well as the final argument 518*reserved_io_buffer_size*, are treated similarly to the :ref:`client 519<tls_client>`. 520 521If a client sends the ALPN extension, the ``callbacks`` function 522``tls_server_choose_app_protocol`` will be called and the result 523sent back to the client. If the empty string is returned, the server 524will not send an ALPN response. The function can also throw an exception 525to abort the handshake entirely, the ALPN specification says that if this 526occurs the alert should be of type `NO_APPLICATION_PROTOCOL`. 527 528The optional argument *is_datagram* specifies if this is a TLS or DTLS 529server; unlike clients, which know what type of protocol (TLS vs DTLS) 530they are negotiating from the start via the *offer_version*, servers 531would not until they actually received a client hello. 532 533Code Example 534^^^^^^^^^^^^ 535A minimal example of a TLS server is provided below. 536The full code for a TLS server using asio is in `src/cli/tls_proxy.cpp`. 537 538.. code-block:: cpp 539 540 #include <botan/tls_client.h> 541 #include <botan/tls_callbacks.h> 542 #include <botan/tls_session_manager.h> 543 #include <botan/tls_policy.h> 544 #include <botan/auto_rng.h> 545 #include <botan/certstor.h> 546 #include <botan/pk_keys.h> 547 548 #include <memory> 549 550 /** 551 * @brief Callbacks invoked by TLS::Channel. 552 * 553 * Botan::TLS::Callbacks is an abstract class. 554 * For improved readability, only the functions that are mandatory 555 * to implement are listed here. See src/lib/tls/tls_callbacks.h. 556 */ 557 class Callbacks : public Botan::TLS::Callbacks 558 { 559 public: 560 void tls_emit_data(const uint8_t data[], size_t size) override 561 { 562 // send data to tls client, e.g., using BSD sockets or boost asio 563 } 564 565 void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override 566 { 567 // process full TLS record received by tls client, e.g., 568 // by passing it to the application 569 } 570 571 void tls_alert(Botan::TLS::Alert alert) override 572 { 573 // handle a tls alert received from the tls server 574 } 575 576 bool tls_session_established(const Botan::TLS::Session& session) override 577 { 578 // the session with the tls client was established 579 // return false to prevent the session from being cached, true to 580 // cache the session in the configured session manager 581 return false; 582 } 583 }; 584 585 /** 586 * @brief Credentials storage for the tls server. 587 * 588 * It returns a certificate and the associated private key to 589 * authenticate the tls server to the client. 590 * TLS client authentication is not requested. 591 * See src/lib/tls/credentials_manager.h. 592 */ 593 class Server_Credentials : public Botan::Credentials_Manager 594 { 595 public: 596 Server_Credentials() : m_key(Botan::PKCS8::load_key("botan.randombit.net.key")) 597 { 598 } 599 600 std::vector<Botan::Certificate_Store*> trusted_certificate_authorities( 601 const std::string& type, 602 const std::string& context) override 603 { 604 // if client authentication is required, this function 605 // shall return a list of certificates of CAs we trust 606 // for tls client certificates, otherwise return an empty list 607 return std::vector<Certificate_Store*>(); 608 } 609 610 std::vector<Botan::X509_Certificate> cert_chain( 611 const std::vector<std::string>& cert_key_types, 612 const std::string& type, 613 const std::string& context) override 614 { 615 // return the certificate chain being sent to the tls client 616 // e.g., the certificate file "botan.randombit.net.crt" 617 return { Botan::X509_Certificate("botan.randombit.net.crt") }; 618 } 619 620 Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert, 621 const std::string& type, 622 const std::string& context) override 623 { 624 // return the private key associated with the leaf certificate, 625 // in this case the one associated with "botan.randombit.net.crt" 626 return &m_key; 627 } 628 629 private: 630 std::unique_ptr<Botan::Private_Key> m_key; 631 }; 632 633 int main() 634 { 635 // prepare all the parameters 636 Callbacks callbacks; 637 Botan::AutoSeeded_RNG rng; 638 Botan::TLS::Session_Manager_In_Memory session_mgr(rng); 639 Server_Credentials creds; 640 Botan::TLS::Strict_Policy policy; 641 642 // accept tls connection from client 643 Botan::TLS::Server server(callbacks, 644 session_mgr, 645 creds, 646 policy, 647 rng); 648 649 // read data received from the tls client, e.g., using BSD sockets or boost asio 650 // and pass it to server.received_data(). 651 // ... 652 653 // send data to the tls client using server.send_data() 654 // ... 655 } 656 657.. _tls_sessions: 658 659TLS Sessions 660---------------------------------------- 661 662TLS allows clients and servers to support *session resumption*, where 663the end point retains some information about an established session 664and then reuse that information to bootstrap a new session in way that 665is much cheaper computationally than a full handshake. 666 667Every time your handshake callback is called, a new session has been 668established, and a ``TLS::Session`` is included that provides 669information about that session: 670 671.. note:: 672 673 The serialization format of Session is not considered stable and is allowed 674 to change even across minor releases. In the event of such a change, old 675 sessions will no longer be able to be resumed. 676 677.. cpp:class:: TLS::Session 678 679 .. cpp:function:: Protocol_Version version() const 680 681 Returns the :cpp:class:`protocol version <TLS::Protocol_Version>` 682 that was negotiated 683 684 .. cpp:function:: Ciphersuite ciphersite() const 685 686 Returns the :cpp:class:`ciphersuite <TLS::Ciphersuite>` that 687 was negotiated. 688 689 .. cpp:function:: Server_Information server_info() const 690 691 Returns information that identifies the server side of the 692 connection. This is useful for the client in that it 693 identifies what was originally passed to the constructor. For 694 the server, it includes the name the client specified in the 695 server name indicator extension. 696 697 .. cpp:function:: std::vector<X509_Certificate> peer_certs() const 698 699 Returns the certificate chain of the peer 700 701 .. cpp:function:: std::string srp_identifier() const 702 703 If an SRP ciphersuite was used, then this is the identifier 704 that was used for authentication. 705 706 .. cpp:function:: bool secure_renegotiation() const 707 708 Returns ``true`` if the connection was negotiated with the 709 correct extensions to prevent the renegotiation attack. 710 711 .. cpp:function:: std::vector<uint8_t> encrypt(const SymmetricKey& key, \ 712 RandomNumberGenerator& rng) 713 714 Encrypts a session using a symmetric key *key* and returns a raw 715 binary value that can later be passed to ``decrypt``. The key 716 may be of any length. The format is described in 717 :ref:`tls_session_encryption`. 718 719 .. cpp:function:: static Session decrypt(const uint8_t ciphertext[], \ 720 size_t length, \ 721 const SymmetricKey& key) 722 723 Decrypts a session that was encrypted previously with ``encrypt`` and 724 ``key``, or throws an exception if decryption fails. 725 726 .. cpp:function:: secure_vector<uint8_t> DER_encode() const 727 728 Returns a serialized version of the session. 729 730 .. warning:: The return value of ``DER_encode`` contains the 731 master secret for the session, and an attacker who 732 recovers it could recover plaintext of previous 733 sessions or impersonate one side to the other. 734 735.. _tls_session_managers: 736 737TLS Session Managers 738---------------------------------------- 739 740You may want sessions stored in a specific format or storage type. To 741do so, implement the ``TLS::Session_Manager`` interface and pass your 742implementation to the ``TLS::Client`` or ``TLS::Server`` constructor. 743 744.. cpp:class:: TLS::Session_Mananger 745 746 .. cpp:function:: void save(const Session& session) 747 748 Save a new *session*. It is possible that this sessions session 749 ID will replicate a session ID already stored, in which case the 750 new session information should overwrite the previous information. 751 752 .. cpp:function:: void remove_entry(const std::vector<uint8_t>& session_id) 753 754 Remove the session identified by *session_id*. Future attempts 755 at resumption should fail for this session. 756 757 .. cpp:function:: bool load_from_session_id(const std::vector<uint8_t>& session_id, \ 758 Session& session) 759 760 Attempt to resume a session identified by *session_id*. If 761 located, *session* is set to the session data previously passed 762 to *save*, and ``true`` is returned. Otherwise *session* is not 763 modified and ``false`` is returned. 764 765 .. cpp:function:: bool load_from_server_info(const Server_Information& server, \ 766 Session& session) 767 768 Attempt to resume a session with a known server. 769 770 .. cpp:function:: std::chrono::seconds session_lifetime() const 771 772 Returns the expected maximum lifetime of a session when using 773 this session manager. Will return 0 if the lifetime is unknown 774 or has no explicit expiration policy. 775 776.. _tls_session_manager_inmem: 777 778In Memory Session Manager 779^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 780 781The ``TLS::Session_Manager_In_Memory`` implementation saves sessions 782in memory, with an upper bound on the maximum number of sessions and 783the lifetime of a session. 784 785It is safe to share a single object across many threads as it uses a 786lock internally. 787 788.. cpp:class:: TLS::Session_Managers_In_Memory 789 790 .. cpp:function:: Session_Manager_In_Memory(RandomNumberGenerator& rng, \ 791 size_t max_sessions = 1000, \ 792 std::chrono::seconds session_lifetime = 7200) 793 794 Limits the maximum number of saved sessions to *max_sessions*, and 795 expires all sessions older than *session_lifetime*. 796 797Noop Session Mananger 798^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 799 800The ``TLS::Session_Manager_Noop`` implementation does not save 801sessions at all, and thus session resumption always fails. Its 802constructor has no arguments. 803 804SQLite3 Session Manager 805^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 806 807This session manager is only available if support for SQLite3 was 808enabled at build time. If the macro 809``BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER`` is defined, then 810``botan/tls_session_manager_sqlite.h`` contains 811``TLS::Session_Manager_SQLite`` which stores sessions persistently to 812a sqlite3 database. The session data is encrypted using a passphrase, 813and stored in two tables, named ``tls_sessions`` (which holds the 814actual session information) and ``tls_sessions_metadata`` (which holds 815the PBKDF information). 816 817.. warning:: The hostnames associated with the saved sessions are 818 stored in the database in plaintext. This may be a 819 serious privacy risk in some applications. 820 821.. cpp:class:: TLS::Session_Manager_SQLite 822 823 .. cpp:function:: Session_Manager_SQLite( \ 824 const std::string& passphrase, \ 825 RandomNumberGenerator& rng, \ 826 const std::string& db_filename, \ 827 size_t max_sessions = 1000, \ 828 std::chrono::seconds session_lifetime = 7200) 829 830 Uses the sqlite3 database named by *db_filename*. 831 832TLS Policies 833---------------------------------------- 834 835``TLS::Policy`` is how an application can control details of what will 836be negotiated during a handshake. The base class acts as the default 837policy. There is also a ``Strict_Policy`` (which forces only secure 838options, reducing compatibility) and ``Text_Policy`` which reads 839policy settings from a file. 840 841.. cpp:class:: TLS::Policy 842 843 .. cpp:function:: std::vector<std::string> allowed_ciphers() const 844 845 Returns the list of ciphers we are willing to negotiate, in order 846 of preference. 847 848 Clients send a list of ciphersuites in order of preference, 849 servers are free to choose any of them. Some servers will use the 850 clients preferences, others choose from the clients list 851 prioritizing based on its preferences. 852 853 No export key exchange mechanisms or ciphersuites are supported 854 by botan. The null encryption ciphersuites (which provide only 855 authentication, sending data in cleartext) are also not supported 856 by the implementation and cannot be negotiated. 857 858 Cipher names without an explicit mode refers to CBC+HMAC ciphersuites. 859 860 Default value: "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM" 861 862 Also allowed: "AES-256", "AES-128", 863 "AES-256/CCM", "AES-128/CCM", "AES-256/CCM(8)", "AES-128/CCM(8)", 864 "Camellia-256/GCM", "Camellia-128/GCM", "ARIA-256/GCM", "ARIA-128/GCM", 865 "Camellia-256", "Camellia-128" 866 867 Also allowed (though currently experimental): "AES-128/OCB(12)", 868 "AES-256/OCB(12)" 869 870 In versions up to 2.8.0, the CBC and CCM ciphersuites "AES-256", 871 "AES-128", "AES-256/CCM" and "AES-128/CCM" were enabled by default. 872 873 Also allowed (although **not recommended**): "SEED", "3DES" 874 875 .. note:: 876 877 Before 1.11.30 only the non-standard ChaCha20Poly1305 ciphersuite 878 was implemented. The RFC 7905 ciphersuites are supported in 1.11.30 879 onwards. 880 881 .. note:: 882 883 Support for the broken RC4 cipher was removed in 1.11.17 884 885 .. note:: 886 887 SEED and 3DES are deprecated and will be removed in a future release. 888 889 .. cpp:function:: std::vector<std::string> allowed_macs() const 890 891 Returns the list of algorithms we are willing to use for 892 message authentication, in order of preference. 893 894 Default: "AEAD", "SHA-256", "SHA-384", "SHA-1" 895 896 A plain hash function indicates HMAC 897 898 .. note:: 899 900 SHA-256 is preferred over SHA-384 in CBC mode because the 901 protections against the Lucky13 attack are somewhat more 902 effective for SHA-256 than SHA-384. 903 904 .. cpp:function:: std::vector<std::string> allowed_key_exchange_methods() const 905 906 Returns the list of key exchange methods we are willing to use, 907 in order of preference. 908 909 Default: "CECPQ1", "ECDH", "DH" 910 911 .. note:: 912 913 CECPQ1 key exchange provides post-quantum security to the key exchange 914 by combining NewHope with a standard x25519 ECDH exchange. This prevents 915 an attacker, even one with a quantum computer, from later decrypting the 916 contents of a recorded TLS transcript. The NewHope algorithm is very 917 fast, but adds roughly 4 KiB of additional data transfer to every TLS 918 handshake. And even if NewHope ends up completely broken, the 'extra' 919 x25519 exchange secures the handshake. 920 921 For applications where the additional data transfer size is unacceptable, 922 simply allow only ECDH key exchange in the application policy. DH 923 exchange also often involves transferring several additional Kb (without 924 the benefit of post quantum security) so if CECPQ1 is being disabled for 925 traffic overhead reasons, DH should also be avoided. 926 927 Also allowed: "RSA", "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK" 928 929 .. note:: 930 931 Static RSA ciphersuites are disabled by default since 1.11.34. 932 In addition to not providing forward security, any server which is 933 willing to negotiate these ciphersuites exposes themselves to a variety 934 of chosen ciphertext oracle attacks which are all easily avoided by 935 signing (as in PFS) instead of decrypting. 936 937 .. note:: 938 939 In order to enable RSA, SRP, or PSK ciphersuites one must also enable 940 authentication method "IMPLICIT", see :cpp:func:`allowed_signature_methods`. 941 942 .. cpp:function:: std::vector<std::string> allowed_signature_hashes() const 943 944 Returns the list of hash algorithms we are willing to use for 945 public key signatures, in order of preference. 946 947 Default: "SHA-512", "SHA-384", "SHA-256" 948 949 Also allowed (although **not recommended**): "SHA-1" 950 951 .. note:: 952 953 This is only used with TLS v1.2. In earlier versions of the 954 protocol, signatures are fixed to using only SHA-1 (for 955 DSA/ECDSA) or a MD5/SHA-1 pair (for RSA). 956 957 .. cpp:function:: std::vector<std::string> allowed_signature_methods() const 958 959 Default: "ECDSA", "RSA" 960 961 Also allowed (disabled by default): "DSA", "IMPLICIT", "ANONYMOUS" 962 963 "IMPLICIT" enables ciphersuites which are authenticated not by a signature 964 but through a side-effect of the key exchange. In particular this setting 965 is required to enable PSK, SRP, and static RSA ciphersuites. 966 967 "ANONYMOUS" allows purely anonymous DH/ECDH key exchanges. **Enabling this 968 is not recommended** 969 970 .. note:: 971 972 Both DSA authentication and anonymous DH ciphersuites are deprecated, 973 and will be removed in a future release. 974 975 .. cpp:function:: std::vector<Group_Params> key_exchange_groups() const 976 977 Return a list of ECC curve and DH group TLS identifiers we are willing to use, in order of preference. 978 The default ordering puts the best performing ECC first. 979 980 Default: 981 Group_Params::X25519, 982 Group_Params::SECP256R1, Group_Params::BRAINPOOL256R1, 983 Group_Params::SECP384R1, Group_Params::BRAINPOOL384R1, 984 Group_Params::SECP521R1, Group_Params::BRAINPOOL512R1, 985 Group_Params::FFDHE_2048, Group_Params::FFDHE_3072, Group_Params::FFDHE_4096, 986 Group_Params::FFDHE_6144, Group_Params::FFDHE_8192 987 988 No other values are currently defined. 989 990 .. cpp:function:: bool use_ecc_point_compression() const 991 992 Prefer ECC point compression. 993 994 Signals that we prefer ECC points to be compressed when transmitted to us. 995 The other party may not support ECC point compression and therefore may still 996 send points uncompressed. 997 998 Note that the certificate used during authentication must also follow the other 999 party's preference. 1000 1001 Default: false 1002 1003 .. note:: 1004 1005 Support for EC point compression is deprecated and will be removed in a 1006 future major release. 1007 1008 .. cpp:function:: bool acceptable_protocol_version(Protocol_Version version) 1009 1010 Return true if this version of the protocol is one that we are 1011 willing to negotiate. 1012 1013 Default: Accepts TLS v1.2 and DTLS v1.2, and rejects all older versions. 1014 1015 .. cpp:function:: bool server_uses_own_ciphersuite_preferences() const 1016 1017 If this returns true, a server will pick the cipher it prefers the 1018 most out of the client's list. Otherwise, it will negotiate the 1019 first cipher in the client's ciphersuite list that it supports. 1020 1021 Default: true 1022 1023 .. cpp:function:: bool allow_client_initiated_renegotiation() const 1024 1025 If this function returns true, a server will accept a 1026 client-initiated renegotiation attempt. Otherwise it will send 1027 the client a non-fatal ``no_renegotiation`` alert. 1028 1029 Default: false 1030 1031 .. cpp:function:: bool allow_server_initiated_renegotiation() const 1032 1033 If this function returns true, a client will accept a 1034 server-initiated renegotiation attempt. Otherwise it will send 1035 the server a non-fatal ``no_renegotiation`` alert. 1036 1037 Default: false 1038 1039 .. cpp:function:: bool abort_connection_on_undesired_renegotiation() const 1040 1041 If a renegotiation attempt is being rejected due to the configuration of 1042 :cpp:func:`TLS::Policy::allow_client_initiated_renegotiation` or 1043 :cpp:func:`TLS::Policy::allow_server_initiated_renegotiation`, and 1044 this function returns true then the connection is closed with a fatal 1045 alert instead of the default warning alert. 1046 1047 Default: false 1048 1049 .. cpp:function:: bool allow_insecure_renegotiation() const 1050 1051 If this function returns true, we will allow renegotiation attempts 1052 even if the counterparty does not support the RFC 5746 extensions. 1053 1054 .. warning:: Returning true here could expose you to attacks 1055 1056 Default: false 1057 1058 .. cpp:function:: size_t minimum_signature_strength() const 1059 1060 Return the minimum strength (as ``n``, representing ``2**n`` work) 1061 we will accept for a signature algorithm on any certificate. 1062 1063 Use 80 to enable RSA-1024 (*not recommended*), or 128 to require 1064 either ECC or large (~3000 bit) RSA keys. 1065 1066 Default: 110 (allowing 2048 bit RSA) 1067 1068 .. cpp:function:: bool require_cert_revocation_info() const 1069 1070 If this function returns true, and a ciphersuite using certificates was 1071 negotiated, then we must have access to a valid CRL or OCSP response in 1072 order to trust the certificate. 1073 1074 .. warning:: Returning false here could expose you to attacks 1075 1076 Default: true 1077 1078 .. cpp:function:: Group_Params default_dh_group() const 1079 1080 For ephemeral Diffie-Hellman key exchange, the server sends a 1081 group parameter. Return the 2 Byte TLS group identifier specifying the group parameter a 1082 server should use. 1083 1084 Default: 2048 bit IETF IPsec group ("modp/ietf/2048") 1085 1086 .. cpp:function:: size_t minimum_dh_group_size() const 1087 1088 Return the minimum size in bits for a Diffie-Hellman group that a 1089 client will accept. Due to the design of the protocol the client 1090 has only two options - accept the group, or reject it with a 1091 fatal alert then attempt to reconnect after disabling ephemeral 1092 Diffie-Hellman. 1093 1094 Default: 2048 bits 1095 1096 .. cpp:function:: bool allow_tls10() const 1097 1098 Return true from here to allow TLS v1.0. Since 2.8.0, returns 1099 ``false`` by default. 1100 1101 .. cpp:function:: bool allow_tls11() const 1102 1103 Return true from here to allow TLS v1.1. Since 2.8.0, returns 1104 ``false`` by default. 1105 1106 .. cpp:function:: bool allow_tls12() const 1107 1108 Return true from here to allow TLS v1.2. Returns ``true`` by default. 1109 1110 .. cpp:function:: size_t minimum_rsa_bits() const 1111 1112 Minimum accepted RSA key size. Default 2048 bits. 1113 1114 .. cpp:function:: size_t minimum_dsa_group_size() const 1115 1116 Minimum accepted DSA key size. Default 2048 bits. 1117 1118 .. cpp:function:: size_t minimum_ecdsa_group_size() const 1119 1120 Minimum size for ECDSA keys (256 bits). 1121 1122 .. cpp:function:: size_t minimum_ecdh_group_size() const 1123 1124 Minimum size for ECDH keys (255 bits). 1125 1126 .. cpp:function:: void check_peer_key_acceptable(const Public_Key& public_key) const 1127 1128 Allows the policy to examine peer public keys. Throw an exception 1129 if the key should be rejected. Default implementation checks 1130 against policy values `minimum_dh_group_size`, `minimum_rsa_bits`, 1131 `minimum_ecdsa_group_size`, and `minimum_ecdh_group_size`. 1132 1133 .. cpp:function:: bool hide_unknown_users() const 1134 1135 The SRP and PSK suites work using an identifier along with a 1136 shared secret. If this function returns true, when an identifier 1137 that the server does not recognize is provided by a client, a 1138 random shared secret will be generated in such a way that a 1139 client should not be able to tell the difference between the 1140 identifier not being known and the secret being wrong. This can 1141 help protect against some username probing attacks. If it 1142 returns false, the server will instead send an 1143 ``unknown_psk_identity`` alert when an unknown identifier is 1144 used. 1145 1146 Default: false 1147 1148 .. cpp:function:: u32bit session_ticket_lifetime() const 1149 1150 Return the lifetime of session tickets. Each session includes the 1151 start time. Sessions resumptions using tickets older than 1152 ``session_ticket_lifetime`` seconds will fail, forcing a full 1153 renegotiation. 1154 1155 Default: 86400 seconds (1 day) 1156 1157TLS Ciphersuites 1158---------------------------------------- 1159 1160.. cpp:class:: TLS::Ciphersuite 1161 1162 .. cpp:function:: uint16_t ciphersuite_code() const 1163 1164 Return the numerical code for this ciphersuite 1165 1166 .. cpp:function:: std::string to_string() const 1167 1168 Return the full name of ciphersuite (for example 1169 "RSA_WITH_RC4_128_SHA" or "ECDHE_RSA_WITH_AES_128_GCM_SHA256") 1170 1171 .. cpp:function:: std::string kex_algo() const 1172 1173 Return the key exchange algorithm of this ciphersuite 1174 1175 .. cpp:function:: std::string sig_algo() const 1176 1177 Return the signature algorithm of this ciphersuite 1178 1179 .. cpp:function:: std::string cipher_algo() const 1180 1181 Return the cipher algorithm of this ciphersuite 1182 1183 .. cpp:function:: std::string mac_algo() const 1184 1185 Return the authentication algorithm of this ciphersuite 1186 1187 .. cpp:function:: bool acceptable_ciphersuite(const Ciphersuite& suite) const 1188 1189 Return true if ciphersuite is accepted by the policy. 1190 1191 Allows an application to reject any ciphersuites, which are 1192 undesirable for whatever reason without having to reimplement 1193 :cpp:func:`TLS::Ciphersuite::ciphersuite_list` 1194 1195 .. cpp:function:: std::vector<uint16_t> ciphersuite_list(Protocol_Version version, bool have_srp) const 1196 1197 Return allowed ciphersuites in order of preference 1198 1199 Allows an application to have full control over ciphersuites 1200 by returning desired ciphersuites in preference order. 1201 1202.. _tls_alerts: 1203 1204TLS Alerts 1205---------------------------------------- 1206 1207A ``TLS::Alert`` is passed to every invocation of a channel's *alert_cb*. 1208 1209.. cpp:class:: TLS::Alert 1210 1211 .. cpp:function:: is_valid() const 1212 1213 Return true if this alert is not a null alert 1214 1215 .. cpp:function:: is_fatal() const 1216 1217 Return true if this alert is fatal. A fatal alert causes the 1218 connection to be immediately disconnected. Otherwise, the alert 1219 is a warning and the connection remains valid. 1220 1221 .. cpp:function:: Type type() const 1222 1223 Returns the type of the alert as an enum 1224 1225 .. cpp:function:: std::string type_string() 1226 1227 Returns the type of the alert as a string 1228 1229TLS Protocol Version 1230---------------------------------------- 1231 1232TLS has several different versions with slightly different behaviors. 1233The ``TLS::Protocol_Version`` class represents a specific version: 1234 1235.. cpp:class:: TLS::Protocol_Version 1236 1237 .. cpp:enum:: Version_Code 1238 1239 ``TLS_V10``, ``TLS_V11``, ``TLS_V12``, ``DTLS_V10``, ``DTLS_V12`` 1240 1241 .. cpp:function:: Protocol_Version(Version_Code named_version) 1242 1243 Create a specific version 1244 1245 .. cpp:function:: uint8_t major_version() const 1246 1247 Returns major number of the protocol version 1248 1249 .. cpp:function:: uint8_t minor_version() const 1250 1251 Returns minor number of the protocol version 1252 1253 .. cpp:function:: std::string to_string() const 1254 1255 Returns string description of the version, for instance "TLS 1256 v1.1" or "DTLS v1.0". 1257 1258 .. cpp:function:: static Protocol_Version latest_tls_version() 1259 1260 Returns the latest version of the TLS protocol known to the library 1261 (currently TLS v1.2) 1262 1263 .. cpp:function:: static Protocol_Version latest_dtls_version() 1264 1265 Returns the latest version of the DTLS protocol known to the 1266 library (currently DTLS v1.2) 1267 1268TLS Custom Curves 1269---------------------------------------- 1270 1271The supported_groups TLS extension is used in the client hello to advertise a list of supported elliptic curves 1272and DH groups. The server subsequently selects one of the groups, which is supported by both endpoints. 1273The groups are represented by their TLS identifier. This 2 Byte identifier is standardized for commonly used groups and curves. 1274In addition, the standard reserves the identifiers 0xFE00 to 0xFEFF for custom groups or curves. 1275 1276Using non standardized custom curves is however not recommended and can be a serious risk if an 1277insecure curve is used. Still, it might be desired in some scenarios to use custom curves or groups in the TLS handshake. 1278 1279To use custom curves with the Botan :cpp:class:`TLS::Client` or :cpp:class:`TLS::Server` the following additional adjustments have to be implemented 1280as shown in the following code examples. 1281 12821. Registration of the custom curve 12832. Implementation TLS callback ``tls_decode_group_param`` 12843. Adjustment of the TLS policy by allowing the custom curve 1285 1286Client Code Example 1287^^^^^^^^^^^^^^^^^^^^ 1288 1289.. code-block:: cpp 1290 1291 #include <botan/tls_client.h> 1292 #include <botan/tls_callbacks.h> 1293 #include <botan/tls_session_manager.h> 1294 #include <botan/tls_policy.h> 1295 #include <botan/auto_rng.h> 1296 #include <botan/certstor.h> 1297 1298 #include <botan/ec_group.h> 1299 #include <botan/oids.h> 1300 1301 1302 /** 1303 * @brief Callbacks invoked by TLS::Channel. 1304 * 1305 * Botan::TLS::Callbacks is an abstract class. 1306 * For improved readability, only the functions that are mandatory 1307 * to implement are listed here. See src/lib/tls/tls_callbacks.h. 1308 */ 1309 class Callbacks : public Botan::TLS::Callbacks 1310 { 1311 public: 1312 void tls_emit_data(const uint8_t data[], size_t size) override 1313 { 1314 // send data to tls server, e.g., using BSD sockets or boost asio 1315 } 1316 1317 void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override 1318 { 1319 // process full TLS record received by tls server, e.g., 1320 // by passing it to the application 1321 } 1322 1323 void tls_alert(Botan::TLS::Alert alert) override 1324 { 1325 // handle a tls alert received from the tls server 1326 } 1327 1328 bool tls_session_established(const Botan::TLS::Session& session) override 1329 { 1330 // the session with the tls server was established 1331 // return false to prevent the session from being cached, true to 1332 // cache the session in the configured session manager 1333 return false; 1334 } 1335 std::string tls_decode_group_param(Botan::TLS::Group_Params group_param) override 1336 { 1337 // handle TLS group identifier decoding and return name as string 1338 // return empty string to indicate decoding failure 1339 1340 switch(static_cast<uint16_t>(group_param)) 1341 { 1342 case 0xFE00: 1343 return "testcurve1102"; 1344 default: 1345 //decode non-custom groups 1346 return Botan::TLS::Callbacks::tls_decode_group_param(group_param); 1347 } 1348 } 1349 }; 1350 1351 /** 1352 * @brief Credentials storage for the tls client. 1353 * 1354 * It returns a list of trusted CA certificates from a local directory. 1355 * TLS client authentication is disabled. See src/lib/tls/credentials_manager.h. 1356 */ 1357 class Client_Credentials : public Botan::Credentials_Manager 1358 { 1359 public: 1360 std::vector<Botan::Certificate_Store*> trusted_certificate_authorities( 1361 const std::string& type, 1362 const std::string& context) override 1363 { 1364 // return a list of certificates of CAs we trust for tls server certificates, 1365 // e.g., all the certificates in the local directory "cas" 1366 return { new Botan::Certificate_Store_In_Memory("cas") }; 1367 } 1368 1369 std::vector<Botan::X509_Certificate> cert_chain( 1370 const std::vector<std::string>& cert_key_types, 1371 const std::string& type, 1372 const std::string& context) override 1373 { 1374 // when using tls client authentication (optional), return 1375 // a certificate chain being sent to the tls server, 1376 // else an empty list 1377 return std::vector<Botan::X509_Certificate>(); 1378 } 1379 1380 Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert, 1381 const std::string& type, 1382 const std::string& context) override 1383 { 1384 // when returning a chain in cert_chain(), return the private key 1385 // associated with the leaf certificate here 1386 return nullptr; 1387 } 1388 }; 1389 1390 class Client_Policy : public Botan::TLS::Strict_Policy 1391 { 1392 public: 1393 std::vector<Botan::TLS::Group_Params> key_exchange_groups() const override 1394 { 1395 // modified strict policy to allow our custom curves 1396 return 1397 { 1398 static_cast<Botan::TLS::Group_Params>(0xFE00) 1399 }; 1400 } 1401 }; 1402 1403 int main() 1404 { 1405 // prepare rng 1406 Botan::AutoSeeded_RNG rng; 1407 1408 // prepare custom curve 1409 1410 // prepare curve parameters 1411 const Botan::BigInt p("0x92309a3e88b94312f36891a2055725bb35ab51af96b3a651d39321b7bbb8c51575a76768c9b6b323"); 1412 const Botan::BigInt a("0x4f30b8e311f6b2dce62078d70b35dacb96aa84b758ab5a8dff0c9f7a2a1ff466c19988aa0acdde69"); 1413 const Botan::BigInt b("0x9045A513CFFF9AE1F1CC84039D852D240344A1D5C9DB203C844089F855C387823EB6FCDDF49C909C"); 1414 1415 const Botan::BigInt x("0x9120f3779a31296cefcb5a5a08831f1a6d438ad5a3f2ce60585ac19c74eebdc65cadb96bb92622c7"); 1416 const Botan::BigInt y("0x836db8251c152dfee071b72c6b06c5387d82f1b5c30c5a5b65ee9429aa2687e8426d5d61276a4ede"); 1417 const Botan::BigInt order("0x248c268fa22e50c4bcda24688155c96ecd6ad46be5c82d7a6be6e7068cb5d1ca72b2e07e8b90d853"); 1418 1419 const Botan::BigInt cofactor(4); 1420 1421 const Botan::OID oid("1.2.3.1"); 1422 1423 // create EC_Group object to register the curve 1424 Botan::EC_Group testcurve1102(p, a, b, x, y, order, cofactor, oid); 1425 1426 if(!testcurve1102.verify_group(rng)) 1427 { 1428 // Warning: if verify_group returns false the curve parameters are insecure 1429 } 1430 1431 // register name to specified oid 1432 Botan::OIDS::add_oid(oid, "testcurve1102"); 1433 1434 // prepare all the parameters 1435 Callbacks callbacks; 1436 Botan::TLS::Session_Manager_In_Memory session_mgr(rng); 1437 Client_Credentials creds; 1438 Client_Policy policy; 1439 1440 // open the tls connection 1441 Botan::TLS::Client client(callbacks, 1442 session_mgr, 1443 creds, 1444 policy, 1445 rng, 1446 Botan::TLS::Server_Information("botan.randombit.net", 443), 1447 Botan::TLS::Protocol_Version::TLS_V12); 1448 1449 1450 while(!client.is_closed()) 1451 { 1452 // read data received from the tls server, e.g., using BSD sockets or boost asio 1453 // ... 1454 1455 // send data to the tls server using client.send_data() 1456 1457 } 1458 } 1459 1460Server Code Example 1461^^^^^^^^^^^^^^^^^^^^^ 1462 1463.. code-block:: cpp 1464 1465 #include <botan/tls_server.h> 1466 #include <botan/tls_callbacks.h> 1467 #include <botan/tls_session_manager.h> 1468 #include <botan/tls_policy.h> 1469 #include <botan/auto_rng.h> 1470 #include <botan/certstor.h> 1471 #include <botan/pk_keys.h> 1472 #include <botan/pkcs8.h> 1473 1474 #include <botan/ec_group.h> 1475 #include <botan/oids.h> 1476 1477 #include <memory> 1478 1479 /** 1480 * @brief Callbacks invoked by TLS::Channel. 1481 * 1482 * Botan::TLS::Callbacks is an abstract class. 1483 * For improved readability, only the functions that are mandatory 1484 * to implement are listed here. See src/lib/tls/tls_callbacks.h. 1485 */ 1486 class Callbacks : public Botan::TLS::Callbacks 1487 { 1488 public: 1489 void tls_emit_data(const uint8_t data[], size_t size) override 1490 { 1491 // send data to tls client, e.g., using BSD sockets or boost asio 1492 } 1493 1494 void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override 1495 { 1496 // process full TLS record received by tls client, e.g., 1497 // by passing it to the application 1498 } 1499 1500 void tls_alert(Botan::TLS::Alert alert) override 1501 { 1502 // handle a tls alert received from the tls server 1503 } 1504 1505 bool tls_session_established(const Botan::TLS::Session& session) override 1506 { 1507 // the session with the tls client was established 1508 // return false to prevent the session from being cached, true to 1509 // cache the session in the configured session manager 1510 return false; 1511 } 1512 1513 std::string tls_decode_group_param(Botan::TLS::Group_Params group_param) override 1514 { 1515 // handle TLS group identifier decoding and return name as string 1516 // return empty string to indicate decoding failure 1517 1518 switch(static_cast<uint16_t>(group_param)) 1519 { 1520 case 0xFE00: 1521 return "testcurve1102"; 1522 default: 1523 //decode non-custom groups 1524 return Botan::TLS::Callbacks::tls_decode_group_param(group_param); 1525 } 1526 } 1527 }; 1528 1529 /** 1530 * @brief Credentials storage for the tls server. 1531 * 1532 * It returns a certificate and the associated private key to 1533 * authenticate the tls server to the client. 1534 * TLS client authentication is not requested. 1535 * See src/lib/tls/credentials_manager.h. 1536 */ 1537 class Server_Credentials : public Botan::Credentials_Manager 1538 { 1539 public: 1540 Server_Credentials() : m_key(Botan::PKCS8::load_key("botan.randombit.net.key") 1541 { 1542 } 1543 1544 std::vector<Botan::Certificate_Store*> trusted_certificate_authorities( 1545 const std::string& type, 1546 const std::string& context) override 1547 { 1548 // if client authentication is required, this function 1549 // shall return a list of certificates of CAs we trust 1550 // for tls client certificates, otherwise return an empty list 1551 return std::vector<Botan::Certificate_Store*>(); 1552 } 1553 1554 std::vector<Botan::X509_Certificate> cert_chain( 1555 const std::vector<std::string>& cert_key_types, 1556 const std::string& type, 1557 const std::string& context) override 1558 { 1559 // return the certificate chain being sent to the tls client 1560 // e.g., the certificate file "botan.randombit.net.crt" 1561 return { Botan::X509_Certificate("botan.randombit.net.crt") }; 1562 } 1563 1564 Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert, 1565 const std::string& type, 1566 const std::string& context) override 1567 { 1568 // return the private key associated with the leaf certificate, 1569 // in this case the one associated with "botan.randombit.net.crt" 1570 return m_key.get(); 1571 } 1572 1573 private: 1574 std::unique_ptr<Botan::Private_Key> m_key; 1575 }; 1576 1577 class Server_Policy : public Botan::TLS::Strict_Policy 1578 { 1579 public: 1580 std::vector<Botan::TLS::Group_Params> key_exchange_groups() const override 1581 { 1582 // modified strict policy to allow our custom curves 1583 return 1584 { 1585 static_cast<Botan::TLS::Group_Params>(0xFE00) 1586 }; 1587 } 1588 }; 1589 1590 int main() 1591 { 1592 1593 // prepare rng 1594 Botan::AutoSeeded_RNG rng; 1595 1596 // prepare custom curve 1597 1598 // prepare curve parameters 1599 const Botan::BigInt p("0x92309a3e88b94312f36891a2055725bb35ab51af96b3a651d39321b7bbb8c51575a76768c9b6b323"); 1600 const Botan::BigInt a("0x4f30b8e311f6b2dce62078d70b35dacb96aa84b758ab5a8dff0c9f7a2a1ff466c19988aa0acdde69"); 1601 const Botan::BigInt b("0x9045A513CFFF9AE1F1CC84039D852D240344A1D5C9DB203C844089F855C387823EB6FCDDF49C909C"); 1602 1603 const Botan::BigInt x("0x9120f3779a31296cefcb5a5a08831f1a6d438ad5a3f2ce60585ac19c74eebdc65cadb96bb92622c7"); 1604 const Botan::BigInt y("0x836db8251c152dfee071b72c6b06c5387d82f1b5c30c5a5b65ee9429aa2687e8426d5d61276a4ede"); 1605 const Botan::BigInt order("0x248c268fa22e50c4bcda24688155c96ecd6ad46be5c82d7a6be6e7068cb5d1ca72b2e07e8b90d853"); 1606 1607 const Botan::BigInt cofactor(4); 1608 1609 const Botan::OID oid("1.2.3.1"); 1610 1611 // create EC_Group object to register the curve 1612 Botan::EC_Group testcurve1102(p, a, b, x, y, order, cofactor, oid); 1613 1614 if(!testcurve1102.verify_group(rng)) 1615 { 1616 // Warning: if verify_group returns false the curve parameters are insecure 1617 } 1618 1619 // register name to specified oid 1620 Botan::OIDS::add_oid(oid, "testcurve1102"); 1621 1622 // prepare all the parameters 1623 Callbacks callbacks; 1624 Botan::TLS::Session_Manager_In_Memory session_mgr(rng); 1625 Server_Credentials creds; 1626 Server_Policy policy; 1627 1628 // accept tls connection from client 1629 Botan::TLS::Server server(callbacks, 1630 session_mgr, 1631 creds, 1632 policy, 1633 rng); 1634 1635 // read data received from the tls client, e.g., using BSD sockets or boost asio 1636 // and pass it to server.received_data(). 1637 // ... 1638 1639 // send data to the tls client using server.send_data() 1640 // ... 1641 } 1642 1643TLS Stream 1644---------------------------------------- 1645 1646:cpp:class:`TLS::Stream` offers a Boost.Asio compatible wrapper around :cpp:class:`TLS::Client` and :cpp:class:`TLS::Server`. 1647It can be used as an alternative to Boost.Asio's `ssl::stream <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ssl__stream.html>`_ with minor adjustments to the using code. 1648It offers the following interface: 1649 1650.. cpp:class:: template <class StreamLayer, class ChannelT> TLS::Stream 1651 1652 *StreamLayer* specifies the type of the stream's *next layer*, for example a `Boost.Asio TCP socket <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ip__tcp/socket.html>`_. 1653 *ChannelT* is the type of the stream's *native handle*; it defaults to :cpp:class:`TLS::Channel` and should not be specified manually. 1654 1655 .. cpp:function:: template <typename... Args> \ 1656 explicit Stream(Context& context, Args&& ... args) 1657 1658 Construct a new TLS stream. 1659 The *context* parameter will be used to initialize the underlying *native handle*, i.e. the :ref:`TLS::Client <tls_client>` or :ref:`TLS::Server <tls_server>`, when :cpp:func:`handshake` is called. 1660 Using code must ensure the context is kept alive for the lifetime of the stream. 1661 The further *args* will be forwarded to the *next layer*'s constructor. 1662 1663 .. cpp:function:: template <typename... Args> \ 1664 explicit Stream(Arg&& arg, Context& context) 1665 1666 Convenience constructor for :cpp:class:`boost::asio::ssl::stream` compatibility. 1667 The parameters have the same meaning as for the first constructor, but their order is changed and only one argument can be passed to the *next layer* constructor. 1668 1669 1670 .. cpp:function:: void handshake(Connection_Side side, boost::system::error_code& ec) 1671 1672 Set up the *native handle* and perform the TLS handshake. 1673 1674 .. cpp:function:: void handshake(Connection_Side side) 1675 1676 Overload of :cpp:func:`handshake` that throws an exception if an error occurs. 1677 1678 .. cpp:function:: template <typename HandshakeHandler> \ 1679 DEDUCED async_handshake(Connection_Side side, HandshakeHandler&& handler) 1680 1681 Asynchronous variant of :cpp:func:`handshake`. 1682 The function returns immediately and calls the *handler* callback function after performing asynchronous I/O to complete the TLS handshake. 1683 The return type is an automatically deduced specialization of :cpp:class:`boost::asio::async_result`, depending on the *HandshakeHandler* type. 1684 1685 1686 .. cpp:function:: void shutdown(boost::system::error_code& ec) 1687 1688 Calls :cpp:func:`TLS::Channel::close` on the native handle and writes the TLS alert to the *next layer*. 1689 1690 .. cpp:function:: void shutdown() 1691 1692 Overload of :cpp:func:`shutdown` that throws an exception if an error occurs. 1693 1694 .. cpp:function:: template <typename ShutdownHandler> \ 1695 void async_shutdown(ShutdownHandler&& handler) 1696 1697 Asynchronous variant of :cpp:func:`shutdown`. 1698 The function returns immediately and calls the *handler* callback function after performing asynchronous I/O to complete the TLS shutdown. 1699 1700 1701 .. cpp:function:: template <typename MutableBufferSequence> \ 1702 std::size_t read_some(const MutableBufferSequence& buffers, boost::system::error_code& ec) 1703 1704 Reads encrypted data from the *next layer*, decrypts it, and writes it into the provided *buffers*. 1705 If an error occurs, *error_code* is set. 1706 Returns the number of bytes read. 1707 1708 .. cpp:function:: template <typename MutableBufferSequence> \ 1709 std::size_t read_some(const MutableBufferSequence& buffers) 1710 1711 Overload of :cpp:func:`read_some` that throws an exception if an error occurs. 1712 1713 .. cpp:function:: template <typename MutableBufferSequence, typename ReadHandler> \ 1714 DEDUCED async_read_some(const MutableBufferSequence& buffers, ReadHandler&& handler) 1715 1716 Asynchronous variant of :cpp:func:`read_some`. 1717 The function returns immediately and calls the *handler* callback function after writing the decrypted data into the provided *buffers*. 1718 The return type is an automatically deduced specialization of :cpp:class:`boost::asio::async_result`, depending on the *ReadHandler* type. 1719 *ReadHandler* should suffice the `requirements to a Boost.Asio read handler <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ReadHandler.html>`_. 1720 1721 1722 .. cpp:function:: template <typename ConstBufferSequence> \ 1723 std::size_t write_some(const ConstBufferSequence& buffers, boost::system::error_code& ec) 1724 1725 Encrypts data from the provided *buffers* and writes it to the *next layer*. 1726 If an error occurs, *error_code* is set. 1727 Returns the number of bytes written. 1728 1729 .. cpp:function:: template <typename ConstBufferSequence> \ 1730 std::size_t write_some(const ConstBufferSequence& buffers) 1731 1732 Overload of :cpp:func:`write_some` that throws an exception rather than setting an error code. 1733 1734 .. cpp:function:: template <typename ConstBufferSequence, typename WriteHandler> \ 1735 DEDUCED async_write_some(const ConstBufferSequence& buffers, WriteHandler&& handler) 1736 1737 Asynchronous variant of :cpp:func:`write_some`. 1738 The function returns immediately and calls the *handler* callback function after writing the encrypted data to the *next layer*. 1739 The return type is an automatically deduced specialization of :cpp:class:`boost::asio::async_result`, depending on the *WriteHandler* type. 1740 *WriteHandler* should suffice the `requirements to a Boost.Asio write handler <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/WriteHandler.html>`_. 1741 1742.. cpp:class:: TLS::Context 1743 1744 A helper class to initialize and configure the Stream's underlying *native handle* (see :cpp:class:`TLS::Client` and :cpp:class:`TLS::Server`). 1745 1746 .. cpp:function:: Context(Credentials_Manager& credentialsManager, \ 1747 RandomNumberGenerator& randomNumberGenerator, \ 1748 Session_Manager& sessionManager, \ 1749 Policy& policy, \ 1750 Server_Information serverInfo = Server_Information()) 1751 1752 Constructor for TLS::Context. 1753 1754 .. cpp:function:: void set_verify_callback(Verify_Callback_T callback) 1755 1756 Set a user-defined callback function for certificate chain verification. This 1757 will cause the stream to override the default implementation of the 1758 :cpp:func:`tls_verify_cert_chain` callback. 1759 1760TLS Stream Client Code Example 1761^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1762 1763The code below illustrates how to build a simple HTTPS client based on the TLS Stream and Boost.Beast. When run, it fetches the content of `https://botan.randombit.net/news.html` and prints it to stdout. 1764 1765.. code-block:: cpp 1766 1767 #include <iostream> 1768 1769 #include <botan/asio_stream.h> 1770 #include <botan/auto_rng.h> 1771 #include <botan/certstor_system.h> 1772 1773 #include <boost/asio.hpp> 1774 #include <boost/beast.hpp> 1775 #include <boost/bind.hpp> 1776 1777 namespace http = boost::beast::http; 1778 namespace _ = boost::asio::placeholders; 1779 1780 // very basic credentials manager 1781 class Credentials_Manager : public Botan::Credentials_Manager 1782 { 1783 public: 1784 Credentials_Manager() {} 1785 1786 std::vector<Botan::Certificate_Store*> 1787 trusted_certificate_authorities(const std::string&, const std::string&) override 1788 { 1789 return {&cert_store_}; 1790 } 1791 1792 private: 1793 Botan::System_Certificate_Store cert_store_; 1794 }; 1795 1796 // a simple https client based on TLS::Stream 1797 class client 1798 { 1799 public: 1800 client(boost::asio::io_context& io_context, 1801 boost::asio::ip::tcp::resolver::iterator endpoint_iterator, 1802 http::request<http::string_body> req) 1803 : request_(req) 1804 , ctx_(credentials_mgr_, 1805 rng_, 1806 session_mgr_, 1807 policy_, 1808 Botan::TLS::Server_Information()) 1809 , stream_(io_context, ctx_) 1810 { 1811 boost::asio::async_connect(stream_.lowest_layer(), endpoint_iterator, 1812 boost::bind(&client::handle_connect, this, _::error)); 1813 } 1814 1815 void handle_connect(const boost::system::error_code& error) 1816 { 1817 if(error) 1818 { 1819 std::cout << "Connect failed: " << error.message() << "\n"; 1820 return; 1821 } 1822 stream_.async_handshake(Botan::TLS::Connection_Side::CLIENT, 1823 boost::bind(&client::handle_handshake, this, _::error)); 1824 } 1825 1826 void handle_handshake(const boost::system::error_code& error) 1827 { 1828 if(error) 1829 { 1830 std::cout << "Handshake failed: " << error.message() << "\n"; 1831 return; 1832 } 1833 http::async_write(stream_, request_, 1834 boost::bind(&client::handle_write, this, _::error, _::bytes_transferred)); 1835 } 1836 1837 void handle_write(const boost::system::error_code& error, size_t) 1838 { 1839 if(error) 1840 { 1841 std::cout << "Write failed: " << error.message() << "\n"; 1842 return; 1843 } 1844 http::async_read(stream_, reply_, response_, 1845 boost::bind(&client::handle_read, this, _::error, _::bytes_transferred)); 1846 } 1847 1848 void handle_read(const boost::system::error_code& error, size_t) 1849 { 1850 if(!error) 1851 { 1852 std::cout << "Reply: "; 1853 std::cout << response_.body() << "\n"; 1854 } 1855 else 1856 { 1857 std::cout << "Read failed: " << error.message() << "\n"; 1858 } 1859 } 1860 1861 private: 1862 http::request<http::dynamic_body> request_; 1863 http::response<http::string_body> response_; 1864 boost::beast::flat_buffer reply_; 1865 1866 Botan::TLS::Session_Manager_Noop session_mgr_; 1867 Botan::AutoSeeded_RNG rng_; 1868 Credentials_Manager credentials_mgr_; 1869 Botan::TLS::Policy policy_; 1870 1871 Botan::TLS::Context ctx_; 1872 Botan::TLS::Stream<boost::asio::ip::tcp::socket> stream_; 1873 }; 1874 1875 int main() 1876 { 1877 boost::asio::io_context io_context; 1878 1879 boost::asio::ip::tcp::resolver resolver(io_context); 1880 boost::asio::ip::tcp::resolver::query query("botan.randombit.net", "443"); 1881 boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); 1882 1883 http::request<http::string_body> req; 1884 req.version(11); 1885 req.method(http::verb::get); 1886 req.target("/news.html"); 1887 req.set(http::field::host, "botan.randombit.net"); 1888 1889 client c(io_context, iterator, req); 1890 1891 io_context.run(); 1892 } 1893 1894.. _tls_session_encryption: 1895 1896TLS Session Encryption 1897------------------------- 1898 1899A unified format is used for encrypting TLS sessions either for durable storage 1900(on client or server) or when creating TLS session tickets. This format is *not 1901stable* even across the same major version. 1902 1903The current session encryption scheme was introduced in 2.13.0, replacing the 1904format previously used since 1.11.13. 1905 1906Session encryption accepts a key of any length, though for best security a key 1907of 256 bits should be used. This master key is used to key an instance of HMAC 1908using the SHA-512/256 hash. 1909 1910First a "key name" or identifier is created, by HMAC'ing the fixed string "BOTAN 1911TLS SESSION KEY NAME" and truncating to 4 bytes. This is the initial prefix of 1912the encrypted session, and will remain fixed as long as the same ticket key is 1913used. This allows quickly rejecting sessions which are encrypted using an 1914unknown or incorrect key. 1915 1916Then a key used for AES-256 in GCM mode is created by first choosing a 128 bit 1917random seed, and HMAC'ing it to produce a 256-bit value. This means for any one 1918master key as many as 2\ :sup:`128` GCM keys can be created. This is done 1919because NIST recommends that when using random nonces no one GCM key be used to 1920encrypt more than 2\ :sup:`32` messages (to avoid the possiblity of nonce 1921reuse). 1922 1923A random 96-bit nonce is created and included in the header. 1924 1925AES in GCM is used to encrypt and authenticate the serialized session. The 1926key name, key seed, and AEAD nonce are all included as additional data. 1927