diff options
author | Matt Caswell <matt@openssl.org> | 2023-06-07 15:58:42 +0100 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2023-06-14 13:08:37 +1000 |
commit | 2df71d618505056f86cf4e033d9fdfcde0e6574a (patch) | |
tree | 6b705d9cd103faa9a62b2b957ad219433b2ae366 | |
parent | a2b6865be563810fad17e2d925304fde8d7eaf30 (diff) |
Split the blocking TLS client guide page into two
We split the page into two: one covering basic TLS introductory material
that applies to both clients and servers, and one with the specific
material on writing a blocking TLS client.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21133)
-rw-r--r-- | doc/build.info | 6 | ||||
-rw-r--r-- | doc/man7/ossl-guide-tls-client-block.pod | 302 | ||||
-rw-r--r-- | doc/man7/ossl-guide-tls-introduction.pod | 314 |
3 files changed, 340 insertions, 282 deletions
diff --git a/doc/build.info b/doc/build.info index 64d593d8ff..b8748d073d 100644 --- a/doc/build.info +++ b/doc/build.info @@ -4761,6 +4761,10 @@ DEPEND[html/man7/ossl-guide-tls-client-block.html]=man7/ossl-guide-tls-client-bl GENERATE[html/man7/ossl-guide-tls-client-block.html]=man7/ossl-guide-tls-client-block.pod DEPEND[man/man7/ossl-guide-tls-client-block.7]=man7/ossl-guide-tls-client-block.pod GENERATE[man/man7/ossl-guide-tls-client-block.7]=man7/ossl-guide-tls-client-block.pod +DEPEND[html/man7/ossl-guide-tls-introduction.html]=man7/ossl-guide-tls-introduction.pod +GENERATE[html/man7/ossl-guide-tls-introduction.html]=man7/ossl-guide-tls-introduction.pod +DEPEND[man/man7/ossl-guide-tls-introduction.7]=man7/ossl-guide-tls-introduction.pod +GENERATE[man/man7/ossl-guide-tls-introduction.7]=man7/ossl-guide-tls-introduction.pod DEPEND[html/man7/ossl_store-file.html]=man7/ossl_store-file.pod GENERATE[html/man7/ossl_store-file.html]=man7/ossl_store-file.pod DEPEND[man/man7/ossl_store-file.7]=man7/ossl_store-file.pod @@ -4970,6 +4974,7 @@ html/man7/openssl-quic.html \ html/man7/openssl-threads.html \ html/man7/openssl_user_macros.html \ html/man7/ossl-guide-tls-client-block.html \ +html/man7/ossl-guide-tls-introduction.html \ html/man7/ossl_store-file.html \ html/man7/ossl_store.html \ html/man7/passphrase-encoding.html \ @@ -5104,6 +5109,7 @@ man/man7/openssl-quic.7 \ man/man7/openssl-threads.7 \ man/man7/openssl_user_macros.7 \ man/man7/ossl-guide-tls-client-block.7 \ +man/man7/ossl-guide-tls-introduction.7 \ man/man7/ossl_store-file.7 \ man/man7/ossl_store.7 \ man/man7/passphrase-encoding.7 \ diff --git a/doc/man7/ossl-guide-tls-client-block.pod b/doc/man7/ossl-guide-tls-client-block.pod index eb65615c13..30832c5b20 100644 --- a/doc/man7/ossl-guide-tls-client-block.pod +++ b/doc/man7/ossl-guide-tls-client-block.pod @@ -12,281 +12,9 @@ demos/guide/tls-client-block.c ossl-guide-tls-client-block - OpenSSL Guide: Writing a simple blocking TLS client -=head1 INTRODUCTION - -This page will walk you through the process of writing a simple blocking TLS -client using OpenSSL. - -It assumes that you already have OpenSSL installed on your system; that you -understand fundamental OpenSSL concepts (see L<crypto(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. - -=head1 WHAT IS TLS? - -TLS stands for Transport Layer Security. TLS allows applications to securely -communicate with each other across a network such that the confidentiality of -the information exchanged is protected (i.e. it prevents eavesdroppers from -listening in to the communication). Additionally it protects the integrity of -the information exchanged to prevent an attacker from changing it. Finally it -provides authentication so that one or both parties can be sure that they are -talking to who they think they are talking to and not some imposter. - -Sometimes TLS is referred to by its predecessor's name SSL (Secure Sockets -Layer). OpenSSL dates from a time when the SSL name was still in common use and -hence many of the functions and names used by OpenSSL contain the "SSL" -abbreviation. Nonetheless OpenSSL contains a fully fledged TLS implementation. - -TLS is based on a client/server model. The application that initiates a -communication is known as the client. The application that responds to a -remotely initiated communication is the server. - -TLS is a standardised protocol and there are numerous different implementations -of it. Due to the standards an OpenSSL client or server is able to communicate -seamlessly with an application using some different implementation of TLS. TLS -(and its predecessor SSL) have been around for a significant period of time and -the protocol has undergone various changes over the years. Consequently there -are different versions of the protocol available. TLS includes the ability to -perform version negotiation so that the highest protocol version that the client -and server share in common is used. - -=head1 SSL AND TLS VERSIONS - -SSL was initially developed by Netscape Communications and its first publicly -released version was SSLv2 in 1995. Note that SSLv1 was never publicly released. -SSLv3 came along quickly afterwards in 1996. Subsequently development of the -protocol moved to the IETF which released the first version of TLS (TLSv1.0) in -1999 as RFC2246. TLSv1.1 was released in 2006 as RFC4346 and TLSv1.2 came along -in 2008 as RFC5246. The most recent version of the standard is TLSv1.3 which -was released in 2018 as RFC8446. - -Today TLSv1.3 and TLSv1.2 are the most commonly deployed versions of the -protocol. The IETF have formally deprecated TLSv1.1 and TLSv1.0, so anything -below TLSv1.2 should be avoided since the older protocol versions are -susceptible to security problems. - -OpenSSL does not support SSLv2 (it was removed in OpenSSL 1.1.0). Support for -SSLv3 is available as a compile time option - but it is not built by default. -Support for TLSv1.0, TLSv1.1, TLSv1.2 and TLSv1.3 are all available by default -in a standard build of OpenSSL. However special run-time configuration is -required in order to make TLSv1.0 and TLSv1.1 work successfully. - -OpenSSL will always try to negotiate the highest protocol version that it has -been configured to support. In most cases this will mean either TLSv1.3 or -TLSv1.2 is chosen. - -=head1 CERTIFICATES - -In order for a client to establish a connection to a server it must authenticate -the identify of that server, i.e. it needs to confirm that the server is really -the server that it claims to be and not some imposter. In order to do this the -server will send to the client a digital certificate (also commonly referred to -as an X.509 certificate). The certificate contains various information about the -server including its full DNS hostname. Also within the certificate is the -server's public key. The server operator will have a private key which is -linked to the public key and must not be published. - -Along with the certificate the server will also send to the client proof that it -knows the private key associated with the public key in the certificate. It does -this by digitally signing a message to the client using that private key. The -client can verify the signature using the public key from the certificate. If -the signature verifies successfully then the client knows that the server is in -possession of the correct private key. - -The certificate that the server sends will also be signed by a Certificate -Authority. The Certificate Authority (commonly known as a CA) is a third party -organisation that is responsible for verifying the information in the server's -certificate (including its DNS hostname). The CA should only sign the -certificate if it has been able to confirm that the server operator does indeed -have control of the server associated with its DNS hostname and that the server -operator has control of the private key. - -In this way, if the client trusts the CA that has signed the server's -certificate and it can verify that the server has the right private key then it -can trust that the server truly does represent the DNS hostname given in the -certificate. The client must also verify that the hostname given in the -certificate matches the hostname that it originally sent the request to. - -Once all of these checks have been done the client has successfully verified the -identify of the server. OpenSSL can perform all of these checks automatically -but it must be provided with certain information in order to do so, i.e. the set -of CAs that the client trusts as well as the DNS hostname for the server that -this client is trying to connect to. - -Note that it is common for certificates to be built up into a chain. For example -a server's certificate may be signed by a key owned by a an intermediate CA. -That intermediate CA also has a certificate containing its public key which is -in turn signed by a key owned by a root CA. The client may only trust the root -CA, but if the server sends both its own certificate and the certificate for the -intermediate CA then the client can still successfully verify the identity of -the server. There is a chain of trust between the root CA and the server. - -=head1 TRUSTED CERTIFICATE STORE - -The system described above only works if a chain of trust can be built between -the set of CAs that the client trusts and the certificate that the server is -using. The client must therefore have a set of certificates for CAs that it -trusts before any communication can take place. OpenSSL itself does not provide -such a set of certificates. Therefore you will need to make sure you have them -before you start. - -Fortunately other organisations do maintain such a set of certificates. If you -have obtained your copy of OpenSSL from an Operating System (OS) vendor (e.g. a -Linux distribution) then normally the set of CA certificates will also be -distributed with that copy. - -You can check this by running the OpenSSL command line application like this: - - openssl version -d - -This will display a value for B<OPENSSLDIR>. Look in the B<certs> sub directory -of B<OPENSSLDIR> and check its contents. For example if B<OPENSSLDIR> is -"/usr/local/ssl", then check the contents of the "/usr/local/ssl/certs" -directory. - -You are expecting to see a list of files, typically with the suffix ".pem" or -".0". If they exist then you already have a suitable trusted certificate store. - -If you are running your version of OpenSSL on Windows then OpenSSL (from version -3.2 onwards) will use the default Windows set of trusted CAs. - -If you have built your version of OpenSSL from source, or obtained it from some -other location and it does not have a set of trusted CA certificates then you -will have to obtain them yourself. One such source is the Curl project. See the -page L<https://curl.se/docs/caextract.html> where you can download trusted -certificates in a single file. Rename the file to "cert.pem" and store it -directly in B<OPENSSLDIR>. For example if B<OPENSSLDIR> is "/usr/local/ssl", -then save it as "/usr/local/ssl/cert.pem". - -You can also use environment variables to override the default location that -OpenSSL will look for its trusted certificate store. Set the B<SSL_CERT_PATH> -environment variable to give the directory where OpenSSL should looks for its -certificates or the B<SSL_CERT_FILE> environment variable to give the name of -a single file containing all of the certifictes. See L<openssl-env(7)> for -further details about OpenSSL environment variables. For example you could use -this capability to have multiple versions of OpenSSL all installed on the same -system using different values for B<OPENSSLDIR> but all using the same -trusted certificate store. - -You can test that your trusted certificate store is setup correctly by using it -via the OpenSSL command line. Use the following command to connect to a TLS -server: - - openssl s_client www.openssl.org:443 - -Once the command has connected type the letter "Q" followed by "<enter>" to exit -the session. This will print a lot of information on the screen about the -connection. Look for a block of text like this: - - SSL handshake has read 4584 bytes and written 403 bytes - Verification: OK - -Hopefully if everything has worked then the "Verification" line will say "OK". -If its not working as expected then you might see output like this instead: - - SSL handshake has read 4584 bytes and written 403 bytes - Verification error: unable to get local issuer certificate - -The "unable to get local issuer certificate" error means that OpenSSL has been -unable to find a trusted CA for the chain of certifictes provided by the server -in its trusted certificate store. Check your trusted certificate store -configuration again. - -Note that s_client is a testing tool and will still allow you to connect to the -TLS server regardless of the verification error. Most applications should not do -this and should abort the connection in the event of a verification error. - -=head1 IMPORTANT OBJECTS FOR TLS CLIENT APPLICATION - -A TLS connection is represented by the B<SSL> object in an OpenSSL based -application. Once a connection with a server has been established a client can -"write" data to the B<SSL> object to send data to the server, or "read" data -from it to receive data from the server. - -A new B<SSL> object is created from an B<SSL_CTX> object. Think of an B<SSL_CTX> -as a "factory" for creating B<SSL> objects. You can create a single B<SSL_CTX> -object and then create multiple connections (i.e. B<SSL> objects) from it. -Typically you can set up common configuration options on the B<SSL_CTX> so that -all the B<SSL> object created from it inherit the same configuration options. - -Note that internaly to OpenSSL various items that are shared between multiple -B<SSL> objects are cached in the B<SSL_CTX> for performance reasons. Therefore -it is considered best practice to create one B<SSL_CTX> for use by multiple -B<SSL> objects instead of having one B<SSL_CTX> for each B<SSL> object that you -create. - -Each B<SSL> object is also associated with two B<BIO> objects. A B<BIO> object -is used for sending or receiving data from the underlying transport layer. For -example you might create a B<BIO> to represent a TCP socket. The B<SSL> object -uses one B<BIO> for reading data and one B<BIO> for writing data. In most cases -you would use the same B<BIO> for each direction but there could be some -circumstances where you want them to be different. - -It is up to the application programmer to create the B<BIO> objects that are -needed and supply them to the B<SSL> object. See L</Creating the socket and BIO> -below for further information. - -Finally, a client can establish a "session" with a server. The session holds -various TLS parameters about the connection between the client and the server. -The session details can then be reused in a subsequent connection attempt to -speed up the process of connecting. This is known as "resumption". Sessions are -represented in OpenSSL by the B<SSL_SESSION> object. In TLSv1.2 there is always -exactly one session per connection. In TLSv1.3 there can be any number per -connection including none. The example presented on this page does not use the -resumption capability and so we will not use the B<SSL_SESSION> object at this -time. - -=head1 PHASES OF A TLS CONNECTION - -A client side TLS connection starts with an initial "set up" phase. The client -creates the B<SSL_CTX> (if one has not already been created) and then creates an -B<SSL> object to represent the TLS connection. Any connection specific -configuration parameters are then applied and the underlying socket is created -and associated with the B<SSL> via B<BIO> objects. - -After set up is complete the TLS "handshake" phase begins. A TLS handshake -consists of the client and server exchanging a series of TLS handshake messages -to establish the connection. The client starts by sending a "ClientHello" -handshake message and the server responds with a "ServerHello". The handshake is -complete once an endpoint has sent its last message (known as the "Finished" -message) and received a Finished message from its peer. Note that this might -occur at slightly different times for each peer. For example in TLSv1.3 the -server always sends its Finished message before the client. The client later -responds with its Finished message. At this point the client has completed the -handshake because it has both sent and received a Finished message. The server -has sent its Finished message but the Finished message from the client may still -be in-flight, so the server is still in the handshake phase. It is even possible -that the server will fail to complete the handshake (if it considers there is -some problem with the messages sent from the client), even though the client may -have already progressed to sending application data. In TLSv1.2 this can happen -the other way around, i.e. the server finishes first and the client finishes -second. - -Once the handshake is complete the application data transfer phase begins. -Strictly speaking there are some situations where the client can start sending -application data even earlier (using the TLSv1.3 "early data" capability) - but -we're going to skip over that for this basic introduction. - -During application data transfer the client and server can read and write data -to the connection freely. The details of this are typically left to some higher -level application protocol (for example HTTP). Not all information exchanged -during this phase is application data. Some protocol level messages may still -be exchanged - so it is not necessarily the case that, just because the -underlying socket is "readable", that application data will be available to read. - -When the connection is no longer required then it should be shutdown. A shutdown -may be initiated by either the client or the server via a message known as a -"close_notify" alert. The client or server that receives a close_notify may -respond with one and then the connection is fully closed and application data -can no longer be sent or received. - -Once shutdown is complete a TLS application must clean up by freeing the SSL -object. - =head1 SIMPLE BLOCKING TLS CLIENT EXAMPLE -This section will present various source code samples demonstrating how to write +This page will present various source code samples demonstrating how to write a simple TLS client application which connects to a server, sends an HTTP/1.0 request to it, and reads back the response. @@ -306,14 +34,23 @@ the B<demos/guide> directory of the OpenSSL source distribution in the file B<tls-client-block.c>. It is also available online at L<https://github.com/openssl/openssl/blob/master/demos/guide/tls-client-block.c>. +We assume that you already have OpenSSL installed on your system; that you +already have some fundamental understanding of OpenSSL concepts and TLS (see +L<crypto(7)> and L<ossl-guide-tls-introduction(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. + =head2 Creating the SSL_CTX and SSL objects The first step is to create an B<SSL_CTX> object for our client. We use the -L<SSL_CTX_new(3)> function for this purpose. We pass as an argument the return -value of the function L<TLS_client_method(3)>. You should use this method -whenever you are writing a TLS client. This method will automatically use TLS -version negotiation to select the highest version of the protocol that is -mutually supported by both the client and the server. +L<SSL_CTX_new(3)> function for this purpose. We could alternatively use +L<SSL_CTX_new_ex(3)> if we want to associate the B<SSL_CTX> with a particular +B<OSSL_LIB_CTX> (see L<crypto(7)> to learn about B<OSSL_LIB_CTX>). We pass as an +argument the return value of the function L<TLS_client_method(3)>. You should +use this method whenever you are writing a TLS client. This method will +automatically use TLS version negotiation to select the highest version of the +protocol that is mutually supported by both the client and the server. /* * Create an SSL_CTX which we can use to create SSL objects from. We @@ -341,8 +78,9 @@ can safely be set to NULL to get the default handling. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); In order for certificate verification to be successful you must have configured -where the trusted certifcate store to be used is located. In most cases you just -want to use the default store so we call L<SSL_CTX_set_default_verify_paths(3)>. +where the trusted certifcate store to be used is located (see +L<ossl-guide-tls-introduction(7)>). In most cases you just want to use the +default store so we call L<SSL_CTX_set_default_verify_paths(3)>. /* Use the default trusted certificate store */ if (!SSL_CTX_set_default_verify_paths(ctx)) { @@ -766,7 +504,7 @@ reasons. For example =item Failure to correctly setup the trusted certificate store -See the section L</TRUSTED CERTIFICATE STORE> and check that your trusted +See the page L<ossl-guide-tls-introduction(7)> and check that your trusted certificate store is correctly configured =item Unrecognised CA @@ -803,7 +541,7 @@ intermediate CAs, or the issuer is simply unrecognised). =head1 SEE ALSO -L<crypto(7)> +L<crypto(7)>, L<ossl-guide-tls-introduction(7)> =head1 COPYRIGHT diff --git a/doc/man7/ossl-guide-tls-introduction.pod b/doc/man7/ossl-guide-tls-introduction.pod new file mode 100644 index 0000000000..925cc69737 --- /dev/null +++ b/doc/man7/ossl-guide-tls-introduction.pod @@ -0,0 +1,314 @@ +=pod + +=head1 NAME + +ossl-guide-tls-introduction +- OpenSSL Guide: An introduction to TLS in OpenSSL + +=head1 INTRODUCTION + +This page will provide an introduction to some basic TLS concepts and background +and how it is used within OpenSSL. It assumes that you have a basic +understanding of TCP/IP and sockets. + +=head1 WHAT IS TLS? + +TLS stands for Transport Layer Security. TLS allows applications to securely +communicate with each other across a network such that the confidentiality of +the information exchanged is protected (i.e. it prevents eavesdroppers from +listening in to the communication). Additionally it protects the integrity of +the information exchanged to prevent an attacker from changing it. Finally it +provides authentication so that one or both parties can be sure that they are +talking to who they think they are talking to and not some imposter. + +Sometimes TLS is referred to by its predecessor's name SSL (Secure Sockets +Layer). OpenSSL dates from a time when the SSL name was still in common use and +hence many of the functions and names used by OpenSSL contain the "SSL" +abbreviation. Nonetheless OpenSSL contains a fully fledged TLS implementation. + +TLS is based on a client/server model. The application that initiates a +communication is known as the client. The application that responds to a +remotely initiated communication is the server. The term "endpoint" refers to +either of the client or the server in a communication. The term "peer" refers to +the endpoint at the other side of the communication that we are currently +referring to. So if we are currently talking about the client then the peer +would be the server. + +TLS is a standardised protocol and there are numerous different implementations +of it. Due to the standards an OpenSSL client or server is able to communicate +seamlessly with an application using some different implementation of TLS. TLS +(and its predecessor SSL) have been around for a significant period of time and +the protocol has undergone various changes over the years. Consequently there +are different versions of the protocol available. TLS includes the ability to +perform version negotiation so that the highest protocol version that the client +and server share in common is used. + +TLS acts as a security layer over some lower level transport protocol. Typically +the transport layer will be TCP. + +=head1 SSL AND TLS VERSIONS + +SSL was initially developed by Netscape Communications and its first publicly +released version was SSLv2 in 1995. Note that SSLv1 was never publicly released. +SSLv3 came along quickly afterwards in 1996. Subsequently development of the +protocol moved to the IETF which released the first version of TLS (TLSv1.0) in +1999 as RFC2246. TLSv1.1 was released in 2006 as RFC4346 and TLSv1.2 came along +in 2008 as RFC5246. The most recent version of the standard is TLSv1.3 which +was released in 2018 as RFC8446. + +Today TLSv1.3 and TLSv1.2 are the most commonly deployed versions of the +protocol. The IETF have formally deprecated TLSv1.1 and TLSv1.0, so anything +below TLSv1.2 should be avoided since the older protocol versions are +susceptible to security problems. + +OpenSSL does not support SSLv2 (it was removed in OpenSSL 1.1.0). Support for +SSLv3 is available as a compile time option - but it is not built by default. +Support for TLSv1.0, TLSv1.1, TLSv1.2 and TLSv1.3 are all available by default +in a standard build of OpenSSL. However special run-time configuration is +required in order to make TLSv1.0 and TLSv1.1 work successfully. + +OpenSSL will always try to negotiate the highest protocol version that it has +been configured to support. In most cases this will mean either TLSv1.3 or +TLSv1.2 is chosen. + +=head1 CERTIFICATES + +In order for a client to establish a connection to a server it must authenticate +the identify of that server, i.e. it needs to confirm that the server is really +the server that it claims to be and not some imposter. In order to do this the +server will send to the client a digital certificate (also commonly referred to +as an X.509 certificate). The certificate contains various information about the +server including its full DNS hostname. Also within the certificate is the +server's public key. The server operator will have a private key which is +linked to the public key and must not be published. + +Along with the certificate the server will also send to the client proof that it +knows the private key associated with the public key in the certificate. It does +this by digitally signing a message to the client using that private key. The +client can verify the signature using the public key from the certificate. If +the signature verifies successfully then the client knows that the server is in +possession of the correct private key. + +The certificate that the server sends will also be signed by a Certificate +Authority. The Certificate Authority (commonly known as a CA) is a third party +organisation that is responsible for verifying the information in the server's +certificate (including its DNS hostname). The CA should only sign the +certificate if it has been able to confirm that the server operator does indeed +have control of the server associated with its DNS hostname and that the server +operator has control of the private key. + +In this way, if the client trusts the CA that has signed the server's +certificate and it can verify that the server has the right private key then it +can trust that the server truly does represent the DNS hostname given in the +certificate. The client must also verify that the hostname given in the +certificate matches the hostname that it originally sent the request to. + +Once all of these checks have been done the client has successfully verified the +identify of the server. OpenSSL can perform all of these checks automatically +but it must be provided with certain information in order to do so, i.e. the set +of CAs that the client trusts as well as the DNS hostname for the server that +this client is trying to connect to. + +Note that it is common for certificates to be built up into a chain. For example +a server's certificate may be signed by a key owned by a an intermediate CA. +That intermediate CA also has a certificate containing its public key which is +in turn signed by a key owned by a root CA. The client may only trust the root +CA, but if the server sends both its own certificate and the certificate for the +intermediate CA then the client can still successfully verify the identity of +the server. There is a chain of trust between the root CA and the server. + +By default it is only the client that authenticates the server using this +method. However it is also possible to set things up such that the server +additionally autenticates the client. This is known as "client authentication". +In this approach the client will still authenticate the server in the same way, +but the server will request a certificate from the client. The client sends the +server its certificate and the server authenticates it in the same way that the +client does. + +=head1 TRUSTED CERTIFICATE STORE + +The system described above only works if a chain of trust can be built between +the set of CAs that the endpoint trusts and the certificate that the peer is +using. The endpoint must therefore have a set of certificates for CAs that it +trusts before any communication can take place. OpenSSL itself does not provide +such a set of certificates. Therefore you will need to make sure you have them +before you start if you are going to be verifying certificates (i.e. always if +the endpoint is a client, and only if client authentication is in use for a +server). + +Fortunately other organisations do maintain such a set of certificates. If you +have obtained your copy of OpenSSL from an Operating System (OS) vendor (e.g. a +Linux distribution) then normally the set of CA certificates will also be +distributed with that copy. + +You can check this by running the OpenSSL command line application like this: + + openssl version -d + +This will display a value for B<OPENSSLDIR>. Look in the B<certs> sub directory +of B<OPENSSLDIR> and check its contents. For example if B<OPENSSLDIR> is +"/usr/local/ssl", then check the contents of the "/usr/local/ssl/certs" +directory. + +You are expecting to see a list of files, typically with the suffix ".pem" or +".0". If they exist then you already have a suitable trusted certificate store. + +If you are running your version of OpenSSL on Windows then OpenSSL (from version +3.2 onwards) will use the default Windows set of trusted CAs. + +If you have built your version of OpenSSL from source, or obtained it from some +other location and it does not have a set of trusted CA certificates then you +will have to obtain them yourself. One such source is the Curl project. See the +page L<https://curl.se/docs/caextract.html> where you can download trusted +certificates in a single file. Rename the file to "cert.pem" and store it +directly in B<OPENSSLDIR>. For example if B<OPENSSLDIR> is "/usr/local/ssl", +then save it as "/usr/local/ssl/cert.pem". + +You can also use environment variables to override the default location that +OpenSSL will look for its trusted certificate store. Set the B<SSL_CERT_PATH> +environment variable to give the directory where OpenSSL should looks for its +certificates or the B<SSL_CERT_FILE> environment variable to give the name of +a single file containing all of the certifictes. See L<openssl-env(7)> for +further details about OpenSSL environment variables. For example you could use +this capability to have multiple versions of OpenSSL all installed on the same +system using different values for B<OPENSSLDIR> but all using the same +trusted certificate store. + +You can test that your trusted certificate store is setup correctly by using it +via the OpenSSL command line. Use the following command to connect to a TLS +server: + + openssl s_client www.openssl.org:443 + +Once the command has connected type the letter "Q" followed by "<enter>" to exit +the session. This will print a lot of information on the screen about the +connection. Look for a block of text like this: + + SSL handshake has read 4584 bytes and written 403 bytes + Verification: OK + +Hopefully if everything has worked then the "Verification" line will say "OK". +If its not working as expected then you might see output like this instead: + + SSL handshake has read 4584 bytes and written 403 bytes + Verification error: unable to get local issuer certificate + +The "unable to get local issuer certificate" error means that OpenSSL has been +unable to find a trusted CA for the chain of certifictes provided by the server +in its trusted certificate store. Check your trusted certificate store +configuration again. + +Note that s_client is a testing tool and will still allow you to connect to the +TLS server regardless of the verification error. Most applications should not do +this and should abort the connection in the event of a verification error. + +=head1 IMPORTANT OBJECTS FOR AN OPENSSL TLS APPLICATION + +A TLS connection is represented by the B<SSL> object in an OpenSSL based +application. Once a connection with a remote peer has been established an +endpoint can "write" data to the B<SSL> object to send data to the peer, or +"read" data from it to receive data from the server. + +A new B<SSL> object is created from an B<SSL_CTX> object. Think of an B<SSL_CTX> +as a "factory" for creating B<SSL> objects. You can create a single B<SSL_CTX> +object and then create multiple connections (i.e. B<SSL> objects) from it. +Typically you can set up common configuration options on the B<SSL_CTX> so that +all the B<SSL> object created from it inherit the same configuration options. + +Note that internaly to OpenSSL various items that are shared between multiple +B<SSL> objects are cached in the B<SSL_CTX> for performance reasons. Therefore +it is considered best practice to create one B<SSL_CTX> for use by multiple +B<SSL> objects instead of having one B<SSL_CTX> for each B<SSL> object that you +create. + +Each B<SSL> object is also associated with two B<BIO> objects. A B<BIO> object +is used for sending or receiving data from the underlying transport layer. For +example you might create a B<BIO> to represent a TCP socket. The B<SSL> object +uses one B<BIO> for reading data and one B<BIO> for writing data. In most cases +you would use the same B<BIO> for each direction but there could be some +circumstances where you want them to be different. + +It is up to the application programmer to create the B<BIO> objects that are +needed and supply them to the B<SSL> object. See +L<ossl-guide-tls-client-block(7)> for further information. + +Finally, an endpoint can establish a "session" with its peer. The session holds +various TLS parameters about the connection between the client and the server. +The session details can then be reused in a subsequent connection attempt to +speed up the process of connecting. This is known as "resumption". Sessions are +represented in OpenSSL by the B<SSL_SESSION> object. In TLSv1.2 there is always +exactly one session per connection. In TLSv1.3 there can be any number per +connection including none. + +=head1 PHASES OF A TLS CONNECTION + +A TLS connection starts with an initial "set up" phase. The endpoint creates the +B<SSL_CTX> (if one has not already been created) and configures it. + +A client then creates an B<SSL> object to represent the new TLS connection. Any +connection specific configuration parameters are then applied and the underlying +socket is created and associated with the B<SSL> via B<BIO> objects. + +A server will create a socket for listening for incoming connection attempts +from clients. Once a connection attempt is made the server will create an B<SSL> +object in the same way as for a client and associate it with a B<BIO> for the +newly created incoming socket. + +After set up is complete the TLS "handshake" phase begins. A TLS handshake +consists of the client and server exchanging a series of TLS handshake messages +to establish the connection. The client starts by sending a "ClientHello" +handshake message and the server responds with a "ServerHello". The handshake is +complete once an endpoint has sent its last message (known as the "Finished" +message) and received a Finished message from its peer. Note that this might +occur at slightly different times for each peer. For example in TLSv1.3 the +server always sends its Finished message before the client. The client later +responds with its Finished message. At this point the client has completed the +handshake because it has both sent and received a Finished message. The server +has sent its Finished message but the Finished message from the client may still +be in-flight, so the server is still in the handshake phase. It is even possible +that the server will fail to complete the handshake (if it considers there is +some problem with the messages sent from the client), even though the client may +have already progressed to sending application data. In TLSv1.2 this can happen +the other way around, i.e. the server finishes first and the client finishes +second. + +Once the handshake is complete the application data transfer phase begins. +Strictly speaking there are some situations where the client can start sending +application data even earlier (using the TLSv1.3 "early data" capability) - but +we're going to skip over that for this basic introduction. + +During application data transfer the client and server can read and write data +to the connection freely. The details of this are typically left to some higher +level application protocol (for example HTTP). Not all information exchanged +during this phase is application data. Some protocol level messages may still +be exchanged - so it is not necessarily the case that, just because the +underlying socket is "readable", that application data will be available to read. + +When the connection is no longer required then it should be shutdown. A shutdown +may be initiated by either the client or the server via a message known as a +"close_notify" alert. The client or server that receives a close_notify may +respond with one and then the connection is fully closed and application data +can no longer be sent or received. + +Once shutdown is complete a TLS application must clean up by freeing the SSL +object. + +=head1 FURTHER READING + +See L<ossl-guide-tls-client-block(7)> to see an example of applying these +concepts in order to write a simple TLS client based on a blocking socket. + +=head1 SEE ALSO + +L<crypto(7)>, L<ossl-guide-tls-client-block(7)> + +=head1 COPYRIGHT + +Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + +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 +L<https://www.openssl.org/source/license.html>. + +=cut |