[text] client.c

Viewer

copydownloadembedprintName: client.c
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h> // Include functions related to POSIX operating system API
  5. #include <arpa/inet.h> // Include functions and structures for internet operations
  6. #include <openssl/ssl.h> // Include OpenSSL SSL/TLS library
  7. #include <openssl/err.h> // Include OpenSSL error handling functions
  8.  
  9. // Define the IP address of the server to connect to
  10. #define SERVER_ADDR "127.0.0.1"
  11. // Define the port number of the server to connect to
  12. #define SERVER_PORT 4433
  13. // Define the file path to the Certificate Authority (CA) certificate file 
  14. #define CA_CERT "./ca.crt"  
  15.  
  16. // Functions Prototypes
  17. void init_openssl(); // Initializes the OpenSSL library
  18. SSL_CTX* create_context(); // Configures an SSL context with specific verification options
  19. void configure_context(SSL_CTX *ctx); // Handles the response received from the server over the SSL connection.
  20. void handle_response(SSL *ssl); // Handles the response received from the server over the SSL connection
  21.  
  22. // Beginning of main()
  23. int main() {
  24.     // Declare SSL context pointer
  25.     SSL_CTX *ctx;
  26.     // Declare Socket file descriptor
  27.     int sockfd;
  28.     // Address structure for server
  29.     struct sockaddr_in addr;
  30.     // SSL connection pointer
  31.     SSL *ssl;
  32.  
  33.     // Initialize OpenSSL library
  34.     init_openssl();
  35.     // Create SSL context
  36.     ctx = create_context();
  37.     // Configure SSL context
  38.     configure_context(ctx);
  39.  
  40.     // Create socket
  41.     sockfd = socket(AF_INET, SOCK_STREAM, 0);
  42.     // Checks if the socket file descriptor sockfd < 0, which indicates that the socket creation failed.
  43.     if (sockfd < 0) {
  44.         // prints an error message to stderr
  45.         perror("Unable to create socket");
  46.         exit(EXIT_FAILURE); // exits the program with a failure status.
  47.     }
  48.  
  49.     // Configure server address
  50.     memset(&addr, 0, sizeof(addr)); // Initialize the memory block pointed to by 'addr' to zero
  51.     addr.sin_family = AF_INET; // Set the address family to AF_INET, indicating IPv4
  52.     addr.sin_addr.s_addr = inet_addr(SERVER_ADDR); // Set the IP address to the server's address specified by SERVER_ADDR
  53.     addr.sin_port = htons(SERVER_PORT); // Set the port number to the server's port specified by SERVER_PORT
  54.  
  55.     // Checks a connection to the server using the connect() system call
  56.     // the specified socket and server address. 
  57.     // If the connection attempt fails, it prints an error message and exits the program with a failure status.
  58.     if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  59.         perror("Unable to connect to server");
  60.         exit(EXIT_FAILURE);
  61.     }
  62.  
  63.     // Creates a new SSL/TLS connection instance (ssl) based on the provided SSL context (ctx)
  64.     ssl = SSL_new(ctx);
  65.     // Associates the SSL/TLS connection instance (ssl) with the existing socket file descriptor (sockfd)
  66.     SSL_set_fd(ssl, sockfd);
  67.     // Perform SSL handshake and verifying the success of the handshake process
  68.     if (SSL_connect(ssl) <= 0) {
  69.         // If the handshake process fails, this line prints error messages related to the SSL/TLS connection to the standard error stream
  70.         ERR_print_errors_fp(stderr);
  71.         exit(EXIT_FAILURE); // exits the program with a failure status
  72.     }
  73.     // Connection successful, print message
  74.     printf("Connected to server\n");
  75.     // Handle server response
  76.     handle_response(ssl);
  77.  
  78.     // Shutdown SSL connection
  79.     SSL_shutdown(ssl);
  80.     // Free SSL connection
  81.     SSL_free(ssl);
  82.     // Close socket
  83.     close(sockfd);
  84.     // Free SSL context
  85.     SSL_CTX_free(ctx);
  86.  
  87.     return 0; // Return success status
  88. } // end of main()
  89.  
  90.  
  91. // Functions Definitions
  92. /*
  93. Function initializes the OpenSSL library by loading error strings 
  94. and initializing the library itself. 
  95. Input: None
  96. Output: None
  97. */
  98. void init_openssl() {
  99.     // Load error strings for OpenSSL functions
  100.     SSL_load_error_strings(); 
  101.     // Initialize the OpenSSL library
  102.     SSL_library_init();
  103. } // end of func
  104.  
  105. /*
  106. Function creates an SSL context
  107. Input: None
  108. Output: SSL_CTX* - A pointer to the created SSL context
  109. */
  110. SSL_CTX* create_context() {
  111.     // SSL/TLS protocol method
  112.     const SSL_METHOD *method;
  113.     // SSL context pointer
  114.     SSL_CTX *ctx;
  115.  
  116.     // Select TLS client method
  117.     method = TLS_client_method();
  118.     // Create new SSL context
  119.     ctx = SSL_CTX_new(method);
  120.     // If ctx is NULL, it means that the creation of the SSL context failed.
  121.     if (!ctx) {
  122.         // Print error message
  123.         perror("Unable to create SSL context");
  124.         // Print OpenSSL errors
  125.         ERR_print_errors_fp(stderr);
  126.         exit(EXIT_FAILURE); // Exit the program
  127.     }
  128.  
  129.     // Load the CA certificate for verifying the server's certificate
  130.     // Checks the return value of the function SSL_CTX_load_verify_locations()
  131.     // to verify whether the loading of the CA certificate file was successful or not
  132.     if (SSL_CTX_load_verify_locations(ctx, CA_CERT, NULL) != 1) {
  133.         perror("Unable to load CA certificate"); // Print error message
  134.         ERR_print_errors_fp(stderr);
  135.         exit(EXIT_FAILURE);
  136.     }
  137.     // Return pointer to the created SSL context
  138.     return ctx;
  139. } // end of func
  140.  
  141. /*
  142. Function configures the SSL context to request and
  143. verify the server's certificate during SSL/TLS communication
  144. Input: SSL_CTX *ctx
  145. Output: None
  146. */
  147. void configure_context(SSL_CTX *ctx) {
  148.     // Set verification mode for SSL context to request and verify server's certificate,
  149.     // fail if server does not provide certificate, and verify client's certificate once
  150.     // during handshake. No custom verification callback is specified.
  151.     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, NULL);
  152.     // Override previous verification mode and set it to only verify the server's certificate.
  153.     // Disables client certificate verification and ensures that
  154.     // only the server's certificate is verified during SSL/TLS communication.
  155.     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
  156. } // end of func
  157.  
  158. /*
  159. Function reads data from the SSL connection and prints the received data to the standard output.
  160. Input: SSL *ssl - Pointer to the SSL structure representing the SSL connection.
  161. Output: None
  162. */
  163. void handle_response(SSL *ssl) {
  164.     // Initialize the buffer to store received data
  165.     char buffer[1024];
  166.     // Declare the number of bytes read
  167.     int bytes;
  168.     //// Read data from the SSL connection into the buffer
  169.     bytes = SSL_read(ssl, buffer, sizeof(buffer));
  170.     // If data is successfully read, print it to the standard output
  171.     if (bytes > 0) {
  172.         printf("Received: %.*s\n", bytes, buffer);
  173.     } else { // If an error occurs during reading, print OpenSSL error messages to stderr
  174.         ERR_print_errors_fp(stderr);
  175.     }
  176. } // end of func

Editor

You can edit this paste and save as new:


File Description
  • client.c
  • Paste Code
  • 02 May-2024
  • 6.79 Kb
You can Share it: