#include #include #include #include #include #include #include #include "socketHelp.h" /* * This function turns a IPv4 four byte octet into * an unsigned 32 bit integer which can be used when * opening new socket connections */ uint32_t addr2sin_addr(char *addr) { char *token; int i = 0; uint32_t addrNum = 0; unsigned long addrTempNum = 0; token = strtok(addr, "."); while(token != NULL) { addrTempNum = strtoul(token, NULL,10); if ( addrTempNum > 255 ) { // Check if octet is valid printf("Invalid IP octet: %ld\n", addrTempNum); free(token); return -1; } // Adding value to addr number addrNum = addrNum + ( addrTempNum << (8*(3-i)) ); token = strtok(NULL, "."); i++; } free(token); return addrNum; } SSL_CTX* InitServerCTX() { const SSL_METHOD *method; SSL_CTX *ctx; OpenSSL_add_all_algorithms(); SSL_load_error_strings(); method = TLS_server_method(); ctx = SSL_CTX_new(method); if ( ctx == NULL ) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } return ctx; } void LoadCertificates(SSL_CTX* ctx, char* certFile, char* keyFile) { // Set local certificate from certFile if ( SSL_CTX_use_certificate_file(ctx, certFile, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } // Set local priv key from keyFile if ( SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) <=0 ) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } // Verify priv key if ( !SSL_CTX_check_private_key(ctx) ) { fprintf(stderr, "Private key does not match passed certificate file\n"); exit(EXIT_FAILURE); } return; } int createSecureSocket(int port, int *server_fd, struct sockaddr_in *address, int *addrlen, uint32_t listenAddr, SSL_CTX **ctx, char certFile[], char keyFile[]) { SSL_library_init(); *ctx = InitServerCTX(); LoadCertificates(*ctx, certFile, keyFile); if ( createSocket(port, server_fd, address, addrlen, listenAddr) ) { fprintf(stderr, "Error create socket\n"); exit(EXIT_FAILURE); } return 0; } int createSocket(int port, int *server_fd, struct sockaddr_in *address, int *addrlen, uint32_t listenAddr) { int opt = 1; // Create socket fd if ((*server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Attach socket to PORT if (setsockopt(*server_fd, SOL_SOCKET, SO_REUSEADDR |SO_REUSEPORT, &opt, sizeof(opt))) { perror("Set socket opt failure"); exit(EXIT_FAILURE); } address->sin_family = AF_INET; if (listenAddr != -1) { // Checking to see if listenAddr is passed address->sin_addr.s_addr = htonl(listenAddr); } else { // Default to any addr address->sin_addr.s_addr = INADDR_ANY; } address->sin_port = htons (port); // Attach to PORT if (bind(*server_fd, (struct sockaddr *)address, sizeof(*address))<0) { perror("Failed to bind"); exit(EXIT_FAILURE); } if (listen(*server_fd, 3) < 0) { perror("Failed to listen"); exit(EXIT_FAILURE); } return 0; }