| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- .\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
- .\"
- .\" 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
- ..
- .\" Set up some character translations and predefined strings. \*(-- will
- .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
- .\" double quote, and \*(R" will give a right double quote. \*(C+ will
- .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
- .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
- .\" nothing in troff, for use with C<>.
- .tr \(*W-
- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
- .ie n \{\
- . ds -- \(*W-
- . ds PI pi
- . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
- . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
- . ds L" ""
- . ds R" ""
- . ds C` ""
- . ds C' ""
- 'br\}
- .el\{\
- . ds -- \|\(em\|
- . ds PI \(*p
- . ds L" ``
- . ds R" ''
- . 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
- .\"
- .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
- .\" Fear. Run. Save yourself. No user-serviceable parts.
- . \" fudge factors for nroff and troff
- .if n \{\
- . ds #H 0
- . ds #V .8m
- . ds #F .3m
- . ds #[ \f1
- . ds #] \fP
- .\}
- .if t \{\
- . ds #H ((1u-(\\\\n(.fu%2u))*.13m)
- . ds #V .6m
- . ds #F 0
- . ds #[ \&
- . ds #] \&
- .\}
- . \" simple accents for nroff and troff
- .if n \{\
- . ds ' \&
- . ds ` \&
- . ds ^ \&
- . ds , \&
- . ds ~ ~
- . ds /
- .\}
- .if t \{\
- . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
- . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
- . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
- . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
- . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
- . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
- .\}
- . \" troff and (daisy-wheel) nroff accents
- .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
- .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
- .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
- .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
- .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
- .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
- .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
- .ds ae a\h'-(\w'a'u*4/10)'e
- .ds Ae A\h'-(\w'A'u*4/10)'E
- . \" corrections for vroff
- .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
- .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
- . \" for low resolution devices (crt and lpr)
- .if \n(.H>23 .if \n(.V>19 \
- \{\
- . ds : e
- . ds 8 ss
- . ds o a
- . ds d- d\h'-1'\(ga
- . ds D- D\h'-1'\(hy
- . ds th \o'bp'
- . ds Th \o'LP'
- . ds ae ae
- . ds Ae AE
- .\}
- .rm #[ #] #H #V #F C
- .\" ========================================================================
- .\"
- .IX Title "OSSL-GUIDE-TLS-INTRODUCTION 7ossl"
- .TH OSSL-GUIDE-TLS-INTRODUCTION 7ossl "2024-09-03" "3.3.2" "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\-introduction
- \&\- OpenSSL Guide: An introduction to SSL/TLS in OpenSSL
- .SH "INTRODUCTION"
- .IX Header "INTRODUCTION"
- This page will provide an introduction to some basic \s-1SSL/TLS\s0 concepts and
- background and how it is used within OpenSSL. It assumes that you have a basic
- understanding of \s-1TCP/IP\s0 and sockets.
- .SH "WHAT IS TLS?"
- .IX Header "WHAT IS TLS?"
- \&\s-1TLS\s0 stands for Transport Layer Security. \s-1TLS\s0 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.
- .PP
- Sometimes \s-1TLS\s0 is referred to by its predecessor's name \s-1SSL\s0 (Secure Sockets
- Layer). OpenSSL dates from a time when the \s-1SSL\s0 name was still in common use and
- hence many of the functions and names used by OpenSSL contain the \*(L"\s-1SSL\*(R"\s0
- abbreviation. Nonetheless OpenSSL contains a fully fledged \s-1TLS\s0 implementation.
- .PP
- \&\s-1TLS\s0 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 \*(L"endpoint\*(R" refers to
- either of the client or the server in a communication. The term \*(L"peer\*(R" 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.
- .PP
- \&\s-1TLS\s0 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 \s-1TLS. TLS\s0
- (and its predecessor \s-1SSL\s0) 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. \s-1TLS\s0 includes the ability to
- perform version negotiation so that the highest protocol version that the client
- and server share in common is used.
- .PP
- \&\s-1TLS\s0 acts as a security layer over some lower level transport protocol. Typically
- the transport layer will be \s-1TCP.\s0
- .SH "SSL AND TLS VERSIONS"
- .IX Header "SSL AND TLS VERSIONS"
- \&\s-1SSL\s0 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 \s-1IETF\s0 which released the first version of \s-1TLS\s0 (TLSv1.0) in
- 1999 as \s-1RFC2246.\s0 TLSv1.1 was released in 2006 as \s-1RFC4346\s0 and TLSv1.2 came along
- in 2008 as \s-1RFC5246.\s0 The most recent version of the standard is TLSv1.3 which
- was released in 2018 as \s-1RFC8446.\s0
- .PP
- Today TLSv1.3 and TLSv1.2 are the most commonly deployed versions of the
- protocol. The \s-1IETF\s0 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.
- .PP
- 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.
- .PP
- 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.
- .SH "CERTIFICATES"
- .IX Header "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 \s-1DNS\s0 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.
- .PP
- 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.
- .PP
- The certificate that the server sends will also be signed by a Certificate
- Authority. The Certificate Authority (commonly known as a \s-1CA\s0) is a third party
- organisation that is responsible for verifying the information in the server's
- certificate (including its \s-1DNS\s0 hostname). The \s-1CA\s0 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 \s-1DNS\s0 hostname and that the server
- operator has control of the private key.
- .PP
- In this way, if the client trusts the \s-1CA\s0 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 \s-1DNS\s0 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.
- .PP
- 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 \s-1DNS\s0 hostname for the server that
- this client is trying to connect to.
- .PP
- 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 \s-1CA.\s0
- That intermediate \s-1CA\s0 also has a certificate containing its public key which is
- in turn signed by a key owned by a root \s-1CA.\s0 The client may only trust the root
- \&\s-1CA,\s0 but if the server sends both its own certificate and the certificate for the
- intermediate \s-1CA\s0 then the client can still successfully verify the identity of
- the server. There is a chain of trust between the root \s-1CA\s0 and the server.
- .PP
- 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 authenticates the client. This is known as \*(L"client authentication\*(R".
- 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.
- .SH "TRUSTED CERTIFICATE STORE"
- .IX Header "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).
- .PP
- Fortunately other organisations do maintain such a set of certificates. If you
- have obtained your copy of OpenSSL from an Operating System (\s-1OS\s0) vendor (e.g. a
- Linux distribution) then normally the set of \s-1CA\s0 certificates will also be
- distributed with that copy.
- .PP
- You can check this by running the OpenSSL command line application like this:
- .PP
- .Vb 1
- \& openssl version \-d
- .Ve
- .PP
- This will display a value for \fB\s-1OPENSSLDIR\s0\fR. Look in the \fBcerts\fR sub directory
- of \fB\s-1OPENSSLDIR\s0\fR and check its contents. For example if \fB\s-1OPENSSLDIR\s0\fR is
- \&\*(L"/usr/local/ssl\*(R", then check the contents of the \*(L"/usr/local/ssl/certs\*(R"
- directory.
- .PP
- You are expecting to see a list of files, typically with the suffix \*(L".pem\*(R" or
- \&\*(L".0\*(R". If they exist then you already have a suitable trusted certificate store.
- .PP
- 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.
- .PP
- 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 \s-1CA\s0 certificates then you
- will have to obtain them yourself. One such source is the Curl project. See the
- page <https://curl.se/docs/caextract.html> where you can download trusted
- certificates in a single file. Rename the file to \*(L"cert.pem\*(R" and store it
- directly in \fB\s-1OPENSSLDIR\s0\fR. For example if \fB\s-1OPENSSLDIR\s0\fR is \*(L"/usr/local/ssl\*(R",
- then save it as \*(L"/usr/local/ssl/cert.pem\*(R".
- .PP
- You can also use environment variables to override the default location that
- OpenSSL will look for its trusted certificate store. Set the \fB\s-1SSL_CERT_PATH\s0\fR
- environment variable to give the directory where OpenSSL should looks for its
- certificates or the \fB\s-1SSL_CERT_FILE\s0\fR environment variable to give the name of
- a single file containing all of the certificates. See \fBopenssl\-env\fR\|(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 \fB\s-1OPENSSLDIR\s0\fR but all using the same
- trusted certificate store.
- .PP
- 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 \s-1TLS\s0
- server:
- .PP
- .Vb 1
- \& openssl s_client www.openssl.org:443
- .Ve
- .PP
- Once the command has connected type the letter \*(L"Q\*(R" followed by \*(L"<enter>\*(R" 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:
- .PP
- .Vb 2
- \& SSL handshake has read 4584 bytes and written 403 bytes
- \& Verification: OK
- .Ve
- .PP
- Hopefully if everything has worked then the \*(L"Verification\*(R" line will say \*(L"\s-1OK\*(R".\s0
- If its not working as expected then you might see output like this instead:
- .PP
- .Vb 2
- \& SSL handshake has read 4584 bytes and written 403 bytes
- \& Verification error: unable to get local issuer certificate
- .Ve
- .PP
- The \*(L"unable to get local issuer certificate\*(R" error means that OpenSSL has been
- unable to find a trusted \s-1CA\s0 for the chain of certificates provided by the server
- in its trusted certificate store. Check your trusted certificate store
- configuration again.
- .PP
- Note that s_client is a testing tool and will still allow you to connect to the
- \&\s-1TLS\s0 server regardless of the verification error. Most applications should not do
- this and should abort the connection in the event of a verification error.
- .SH "IMPORTANT OBJECTS FOR AN OPENSSL TLS APPLICATION"
- .IX Header "IMPORTANT OBJECTS FOR AN OPENSSL TLS APPLICATION"
- A \s-1TLS\s0 connection is represented by the \fB\s-1SSL\s0\fR object in an OpenSSL based
- application. Once a connection with a remote peer has been established an
- endpoint can \*(L"write\*(R" data to the \fB\s-1SSL\s0\fR object to send data to the peer, or
- \&\*(L"read\*(R" data from it to receive data from the server.
- .PP
- A new \fB\s-1SSL\s0\fR object is created from an \fB\s-1SSL_CTX\s0\fR object. Think of an \fB\s-1SSL_CTX\s0\fR
- as a \*(L"factory\*(R" for creating \fB\s-1SSL\s0\fR objects. You can create a single \fB\s-1SSL_CTX\s0\fR
- object and then create multiple connections (i.e. \fB\s-1SSL\s0\fR objects) from it.
- Typically you can set up common configuration options on the \fB\s-1SSL_CTX\s0\fR so that
- all the \fB\s-1SSL\s0\fR object created from it inherit the same configuration options.
- .PP
- Note that internally to OpenSSL various items that are shared between multiple
- \&\fB\s-1SSL\s0\fR objects are cached in the \fB\s-1SSL_CTX\s0\fR for performance reasons. Therefore
- it is considered best practice to create one \fB\s-1SSL_CTX\s0\fR for use by multiple
- \&\fB\s-1SSL\s0\fR objects instead of having one \fB\s-1SSL_CTX\s0\fR for each \fB\s-1SSL\s0\fR object that you
- create.
- .PP
- Each \fB\s-1SSL\s0\fR object is also associated with two \fB\s-1BIO\s0\fR objects. A \fB\s-1BIO\s0\fR object
- is used for sending or receiving data from the underlying transport layer. For
- example you might create a \fB\s-1BIO\s0\fR to represent a \s-1TCP\s0 socket. The \fB\s-1SSL\s0\fR object
- uses one \fB\s-1BIO\s0\fR for reading data and one \fB\s-1BIO\s0\fR for writing data. In most cases
- you would use the same \fB\s-1BIO\s0\fR for each direction but there could be some
- circumstances where you want them to be different.
- .PP
- It is up to the application programmer to create the \fB\s-1BIO\s0\fR objects that are
- needed and supply them to the \fB\s-1SSL\s0\fR object. See
- \&\fBossl\-guide\-tls\-client\-block\fR\|(7) for further information.
- .PP
- Finally, an endpoint can establish a \*(L"session\*(R" with its peer. The session holds
- various \s-1TLS\s0 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 \*(L"resumption\*(R". Sessions are
- represented in OpenSSL by the \fB\s-1SSL_SESSION\s0\fR object. In TLSv1.2 there is always
- exactly one session per connection. In TLSv1.3 there can be any number per
- connection including none.
- .SH "PHASES OF A TLS CONNECTION"
- .IX Header "PHASES OF A TLS CONNECTION"
- A \s-1TLS\s0 connection starts with an initial \*(L"set up\*(R" phase. The endpoint creates the
- \&\fB\s-1SSL_CTX\s0\fR (if one has not already been created) and configures it.
- .PP
- A client then creates an \fB\s-1SSL\s0\fR object to represent the new \s-1TLS\s0 connection. Any
- connection specific configuration parameters are then applied and the underlying
- socket is created and associated with the \fB\s-1SSL\s0\fR via \fB\s-1BIO\s0\fR objects.
- .PP
- 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 \fB\s-1SSL\s0\fR
- object in the same way as for a client and associate it with a \fB\s-1BIO\s0\fR for the
- newly created incoming socket.
- .PP
- After set up is complete the \s-1TLS\s0 \*(L"handshake\*(R" phase begins. A \s-1TLS\s0 handshake
- consists of the client and server exchanging a series of \s-1TLS\s0 handshake messages
- to establish the connection. The client starts by sending a \*(L"ClientHello\*(R"
- handshake message and the server responds with a \*(L"ServerHello\*(R". The handshake is
- complete once an endpoint has sent its last message (known as the \*(L"Finished\*(R"
- 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.
- .PP
- 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 \*(L"early data\*(R" capability) \- but
- we're going to skip over that for this basic introduction.
- .PP
- 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 \s-1HTTP\s0). 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 \*(L"readable\*(R", that application data will be available to read.
- .PP
- 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
- \&\*(L"close_notify\*(R" 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.
- .PP
- Once shutdown is complete a \s-1TLS\s0 application must clean up by freeing the \s-1SSL\s0
- object.
- .SH "FURTHER READING"
- .IX Header "FURTHER READING"
- See \fBossl\-guide\-tls\-client\-block\fR\|(7) to see an example of applying these
- concepts in order to write a simple \s-1TLS\s0 client based on a blocking socket.
- See \fBossl\-guide\-quic\-introduction\fR\|(7) for an introduction to \s-1QUIC\s0 in OpenSSL.
- .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\-client\-block\fR\|(7),
- \&\fBossl\-guide\-quic\-introduction\fR\|(7)
- .SH "COPYRIGHT"
- .IX Header "COPYRIGHT"
- Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
- .PP
- Licensed under the Apache License 2.0 (the \*(L"License\*(R"). You may not use
- this file except in compliance with the License. You can obtain a copy
- in the file \s-1LICENSE\s0 in the source distribution or at
- <https://www.openssl.org/source/license.html>.
|