- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h> // Include functions related to POSIX operating system API
- #include <arpa/inet.h> // Include functions and structures for internet operations
- #include <openssl/ssl.h> // Include OpenSSL SSL/TLS library
- #include <openssl/err.h> // Include OpenSSL error handling functions
- // Define the IP address of the server to connect to
- #define SERVER_ADDR "127.0.0.1"
- // Define the port number of the server to connect to
- #define SERVER_PORT 4433
- // Define the file path to the Certificate Authority (CA) certificate file
- #define CA_CERT "./ca.crt"
- // Functions Prototypes
- void init_openssl(); // Initializes the OpenSSL library
- SSL_CTX* create_context(); // Configures an SSL context with specific verification options
- void configure_context(SSL_CTX *ctx); // Handles the response received from the server over the SSL connection.
- void handle_response(SSL *ssl); // Handles the response received from the server over the SSL connection
- // Beginning of main()
- int main() {
- // Declare SSL context pointer
- SSL_CTX *ctx;
- // Declare Socket file descriptor
- int sockfd;
- // Address structure for server
- struct sockaddr_in addr;
- // SSL connection pointer
- SSL *ssl;
- // Initialize OpenSSL library
- init_openssl();
- // Create SSL context
- ctx = create_context();
- // Configure SSL context
- configure_context(ctx);
- // Create socket
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- // Checks if the socket file descriptor sockfd < 0, which indicates that the socket creation failed.
- if (sockfd < 0) {
- // prints an error message to stderr
- perror("Unable to create socket");
- exit(EXIT_FAILURE); // exits the program with a failure status.
- }
- // Configure server address
- memset(&addr, 0, sizeof(addr)); // Initialize the memory block pointed to by 'addr' to zero
- addr.sin_family = AF_INET; // Set the address family to AF_INET, indicating IPv4
- addr.sin_addr.s_addr = inet_addr(SERVER_ADDR); // Set the IP address to the server's address specified by SERVER_ADDR
- addr.sin_port = htons(SERVER_PORT); // Set the port number to the server's port specified by SERVER_PORT
- // Checks a connection to the server using the connect() system call
- // the specified socket and server address.
- // If the connection attempt fails, it prints an error message and exits the program with a failure status.
- if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- perror("Unable to connect to server");
- exit(EXIT_FAILURE);
- }
- // Creates a new SSL/TLS connection instance (ssl) based on the provided SSL context (ctx)
- ssl = SSL_new(ctx);
- // Associates the SSL/TLS connection instance (ssl) with the existing socket file descriptor (sockfd)
- SSL_set_fd(ssl, sockfd);
- // Perform SSL handshake and verifying the success of the handshake process
- if (SSL_connect(ssl) <= 0) {
- // If the handshake process fails, this line prints error messages related to the SSL/TLS connection to the standard error stream
- ERR_print_errors_fp(stderr);
- exit(EXIT_FAILURE); // exits the program with a failure status
- }
- // Connection successful, print message
- printf("Connected to server\n");
- // Handle server response
- handle_response(ssl);
- // Shutdown SSL connection
- SSL_shutdown(ssl);
- // Free SSL connection
- SSL_free(ssl);
- // Close socket
- close(sockfd);
- // Free SSL context
- SSL_CTX_free(ctx);
- return 0; // Return success status
- } // end of main()
- // Functions Definitions
- /*
- Function initializes the OpenSSL library by loading error strings
- and initializing the library itself.
- Input: None
- Output: None
- */
- void init_openssl() {
- // Load error strings for OpenSSL functions
- SSL_load_error_strings();
- // Initialize the OpenSSL library
- SSL_library_init();
- } // end of func
- /*
- Function creates an SSL context
- Input: None
- Output: SSL_CTX* - A pointer to the created SSL context
- */
- SSL_CTX* create_context() {
- // SSL/TLS protocol method
- const SSL_METHOD *method;
- // SSL context pointer
- SSL_CTX *ctx;
- // Select TLS client method
- method = TLS_client_method();
- // Create new SSL context
- ctx = SSL_CTX_new(method);
- // If ctx is NULL, it means that the creation of the SSL context failed.
- if (!ctx) {
- // Print error message
- perror("Unable to create SSL context");
- // Print OpenSSL errors
- ERR_print_errors_fp(stderr);
- exit(EXIT_FAILURE); // Exit the program
- }
- // Load the CA certificate for verifying the server's certificate
- // Checks the return value of the function SSL_CTX_load_verify_locations()
- // to verify whether the loading of the CA certificate file was successful or not
- if (SSL_CTX_load_verify_locations(ctx, CA_CERT, NULL) != 1) {
- perror("Unable to load CA certificate"); // Print error message
- ERR_print_errors_fp(stderr);
- exit(EXIT_FAILURE);
- }
- // Return pointer to the created SSL context
- return ctx;
- } // end of func
- /*
- Function configures the SSL context to request and
- verify the server's certificate during SSL/TLS communication
- Input: SSL_CTX *ctx
- Output: None
- */
- void configure_context(SSL_CTX *ctx) {
- // Set verification mode for SSL context to request and verify server's certificate,
- // fail if server does not provide certificate, and verify client's certificate once
- // during handshake. No custom verification callback is specified.
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, NULL);
- // Override previous verification mode and set it to only verify the server's certificate.
- // Disables client certificate verification and ensures that
- // only the server's certificate is verified during SSL/TLS communication.
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
- } // end of func
- /*
- Function reads data from the SSL connection and prints the received data to the standard output.
- Input: SSL *ssl - Pointer to the SSL structure representing the SSL connection.
- Output: None
- */
- void handle_response(SSL *ssl) {
- // Initialize the buffer to store received data
- char buffer[1024];
- // Declare the number of bytes read
- int bytes;
- //// Read data from the SSL connection into the buffer
- bytes = SSL_read(ssl, buffer, sizeof(buffer));
- // If data is successfully read, print it to the standard output
- if (bytes > 0) {
- printf("Received: %.*s\n", bytes, buffer);
- } else { // If an error occurs during reading, print OpenSSL error messages to stderr
- ERR_print_errors_fp(stderr);
- }
- } // end of func
[text] client.c
Viewer
*** This page was generated with the meta tag "noindex, nofollow". This happened because you selected this option before saving or the system detected it as spam. This means that this page will never get into the search engines and the search bot will not crawl it. There is nothing to worry about, you can still share it with anyone.
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:
Latest Code Pastes