Home | History | Annotate | Line # | Download | only in guide
      1 /*
      2  *  Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  *  Licensed under the Apache License 2.0 (the "License").  You may not use
      5  *  this file except in compliance with the License.  You can obtain a copy
      6  *  in the file LICENSE in the source distribution or at
      7  *  https://www.openssl.org/source/license.html
      8  */
      9 
     10 /*
     11  * NB: Changes to this file should also be reflected in
     12  * doc/man7/ossl-guide-quic-client-block.pod
     13  */
     14 
     15 #include <string.h>
     16 
     17 /* Include the appropriate header file for SOCK_DGRAM */
     18 #ifdef _WIN32 /* Windows */
     19 #include <winsock2.h>
     20 #else /* Linux/Unix */
     21 #include <sys/socket.h>
     22 #endif
     23 
     24 #include <openssl/bio.h>
     25 #include <openssl/ssl.h>
     26 #include <openssl/err.h>
     27 
     28 /* Helper function to create a BIO connected to the server */
     29 static BIO *create_socket_bio(const char *hostname, const char *port,
     30     int family, BIO_ADDR **peer_addr)
     31 {
     32     int sock = -1;
     33     BIO_ADDRINFO *res;
     34     const BIO_ADDRINFO *ai = NULL;
     35     BIO *bio;
     36 
     37     /*
     38      * Lookup IP address info for the server.
     39      */
     40     if (!BIO_lookup_ex(hostname, port, BIO_LOOKUP_CLIENT, family, SOCK_DGRAM, 0,
     41             &res))
     42         return NULL;
     43 
     44     /*
     45      * Loop through all the possible addresses for the server and find one
     46      * we can connect to.
     47      */
     48     for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
     49         /*
     50          * Create a UDP socket. We could equally use non-OpenSSL calls such
     51          * as "socket" here for this and the subsequent connect and close
     52          * functions. But for portability reasons and also so that we get
     53          * errors on the OpenSSL stack in the event of a failure we use
     54          * OpenSSL's versions of these functions.
     55          */
     56         sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0);
     57         if (sock == -1)
     58             continue;
     59 
     60         /* Connect the socket to the server's address */
     61         if (!BIO_connect(sock, BIO_ADDRINFO_address(ai), 0)) {
     62             BIO_closesocket(sock);
     63             sock = -1;
     64             continue;
     65         }
     66 
     67         /* Set to nonblocking mode */
     68         if (!BIO_socket_nbio(sock, 1)) {
     69             BIO_closesocket(sock);
     70             sock = -1;
     71             continue;
     72         }
     73 
     74         break;
     75     }
     76 
     77     if (sock != -1) {
     78         *peer_addr = BIO_ADDR_dup(BIO_ADDRINFO_address(ai));
     79         if (*peer_addr == NULL) {
     80             BIO_closesocket(sock);
     81             return NULL;
     82         }
     83     }
     84 
     85     /* Free the address information resources we allocated earlier */
     86     BIO_ADDRINFO_free(res);
     87 
     88     /* If sock is -1 then we've been unable to connect to the server */
     89     if (sock == -1)
     90         return NULL;
     91 
     92     /* Create a BIO to wrap the socket */
     93     bio = BIO_new(BIO_s_datagram());
     94     if (bio == NULL) {
     95         BIO_closesocket(sock);
     96         return NULL;
     97     }
     98 
     99     /*
    100      * Associate the newly created BIO with the underlying socket. By
    101      * passing BIO_CLOSE here the socket will be automatically closed when
    102      * the BIO is freed. Alternatively you can use BIO_NOCLOSE, in which
    103      * case you must close the socket explicitly when it is no longer
    104      * needed.
    105      */
    106     BIO_set_fd(bio, sock, BIO_CLOSE);
    107 
    108     return bio;
    109 }
    110 
    111 /*
    112  * Simple application to send a basic HTTP/1.0 request to a server and
    113  * print the response on the screen. Note that HTTP/1.0 over QUIC is
    114  * non-standard and will not typically be supported by real world servers. This
    115  * is for demonstration purposes only.
    116  */
    117 int main(int argc, char *argv[])
    118 {
    119     SSL_CTX *ctx = NULL;
    120     SSL *ssl = NULL;
    121     BIO *bio = NULL;
    122     int res = EXIT_FAILURE;
    123     int ret;
    124     unsigned char alpn[] = { 8, 'h', 't', 't', 'p', '/', '1', '.', '0' };
    125     const char *request_start = "GET / HTTP/1.0\r\nConnection: close\r\nHost: ";
    126     const char *request_end = "\r\n\r\n";
    127     size_t written, readbytes;
    128     char buf[160];
    129     BIO_ADDR *peer_addr = NULL;
    130     char *hostname, *port;
    131     int argnext = 1;
    132     int ipv6 = 0;
    133 
    134     if (argc < 3) {
    135         printf("Usage: quic-client-block [-6] hostname port\n");
    136         goto end;
    137     }
    138 
    139     if (!strcmp(argv[argnext], "-6")) {
    140         if (argc < 4) {
    141             printf("Usage: quic-client-block [-6] hostname port\n");
    142             goto end;
    143         }
    144         ipv6 = 1;
    145         argnext++;
    146     }
    147     hostname = argv[argnext++];
    148     port = argv[argnext];
    149 
    150     /*
    151      * Create an SSL_CTX which we can use to create SSL objects from. We
    152      * want an SSL_CTX for creating clients so we use
    153      * OSSL_QUIC_client_method() here.
    154      */
    155     ctx = SSL_CTX_new(OSSL_QUIC_client_method());
    156     if (ctx == NULL) {
    157         printf("Failed to create the SSL_CTX\n");
    158         goto end;
    159     }
    160 
    161     /*
    162      * Configure the client to abort the handshake if certificate
    163      * verification fails. Virtually all clients should do this unless you
    164      * really know what you are doing.
    165      */
    166     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
    167 
    168     /* Use the default trusted certificate store */
    169     if (!SSL_CTX_set_default_verify_paths(ctx)) {
    170         printf("Failed to set the default trusted certificate store\n");
    171         goto end;
    172     }
    173 
    174     /* Create an SSL object to represent the TLS connection */
    175     ssl = SSL_new(ctx);
    176     if (ssl == NULL) {
    177         printf("Failed to create the SSL object\n");
    178         goto end;
    179     }
    180 
    181     /*
    182      * Create the underlying transport socket/BIO and associate it with the
    183      * connection.
    184      */
    185     bio = create_socket_bio(hostname, port, ipv6 ? AF_INET6 : AF_INET, &peer_addr);
    186     if (bio == NULL) {
    187         printf("Failed to crete the BIO\n");
    188         goto end;
    189     }
    190     SSL_set_bio(ssl, bio, bio);
    191 
    192     /*
    193      * Tell the server during the handshake which hostname we are attempting
    194      * to connect to in case the server supports multiple hosts.
    195      */
    196     if (!SSL_set_tlsext_host_name(ssl, hostname)) {
    197         printf("Failed to set the SNI hostname\n");
    198         goto end;
    199     }
    200 
    201     /*
    202      * Ensure we check during certificate verification that the server has
    203      * supplied a certificate for the hostname that we were expecting.
    204      * Virtually all clients should do this unless you really know what you
    205      * are doing.
    206      */
    207     if (!SSL_set1_host(ssl, hostname)) {
    208         printf("Failed to set the certificate verification hostname");
    209         goto end;
    210     }
    211 
    212     /* SSL_set_alpn_protos returns 0 for success! */
    213     if (SSL_set_alpn_protos(ssl, alpn, sizeof(alpn)) != 0) {
    214         printf("Failed to set the ALPN for the connection\n");
    215         goto end;
    216     }
    217 
    218     /* Set the IP address of the remote peer */
    219     if (!SSL_set1_initial_peer_addr(ssl, peer_addr)) {
    220         printf("Failed to set the initial peer address\n");
    221         goto end;
    222     }
    223 
    224     /* Do the handshake with the server */
    225     if (SSL_connect(ssl) < 1) {
    226         printf("Failed to connect to the server\n");
    227         /*
    228          * If the failure is due to a verification error we can get more
    229          * information about it from SSL_get_verify_result().
    230          */
    231         if (SSL_get_verify_result(ssl) != X509_V_OK)
    232             printf("Verify error: %s\n",
    233                 X509_verify_cert_error_string(SSL_get_verify_result(ssl)));
    234         goto end;
    235     }
    236 
    237     /* Write an HTTP GET request to the peer */
    238     if (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
    239         printf("Failed to write start of HTTP request\n");
    240         goto end;
    241     }
    242     if (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
    243         printf("Failed to write hostname in HTTP request\n");
    244         goto end;
    245     }
    246     if (!SSL_write_ex2(ssl, request_end, strlen(request_end),
    247             SSL_WRITE_FLAG_CONCLUDE, &written)) {
    248         printf("Failed to write end of HTTP request\n");
    249         goto end;
    250     }
    251 
    252     /*
    253      * Get up to sizeof(buf) bytes of the response. We keep reading until the
    254      * server closes the connection.
    255      */
    256     while (SSL_read_ex(ssl, buf, sizeof(buf), &readbytes)) {
    257         /*
    258          * OpenSSL does not guarantee that the returned data is a string or
    259          * that it is NUL terminated so we use fwrite() to write the exact
    260          * number of bytes that we read. The data could be non-printable or
    261          * have NUL characters in the middle of it. For this simple example
    262          * we're going to print it to stdout anyway.
    263          */
    264         fwrite(buf, 1, readbytes, stdout);
    265     }
    266     /* In case the response didn't finish with a newline we add one now */
    267     printf("\n");
    268 
    269     /*
    270      * Check whether we finished the while loop above normally or as the
    271      * result of an error. The 0 argument to SSL_get_error() is the return
    272      * code we received from the SSL_read_ex() call. It must be 0 in order
    273      * to get here. Normal completion is indicated by SSL_ERROR_ZERO_RETURN. In
    274      * QUIC terms this means that the peer has sent FIN on the stream to
    275      * indicate that no further data will be sent.
    276      */
    277     switch (SSL_get_error(ssl, 0)) {
    278     case SSL_ERROR_ZERO_RETURN:
    279         /* Normal completion of the stream */
    280         break;
    281 
    282     case SSL_ERROR_SSL:
    283         /*
    284          * Some stream fatal error occurred. This could be because of a stream
    285          * reset - or some failure occurred on the underlying connection.
    286          */
    287         switch (SSL_get_stream_read_state(ssl)) {
    288         case SSL_STREAM_STATE_RESET_REMOTE:
    289             printf("Stream reset occurred\n");
    290             /* The stream has been reset but the connection is still healthy. */
    291             break;
    292 
    293         case SSL_STREAM_STATE_CONN_CLOSED:
    294             printf("Connection closed\n");
    295             /* Connection is already closed. Skip SSL_shutdown() */
    296             goto end;
    297 
    298         default:
    299             printf("Unknown stream failure\n");
    300             break;
    301         }
    302         break;
    303 
    304     default:
    305         /* Some other unexpected error occurred */
    306         printf("Failed reading remaining data\n");
    307         break;
    308     }
    309 
    310     /*
    311      * Repeatedly call SSL_shutdown() until the connection is fully
    312      * closed.
    313      */
    314     do {
    315         ret = SSL_shutdown(ssl);
    316         if (ret < 0) {
    317             printf("Error shutting down: %d\n", ret);
    318             goto end;
    319         }
    320     } while (ret != 1);
    321 
    322     /* Success! */
    323     res = EXIT_SUCCESS;
    324 end:
    325     /*
    326      * If something bad happened then we will dump the contents of the
    327      * OpenSSL error stack to stderr. There might be some useful diagnostic
    328      * information there.
    329      */
    330     if (res == EXIT_FAILURE)
    331         ERR_print_errors_fp(stderr);
    332 
    333     /*
    334      * Free the resources we allocated. We do not free the BIO object here
    335      * because ownership of it was immediately transferred to the SSL object
    336      * via SSL_set_bio(). The BIO will be freed when we free the SSL object.
    337      */
    338     SSL_free(ssl);
    339     SSL_CTX_free(ctx);
    340     BIO_ADDR_free(peer_addr);
    341     return res;
    342 }
    343