Compile with gcc -o request request.c -lssl -lcrypto
#include <stdio.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#define HOST "www.python.org"
#define PORT "443"
#define REQUEST "GET / HTTP/1.1\\r\\nHost: www.python.org\\r\\nConnection: close\\r\\n\\r\\n"
void handle_openssl_error() {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
int main() {
SSL_CTX *ctx;
SSL *ssl;
int sock;
struct addrinfo hints, *res;
char buffer[4096];
ssize_t bytes;
// Initialize OpenSSL
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
// Create SSL context
ctx = SSL_CTX_new(TLS_client_method());
if (!ctx) {
handle_openssl_error();
}
// Set up kTLS
if (!SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS)) {
fprintf(stderr, "Failed to enable kTLS.\\n");
handle_openssl_error();
}
// Resolve the host
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(HOST, PORT, &hints, &res) != 0) {
perror("getaddrinfo");
exit(EXIT_FAILURE);
}
// Create a socket
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// Create an SSL object
ssl = SSL_new(ctx);
if (!ssl) {
handle_openssl_error();
}
// Bind the socket to SSL
SSL_set_fd(ssl, sock);
// Connect to the server
if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
perror("connect");
exit(EXIT_FAILURE);
}
freeaddrinfo(res);
// Establish TLS connection
if (SSL_connect(ssl) <= 0) {
handle_openssl_error();
}
printf("kTLS used: %d\\n", BIO_get_ktls_send(SSL_get_wbio(ssl)));
printf("Connected with %s encryption\\n\\n\\n", SSL_get_cipher(ssl));
// Send HTTP request
if (SSL_write(ssl, REQUEST, strlen(REQUEST)) <= 0) {
handle_openssl_error();
}
// Read the response
while ((bytes = SSL_read(ssl, buffer, sizeof(buffer) - 1)) > 0) {
buffer[bytes] = '\\0';
printf("%s", buffer);
break;
}
// Clean up
SSL_shutdown(ssl);
SSL_free(ssl);
close(sock);
SSL_CTX_free(ctx);
EVP_cleanup();
return 0;
}