[text] server.c

Viewer

copydownloadembedprintName: server.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 <netinet/in.h> // Include internet address family structures
  7. #include <openssl/ssl.h> // Include OpenSSL SSL/TLS library
  8. #include <openssl/err.h> // Include OpenSSL error handling functions
  9.  
  10. // Define the file path for the server certificate
  11. #define SERVER_CERT "./server.crt"
  12. // Define the file path for the server's private key
  13. #define SERVER_KEY "./server.key"
  14. // Define the file path for the Certificate Authority (CA) certificate
  15. #define CA_CERT "./ca.crt"  
  16.  
  17. // Functions Prototypes
  18. void init_openssl(); // Initializes the OpenSSL library
  19. SSL_CTX* create_context(); // Creates an SSL context for the server
  20. void configure_context(SSL_CTX *ctx); // Configures SSL context for the server
  21. void handle_client(SSL *ssl); // Handle SSL connection with a client
  22.  
  23. int main() {
  24.     // Declares SSL context
  25.     SSL_CTX *ctx;
  26.     // Declares server socket file descriptor
  27.     int server_fd;
  28.     // Declares server address structure
  29.     struct sockaddr_in addr;
  30.     // Declares client socket file descriptor
  31.     int client_fd;
  32.     // Declares length of client address structure
  33.     socklen_t len;
  34.     // Declares SSL structure representing SSL connection
  35.     SSL *ssl;
  36.  
  37.      // Initialize OpenSSL library
  38.     init_openssl();
  39.     // Create SSL context
  40.     ctx = create_context();
  41.     // Configure SSL context
  42.     configure_context(ctx);
  43.  
  44.     // Create a TCP socket for the server
  45.     server_fd = socket(AF_INET, SOCK_STREAM, 0);
  46.     // Check if server socket creation was successful
  47.     if (server_fd < 0) {
  48.         // Print error message to stderr if socket creation fails
  49.         perror("Unable to create socket");
  50.         // Exit the program with failure status
  51.         exit(EXIT_FAILURE);
  52.     }
  53.     // Initialize the server address structure with zeros
  54.     memset(&addr, 0, sizeof(addr));
  55.     // Set the address family to AF_INET (IPv4)
  56.     addr.sin_family = AF_INET;
  57.     // Set the IP address to INADDR_ANY, allowing connections from any interface
  58.     addr.sin_addr.s_addr = htonl(INADDR_ANY);
  59.     // Set the port number to 4433, converted to network byte order
  60.     addr.sin_port = htons(4433);
  61.  
  62.     // Bind the server socket to the specified address
  63.     if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  64.         // Print error message to stderr if binding fails
  65.         perror("Unable to bind");
  66.         exit(EXIT_FAILURE);
  67.     }
  68.  
  69.     // Starts listening for incoming connections on the server socket
  70.     if (listen(server_fd, 1) < 0) {
  71.         // Prints error message to stderr if listening fails
  72.         perror("Unable to listen");
  73.         exit(EXIT_FAILURE);
  74.     }
  75.  
  76.     // Print a message indicating that the server is listening on port 4433
  77.     printf("Server listening on port 4433\n");
  78.  
  79.     // Infinite loop to continuously accept and handle client connections
  80.     while (1) {
  81.         // Accepts incoming connection and obtain client socket file descriptor
  82.         client_fd = accept(server_fd, NULL, NULL);
  83.         // Checks if accepting connection was successful
  84.         if (client_fd < 0) {
  85.             // Print error message to stderr if accepting connection fails
  86.             perror("Unable to accept");
  87.             exit(EXIT_FAILURE);
  88.         }
  89.  
  90.         // Creates new SSL structure for the connection
  91.         ssl = SSL_new(ctx);
  92.         // Associates SSL structure with client socket file descriptor
  93.         SSL_set_fd(ssl, client_fd);
  94.  
  95.         // Perform SSL handshake
  96.         if (SSL_accept(ssl) <= 0) {
  97.             // Print SSL handshake errors to stderr
  98.             ERR_print_errors_fp(stderr);
  99.         } else {
  100.             handle_client(ssl);  // Handle SSL connection with client
  101.         }
  102.  
  103.         // Shutdown SSL connection
  104.         SSL_shutdown(ssl);
  105.         // Free SSL structure
  106.         SSL_free(ssl);
  107.         // Close client socket
  108.         close(client_fd);
  109.     }
  110.     // Close the server socket
  111.     close(server_fd);
  112.     // Free the SSL context
  113.     SSL_CTX_free(ctx);
  114.  
  115.     return 0;
  116. } // end of main()
  117.  
  118. // Functions Definitions.
  119.  
  120. // Func initializes the OpenSSL library
  121. // Input: None
  122. // Output: None
  123. void init_openssl() {
  124.     // Load error strings for SSL functions
  125.     SSL_load_error_strings();
  126.     // Initialize the SSL library
  127.     SSL_library_init();
  128. } // end of func
  129.  
  130. /*
  131. Func creates an SSL context for the server
  132. Input: None
  133. Output: SSL_CTX* - Pointer to the created SSL context
  134. */
  135. SSL_CTX* create_context() {
  136.     // declares a pointer method of type const SSL_METHOD
  137.     const SSL_METHOD *method;
  138.     // declares a pointer ctx of type SSL_CTX
  139.     SSL_CTX *ctx;
  140.  
  141.     // Use TLS server method
  142.     method = TLS_server_method();
  143.     // Create new SSL context
  144.     ctx = SSL_CTX_new(method);
  145.     // Check if the SSL context creation was successful
  146.     if (!ctx) {
  147.         // Print error message to stderr if context creation fails
  148.         perror("Unable to create SSL context");
  149.         // Print OpenSSL error messages to stderr
  150.         ERR_print_errors_fp(stderr);
  151.         // Exit the program with failure status
  152.         exit(EXIT_FAILURE);
  153.     }
  154.  
  155.     // Load CA certificate file into the SSL context
  156.     if (SSL_CTX_load_verify_locations(ctx, CA_CERT, NULL) != 1) {
  157.         // Print error message to stderr if loading CA certificate fails
  158.         perror("Unable to load CA certificate");
  159.         // Print OpenSSL error messages to stderr
  160.         ERR_print_errors_fp(stderr);
  161.         exit(EXIT_FAILURE);
  162.     }
  163.     // returns the SSL context (ctx) from the function
  164.     return ctx;
  165. } // end of func
  166.  
  167. /*
  168. Func configures SSL context for the server
  169. Input: ctx: SSL_CTX* - Pointer to the SSL context to be configured
  170. Output: None
  171. */
  172. void configure_context(SSL_CTX *ctx) {
  173.     // Enable automatic selection of elliptic curves
  174.     SSL_CTX_set_ecdh_auto(ctx, 1);
  175.     // Use server certificate file
  176.     if (SSL_CTX_use_certificate_file(ctx, SERVER_CERT, SSL_FILETYPE_PEM) <= 0) {
  177.         ERR_print_errors_fp(stderr); // Print error message if loading server certificate fails
  178.         exit(EXIT_FAILURE); // Exit the program with failure status
  179.     }
  180.     // Use server private key file
  181.     if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY, SSL_FILETYPE_PEM) <= 0) {
  182.         ERR_print_errors_fp(stderr); // Print error message if loading server private key fails
  183.         exit(EXIT_FAILURE);
  184.     }
  185.  
  186.     // Require client certificate verification (optional)
  187.     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
  188. } // end of func
  189.  
  190. /*
  191. Func handles SSL connection with a client
  192. Input: SSL *ssl - Pointer to the SSL structure representing the SSL connection
  193. Output: None
  194. */
  195. void handle_client(SSL *ssl) {
  196.     // Prepare response message
  197.     const char *response = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nHello, World!";
  198.     // Send response to client
  199.     SSL_write(ssl, response, strlen(response));
  200. } // end of func
  201.  

Editor

You can edit this paste and save as new:


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