xref: /freebsd/crypto/openssl/doc/man7/ossl-guide-tls-client-block.pod (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery=pod
2*e7be843bSPierre Pronchery
3*e7be843bSPierre Pronchery=begin comment
4*e7be843bSPierre Pronchery
5*e7be843bSPierre ProncheryNB: Changes to the source code samples in this file should also be reflected in
6*e7be843bSPierre Proncherydemos/guide/tls-client-block.c
7*e7be843bSPierre Pronchery
8*e7be843bSPierre Pronchery=end comment
9*e7be843bSPierre Pronchery
10*e7be843bSPierre Pronchery=head1 NAME
11*e7be843bSPierre Pronchery
12*e7be843bSPierre Proncheryossl-guide-tls-client-block
13*e7be843bSPierre Pronchery- OpenSSL Guide: Writing a simple blocking TLS client
14*e7be843bSPierre Pronchery
15*e7be843bSPierre Pronchery=head1 SIMPLE BLOCKING TLS CLIENT EXAMPLE
16*e7be843bSPierre Pronchery
17*e7be843bSPierre ProncheryThis page will present various source code samples demonstrating how to write
18*e7be843bSPierre Proncherya simple TLS client application which connects to a server, sends an HTTP/1.0
19*e7be843bSPierre Proncheryrequest to it, and reads back the response.
20*e7be843bSPierre Pronchery
21*e7be843bSPierre ProncheryWe use a blocking socket for the purposes of this example. This means that
22*e7be843bSPierre Proncheryattempting to read data from a socket that has no data available on it to read
23*e7be843bSPierre Proncherywill block (and the function will not return), until data becomes available.
24*e7be843bSPierre ProncheryFor example, this can happen if we have sent our request, but we are still
25*e7be843bSPierre Proncherywaiting for the server's response. Similarly any attempts to write to a socket
26*e7be843bSPierre Proncherythat is not able to write at the moment will block until writing is possible.
27*e7be843bSPierre Pronchery
28*e7be843bSPierre ProncheryThis blocking behaviour simplifies the implementation of a client because you do
29*e7be843bSPierre Proncherynot have to worry about what happens if data is not yet available. The
30*e7be843bSPierre Proncheryapplication will simply wait until it is available.
31*e7be843bSPierre Pronchery
32*e7be843bSPierre ProncheryThe complete source code for this example blocking TLS client is available in
33*e7be843bSPierre Proncherythe B<demos/guide> directory of the OpenSSL source distribution in the file
34*e7be843bSPierre ProncheryB<tls-client-block.c>. It is also available online at
35*e7be843bSPierre ProncheryL<https://github.com/openssl/openssl/blob/master/demos/guide/tls-client-block.c>.
36*e7be843bSPierre Pronchery
37*e7be843bSPierre ProncheryWe assume that you already have OpenSSL installed on your system; that you
38*e7be843bSPierre Proncheryalready have some fundamental understanding of OpenSSL concepts and TLS (see
39*e7be843bSPierre ProncheryL<ossl-guide-libraries-introduction(7)> and L<ossl-guide-tls-introduction(7)>);
40*e7be843bSPierre Proncheryand that you know how to write and build C code and link it against the
41*e7be843bSPierre Proncherylibcrypto and libssl libraries that are provided by OpenSSL. It also assumes
42*e7be843bSPierre Proncherythat you have a basic understanding of TCP/IP and sockets.
43*e7be843bSPierre Pronchery
44*e7be843bSPierre Pronchery=head2 Creating the SSL_CTX and SSL objects
45*e7be843bSPierre Pronchery
46*e7be843bSPierre ProncheryThe first step is to create an B<SSL_CTX> object for our client. We use the
47*e7be843bSPierre ProncheryL<SSL_CTX_new(3)> function for this purpose. We could alternatively use
48*e7be843bSPierre ProncheryL<SSL_CTX_new_ex(3)> if we want to associate the B<SSL_CTX> with a particular
49*e7be843bSPierre ProncheryB<OSSL_LIB_CTX> (see L<ossl-guide-libraries-introduction(7)> to learn about
50*e7be843bSPierre ProncheryB<OSSL_LIB_CTX>). We pass as an argument the return value of the function
51*e7be843bSPierre ProncheryL<TLS_client_method(3)>. You should use this method whenever you are writing a
52*e7be843bSPierre ProncheryTLS client. This method will automatically use TLS version negotiation to select
53*e7be843bSPierre Proncherythe highest version of the protocol that is mutually supported by both the
54*e7be843bSPierre Proncheryclient and the server.
55*e7be843bSPierre Pronchery
56*e7be843bSPierre Pronchery    /*
57*e7be843bSPierre Pronchery     * Create an SSL_CTX which we can use to create SSL objects from. We
58*e7be843bSPierre Pronchery     * want an SSL_CTX for creating clients so we use TLS_client_method()
59*e7be843bSPierre Pronchery     * here.
60*e7be843bSPierre Pronchery     */
61*e7be843bSPierre Pronchery    ctx = SSL_CTX_new(TLS_client_method());
62*e7be843bSPierre Pronchery    if (ctx == NULL) {
63*e7be843bSPierre Pronchery        printf("Failed to create the SSL_CTX\n");
64*e7be843bSPierre Pronchery        goto end;
65*e7be843bSPierre Pronchery    }
66*e7be843bSPierre Pronchery
67*e7be843bSPierre ProncherySince we are writing a client we must ensure that we verify the server's
68*e7be843bSPierre Proncherycertificate. We do this by calling the L<SSL_CTX_set_verify(3)> function and
69*e7be843bSPierre Proncherypass the B<SSL_VERIFY_PEER> value to it. The final argument to this function
70*e7be843bSPierre Proncheryis a callback that you can optionally supply to override the default handling
71*e7be843bSPierre Proncheryfor certificate verification. Most applications do not need to do this so this
72*e7be843bSPierre Proncherycan safely be set to NULL to get the default handling.
73*e7be843bSPierre Pronchery
74*e7be843bSPierre Pronchery    /*
75*e7be843bSPierre Pronchery     * Configure the client to abort the handshake if certificate
76*e7be843bSPierre Pronchery     * verification fails. Virtually all clients should do this unless you
77*e7be843bSPierre Pronchery     * really know what you are doing.
78*e7be843bSPierre Pronchery     */
79*e7be843bSPierre Pronchery    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
80*e7be843bSPierre Pronchery
81*e7be843bSPierre ProncheryIn order for certificate verification to be successful you must have configured
82*e7be843bSPierre Proncherywhere the trusted certificate store to be used is located (see
83*e7be843bSPierre ProncheryL<ossl-guide-tls-introduction(7)>). In most cases you just want to use the
84*e7be843bSPierre Proncherydefault store so we call L<SSL_CTX_set_default_verify_paths(3)>.
85*e7be843bSPierre Pronchery
86*e7be843bSPierre Pronchery    /* Use the default trusted certificate store */
87*e7be843bSPierre Pronchery    if (!SSL_CTX_set_default_verify_paths(ctx)) {
88*e7be843bSPierre Pronchery        printf("Failed to set the default trusted certificate store\n");
89*e7be843bSPierre Pronchery        goto end;
90*e7be843bSPierre Pronchery    }
91*e7be843bSPierre Pronchery
92*e7be843bSPierre ProncheryWe would also like to restrict the TLS versions that we are willing to accept to
93*e7be843bSPierre ProncheryTLSv1.2 or above. TLS protocol versions earlier than that are generally to be
94*e7be843bSPierre Proncheryavoided where possible. We can do that using
95*e7be843bSPierre ProncheryL<SSL_CTX_set_min_proto_version(3)>:
96*e7be843bSPierre Pronchery
97*e7be843bSPierre Pronchery    /*
98*e7be843bSPierre Pronchery     * TLSv1.1 or earlier are deprecated by IETF and are generally to be
99*e7be843bSPierre Pronchery     * avoided if possible. We require a minimum TLS version of TLSv1.2.
100*e7be843bSPierre Pronchery     */
101*e7be843bSPierre Pronchery    if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)) {
102*e7be843bSPierre Pronchery        printf("Failed to set the minimum TLS protocol version\n");
103*e7be843bSPierre Pronchery        goto end;
104*e7be843bSPierre Pronchery    }
105*e7be843bSPierre Pronchery
106*e7be843bSPierre ProncheryThat is all the setup that we need to do for the B<SSL_CTX>, so next we need to
107*e7be843bSPierre Proncherycreate an B<SSL> object to represent the TLS connection. In a real application
108*e7be843bSPierre Proncherywe might expect to be creating more than one TLS connection over time. In that
109*e7be843bSPierre Proncherycase we would expect to reuse the B<SSL_CTX> that we already created each time.
110*e7be843bSPierre ProncheryThere is no need to repeat those steps. In fact it is best not to since certain
111*e7be843bSPierre Proncheryinternal resources are cached in the B<SSL_CTX>. You will get better performance
112*e7be843bSPierre Proncheryby reusing an existing B<SSL_CTX> instead of creating a new one each time.
113*e7be843bSPierre Pronchery
114*e7be843bSPierre ProncheryCreating the B<SSL> object is a simple matter of calling the B<SSL_new(3)>
115*e7be843bSPierre Proncheryfunction and passing the B<SSL_CTX> we created as an argument.
116*e7be843bSPierre Pronchery
117*e7be843bSPierre Pronchery    /* Create an SSL object to represent the TLS connection */
118*e7be843bSPierre Pronchery    ssl = SSL_new(ctx);
119*e7be843bSPierre Pronchery    if (ssl == NULL) {
120*e7be843bSPierre Pronchery        printf("Failed to create the SSL object\n");
121*e7be843bSPierre Pronchery        goto end;
122*e7be843bSPierre Pronchery    }
123*e7be843bSPierre Pronchery
124*e7be843bSPierre Pronchery=head2 Creating the socket and BIO
125*e7be843bSPierre Pronchery
126*e7be843bSPierre ProncheryTLS data is transmitted over an underlying transport layer. Normally a TCP
127*e7be843bSPierre Proncherysocket. It is the application's responsibility for ensuring that the socket is
128*e7be843bSPierre Proncherycreated and associated with an SSL object (via a BIO).
129*e7be843bSPierre Pronchery
130*e7be843bSPierre ProncherySocket creation for use by a client is typically a 2 step process, i.e.
131*e7be843bSPierre Proncheryconstructing the socket; and connecting the socket.
132*e7be843bSPierre Pronchery
133*e7be843bSPierre ProncheryHow to construct a socket is platform specific - but most platforms (including
134*e7be843bSPierre ProncheryWindows) provide a POSIX compatible interface via the I<socket> function, e.g.
135*e7be843bSPierre Proncheryto create an IPv4 TCP socket:
136*e7be843bSPierre Pronchery
137*e7be843bSPierre Pronchery    int sock;
138*e7be843bSPierre Pronchery
139*e7be843bSPierre Pronchery    sock = socket(AF_INET, SOCK_STREAM, 0);
140*e7be843bSPierre Pronchery    if (sock == -1)
141*e7be843bSPierre Pronchery        return NULL;
142*e7be843bSPierre Pronchery
143*e7be843bSPierre ProncheryOnce the socket is constructed it must be connected to the remote server. Again
144*e7be843bSPierre Proncherythe details are platform specific but most platforms (including Windows)
145*e7be843bSPierre Proncheryprovide the POSIX compatible I<connect> function. For example:
146*e7be843bSPierre Pronchery
147*e7be843bSPierre Pronchery    struct sockaddr_in serveraddr;
148*e7be843bSPierre Pronchery    struct hostent *server;
149*e7be843bSPierre Pronchery
150*e7be843bSPierre Pronchery    server = gethostbyname("www.openssl.org");
151*e7be843bSPierre Pronchery    if (server == NULL) {
152*e7be843bSPierre Pronchery        close(sock);
153*e7be843bSPierre Pronchery        return NULL;
154*e7be843bSPierre Pronchery    }
155*e7be843bSPierre Pronchery
156*e7be843bSPierre Pronchery    memset(&serveraddr, 0, sizeof(serveraddr));
157*e7be843bSPierre Pronchery    serveraddr.sin_family = server->h_addrtype;
158*e7be843bSPierre Pronchery    serveraddr.sin_port = htons(443);
159*e7be843bSPierre Pronchery    memcpy(&serveraddr.sin_addr.s_addr, server->h_addr, server->h_length);
160*e7be843bSPierre Pronchery
161*e7be843bSPierre Pronchery    if (connect(sock, (struct sockaddr *)&serveraddr,
162*e7be843bSPierre Pronchery                sizeof(serveraddr)) == -1) {
163*e7be843bSPierre Pronchery        close(sock);
164*e7be843bSPierre Pronchery        return NULL;
165*e7be843bSPierre Pronchery    }
166*e7be843bSPierre Pronchery
167*e7be843bSPierre ProncheryOpenSSL provides portable helper functions to do these tasks which also
168*e7be843bSPierre Proncheryintegrate into the OpenSSL error system to log error data, e.g.
169*e7be843bSPierre Pronchery
170*e7be843bSPierre Pronchery    int sock = -1;
171*e7be843bSPierre Pronchery    BIO_ADDRINFO *res;
172*e7be843bSPierre Pronchery    const BIO_ADDRINFO *ai = NULL;
173*e7be843bSPierre Pronchery
174*e7be843bSPierre Pronchery    /*
175*e7be843bSPierre Pronchery     * Lookup IP address info for the server.
176*e7be843bSPierre Pronchery     */
177*e7be843bSPierre Pronchery    if (!BIO_lookup_ex(hostname, port, BIO_LOOKUP_CLIENT, family, SOCK_STREAM, 0,
178*e7be843bSPierre Pronchery                       &res))
179*e7be843bSPierre Pronchery        return NULL;
180*e7be843bSPierre Pronchery
181*e7be843bSPierre Pronchery    /*
182*e7be843bSPierre Pronchery     * Loop through all the possible addresses for the server and find one
183*e7be843bSPierre Pronchery     * we can connect to.
184*e7be843bSPierre Pronchery     */
185*e7be843bSPierre Pronchery    for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
186*e7be843bSPierre Pronchery        /*
187*e7be843bSPierre Pronchery         * Create a TCP socket. We could equally use non-OpenSSL calls such
188*e7be843bSPierre Pronchery         * as "socket" here for this and the subsequent connect and close
189*e7be843bSPierre Pronchery         * functions. But for portability reasons and also so that we get
190*e7be843bSPierre Pronchery         * errors on the OpenSSL stack in the event of a failure we use
191*e7be843bSPierre Pronchery         * OpenSSL's versions of these functions.
192*e7be843bSPierre Pronchery         */
193*e7be843bSPierre Pronchery        sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_STREAM, 0, 0);
194*e7be843bSPierre Pronchery        if (sock == -1)
195*e7be843bSPierre Pronchery            continue;
196*e7be843bSPierre Pronchery
197*e7be843bSPierre Pronchery        /* Connect the socket to the server's address */
198*e7be843bSPierre Pronchery        if (!BIO_connect(sock, BIO_ADDRINFO_address(ai), BIO_SOCK_NODELAY)) {
199*e7be843bSPierre Pronchery            BIO_closesocket(sock);
200*e7be843bSPierre Pronchery            sock = -1;
201*e7be843bSPierre Pronchery            continue;
202*e7be843bSPierre Pronchery        }
203*e7be843bSPierre Pronchery
204*e7be843bSPierre Pronchery        /* We have a connected socket so break out of the loop */
205*e7be843bSPierre Pronchery        break;
206*e7be843bSPierre Pronchery    }
207*e7be843bSPierre Pronchery
208*e7be843bSPierre Pronchery    /* Free the address information resources we allocated earlier */
209*e7be843bSPierre Pronchery    BIO_ADDRINFO_free(res);
210*e7be843bSPierre Pronchery
211*e7be843bSPierre ProncherySee L<BIO_lookup_ex(3)>, L<BIO_socket(3)>, L<BIO_connect(3)>,
212*e7be843bSPierre ProncheryL<BIO_closesocket(3)>, L<BIO_ADDRINFO_next(3)>, L<BIO_ADDRINFO_address(3)> and
213*e7be843bSPierre ProncheryL<BIO_ADDRINFO_free(3)> for further information on the functions used here. In
214*e7be843bSPierre Proncherythe above example code the B<hostname> and B<port> variables are strings, e.g.
215*e7be843bSPierre Pronchery"www.example.com" and "443".  Note also the use of the family variable, which
216*e7be843bSPierre Proncherycan take the values of AF_INET or AF_INET6 based on the command line -6 option,
217*e7be843bSPierre Proncheryto allow specific connections to an ipv4 or ipv6 enabled host.
218*e7be843bSPierre Pronchery
219*e7be843bSPierre ProncherySockets created using the methods described above will automatically be blocking
220*e7be843bSPierre Proncherysockets - which is exactly what we want for this example.
221*e7be843bSPierre Pronchery
222*e7be843bSPierre ProncheryOnce the socket has been created and connected we need to associate it with a
223*e7be843bSPierre ProncheryBIO object:
224*e7be843bSPierre Pronchery
225*e7be843bSPierre Pronchery    BIO *bio;
226*e7be843bSPierre Pronchery
227*e7be843bSPierre Pronchery    /* Create a BIO to wrap the socket */
228*e7be843bSPierre Pronchery    bio = BIO_new(BIO_s_socket());
229*e7be843bSPierre Pronchery    if (bio == NULL) {
230*e7be843bSPierre Pronchery        BIO_closesocket(sock);
231*e7be843bSPierre Pronchery        return NULL;
232*e7be843bSPierre Pronchery    }
233*e7be843bSPierre Pronchery
234*e7be843bSPierre Pronchery    /*
235*e7be843bSPierre Pronchery     * Associate the newly created BIO with the underlying socket. By
236*e7be843bSPierre Pronchery     * passing BIO_CLOSE here the socket will be automatically closed when
237*e7be843bSPierre Pronchery     * the BIO is freed. Alternatively you can use BIO_NOCLOSE, in which
238*e7be843bSPierre Pronchery     * case you must close the socket explicitly when it is no longer
239*e7be843bSPierre Pronchery     * needed.
240*e7be843bSPierre Pronchery     */
241*e7be843bSPierre Pronchery    BIO_set_fd(bio, sock, BIO_CLOSE);
242*e7be843bSPierre Pronchery
243*e7be843bSPierre ProncherySee L<BIO_new(3)>, L<BIO_s_socket(3)> and L<BIO_set_fd(3)> for further
244*e7be843bSPierre Proncheryinformation on these functions.
245*e7be843bSPierre Pronchery
246*e7be843bSPierre ProncheryFinally we associate the B<SSL> object we created earlier with the B<BIO> using
247*e7be843bSPierre Proncherythe L<SSL_set_bio(3)> function. Note that this passes ownership of the B<BIO>
248*e7be843bSPierre Proncheryobject to the B<SSL> object. Once ownership is passed the SSL object is
249*e7be843bSPierre Proncheryresponsible for its management and will free it automatically when the B<SSL> is
250*e7be843bSPierre Proncheryfreed. So, once L<SSL_set_bio(3)> has been been called, you should not call
251*e7be843bSPierre ProncheryL<BIO_free(3)> on the B<BIO>.
252*e7be843bSPierre Pronchery
253*e7be843bSPierre Pronchery    SSL_set_bio(ssl, bio, bio);
254*e7be843bSPierre Pronchery
255*e7be843bSPierre Pronchery=head2 Setting the server's hostname
256*e7be843bSPierre Pronchery
257*e7be843bSPierre ProncheryWe have already connected our underlying socket to the server, but the client
258*e7be843bSPierre Proncherystill needs to know the server's hostname. It uses this information for 2 key
259*e7be843bSPierre Proncherypurposes and we need to set the hostname for each one.
260*e7be843bSPierre Pronchery
261*e7be843bSPierre ProncheryFirstly, the server's hostname is included in the initial ClientHello message
262*e7be843bSPierre Proncherysent by the client. This is known as the Server Name Indication (SNI). This is
263*e7be843bSPierre Proncheryimportant because it is common for multiple hostnames to be fronted by a single
264*e7be843bSPierre Proncheryserver that handles requests for all of them. In other words a single server may
265*e7be843bSPierre Proncheryhave multiple hostnames associated with it and it is important to indicate which
266*e7be843bSPierre Proncheryone we want to connect to. Without this information we may get a handshake
267*e7be843bSPierre Proncheryfailure, or we may get connected to the "default" server which may not be the
268*e7be843bSPierre Proncheryone we were expecting.
269*e7be843bSPierre Pronchery
270*e7be843bSPierre ProncheryTo set the SNI hostname data we call the L<SSL_set_tlsext_host_name(3)> function
271*e7be843bSPierre Proncherylike this:
272*e7be843bSPierre Pronchery
273*e7be843bSPierre Pronchery    /*
274*e7be843bSPierre Pronchery     * Tell the server during the handshake which hostname we are attempting
275*e7be843bSPierre Pronchery     * to connect to in case the server supports multiple hosts.
276*e7be843bSPierre Pronchery     */
277*e7be843bSPierre Pronchery    if (!SSL_set_tlsext_host_name(ssl, hostname)) {
278*e7be843bSPierre Pronchery        printf("Failed to set the SNI hostname\n");
279*e7be843bSPierre Pronchery        goto end;
280*e7be843bSPierre Pronchery    }
281*e7be843bSPierre Pronchery
282*e7be843bSPierre ProncheryHere the C<hostname> argument is a string representing the hostname of the
283*e7be843bSPierre Proncheryserver, e.g. "www.example.com".
284*e7be843bSPierre Pronchery
285*e7be843bSPierre ProncherySecondly, we need to tell OpenSSL what hostname we expect to see in the
286*e7be843bSPierre Proncherycertificate coming back from the server. This is almost always the same one that
287*e7be843bSPierre Proncherywe asked for in the original request. This is important because, without this,
288*e7be843bSPierre Proncherywe do not verify that the hostname in the certificate is what we expect it to be
289*e7be843bSPierre Proncheryand any certificate is acceptable unless your application explicitly checks this
290*e7be843bSPierre Proncheryitself. We do this via the L<SSL_set1_host(3)> function:
291*e7be843bSPierre Pronchery
292*e7be843bSPierre Pronchery    /*
293*e7be843bSPierre Pronchery     * Ensure we check during certificate verification that the server has
294*e7be843bSPierre Pronchery     * supplied a certificate for the hostname that we were expecting.
295*e7be843bSPierre Pronchery     * Virtually all clients should do this unless you really know what you
296*e7be843bSPierre Pronchery     * are doing.
297*e7be843bSPierre Pronchery     */
298*e7be843bSPierre Pronchery    if (!SSL_set1_host(ssl, hostname)) {
299*e7be843bSPierre Pronchery        printf("Failed to set the certificate verification hostname");
300*e7be843bSPierre Pronchery        goto end;
301*e7be843bSPierre Pronchery    }
302*e7be843bSPierre Pronchery
303*e7be843bSPierre ProncheryAll of the above steps must happen before we attempt to perform the handshake
304*e7be843bSPierre Proncheryotherwise they will have no effect.
305*e7be843bSPierre Pronchery
306*e7be843bSPierre Pronchery=head2 Performing the handshake
307*e7be843bSPierre Pronchery
308*e7be843bSPierre ProncheryBefore we can start sending or receiving application data over a TLS connection
309*e7be843bSPierre Proncherythe TLS handshake must be performed. We can do this explicitly via the
310*e7be843bSPierre ProncheryL<SSL_connect(3)> function.
311*e7be843bSPierre Pronchery
312*e7be843bSPierre Pronchery    /* Do the handshake with the server */
313*e7be843bSPierre Pronchery    if (SSL_connect(ssl) < 1) {
314*e7be843bSPierre Pronchery        printf("Failed to connect to the server\n");
315*e7be843bSPierre Pronchery        /*
316*e7be843bSPierre Pronchery         * If the failure is due to a verification error we can get more
317*e7be843bSPierre Pronchery         * information about it from SSL_get_verify_result().
318*e7be843bSPierre Pronchery         */
319*e7be843bSPierre Pronchery        if (SSL_get_verify_result(ssl) != X509_V_OK)
320*e7be843bSPierre Pronchery            printf("Verify error: %s\n",
321*e7be843bSPierre Pronchery                X509_verify_cert_error_string(SSL_get_verify_result(ssl)));
322*e7be843bSPierre Pronchery        goto end;
323*e7be843bSPierre Pronchery    }
324*e7be843bSPierre Pronchery
325*e7be843bSPierre ProncheryThe L<SSL_connect(3)> function can return 1, 0 or less than 0. Only a return
326*e7be843bSPierre Proncheryvalue of 1 is considered a success. For a simple blocking client we only need
327*e7be843bSPierre Proncheryto concern ourselves with whether the call was successful or not. Anything else
328*e7be843bSPierre Proncheryindicates that we have failed to connect to the server.
329*e7be843bSPierre Pronchery
330*e7be843bSPierre ProncheryA common cause of failures at this stage is due to a problem verifying the
331*e7be843bSPierre Proncheryserver's certificate. For example if the certificate has expired, or it is not
332*e7be843bSPierre Proncherysigned by a CA in our trusted certificate store. We can use the
333*e7be843bSPierre ProncheryL<SSL_get_verify_result(3)> function to find out more information about the
334*e7be843bSPierre Proncheryverification failure. A return value of B<X509_V_OK> indicates that the
335*e7be843bSPierre Proncheryverification was successful (so the connection error must be due to some other
336*e7be843bSPierre Proncherycause). Otherwise we use the L<X509_verify_cert_error_string(3)> function to get
337*e7be843bSPierre Proncherya human readable error message.
338*e7be843bSPierre Pronchery
339*e7be843bSPierre Pronchery=head2 Sending and receiving data
340*e7be843bSPierre Pronchery
341*e7be843bSPierre ProncheryOnce the handshake is complete we are able to send and receive application data.
342*e7be843bSPierre ProncheryExactly what data is sent and in what order is usually controlled by some
343*e7be843bSPierre Proncheryapplication level protocol. In this example we are using HTTP 1.0 which is a
344*e7be843bSPierre Proncheryvery simple request and response protocol. The client sends a request to the
345*e7be843bSPierre Proncheryserver. The server sends the response data and then immediately closes down the
346*e7be843bSPierre Proncheryconnection.
347*e7be843bSPierre Pronchery
348*e7be843bSPierre ProncheryTo send data to the server we use the L<SSL_write_ex(3)> function and to receive
349*e7be843bSPierre Proncherydata from the server we use the L<SSL_read_ex(3)> function. In HTTP 1.0 the
350*e7be843bSPierre Proncheryclient always writes data first. Our HTTP request will include the hostname that
351*e7be843bSPierre Proncherywe are connecting to. For simplicity, we write the HTTP request in three
352*e7be843bSPierre Proncherychunks. First we write the start of the request. Secondly we write the hostname
353*e7be843bSPierre Proncherywe are sending the request to. Finally we send the end of the request.
354*e7be843bSPierre Pronchery
355*e7be843bSPierre Pronchery    size_t written;
356*e7be843bSPierre Pronchery    const char *request_start = "GET / HTTP/1.0\r\nConnection: close\r\nHost: ";
357*e7be843bSPierre Pronchery    const char *request_end = "\r\n\r\n";
358*e7be843bSPierre Pronchery
359*e7be843bSPierre Pronchery    /* Write an HTTP GET request to the peer */
360*e7be843bSPierre Pronchery    if (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
361*e7be843bSPierre Pronchery        printf("Failed to write start of HTTP request\n");
362*e7be843bSPierre Pronchery        goto end;
363*e7be843bSPierre Pronchery    }
364*e7be843bSPierre Pronchery    if (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
365*e7be843bSPierre Pronchery        printf("Failed to write hostname in HTTP request\n");
366*e7be843bSPierre Pronchery        goto end;
367*e7be843bSPierre Pronchery    }
368*e7be843bSPierre Pronchery    if (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
369*e7be843bSPierre Pronchery        printf("Failed to write end of HTTP request\n");
370*e7be843bSPierre Pronchery        goto end;
371*e7be843bSPierre Pronchery    }
372*e7be843bSPierre Pronchery
373*e7be843bSPierre ProncheryThe L<SSL_write_ex(3)> function returns 0 if it fails and 1 if it is successful.
374*e7be843bSPierre ProncheryIf it is successful then we can proceed to waiting for a response from the
375*e7be843bSPierre Proncheryserver.
376*e7be843bSPierre Pronchery
377*e7be843bSPierre Pronchery    size_t readbytes;
378*e7be843bSPierre Pronchery    char buf[160];
379*e7be843bSPierre Pronchery
380*e7be843bSPierre Pronchery    /*
381*e7be843bSPierre Pronchery     * Get up to sizeof(buf) bytes of the response. We keep reading until the
382*e7be843bSPierre Pronchery     * server closes the connection.
383*e7be843bSPierre Pronchery     */
384*e7be843bSPierre Pronchery    while (SSL_read_ex(ssl, buf, sizeof(buf), &readbytes)) {
385*e7be843bSPierre Pronchery        /*
386*e7be843bSPierre Pronchery        * OpenSSL does not guarantee that the returned data is a string or
387*e7be843bSPierre Pronchery        * that it is NUL terminated so we use fwrite() to write the exact
388*e7be843bSPierre Pronchery        * number of bytes that we read. The data could be non-printable or
389*e7be843bSPierre Pronchery        * have NUL characters in the middle of it. For this simple example
390*e7be843bSPierre Pronchery        * we're going to print it to stdout anyway.
391*e7be843bSPierre Pronchery        */
392*e7be843bSPierre Pronchery        fwrite(buf, 1, readbytes, stdout);
393*e7be843bSPierre Pronchery    }
394*e7be843bSPierre Pronchery    /* In case the response didn't finish with a newline we add one now */
395*e7be843bSPierre Pronchery    printf("\n");
396*e7be843bSPierre Pronchery
397*e7be843bSPierre Pronchery
398*e7be843bSPierre ProncheryWe use the L<SSL_read_ex(3)> function to read the response. We don't know
399*e7be843bSPierre Proncheryexactly how much data we are going to receive back so we enter a loop reading
400*e7be843bSPierre Proncheryblocks of data from the server and printing each block that we receive to the
401*e7be843bSPierre Proncheryscreen. The loop ends as soon as L<SSL_read_ex(3)> returns 0 - meaning that it
402*e7be843bSPierre Proncheryfailed to read any data.
403*e7be843bSPierre Pronchery
404*e7be843bSPierre ProncheryA failure to read data could mean that there has been some error, or it could
405*e7be843bSPierre Proncherysimply mean that server has sent all the data that it wants to send and has
406*e7be843bSPierre Proncheryindicated that it has finished by sending a "close_notify" alert. This alert is
407*e7be843bSPierre Proncherya TLS protocol level message indicating that the endpoint has finished sending
408*e7be843bSPierre Proncheryall of its data and it will not send any more. Both of these conditions result
409*e7be843bSPierre Proncheryin a 0 return value from L<SSL_read_ex(3)> and we need to use the function
410*e7be843bSPierre ProncheryL<SSL_get_error(3)> to determine the cause of the 0 return value.
411*e7be843bSPierre Pronchery
412*e7be843bSPierre Pronchery    /*
413*e7be843bSPierre Pronchery     * Check whether we finished the while loop above normally or as the
414*e7be843bSPierre Pronchery     * result of an error. The 0 argument to SSL_get_error() is the return
415*e7be843bSPierre Pronchery     * code we received from the SSL_read_ex() call. It must be 0 in order
416*e7be843bSPierre Pronchery     * to get here. Normal completion is indicated by SSL_ERROR_ZERO_RETURN.
417*e7be843bSPierre Pronchery     */
418*e7be843bSPierre Pronchery    if (SSL_get_error(ssl, 0) != SSL_ERROR_ZERO_RETURN) {
419*e7be843bSPierre Pronchery        /*
420*e7be843bSPierre Pronchery         * Some error occurred other than a graceful close down by the
421*e7be843bSPierre Pronchery         * peer
422*e7be843bSPierre Pronchery         */
423*e7be843bSPierre Pronchery        printf ("Failed reading remaining data\n");
424*e7be843bSPierre Pronchery        goto end;
425*e7be843bSPierre Pronchery    }
426*e7be843bSPierre Pronchery
427*e7be843bSPierre ProncheryIf L<SSL_get_error(3)> returns B<SSL_ERROR_ZERO_RETURN> then we know that the
428*e7be843bSPierre Proncheryserver has finished sending its data. Otherwise an error has occurred.
429*e7be843bSPierre Pronchery
430*e7be843bSPierre Pronchery=head2 Shutting down the connection
431*e7be843bSPierre Pronchery
432*e7be843bSPierre ProncheryOnce we have finished reading data from the server then we are ready to close
433*e7be843bSPierre Proncherythe connection down. We do this via the L<SSL_shutdown(3)> function which has
434*e7be843bSPierre Proncherythe effect of sending a TLS protocol level message (a "close_notify" alert) to
435*e7be843bSPierre Proncherythe server saying that we have finished writing data:
436*e7be843bSPierre Pronchery
437*e7be843bSPierre Pronchery    /*
438*e7be843bSPierre Pronchery     * The peer already shutdown gracefully (we know this because of the
439*e7be843bSPierre Pronchery     * SSL_ERROR_ZERO_RETURN above). We should do the same back.
440*e7be843bSPierre Pronchery     */
441*e7be843bSPierre Pronchery    ret = SSL_shutdown(ssl);
442*e7be843bSPierre Pronchery    if (ret < 1) {
443*e7be843bSPierre Pronchery        /*
444*e7be843bSPierre Pronchery         * ret < 0 indicates an error. ret == 0 would be unexpected here
445*e7be843bSPierre Pronchery         * because that means "we've sent a close_notify and we're waiting
446*e7be843bSPierre Pronchery         * for one back". But we already know we got one from the peer
447*e7be843bSPierre Pronchery         * because of the SSL_ERROR_ZERO_RETURN above.
448*e7be843bSPierre Pronchery         */
449*e7be843bSPierre Pronchery        printf("Error shutting down\n");
450*e7be843bSPierre Pronchery        goto end;
451*e7be843bSPierre Pronchery    }
452*e7be843bSPierre Pronchery
453*e7be843bSPierre ProncheryThe L<SSL_shutdown(3)> function will either return 1, 0, or less than 0. A
454*e7be843bSPierre Proncheryreturn value of 1 is a success, and a return value less than 0 is an error. More
455*e7be843bSPierre Proncheryprecisely a return value of 1 means that we have sent a "close_notify" alert to
456*e7be843bSPierre Proncherythe server, and that we have also received one back. A return value of 0 means
457*e7be843bSPierre Proncherythat we have sent a "close_notify" alert to the server, but we have not yet
458*e7be843bSPierre Proncheryreceived one back. Usually in this scenario you would call L<SSL_shutdown(3)>
459*e7be843bSPierre Proncheryagain which (with a blocking socket) would block until the "close_notify" is
460*e7be843bSPierre Proncheryreceived. However in this case we already know that the server has sent us a
461*e7be843bSPierre Pronchery"close_notify" because of the SSL_ERROR_ZERO_RETURN that we received from the
462*e7be843bSPierre Proncherycall to L<SSL_read_ex(3)>. So this scenario should never happen in practice. We
463*e7be843bSPierre Proncheryjust treat it as an error in this example.
464*e7be843bSPierre Pronchery
465*e7be843bSPierre Pronchery=head2 Final clean up
466*e7be843bSPierre Pronchery
467*e7be843bSPierre ProncheryBefore the application exits we have to clean up some memory that we allocated.
468*e7be843bSPierre ProncheryIf we are exiting due to an error we might also want to display further
469*e7be843bSPierre Proncheryinformation about that error if it is available to the user:
470*e7be843bSPierre Pronchery
471*e7be843bSPierre Pronchery    /* Success! */
472*e7be843bSPierre Pronchery    res = EXIT_SUCCESS;
473*e7be843bSPierre Pronchery end:
474*e7be843bSPierre Pronchery    /*
475*e7be843bSPierre Pronchery     * If something bad happened then we will dump the contents of the
476*e7be843bSPierre Pronchery     * OpenSSL error stack to stderr. There might be some useful diagnostic
477*e7be843bSPierre Pronchery     * information there.
478*e7be843bSPierre Pronchery     */
479*e7be843bSPierre Pronchery    if (res == EXIT_FAILURE)
480*e7be843bSPierre Pronchery        ERR_print_errors_fp(stderr);
481*e7be843bSPierre Pronchery
482*e7be843bSPierre Pronchery    /*
483*e7be843bSPierre Pronchery     * Free the resources we allocated. We do not free the BIO object here
484*e7be843bSPierre Pronchery     * because ownership of it was immediately transferred to the SSL object
485*e7be843bSPierre Pronchery     * via SSL_set_bio(). The BIO will be freed when we free the SSL object.
486*e7be843bSPierre Pronchery     */
487*e7be843bSPierre Pronchery    SSL_free(ssl);
488*e7be843bSPierre Pronchery    SSL_CTX_free(ctx);
489*e7be843bSPierre Pronchery    return res;
490*e7be843bSPierre Pronchery
491*e7be843bSPierre ProncheryTo display errors we make use of the L<ERR_print_errors_fp(3)> function which
492*e7be843bSPierre Proncherysimply dumps out the contents of any errors on the OpenSSL error stack to the
493*e7be843bSPierre Proncheryspecified location (in this case I<stderr>).
494*e7be843bSPierre Pronchery
495*e7be843bSPierre ProncheryWe need to free up the B<SSL> object that we created for the connection via the
496*e7be843bSPierre ProncheryL<SSL_free(3)> function. Also, since we are not going to be creating any more
497*e7be843bSPierre ProncheryTLS connections we must also free up the B<SSL_CTX> via a call to
498*e7be843bSPierre ProncheryL<SSL_CTX_free(3)>.
499*e7be843bSPierre Pronchery
500*e7be843bSPierre Pronchery=head1 TROUBLESHOOTING
501*e7be843bSPierre Pronchery
502*e7be843bSPierre ProncheryThere are a number of things that might go wrong when running the demo
503*e7be843bSPierre Proncheryapplication. This section describes some common things you might encounter.
504*e7be843bSPierre Pronchery
505*e7be843bSPierre Pronchery=head2 Failure to connect the underlying socket
506*e7be843bSPierre Pronchery
507*e7be843bSPierre ProncheryThis could occur for numerous reasons. For example if there is a problem in the
508*e7be843bSPierre Proncherynetwork route between the client and the server; or a firewall is blocking the
509*e7be843bSPierre Proncherycommunication; or the server is not in DNS. Check the network configuration.
510*e7be843bSPierre Pronchery
511*e7be843bSPierre Pronchery=head2 Verification failure of the server certificate
512*e7be843bSPierre Pronchery
513*e7be843bSPierre ProncheryA verification failure of the server certificate would result in a failure when
514*e7be843bSPierre Proncheryrunning the L<SSL_connect(3)> function. L<ERR_print_errors_fp(3)> would display
515*e7be843bSPierre Proncheryan error which would look something like this:
516*e7be843bSPierre Pronchery
517*e7be843bSPierre Pronchery Verify error: unable to get local issuer certificate
518*e7be843bSPierre Pronchery 40E74AF1F47F0000:error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:2069:
519*e7be843bSPierre Pronchery
520*e7be843bSPierre ProncheryA server certificate verification failure could be caused for a number of
521*e7be843bSPierre Proncheryreasons. For example
522*e7be843bSPierre Pronchery
523*e7be843bSPierre Pronchery=over 4
524*e7be843bSPierre Pronchery
525*e7be843bSPierre Pronchery=item Failure to correctly setup the trusted certificate store
526*e7be843bSPierre Pronchery
527*e7be843bSPierre ProncherySee the page L<ossl-guide-tls-introduction(7)> and check that your trusted
528*e7be843bSPierre Proncherycertificate store is correctly configured
529*e7be843bSPierre Pronchery
530*e7be843bSPierre Pronchery=item Unrecognised CA
531*e7be843bSPierre Pronchery
532*e7be843bSPierre ProncheryIf the CA used by the server's certificate is not in the trusted certificate
533*e7be843bSPierre Proncherystore for the client then this will cause a verification failure during
534*e7be843bSPierre Proncheryconnection. Often this can occur if the server is using a self-signed
535*e7be843bSPierre Proncherycertificate (i.e. a test certificate that has not been signed by a CA at all).
536*e7be843bSPierre Pronchery
537*e7be843bSPierre Pronchery=item Missing intermediate CAs
538*e7be843bSPierre Pronchery
539*e7be843bSPierre ProncheryThis is a server misconfiguration where the client has the relevant root CA in
540*e7be843bSPierre Proncheryits trust store, but the server has not supplied all of the intermediate CA
541*e7be843bSPierre Proncherycertificates between that root CA and the server's own certificate. Therefore
542*e7be843bSPierre Proncherya trust chain cannot be established.
543*e7be843bSPierre Pronchery
544*e7be843bSPierre Pronchery=item Mismatched hostname
545*e7be843bSPierre Pronchery
546*e7be843bSPierre ProncheryIf for some reason the hostname of the server that the client is expecting does
547*e7be843bSPierre Proncherynot match the hostname in the certificate then this will cause verification to
548*e7be843bSPierre Proncheryfail.
549*e7be843bSPierre Pronchery
550*e7be843bSPierre Pronchery=item Expired certificate
551*e7be843bSPierre Pronchery
552*e7be843bSPierre ProncheryThe date that the server's certificate is valid to has passed.
553*e7be843bSPierre Pronchery
554*e7be843bSPierre Pronchery=back
555*e7be843bSPierre Pronchery
556*e7be843bSPierre ProncheryThe "unable to get local issuer certificate" we saw in the example above means
557*e7be843bSPierre Proncherythat we have been unable to find the issuer of the server's certificate (or one
558*e7be843bSPierre Proncheryof its intermediate CA certificates) in our trusted certificate store (e.g.
559*e7be843bSPierre Proncherybecause the trusted certificate store is misconfigured, or there are missing
560*e7be843bSPierre Proncheryintermediate CAs, or the issuer is simply unrecognised).
561*e7be843bSPierre Pronchery
562*e7be843bSPierre Pronchery=head1 FURTHER READING
563*e7be843bSPierre Pronchery
564*e7be843bSPierre ProncherySee L<ossl-guide-tls-client-non-block(7)> to read a tutorial on how to modify
565*e7be843bSPierre Proncherythe client developed on this page to support a nonblocking socket.
566*e7be843bSPierre Pronchery
567*e7be843bSPierre ProncherySee L<ossl-guide-tls-server-block(7)> for a tutorial on how to implement a
568*e7be843bSPierre Proncherysimple TLS server handling one client at a time over a blocking socket.
569*e7be843bSPierre Pronchery
570*e7be843bSPierre ProncherySee L<ossl-guide-quic-client-block(7)> to read a tutorial on how to modify the
571*e7be843bSPierre Proncheryclient developed on this page to support QUIC instead of TLS.
572*e7be843bSPierre Pronchery
573*e7be843bSPierre Pronchery=head1 SEE ALSO
574*e7be843bSPierre Pronchery
575*e7be843bSPierre ProncheryL<ossl-guide-introduction(7)>, L<ossl-guide-libraries-introduction(7)>,
576*e7be843bSPierre ProncheryL<ossl-guide-libssl-introduction(7)>, L<ossl-guide-tls-introduction(7)>,
577*e7be843bSPierre ProncheryL<ossl-guide-tls-client-non-block(7)>, L<ossl-guide-quic-client-block(7)>
578*e7be843bSPierre Pronchery
579*e7be843bSPierre Pronchery=head1 COPYRIGHT
580*e7be843bSPierre Pronchery
581*e7be843bSPierre ProncheryCopyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
582*e7be843bSPierre Pronchery
583*e7be843bSPierre ProncheryLicensed under the Apache License 2.0 (the "License").  You may not use
584*e7be843bSPierre Proncherythis file except in compliance with the License.  You can obtain a copy
585*e7be843bSPierre Proncheryin the file LICENSE in the source distribution or at
586*e7be843bSPierre ProncheryL<https://www.openssl.org/source/license.html>.
587*e7be843bSPierre Pronchery
588*e7be843bSPierre Pronchery=cut
589