Certainly! Here are the C language programs for a simple OpenSSL client and server that can establish a secure communication channel between them:
l
inux环境下
OpenSSL Server Program (server.c):
#include
#include
#include
#include
#include
#include
#include
#include
#define CERT_FILE "server.pem"
#define KEY_FILE "server.key"
void init_openssl() {
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
}
SSL_CTX* create_context() {
const SSL_METHOD *method;
SSL_CTX *ctx;
method = SSLv23_server_method();
ctx = SSL_CTX_new(method);
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
return ctx;
}
void configure_context(SSL_CTX *ctx) {
SSL_CTX_set_ecdh_auto(ctx, 1);
if (SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
if (SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
}
int main() {
int sockfd, clientfd;
struct sockaddr_in serv_addr, client_addr;
socklen_t client_len;
SSL_CTX *ctx;
SSL *ssl;
init_openssl();
ctx = create_context();
configure_context(ctx);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("Unable to create socket");
exit(EXIT_FAILURE);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(8888);
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Unable to bind socket");
exit(EXIT_FAILURE);
}
if (listen(sockfd, 5) < 0) {
perror("Unable to listen");
exit(EXIT_FAILURE);
}
printf("Server listening on port 8888...\n");
while (1) {
client_len = sizeof(client_addr);
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
if (clientfd < 0) {
perror("Unable to accept connection");
exit(EXIT_FAILURE);
}
ssl = SSL_new(ctx);
SSL_set_fd(ssl, clientfd);
if (SSL_accept(ssl) <= 0) {
ERR_print_errors_fp(stderr);
} else {
printf("SSL connection established\n");
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
SSL_read(ssl, buffer, sizeof(buffer));
printf("Received: %s\n", buffer);
char *response = "Hello from server";
SSL_write(ssl, response, strlen(response));
printf("Response sent\n");
SSL_shutdown(ssl);
SSL_free(ssl);
}
close(clientfd);
}
close(sockfd);
SSL_CTX_free(ctx);
cleanup_openssl();
return 0;
}
OpenSSL Client Program (client.c):
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8888
void init_openssl() {
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
}
SSL_CTX* create_context() {
const SSL_METHOD *method;
SSL_CTX *ctx;
method = SSLv23_client_method();
ctx = SSL_CTX_new(method);
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
return ctx;
}
void configure_context(SSL_CTX *ctx) {
SSL_CTX_set_default_verify_paths(ctx);
}
int main() {
int sockfd;
struct sockaddr_in serv_addr;
SSL_CTX *ctx;
SSL *ssl;
init_openssl();
ctx = create_context();
configure_context(ctx);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("Unable to create socket");
exit(EXIT_FAILURE);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERVER_PORTApologies for the abrupt cutoff in the code. Here's the continuation of the OpenSSL client program (client.c):
```c
if (inet_pton(AF_INET, SERVER_IP, &(serv_addr.sin_addr)) <= 0) {
perror("Unable to convert server IP address");
exit(EXIT_FAILURE);
}
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Unable to connect to server");
exit(EXIT_FAILURE);
}
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
if (SSL_connect(ssl) <= 0) {
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
printf("SSL connection established\n");
char *message = "Hello from client";
SSL_write(ssl, message, strlen(message));
printf("Message sent\n");
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
SSL_read(ssl, buffer, sizeof(buffer));
printf("Received: %s\n", buffer);
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
SSL_CTX_free(ctx);
cleanup_openssl();
return 0;
}
To compile and run the programs, you’ll need to make sure you have the OpenSSL library installed on your system. Use the following command to compile the server and client programs:
gcc -o server server.c -lssl -lcrypto
gcc -o client client.c -lssl -lcrypto
Once compiled, you can run the server and client programs separately in different terminal windows. First, start the server:
./server
Then, in another terminal window, run the client:
./client
You should see the client and server establish an SSL connection and exchange messages securely.
Please let me know if you need any further explanation or examples. If you’re ready, we can proceed to the next section: “SSL Certificates and Keys.”