Skip to content

Commit 38c5e5d

Browse files
authored
Merge pull request wolfSSL#477 from JacobBarthelmeh/bio_dtls
add DTLS bio example
2 parents ae1097d + 8775b5c commit 38c5e5d

File tree

2 files changed

+227
-0
lines changed

2 files changed

+227
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ android/wolfssljni-ndk-sample/proguard-project.txt
5656
/dtls/client-dtls
5757
/dtls/client-dtls13
5858
/dtls/client-udp
59+
/dtls/memory-bio-dtls
5960
/dtls/server-dtls-callback
6061
/dtls/server-dtls-ipv6
6162
/dtls/server-dtls-nonblocking

dtls/memory-bio-dtls.c

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/* memory-bio-dtls.c
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL. (formerly known as CyaSSL)
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
23+
/* in memory TLS connection with I/O callbacks, no sockets
24+
*
25+
./configure --enable-opensslall --enable-dtls --enable-dtls13 --enable-debug
26+
make
27+
sudo make install
28+
29+
gcc -o memory-bio-dtls -Wall memory-bio-dtls.c -lwolfssl -lpthread
30+
*/
31+
32+
33+
#ifndef WOLFSSL_USER_SETTINGS
34+
#include <wolfssl/options.h>
35+
#endif
36+
37+
#include <wolfssl/ssl.h>
38+
39+
#include <stdio.h>
40+
#include <stdlib.h>
41+
#include <string.h>
42+
#include <pthread.h>
43+
#include <unistd.h>
44+
#include <semaphore.h>
45+
46+
47+
static void err_sys(const char* msg)
48+
{
49+
printf("wolfSSL error: %s\n", msg);
50+
exit(1);
51+
}
52+
53+
#ifndef NO_RSA
54+
#define CERT_FILE "../certs/server-cert.pem"
55+
#define KEY_FILE "../certs/server-key.pem"
56+
#define CA_FILE "../certs/ca-cert.pem"
57+
#else
58+
#define CERT_FILE "../certs/server-ecc.pem"
59+
#define KEY_FILE "../certs/ecc-key.pem"
60+
#define CA_FILE "../certs/ca-ecc-cert.pem"
61+
#endif
62+
63+
64+
typedef struct IO_HANDLES {
65+
WOLFSSL_BIO* rbio;
66+
WOLFSSL_BIO* wbio;
67+
sem_t bioSem;
68+
} IO_HANDLES;
69+
70+
static void* client_thread(void* args)
71+
{
72+
IO_HANDLES* io = (IO_HANDLES*)args;
73+
WOLFSSL_CTX* cli_ctx = NULL;
74+
WOLFSSL* cli_ssl = NULL;
75+
int err, ret;
76+
77+
/* set up client */
78+
cli_ctx = wolfSSL_CTX_new(
79+
#ifdef WOLFSSL_DTLS13
80+
wolfDTLSv1_3_client_method()
81+
#else
82+
wolfDTLSv1_2_client_method()
83+
#endif
84+
);
85+
if (cli_ctx == NULL) {
86+
err_sys("bad client ctx new");
87+
}
88+
89+
ret = wolfSSL_CTX_load_verify_locations(cli_ctx, CA_FILE, NULL);
90+
if (ret != WOLFSSL_SUCCESS) {
91+
err_sys("bad ca load");
92+
}
93+
94+
cli_ssl = wolfSSL_new(cli_ctx);
95+
if (cli_ctx == NULL) {
96+
err_sys("bad client new");
97+
}
98+
99+
wolfSSL_set_bio(cli_ssl, io->wbio, io->rbio);
100+
101+
#if 1
102+
err = 0;
103+
do {
104+
sem_wait(&io->bioSem);
105+
ret = wolfSSL_connect(cli_ssl);
106+
sem_post(&io->bioSem);
107+
err = wolfSSL_get_error(cli_ssl, ret);
108+
} while (ret != WOLFSSL_SUCCESS &&
109+
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
110+
if (ret != WOLFSSL_SUCCESS) err_sys("bad client tls connect");
111+
printf("wolfSSL client success!\n");
112+
#endif
113+
114+
do {
115+
sem_wait(&io->bioSem);
116+
ret = wolfSSL_write(cli_ssl, "hello memory wolfSSL!", 21);
117+
sem_post(&io->bioSem);
118+
err = wolfSSL_get_error(cli_ssl, ret);
119+
} while (ret <= 0 &&
120+
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
121+
122+
/* clean up, wolfSSL_free would also free the WOLFSSL_BIO's so set as NULL
123+
* since they are also being used with srv_ssl and will be free'd there. */
124+
wolfSSL_set_bio(cli_ssl, NULL, NULL);
125+
wolfSSL_free(cli_ssl);
126+
wolfSSL_CTX_free(cli_ctx);
127+
128+
return NULL;
129+
}
130+
131+
132+
int main()
133+
{
134+
IO_HANDLES io;
135+
unsigned char buf[80];
136+
int ret, err;
137+
WOLFSSL_CTX* srv_ctx = NULL;
138+
WOLFSSL* srv_ssl = NULL;
139+
WOLFSSL_CIPHER* cipher;
140+
const char *name;
141+
pthread_t tid;
142+
143+
#if 0
144+
wolfSSL_Debugging_ON();
145+
#endif
146+
wolfSSL_Init();
147+
148+
io.rbio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
149+
io.wbio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
150+
sem_init(&io.bioSem, 0, 1);
151+
152+
/* set up server */
153+
srv_ctx = wolfSSL_CTX_new(
154+
#ifdef WOLFSSL_DTLS13
155+
wolfDTLSv1_3_server_method()
156+
#else
157+
wolfDTLSv1_2_server_method()
158+
#endif
159+
);
160+
if (srv_ctx == NULL) err_sys("bad server ctx new");
161+
162+
ret = wolfSSL_CTX_use_PrivateKey_file(srv_ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM);
163+
if (ret != WOLFSSL_SUCCESS) {
164+
err_sys("bad server key file load");
165+
}
166+
167+
ret = wolfSSL_CTX_use_certificate_file(srv_ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM);
168+
if (ret != WOLFSSL_SUCCESS) {
169+
err_sys("bad server cert file load");
170+
}
171+
172+
srv_ssl = wolfSSL_new(srv_ctx);
173+
if (srv_ctx == NULL) {
174+
err_sys("bad server new");
175+
}
176+
177+
/* set memory BIO's to use for IO */
178+
wolfSSL_set_bio(srv_ssl, io.rbio, io.wbio);
179+
180+
/* start client thread */
181+
pthread_create(&tid, 0, client_thread, (void*)&io);
182+
183+
#if 1
184+
/* accept tls connection without tcp sockets */
185+
err = 0;
186+
do {
187+
sem_wait(&io.bioSem);
188+
ret = wolfSSL_accept(srv_ssl);
189+
sem_post(&io.bioSem);
190+
err = wolfSSL_get_error(srv_ssl, ret);
191+
} while (ret != WOLFSSL_SUCCESS &&
192+
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
193+
if (ret != WOLFSSL_SUCCESS) err_sys("bad server tls accept");
194+
printf("wolfSSL accept success!\n");
195+
196+
printf("Version: %s\n", wolfSSL_get_version(srv_ssl));
197+
cipher = wolfSSL_get_current_cipher(srv_ssl);
198+
printf("Cipher Suite: %s\n", wolfSSL_CIPHER_get_name(cipher));
199+
if ((name = wolfSSL_get_curve_name(srv_ssl)) != NULL)
200+
printf("Curve: %s\n", name);
201+
#endif
202+
203+
/* read msg post handshake from client */
204+
memset(buf, 0, sizeof(buf));
205+
do {
206+
sem_wait(&io.bioSem);
207+
ret = wolfSSL_read(srv_ssl, buf, sizeof(buf)-1);
208+
sem_post(&io.bioSem);
209+
err = wolfSSL_get_error(srv_ssl, ret);
210+
} while (ret != 0 &&
211+
((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE)));
212+
if (ret >= 0) {
213+
printf("client msg = %s\n", buf);
214+
}
215+
216+
pthread_join(tid, NULL);
217+
218+
/* clean up */
219+
sem_destroy(&io.bioSem);
220+
wolfSSL_free(srv_ssl); /* This also does free on rbio and wbio */
221+
wolfSSL_CTX_free(srv_ctx);
222+
223+
wolfSSL_Cleanup();
224+
225+
return 0;
226+
}

0 commit comments

Comments
 (0)