also see
$ gcc server.c -lcrypto -lssl -o server
k$ ./server
OpenSSL 3.3.2 3 Sep 2024 (Library: OpenSSL 3.3.0 9 Apr 2024)
built on: Tue Jan 14 12:15:04 2025 UTC
platform: linux-x86_64
options: bn(64,64)
client random:
95 63 CE 74 D2 56 D3 B4 E0 F4 4B 16 C9 05 6F FE
CB 88 A0 CF 7A 9E D1 47 E5 43 69 F0 36 4A 05 EA
server random:
89 FB DE 08 F2 0E 09 C8 EC 32 AD AA 6B 58 16 F9
BF 08 6C 15 2C 6C 6E 87 A7 C7 8D 3C 89 F1 D5 00
$ gcc client.c -lcrypto -lssl -o client
$ ./client
OpenSSL 3.3.2 3 Sep 2024 (Library: OpenSSL 3.3.0 9 Apr 2024)
built on: Tue Jan 14 12:15:04 2025 UTC
platform: linux-x86_64
options: bn(64,64)
client random:
95 63 CE 74 D2 56 D3 B4 E0 F4 4B 16 C9 05 6F FE
CB 88 A0 CF 7A 9E D1 47 E5 43 69 F0 36 4A 05 EA
server random:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
test
server.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <stdlib.h>
void handleErrors(void)
{
unsigned long errCode;
printf("An error occurred\n");
while(errCode = ERR_get_error())
{
char *err = ERR_error_string(errCode, NULL);
printf("%s\n", err);
}
abort();
}
#define PSK_ID "Client1"
#define PSK_KEY "6d1bbd1e6235c9d9ec8cdbdf9b32d4d08304a7f305f7c6c67775130d914f4dc4"
unsigned int tls_psk_serv_cb(SSL *ssl, const char *id,
unsigned char *psk,
unsigned int max_psk_len)
{
if (strcmp(PSK_ID, id) != 0) {
printf("Unknown Client's PSK ID\n");
goto err;
}
if (strlen(PSK_KEY) > max_psk_len) {
printf("Insufficient buffer size to copy PSK_KEY\n");
goto err;
}
unsigned char outc[SSL3_RANDOM_SIZE];
SSL_get_client_random(ssl, outc, SSL3_RANDOM_SIZE);
printf("client random:\n");
for (int z = 0; z < SSL3_RANDOM_SIZE; z++) {
printf("%02X%c", outc[z], ((z + 1) % 16) ? ' ' : '\n');
}
unsigned char outs[SSL3_RANDOM_SIZE];
SSL_get_server_random(ssl, outs, SSL3_RANDOM_SIZE);
printf("server random:\n");
for (int z = 0; z < SSL3_RANDOM_SIZE; z++) {
printf("%02X%c", outs[z], ((z + 1) % 16) ? ' ' : '\n');
}
memcpy(psk, PSK_KEY, strlen(PSK_KEY));
return strlen(PSK_KEY);
err:
return 0;
}
int main(int argc, char **argv)
{
int sock;
SSL_CTX *ctx;
printf("%s (Library: %s)\n",
OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
printf("%s\n", OpenSSL_version(OPENSSL_PLATFORM));
printf("options: ");
printf(" %s", BN_options());
printf("\n");
ctx = SSL_CTX_new(TLS_server_method());
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
//SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
//SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8081);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Unable to create socket");
exit(EXIT_FAILURE);
}
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("Unable to bind");
exit(EXIT_FAILURE);
}
if (listen(sock, 1) < 0) {
perror("Unable to listen");
exit(EXIT_FAILURE);
}
while(1) {
struct sockaddr_in addr;
unsigned int len = sizeof(addr);
SSL *ssl;
const char reply[] = "test\n";
int client = accept(sock, (struct sockaddr*)&addr, &len);
if (client < 0) {
perror("Unable to accept");
exit(EXIT_FAILURE);
}
ssl = SSL_new(ctx);
SSL_set_fd(ssl, client);
SSL_set_psk_server_callback(ssl, tls_psk_serv_cb);
if (SSL_accept(ssl) <= 0) {
ERR_print_errors_fp(stderr);
} else {
SSL_write(ssl, reply, strlen(reply));
}
SSL_shutdown(ssl);
SSL_free(ssl);
close(client);
}
close(sock);
SSL_CTX_free(ctx);
}
client.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <stdlib.h>
void handleErrors(void)
{
unsigned long errCode;
printf("An error occurred\n");
while(errCode = ERR_get_error())
{
char *err = ERR_error_string(errCode, NULL);
printf("%s\n", err);
}
abort();
}
#define PSK_ID "Client1"
#define PSK_KEY "6d1bbd1e6235c9d9ec8cdbdf9b32d4d08304a7f305f7c6c67775130d914f4dc4"
unsigned int tls_psk_client_cb(SSL *ssl,
const char *hint,
char *id,
unsigned int max_identity_len,
unsigned char *psk,
unsigned int max_psk_len)
{
memcpy(id, PSK_ID, strlen(PSK_ID));
unsigned char outc[SSL3_RANDOM_SIZE];
SSL_get_client_random(ssl, outc, SSL3_RANDOM_SIZE);
printf("client random:\n");
for (int z = 0; z < SSL3_RANDOM_SIZE; z++) {
printf("%02X%c", outc[z], ((z + 1) % 16) ? ' ' : '\n');
}
unsigned char outs[SSL3_RANDOM_SIZE];
SSL_get_server_random(ssl, outs, SSL3_RANDOM_SIZE);
printf("server random:\n");
for (int z = 0; z < SSL3_RANDOM_SIZE; z++) {
printf("%02X%c", outs[z], ((z + 1) % 16) ? ' ' : '\n');
}
memcpy(psk, PSK_KEY, strlen(PSK_KEY));
return strlen(PSK_KEY);
err:
return 0;
}
int main(int argc, char **argv)
{
SSL_CTX *ctx;
BIO *web = NULL, *out = NULL;
SSL *ssl = NULL;
long res = 1;
printf("%s (Library: %s)\n",
OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
printf("%s\n", OpenSSL_version(OPENSSL_PLATFORM));
printf("options: ");
printf(" %s", BN_options());
printf("\n");
ctx = SSL_CTX_new(TLS_client_method());
if (!ctx) {
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
// SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
// SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
web = BIO_new_ssl_connect(ctx);
if(!(web != NULL)) handleErrors();
res = BIO_set_conn_hostname(web, "127.0.0.1:8081");
if(!(1 == res)) handleErrors();
BIO_get_ssl(web, &ssl);
if(!(ssl != NULL)) handleErrors();
SSL_set_psk_client_callback(ssl, tls_psk_client_cb);
// const char PREFERRED_CIPHERS[] = "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
// res = SSL_set_cipher_list(ssl, PREFERRED_CIPHERS);
// if(!(1 == res)) handleErrors();
out = BIO_new_fp(stdout, BIO_NOCLOSE);
if(!(NULL != out)) handleErrors();
res = BIO_do_connect(web);
if(!(1 == res)) handleErrors();
res = BIO_do_handshake(web);
if(!(1 == res)) handleErrors();
int len = 0;
do
{
char buff[1536] = {};
len = BIO_read(web, buff, sizeof(buff));
if(len > 0)
BIO_write(out, buff, len);
} while (len > 0 || BIO_should_retry(web));
if(out)
BIO_free(out);
if(web != NULL)
BIO_free_all(web);
SSL_CTX_free(ctx);
}