]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Update the OpenSSL Guide tutorials with changes to the demos
authorMatt Caswell <matt@openssl.org>
Mon, 30 Oct 2023 12:39:37 +0000 (12:39 +0000)
committerHugo Landau <hlandau@openssl.org>
Thu, 2 Nov 2023 08:14:46 +0000 (08:14 +0000)
The demo code has changed to accept the hostname/port on the command line.
We update the tutorials to keep in sync with the demo code.

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22552)

doc/man7/ossl-guide-quic-client-non-block.pod
doc/man7/ossl-guide-quic-multi-stream.pod
doc/man7/ossl-guide-tls-client-block.pod
doc/man7/ossl-guide-tls-client-non-block.pod

index 0c2b916b803b00b0c601353c7586ca3982024dc3..f07e9cc6692535a73ee9036f5cd7542f15fda5f6 100644 (file)
@@ -341,13 +341,26 @@ data on a retry. An optional mode does exist
 the buffer being written to change from one retry to the next. However, in this
 case, you must still retry exactly the same data - even though the buffer that
 contains that data may change location. See L<SSL_CTX_set_mode(3)> for further
-details.
+details. As in the TLS tutorials (L<ossl-guide-tls-client-block(7)>) we write
+the request in three chunks.
 
     /* Write an HTTP GET request to the peer */
