227 lines
6.0 KiB
C
227 lines
6.0 KiB
C
/* memory-bio-dtls.c
|
|
*
|
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
|
|
/* in memory TLS connection with I/O callbacks, no sockets
|
|
*
|
|
./configure --enable-opensslall --enable-dtls --enable-dtls13 --enable-debug
|
|
make
|
|
sudo make install
|
|
|
|
gcc -o memory-bio-dtls -Wall memory-bio-dtls.c -lwolfssl -lpthread
|
|
*/
|
|
|
|
|
|
#ifndef WOLFSSL_USER_SETTINGS
|
|
#include <wolfssl/options.h>
|
|
#endif
|
|
|
|
#include <wolfssl/ssl.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
#include <semaphore.h>
|
|
|
|
|
|
static void err_sys(const char* msg)
|
|
{
|
|
printf("wolfSSL error: %s\n", msg);
|
|
exit(1);
|
|
}
|
|
|
|
#ifndef NO_RSA
|
|
#define CERT_FILE "../certs/server-cert.pem"
|
|
#define KEY_FILE "../certs/server-key.pem"
|
|
#define CA_FILE "../certs/ca-cert.pem"
|
|
#else
|
|
#define CERT_FILE "../certs/server-ecc.pem"
|
|
#define KEY_FILE "../certs/ecc-key.pem"
|
|
#define CA_FILE "../certs/ca-ecc-cert.pem"
|
|
#endif
|
|
|
|
|
|
typedef struct IO_HANDLES {
|
|
WOLFSSL_BIO* rbio;
|
|
WOLFSSL_BIO* wbio;
|
|
sem_t bioSem;
|
|
} IO_HANDLES;
|
|
|
|
static void* client_thread(void* args)
|
|
{
|
|
IO_HANDLES* io = (IO_HANDLES*)args;
|
|
WOLFSSL_CTX* cli_ctx = NULL;
|
|
WOLFSSL* cli_ssl = NULL;
|
|
int err, ret;
|
|
|
|
/* set up client */
|
|
cli_ctx = wolfSSL_CTX_new(
|
|
#ifdef WOLFSSL_DTLS13
|
|
wolfDTLSv1_3_client_method()
|
|
#else
|
|
wolfDTLSv1_2_client_method()
|
|
#endif
|
|
);
|
|
if (cli_ctx == NULL) {
|
|
err_sys("bad client ctx new");
|
|
}
|
|
|
|
ret = wolfSSL_CTX_load_verify_locations(cli_ctx, CA_FILE, NULL);
|
|
if (ret != WOLFSSL_SUCCESS) {
|
|
err_sys("bad ca load");
|
|
}
|
|
|
|
cli_ssl = wolfSSL_new(cli_ctx);
|
|
if (cli_ctx == NULL) {
|
|
err_sys("bad client new");
|
|
}
|
|
|
|
wolfSSL_set_bio(cli_ssl, io->wbio, io->rbio);
|
|
|
|
#if 1
|
|
err = 0;
|
|
do {
|
|
sem_wait(&io->bioSem);
|
|
ret = wolfSSL_connect(cli_ssl);
|
|
sem_post(&io->bioSem);
|
|
err = wolfSSL_get_error(cli_ssl, ret);
|
|
} while (ret != WOLFSSL_SUCCESS &&
|
|
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
|
|
if (ret != WOLFSSL_SUCCESS) err_sys("bad client tls connect");
|
|
printf("wolfSSL client success!\n");
|
|
#endif
|
|
|
|
do {
|
|
sem_wait(&io->bioSem);
|
|
ret = wolfSSL_write(cli_ssl, "hello memory wolfSSL!", 21);
|
|
sem_post(&io->bioSem);
|
|
err = wolfSSL_get_error(cli_ssl, ret);
|
|
} while (ret <= 0 &&
|
|
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
|
|
|
|
/* clean up, wolfSSL_free would also free the WOLFSSL_BIO's so set as NULL
|
|
* since they are also being used with srv_ssl and will be free'd there. */
|
|
wolfSSL_set_bio(cli_ssl, NULL, NULL);
|
|
wolfSSL_free(cli_ssl);
|
|
wolfSSL_CTX_free(cli_ctx);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
IO_HANDLES io;
|
|
unsigned char buf[80];
|
|
int ret, err;
|
|
WOLFSSL_CTX* srv_ctx = NULL;
|
|
WOLFSSL* srv_ssl = NULL;
|
|
WOLFSSL_CIPHER* cipher;
|
|
const char *name;
|
|
pthread_t tid;
|
|
|
|
#if 0
|
|
wolfSSL_Debugging_ON();
|
|
#endif
|
|
wolfSSL_Init();
|
|
|
|
io.rbio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
|
|
io.wbio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
|
|
sem_init(&io.bioSem, 0, 1);
|
|
|
|
/* set up server */
|
|
srv_ctx = wolfSSL_CTX_new(
|
|
#ifdef WOLFSSL_DTLS13
|
|
wolfDTLSv1_3_server_method()
|
|
#else
|
|
wolfDTLSv1_2_server_method()
|
|
#endif
|
|
);
|
|
if (srv_ctx == NULL) err_sys("bad server ctx new");
|
|
|
|
ret = wolfSSL_CTX_use_PrivateKey_file(srv_ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM);
|
|
if (ret != WOLFSSL_SUCCESS) {
|
|
err_sys("bad server key file load");
|
|
}
|
|
|
|
ret = wolfSSL_CTX_use_certificate_file(srv_ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM);
|
|
if (ret != WOLFSSL_SUCCESS) {
|
|
err_sys("bad server cert file load");
|
|
}
|
|
|
|
srv_ssl = wolfSSL_new(srv_ctx);
|
|
if (srv_ctx == NULL) {
|
|
err_sys("bad server new");
|
|
}
|
|
|
|
/* set memory BIO's to use for IO */
|
|
wolfSSL_set_bio(srv_ssl, io.rbio, io.wbio);
|
|
|
|
/* start client thread */
|
|
pthread_create(&tid, 0, client_thread, (void*)&io);
|
|
|
|
#if 1
|
|
/* accept tls connection without tcp sockets */
|
|
err = 0;
|
|
do {
|
|
sem_wait(&io.bioSem);
|
|
ret = wolfSSL_accept(srv_ssl);
|
|
sem_post(&io.bioSem);
|
|
err = wolfSSL_get_error(srv_ssl, ret);
|
|
} while (ret != WOLFSSL_SUCCESS &&
|
|
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
|
|
if (ret != WOLFSSL_SUCCESS) err_sys("bad server tls accept");
|
|
printf("wolfSSL accept success!\n");
|
|
|
|
printf("Version: %s\n", wolfSSL_get_version(srv_ssl));
|
|
cipher = wolfSSL_get_current_cipher(srv_ssl);
|
|
printf("Cipher Suite: %s\n", wolfSSL_CIPHER_get_name(cipher));
|
|
if ((name = wolfSSL_get_curve_name(srv_ssl)) != NULL)
|
|
printf("Curve: %s\n", name);
|
|
#endif
|
|
|
|
/* read msg post handshake from client */
|
|
memset(buf, 0, sizeof(buf));
|
|
do {
|
|
sem_wait(&io.bioSem);
|
|
ret = wolfSSL_read(srv_ssl, buf, sizeof(buf)-1);
|
|
sem_post(&io.bioSem);
|
|
err = wolfSSL_get_error(srv_ssl, ret);
|
|
} while (ret != 0 &&
|
|
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
|
|
if (ret >= 0) {
|
|
printf("client msg = %s\n", buf);
|
|
}
|
|
|
|
pthread_join(tid, NULL);
|
|
|
|
/* clean up */
|
|
sem_destroy(&io.bioSem);
|
|
wolfSSL_free(srv_ssl); /* This also does free on rbio and wbio */
|
|
wolfSSL_CTX_free(srv_ctx);
|
|
|
|
wolfSSL_Cleanup();
|
|
|
|
return 0;
|
|
}
|