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-tls-client-block.pod 13 */ 14 15 #include <string.h> 16 17 /* Include the appropriate header file for SOCK_STREAM */ 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, int family) 30 { 31 int sock = -1; 32 BIO_ADDRINFO *res; 33 const BIO_ADDRINFO *ai = NULL; 34 BIO *bio; 35 36 /* 37 * Lookup IP address info for the server. 38 */ 39 if (!BIO_lookup_ex(hostname, port, BIO_LOOKUP_CLIENT, family, SOCK_STREAM, 0, 40 &res)) 41 return NULL; 42 43 /* 44 * Loop through all the possible addresses for the server and find one 45 * we can connect to. 46 */ 47 for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) { 48 /* 49 * Create a TCP socket. We could equally use non-OpenSSL calls such 50 * as "socket" here for this and the subsequent connect and close 51 * functions. But for portability reasons and also so that we get 52 * errors on the OpenSSL stack in the event of a failure we use 53 * OpenSSL's versions of these functions. 54 */ 55 sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_STREAM, 0, 0); 56 if (sock == -1) 57 continue; 58 59 /* Connect the socket to the server's address */ 60 if (!BIO_connect(sock, BIO_ADDRINFO_address(ai), BIO_SOCK_NODELAY)) { 61 BIO_closesocket(sock); 62 sock = -1; 63 continue; 64 } 65 66 /* We have a connected socket so break out of the loop */ 67 break; 68 } 69 70 /* Free the address information resources we allocated earlier */ 71 BIO_ADDRINFO_free(res); 72 73 /* If sock is -1 then we've been unable to connect to the server */ 74 if (sock == -1) 75 return NULL; 76 77 /* Create a BIO to wrap the socket */ 78 bio = BIO_new(BIO_s_socket()); 79 if (bio == NULL) { 80 BIO_closesocket(sock); 81 return NULL; 82 } 83 84 /* 85 * Associate the newly created BIO with the underlying socket. By 86 * passing BIO_CLOSE here the socket will be automatically closed when 87 * the BIO is freed. Alternatively you can use BIO_NOCLOSE, in which 88 * case you must close the socket explicitly when it is no longer 89 * needed. 90 */ 91 BIO_set_fd(bio, sock, BIO_CLOSE); 92 93 return bio; 94 } 95 96 /* 97 * Simple application to send a basic HTTP/1.0 request to a server and 98 * print the response on the screen. 99 */ 100 int main(int argc, char *argv[]) 101 { 102 SSL_CTX *ctx = NULL; 103 SSL *ssl = NULL; 104 BIO *bio = NULL; 105 int res = EXIT_FAILURE; 106 int ret; 107 const char *request_start = "GET / HTTP/1.0\r\nConnection: close\r\nHost: "; 108 const char *request_end = "\r\n\r\n"; 109 size_t written, readbytes; 110 char buf[160]; 111 char *hostname, *port; 112 int argnext = 1; 113 int ipv6 = 0; 114 115 if (argc < 3) { 116 printf("Usage: tls-client-block [-6] hostname port\n"); 117 goto end; 118 } 119 120 if (!strcmp(argv[argnext], "-6")) { 121 if (argc < 4) { 122 printf("Usage: tls-client-block [-6] hostname port\n"); 123 goto end; 124 } 125 ipv6 = 1; 126 argnext++; 127 } 128 hostname = argv[argnext++]; 129 port = argv[argnext]; 130 131 /* 132 * Create an SSL_CTX which we can use to create SSL objects from. We 133 * want an SSL_CTX for creating clients so we use TLS_client_method() 134 * here. 135 */ 136 ctx = SSL_CTX_new(TLS_client_method()); 137 if (ctx == NULL) { 138 printf("Failed to create the SSL_CTX\n"); 139 goto end; 140 } 141 142 /* 143 * Configure the client to abort the handshake if certificate 144 * verification fails. Virtually all clients should do this unless you 145 * really know what you are doing. 146 */ 147 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 148 149 /* Use the default trusted certificate store */ 150 if (!SSL_CTX_set_default_verify_paths(ctx)) { 151 printf("Failed to set the default trusted certificate store\n"); 152 goto end; 153 } 154 155 /* 156 * TLSv1.1 or earlier are deprecated by IETF and are generally to be 157 * avoided if possible. We require a minimum TLS version of TLSv1.2. 158 */ 159 if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)) { 160 printf("Failed to set the minimum TLS protocol version\n"); 161 goto end; 162 } 163 164 /* Create an SSL object to represent the TLS connection */ 165 ssl = SSL_new(ctx); 166 if (ssl == NULL) { 167 printf("Failed to create the SSL object\n"); 168 goto end; 169 } 170 171 /* 172 * Create the underlying transport socket/BIO and associate it with the 173 * connection. 174 */ 175 bio = create_socket_bio(hostname, port, ipv6 ? AF_INET6 : AF_INET); 176 if (bio == NULL) { 177 printf("Failed to create the BIO\n"); 178 goto end; 179 } 180 SSL_set_bio(ssl, bio, bio); 181 182 /* 183 * Tell the server during the handshake which hostname we are attempting 184 * to connect to in case the server supports multiple hosts. 185 */ 186 if (!SSL_set_tlsext_host_name(ssl, hostname)) { 187 printf("Failed to set the SNI hostname\n"); 188 goto end; 189 } 190 191 /* 192 * Ensure we check during certificate verification that the server has 193 * supplied a certificate for the hostname that we were expecting. 194 * Virtually all clients should do this unless you really know what you 195 * are doing. 196 */ 197 if (!SSL_set1_host(ssl, hostname)) { 198 printf("Failed to set the certificate verification hostname"); 199 goto end; 200 } 201 202 /* Do the handshake with the server */ 203 if (SSL_connect(ssl) < 1) { 204 printf("Failed to connect to the server\n"); 205 /* 206 * If the failure is due to a verification error we can get more 207 * information about it from SSL_get_verify_result(). 208 */ 209 if (SSL_get_verify_result(ssl) != X509_V_OK) 210 printf("Verify error: %s\n", 211 X509_verify_cert_error_string(SSL_get_verify_result(ssl))); 212 goto end; 213 } 214 215 /* Write an HTTP GET request to the peer */ 216 if (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) { 217 printf("Failed to write start of HTTP request\n"); 218 goto end; 219 } 220 if (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) { 221 printf("Failed to write hostname in HTTP request\n"); 222 goto end; 223 } 224 if (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) { 225 printf("Failed to write end of HTTP request\n"); 226 goto end; 227 } 228 229 /* 230 * Get up to sizeof(buf) bytes of the response. We keep reading until the 231 * server closes the connection. 232 */ 233 while (SSL_read_ex(ssl, buf, sizeof(buf), &readbytes)) { 234 /* 235 * OpenSSL does not guarantee that the returned data is a string or 236 * that it is NUL terminated so we use fwrite() to write the exact 237 * number of bytes that we read. The data could be non-printable or 238 * have NUL characters in the middle of it. For this simple example 239 * we're going to print it to stdout anyway. 240 */ 241 fwrite(buf, 1, readbytes, stdout); 242 } 243 /* In case the response didn't finish with a newline we add one now */ 244 printf("\n"); 245 246 /* 247 * Check whether we finished the while loop above normally or as the 248 * result of an error. The 0 argument to SSL_get_error() is the return 249 * code we received from the SSL_read_ex() call. It must be 0 in order 250 * to get here. Normal completion is indicated by SSL_ERROR_ZERO_RETURN. 251 */ 252 if (SSL_get_error(ssl, 0) != SSL_ERROR_ZERO_RETURN) { 253 /* 254 * Some error occurred other than a graceful close down by the 255 * peer. 256 */ 257 printf ("Failed reading remaining data\n"); 258 goto end; 259 } 260 261 /* 262 * The peer already shutdown gracefully (we know this because of the 263 * SSL_ERROR_ZERO_RETURN above). We should do the same back. 264 */ 265 ret = SSL_shutdown(ssl); 266 if (ret < 1) { 267 /* 268 * ret < 0 indicates an error. ret == 0 would be unexpected here 269 * because that means "we've sent a close_notify and we're waiting 270 * for one back". But we already know we got one from the peer 271 * because of the SSL_ERROR_ZERO_RETURN above. 272 */ 273 printf("Error shutting down\n"); 274 goto end; 275 } 276 277 /* Success! */ 278 res = EXIT_SUCCESS; 279 end: 280 /* 281 * If something bad happened then we will dump the contents of the 282 * OpenSSL error stack to stderr. There might be some useful diagnostic 283 * information there. 284 */ 285 if (res == EXIT_FAILURE) 286 ERR_print_errors_fp(stderr); 287 288 /* 289 * Free the resources we allocated. We do not free the BIO object here 290 * because ownership of it was immediately transferred to the SSL object 291 * via SSL_set_bio(). The BIO will be freed when we free the SSL object. 292 */ 293 SSL_free(ssl); 294 SSL_CTX_free(ctx); 295 return res; 296 } 297