aboutsummaryrefslogtreecommitdiff
path: root/secure/lib/libcrypto/man/man7/ossl-guide-tls-server-block.7
diff options
context:
space:
mode:
Diffstat (limited to 'secure/lib/libcrypto/man/man7/ossl-guide-tls-server-block.7')
-rw-r--r--secure/lib/libcrypto/man/man7/ossl-guide-tls-server-block.7405
1 files changed, 405 insertions, 0 deletions
diff --git a/secure/lib/libcrypto/man/man7/ossl-guide-tls-server-block.7 b/secure/lib/libcrypto/man/man7/ossl-guide-tls-server-block.7
new file mode 100644
index 000000000000..bcb0631a798d
--- /dev/null
+++ b/secure/lib/libcrypto/man/man7/ossl-guide-tls-server-block.7
@@ -0,0 +1,405 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.0102 (Pod::Simple 3.45)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "OSSL-GUIDE-TLS-SERVER-BLOCK 7ossl"
+.TH OSSL-GUIDE-TLS-SERVER-BLOCK 7ossl 2025-07-01 3.5.1 OpenSSL
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+ossl\-guide\-tls\-server\-block
+\&\- OpenSSL Guide: Writing a simple blocking TLS server
+.SH "SIMPLE BLOCKING TLS SERVER EXAMPLE"
+.IX Header "SIMPLE BLOCKING TLS SERVER EXAMPLE"
+This page will present various source code samples demonstrating how to write a
+simple, non-concurrent, TLS "echo" server application which accepts one client
+connection at a time, echoing input from the client back to the same client.
+Once the current client disconnects, the next client connection is accepted.
+.PP
+Both the acceptor socket and client connections are "blocking". A more typical
+server might use nonblocking sockets with an event loop and callbacks for I/O
+events.
+.PP
+The complete source code for this example blocking TLS server is available in
+the \fBdemos/guide\fR directory of the OpenSSL source distribution in the file
+\&\fBtls\-server\-block.c\fR. It is also available online at
+<https://github.com/openssl/openssl/blob/master/demos/guide/tls\-server\-block.c>.
+.PP
+We assume that you already have OpenSSL installed on your system; that you
+already have some fundamental understanding of OpenSSL concepts and TLS (see
+\&\fBossl\-guide\-libraries\-introduction\fR\|(7) and \fBossl\-guide\-tls\-introduction\fR\|(7));
+and that you know how to write and build C code and link it against the
+libcrypto and libssl libraries that are provided by OpenSSL. It also assumes
+that you have a basic understanding of TCP/IP and sockets.
+.SS "Creating the SSL_CTX and SSL objects"
+.IX Subsection "Creating the SSL_CTX and SSL objects"
+The first step is to create an \fBSSL_CTX\fR object for our server. We use the
+\&\fBSSL_CTX_new\fR\|(3) function for this purpose. We could alternatively use
+\&\fBSSL_CTX_new_ex\fR\|(3) if we want to associate the \fBSSL_CTX\fR with a particular
+\&\fBOSSL_LIB_CTX\fR (see \fBossl\-guide\-libraries\-introduction\fR\|(7) to learn about
+\&\fBOSSL_LIB_CTX\fR). We pass as an argument the return value of the function
+\&\fBTLS_server_method\fR\|(3). You should use this method whenever you are writing a
+TLS server. This method will automatically use TLS version negotiation to select
+the highest version of the protocol that is mutually supported by both the
+server and the client.
+.PP
+.Vb 9
+\& /*
+\& * An SSL_CTX holds shared configuration information for multiple
+\& * subsequent per\-client SSL connections.
+\& */
+\& ctx = SSL_CTX_new(TLS_server_method());
+\& if (ctx == NULL) {
+\& ERR_print_errors_fp(stderr);
+\& errx(res, "Failed to create server SSL_CTX");
+\& }
+.Ve
+.PP
+We would also like to restrict the TLS versions that we are willing to accept to
+TLSv1.2 or above. TLS protocol versions earlier than that are generally to be
+avoided where possible. We can do that using
+\&\fBSSL_CTX_set_min_proto_version\fR\|(3):
+.PP
+.Vb 9
+\& /*
+\& * TLS versions older than TLS 1.2 are deprecated by IETF and SHOULD
+\& * be avoided if possible.
+\& */
+\& if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)) {
+\& SSL_CTX_free(ctx);
+\& ERR_print_errors_fp(stderr);
+\& errx(res, "Failed to set the minimum TLS protocol version");
+\& }
+.Ve
+.PP
+Next we configure some option flags, see \fBSSL_CTX_set_options\fR\|(3) for details:
+.PP
+.Vb 6
+\& /*
+\& * Tolerate clients hanging up without a TLS "shutdown". Appropriate in all
+\& * application protocols which perform their own message "framing", and
+\& * don\*(Aqt rely on TLS to defend against "truncation" attacks.
+\& */
+\& opts = SSL_OP_IGNORE_UNEXPECTED_EOF;
+\&
+\& /*
+\& * Block potential CPU\-exhaustion attacks by clients that request frequent
+\& * renegotiation. This is of course only effective if there are existing
+\& * limits on initial full TLS handshake or connection rates.
+\& */
+\& opts |= SSL_OP_NO_RENEGOTIATION;
+\&
+\& /*
+\& * Most servers elect to use their own cipher preference rather than that of
+\& * the client.
+\& */
+\& opts |= SSL_OP_CIPHER_SERVER_PREFERENCE;
+\&
+\& /* Apply the selection options */
+\& SSL_CTX_set_options(ctx, opts);
+.Ve
+.PP
+Servers need a private key and certificate. Though anonymous ciphers (no
+server certificate) are possible in TLS 1.2, they are rarely applicable, and
+are not currently defined for TLS 1.3. Additional intermediate issuer CA
+certificates are often also required, and both the server (end-entity or EE)
+certificate and the issuer ("chain") certificates are most easily configured in
+a single "chain file". Below we load such a chain file (the EE certificate
+must appear first), and then load the corresponding private key, checking that
+it matches the server certificate. No checks are performed to check the
+integrity of the chain (CA signatures or certificate expiration dates, for
+example).
+.PP
+.Vb 10
+\& /*
+\& * Load the server\*(Aqs certificate *chain* file (PEM format), which includes
+\& * not only the leaf (end\-entity) server certificate, but also any
+\& * intermediate issuer\-CA certificates. The leaf certificate must be the
+\& * first certificate in the file.
+\& *
+\& * In advanced use\-cases this can be called multiple times, once per public
+\& * key algorithm for which the server has a corresponding certificate.
+\& * However, the corresponding private key (see below) must be loaded first,
+\& * *before* moving on to the next chain file.
+\& */
+\& if (SSL_CTX_use_certificate_chain_file(ctx, "chain.pem") <= 0) {
+\& SSL_CTX_free(ctx);
+\& ERR_print_errors_fp(stderr);
+\& errx(res, "Failed to load the server certificate chain file");
+\& }
+\&
+\& /*
+\& * Load the corresponding private key, this also checks that the private
+\& * key matches the just loaded end\-entity certificate. It does not check
+\& * whether the certificate chain is valid, the certificates could be
+\& * expired, or may otherwise fail to form a chain that a client can validate.
+\& */
+\& if (SSL_CTX_use_PrivateKey_file(ctx, "pkey.pem", SSL_FILETYPE_PEM) <= 0) {
+\& SSL_CTX_free(ctx);
+\& ERR_print_errors_fp(stderr);
+\& errx(res, "Error loading the server private key file, "
+\& "possible key/cert mismatch???");
+\& }
+.Ve
+.PP
+Next we enable session caching, which makes it possible for clients to more
+efficiently make additional TLS connections after completing an initial full
+TLS handshake. With TLS 1.3, session resumption typically still performs a fresh
+key agreement, but the certificate exchange is avoided.
+.PP
+.Vb 7
+\& /*
+\& * Servers that want to enable session resumption must specify a cache id
+\& * byte array, that identifies the server application, and reduces the
+\& * chance of inappropriate cache sharing.
+\& */
+\& SSL_CTX_set_session_id_context(ctx, (void *)cache_id, sizeof(cache_id));
+\& SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
+\&
+\& /*
+\& * How many client TLS sessions to cache. The default is
+\& * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (20k in recent OpenSSL versions),
+\& * which may be too small or too large.
+\& */
+\& SSL_CTX_sess_set_cache_size(ctx, 1024);
+\&
+\& /*
+\& * Sessions older than this are considered a cache miss even if still in
+\& * the cache. The default is two hours. Busy servers whose clients make
+\& * many connections in a short burst may want a shorter timeout, on lightly
+\& * loaded servers with sporadic connections from any given client, a longer
+\& * time may be appropriate.
+\& */
+\& SSL_CTX_set_timeout(ctx, 3600);
+.Ve
+.PP
+Most servers, including this one, do not solicit client certificates. We
+therefore do not need a "trust store" and allow the handshake to complete even
+when the client does not present a certificate. Note: Even if a client did
+present a trusted ceritificate, for it to be useful, the server application
+would still need custom code to use the verified identity to grant nondefault
+access to that particular client. Some servers grant access to all clients
+with certificates from a private CA, this then requires processing of
+certificate revocation lists to deauthorise a client. It is often simpler and
+more secure to instead keep a list of authorised public keys.
+.PP
+Though this is the default setting, we explicitly call the
+\&\fBSSL_CTX_set_verify\fR\|(3) function and pass the \fBSSL_VERIFY_NONE\fR value to it.
+The final argument to this function is a callback that you can optionally
+supply to override the default handling for certificate verification. Most
+applications do not need to do this so this can safely be set to NULL to get
+the default handling.
+.PP
+.Vb 12
+\& /*
+\& * Clients rarely employ certificate\-based authentication, and so we don\*(Aqt
+\& * require "mutual" TLS authentication (indeed there\*(Aqs no way to know
+\& * whether or how the client authenticated the server, so the term "mutual"
+\& * is potentially misleading).
+\& *
+\& * Since we\*(Aqre not soliciting or processing client certificates, we don\*(Aqt
+\& * need to configure a trusted\-certificate store, so no call to
+\& * SSL_CTX_set_default_verify_paths() is needed. The server\*(Aqs own
+\& * certificate chain is assumed valid.
+\& */
+\& SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+.Ve
+.PP
+That is all the setup that we need to do for the \fBSSL_CTX\fR. Next we create an
+acceptor BIO on which to accept client connections. This just records the
+intended port (and optional "host:" prefix), without actually creating the
+socket. This delayed processing allows the programmer to specify additional
+behaviours before the listening socket is actually created.
+.PP
+.Vb 10
+\& /*
+\& * Create a listener socket wrapped in a BIO.
+\& * The first call to BIO_do_accept() initialises the socket
+\& */
+\& acceptor_bio = BIO_new_accept(hostport);
+\& if (acceptor_bio == NULL) {
+\& SSL_CTX_free(ctx);
+\& ERR_print_errors_fp(stderr);
+\& errx(res, "Error creating acceptor bio");
+\& }
+.Ve
+.PP
+Servers almost always want to use the "SO_REUSEADDR" option to avoid startup
+failures if there are still lingering client connections, so we do that before
+making the \fBfirst\fR call to \fBBIO_do_accept\fR\|(3) which creates the listening
+socket, without accepting a client connection. Subsequent calls to the same
+function will accept new connections.
+.PP
+.Vb 6
+\& BIO_set_bind_mode(acceptor_bio, BIO_BIND_REUSEADDR);
+\& if (BIO_do_accept(acceptor_bio) <= 0) {
+\& SSL_CTX_free(ctx);
+\& ERR_print_errors_fp(stderr);
+\& errx(res, "Error setting up acceptor socket");
+\& }
+.Ve
+.SS "Server loop"
+.IX Subsection "Server loop"
+The server now enters a "forever" loop handling one client connection at a
+time. Before each connection we clear the OpenSSL error stack, so that any
+error reports are related to just the new connection.
+.PP
+.Vb 2
+\& /* Pristine error stack for each new connection */
+\& ERR_clear_error();
+.Ve
+.PP
+At this point the server blocks to accept the next client:
+.PP
+.Vb 5
+\& /* Wait for the next client to connect */
+\& if (BIO_do_accept(acceptor_bio) <= 0) {
+\& /* Client went away before we accepted the connection */
+\& continue;
+\& }
+.Ve
+.PP
+On success the accepted client connection has been wrapped in a fresh BIO and
+pushed onto the end of the acceptor BIO chain. We pop it off returning the
+acceptor BIO to its initial state.
+.PP
+.Vb 3
+\& /* Pop the client connection from the BIO chain */
+\& client_bio = BIO_pop(acceptor_bio);
+\& fprintf(stderr, "New client connection accepted\en");
+.Ve
+.PP
+Next, we create an \fBSSL\fR object by calling the \fBSSL_new\|(3)\fR function and
+passing the \fBSSL_CTX\fR we created as an argument. The client connection BIO is
+configured as the I/O conduit for this SSL handle. SSL_set_bio transfers
+ownership of the BIO or BIOs involved (our \fBclient_bio\fR) to the SSL handle.
+.PP
+.Vb 8
+\& /* Associate a new SSL handle with the new connection */
+\& if ((ssl = SSL_new(ctx)) == NULL) {
+\& ERR_print_errors_fp(stderr);
+\& warnx("Error creating SSL handle for new connection");
+\& BIO_free(client_bio);
+\& continue;
+\& }
+\& SSL_set_bio(ssl, client_bio, client_bio);
+.Ve
+.PP
+And now we're ready to attempt the SSL handshake. With a blocking socket
+OpenSSL will perform all the read and write operations required to complete the
+handshake (or detect and report a failure) before returning.
+.PP
+.Vb 7
+\& /* Attempt an SSL handshake with the client */
+\& if (SSL_accept(ssl) <= 0) {
+\& ERR_print_errors_fp(stderr);
+\& warnx("Error performing SSL handshake with client");
+\& SSL_free(ssl);
+\& continue;
+\& }
+.Ve
+.PP
+With the handshake complete, the server loops echoing client input back to the
+client:
+.PP
+.Vb 9
+\& while (SSL_read_ex(ssl, buf, sizeof(buf), &nread) > 0) {
+\& if (SSL_write_ex(ssl, buf, nread, &nwritten) > 0 &&
+\& nwritten == nread) {
+\& total += nwritten;
+\& continue;
+\& }
+\& warnx("Error echoing client input");
+\& break;
+\& }
+.Ve
+.PP
+Once the client closes its connection, we report the number of bytes sent to
+\&\fBstderr\fR and free the SSL handle, which also frees the \fBclient_bio\fR and
+closes the underlying socket.
+.PP
+.Vb 2
+\& fprintf(stderr, "Client connection closed, %zu bytes sent\en", total);
+\& SSL_free(ssl);
+.Ve
+.PP
+The server is now ready to accept the next client connection.
+.SS "Final clean up"
+.IX Subsection "Final clean up"
+If the server could somehow manage to break out of the infinite loop, and
+be ready to exit, it would first deallocate the constructed \fBSSL_CTX\fR.
+.PP
+.Vb 5
+\& /*
+\& * Unreachable placeholder cleanup code, the above loop runs forever.
+\& */
+\& SSL_CTX_free(ctx);
+\& return EXIT_SUCCESS;
+.Ve
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fBossl\-guide\-introduction\fR\|(7), \fBossl\-guide\-libraries\-introduction\fR\|(7),
+\&\fBossl\-guide\-libssl\-introduction\fR\|(7), \fBossl\-guide\-tls\-introduction\fR\|(7),
+\&\fBossl\-guide\-tls\-client\-non\-block\fR\|(7), \fBossl\-guide\-quic\-client\-block\fR\|(7)
+.SH COPYRIGHT
+.IX Header "COPYRIGHT"
+Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+.PP
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+<https://www.openssl.org/source/license.html>.