tls-client-block.c 9.2 KB

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