-    while (!SSL_write_ex(ssl, request, strlen(request), &written)) {
+    while (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
         if (handle_io_failure(ssl, 0) == 1)
             continue; /* Retry */
-        printf("Failed to write HTTP request\n");
+        printf("Failed to write start of HTTP request\n");
+        goto end; /* Cannot retry: error */
+    }
+    while (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
+        if (handle_io_failure(ssl, 0) == 1)
+            continue; /* Retry */
+        printf("Failed to write hostname in HTTP request\n");
+        goto end; /* Cannot retry: error */
+    }
+    while (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
+        if (handle_io_failure(ssl, 0) == 1)
+            continue; /* Retry */
+        printf("Failed to write end of HTTP request\n");
         goto end; /* Cannot retry: error */
     }
 
index 5b78409d61eb7060e7a3f75bc930721bd4b39025..1493d1c2b2e8cfa031f7d9ec9726385780ef7c71 100644 (file)
@@ -213,23 +213,43 @@ uni-directional one:
 =head2 Writing data to the streams
 
 Once the streams are successfully created we can start writing data to them. In
-this example we will be sending a different HTTP request on each stream. We
-assume the strings B<request1> and B<request2> hold the appropriate HTTP
-requests. For the sake of simplicity this example does this sequentially,
-writing to B<stream1> first and, when this is successful, writing to B<stream2>
-second. Remember that our client is blocking so these calls will only return
-once they have been successfully completed. A real application would not need to
-do these writes sequentially or in any particular order. For example we could
-start two threads (one for each stream) and write the requests to each stream
-simultaneously.
+this example we will be sending a different HTTP request on each stream. To
+avoid repeating too much code we write a simple helper function to send an HTTP
+request to a stream:
+
+    int write_a_request(SSL *stream, const char *request_start,
+                        const char *hostname)
+    {
+        const char *request_end = "\r\n\r\n";
+        size_t written;
+
+        if (!SSL_write_ex(stream, request_start, strlen(request_start), &written))
+            return 0;
+        if (!SSL_write_ex(stream, hostname, strlen(hostname), &written))
+            return 0;
+        if (!SSL_write_ex(stream, request_end, strlen(request_end), &written))
+            return 0;
+
+        return 1;
+    }
+
+We assume the strings B<request1_start> and B<request2_start> hold the
+appropriate HTTP requests. We can then call our helper function above to send
+the requests on the two streams. For the sake of simplicity this example does
+this sequentially, writing to B<stream1> first and, when this is successful,
+writing to B<stream2> second. Remember that our client is blocking so these
+calls will only return once they have been successfully completed. A real
+application would not need to do these writes sequentially or in any particular
+order. For example we could start two threads (one for each stream) and write
+the requests to each stream simultaneously.
 
     /* Write an HTTP GET request on each of our streams to the peer */
-    if (!SSL_write_ex(stream1, request1, strlen(request1), &written)) {
+    if (!write_a_request(stream1, request1_start, hostname)) {
         printf("Failed to write HTTP request on stream 1\n");
         goto end;
     }
 
-    if (!SSL_write_ex(stream2, request2, strlen(request2), &written)) {
+    if (!write_a_request(stream2, request2_start, hostname)) {
         printf("Failed to write HTTP request on stream 2\n");
         goto end;
     }
index 646b58081ad4c7564c5a580d8def67120c0328a9..cb67bf8fa9bd413608ec6a52822b4219f1c47549 100644 (file)
@@ -272,13 +272,13 @@ like this:
      * Tell the server during the handshake which hostname we are attempting
      * to connect to in case the server supports multiple hosts.
      */
-    if (!SSL_set_tlsext_host_name(ssl, HOSTNAME)) {
+    if (!SSL_set_tlsext_host_name(ssl, hostname)) {
         printf("Failed to set the SNI hostname\n");
         goto end;
     }
 
-Here the HOSTNAME argument is a string representing the hostname of the server,
-e.g. "www.example.com".
+Here the C<hostname> argument is a string representing the hostname of the
+server, e.g. "www.example.com".
 
 Secondly, we need to tell OpenSSL what hostname we expect to see in the
 certificate coming back from the server. This is almost always the same one that
@@ -293,7 +293,7 @@ itself. We do this via the L<SSL_set1_host(3)> function:
      * Virtually all clients should do this unless you really know what you
      * are doing.
      */
-    if (!SSL_set1_host(ssl, HOSTNAME)) {
+    if (!SSL_set1_host(ssl, hostname)) {
         printf("Failed to set the certificate verification hostname");
         goto end;
     }
@@ -345,15 +345,26 @@ connection.
 
 To send data to the server we use the L<SSL_write_ex(3)> function and to receive
 data from the server we use the L<SSL_read_ex(3)> function. In HTTP 1.0 the
-client always writes data first.
+client always writes data first. Our HTTP request will include the hostname that
+we are connecting to. For simplicitly, we write the HTTP request in three
+chunks. First we write the start of the request. Secondly we write the hostname
+we are sending the request to. Finally we send the end of the request.
 
     size_t written;
-    const char *request =
-        "GET / HTTP/1.0\r\nConnection: close\r\nHost: "HOSTNAME"\r\n\r\n";
+    const char *request_start = "GET / HTTP/1.0\r\nConnection: close\r\nHost: ";
+    const char *request_end = "\r\n\r\n";
 
     /* Write an HTTP GET request to the peer */
-    if (!SSL_write_ex(ssl, request, strlen(request), &written)) {
-        printf("Failed to write HTTP request\n");
+    if (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
+        printf("Failed to write start of HTTP request\n");
+        goto end;
+    }
+    if (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
+        printf("Failed to write hostname in HTTP request\n");
+        goto end;
+    }
+    if (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
+        printf("Failed to write end of HTTP request\n");
         goto end;
     }
 
index 1eabcc0b576bee153e4cfcaf8995002d0a0b2910..ee03f6624bc70d4d99ba9aee058a1f9e32f4189d 100644 (file)
@@ -252,13 +252,27 @@ retry. An optional mode does exist (B<SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER>)
 which will configure OpenSSL to allow the buffer being written to change from
 one retry to the next. However, in this case, you must still retry exactly the
 same data - even though the buffer that contains that data may change location.
-See L<SSL_CTX_set_mode(3)> for further details.
+See L<SSL_CTX_set_mode(3)> for further details. As in the TLS client
+blocking tutorial (L<ossl-guide-tls-client-block(7)>) we write the request
+in three chunks.
 
     /* Write an HTTP GET request to the peer */
-    while (!SSL_write_ex(ssl, request, strlen(request), &written)) {
+    while (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
         if (handle_io_failure(ssl, 0) == 1)
             continue; /* Retry */
-        printf("Failed to write HTTP request\n");
+        printf("Failed to write start of HTTP request\n");
+        goto end; /* Cannot retry: error */
+    }
+    while (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
+        if (handle_io_failure(ssl, 0) == 1)
+            continue; /* Retry */
+        printf("Failed to write hostname in HTTP request\n");
+        goto end; /* Cannot retry: error */
+    }
+    while (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
+        if (handle_io_failure(ssl, 0) == 1)
+            continue; /* Retry */
+        printf("Failed to write end of HTTP request\n");
         goto end; /* Cannot retry: error */
     }