Skip to content

Commit ee05a30

Browse files
authored
Merge pull request #323 from julek-wolfssl/dtls13-examples
DTLS 1.3 client and server examples
2 parents 7ff4964 + 2b52c38 commit ee05a30

8 files changed

Lines changed: 1055 additions & 20 deletions

File tree

dtls/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LIBS = -L$(LIB_PATH)/lib -lm
77
# option variables
88
DYN_LIB = -lwolfssl
99
STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a
10-
DEBUG_FLAGS = -g -DDEBUG
10+
DEBUG_FLAGS = -g3 -DDEBUG -O0
1111
DEBUG_INC_PATHS = -MD
1212
OPTIMIZE = -Os
1313

@@ -34,6 +34,10 @@ debug: all
3434
%-shared: CFLAGS+=-pthread
3535
%-shared: LIBS+=-lpthread
3636

37+
# try to build the libevent server. "|| true" ignores the error return.
38+
server-dtls13-event: server-dtls13-event.c
39+
$(CC) -o $@ $< $(CFLAGS) $(LIBS) -levent || true
40+
3741
# build template
3842
%: %.c
3943
$(CC) -o $@ $< $(CFLAGS) $(LIBS)

dtls/bin-msgs/CH1.bin

259 Bytes
Binary file not shown.

dtls/bin-msgs/CH2.bin

332 Bytes
Binary file not shown.

dtls/client-dtls13.c

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* client-dtls13.c
3+
*
4+
* Copyright (C) 2006-2022 wolfSSL Inc.
5+
*
6+
* This file is part of wolfSSL. (formerly known as CyaSSL)
7+
*
8+
* wolfSSL is free software; you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation; either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* wolfSSL is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21+
*
22+
*=============================================================================
23+
*
24+
* Bare-bones example of a DTLS 1.3 client for instructional/learning purposes.
25+
* This example uses blocking sockets for simplicity.
26+
*
27+
* To exit the sending loop enter "end" or Ctrl+D
28+
*
29+
* Define USE_DTLS12 to use DTLS 1.2 instead of DTLS 1.3
30+
*/
31+
32+
#include <wolfssl/options.h>
33+
#include <unistd.h>
34+
#include <wolfssl/ssl.h>
35+
#include <netdb.h>
36+
#include <signal.h>
37+
#include <sys/socket.h>
38+
#include <arpa/inet.h>
39+
#include <netinet/in.h>
40+
#include <stdio.h>
41+
#include <stdlib.h>
42+
#include <string.h>
43+
44+
#include "dtls-common.h"
45+
46+
int main (int argc, char** argv)
47+
{
48+
/* standard variables used in a dtls client*/
49+
int n = 0;
50+
int sockfd = INVALID_SOCKET;
51+
int err;
52+
int ret;
53+
int exitVal = 1;
54+
struct sockaddr_in servAddr;
55+
WOLFSSL* ssl = NULL;
56+
WOLFSSL_CTX* ctx = NULL;
57+
char sendLine[MAXLINE];
58+
char recvLine[MAXLINE - 1];
59+
60+
/* Program argument checking */
61+
if (argc != 2) {
62+
fprintf(stderr, "usage: %s <IP address>\n", argv[0]);
63+
return exitVal;
64+
}
65+
66+
/* Initialize wolfSSL before assigning ctx */
67+
if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
68+
fprintf(stderr, "wolfSSL_CTX_new error.\n");
69+
return exitVal;
70+
}
71+
72+
/* No-op when debugging is not compiled in */
73+
wolfSSL_Debugging_ON();
74+
75+
if ( (ctx = wolfSSL_CTX_new(
76+
#ifndef USE_DTLS12
77+
wolfDTLSv1_3_client_method()
78+
#else
79+
wolfDTLSv1_2_client_method()
80+
#endif
81+
)) == NULL) {
82+
fprintf(stderr, "wolfSSL_CTX_new error.\n");
83+
goto cleanup;
84+
}
85+
86+
/* Load certificates into ctx variable */
87+
if (wolfSSL_CTX_load_verify_locations(ctx, caCertLoc, 0)
88+
!= SSL_SUCCESS) {
89+
fprintf(stderr, "Error loading %s, please check the file.\n", caCertLoc);
90+
goto cleanup;
91+
}
92+
93+
/* Assign ssl variable */
94+
ssl = wolfSSL_new(ctx);
95+
if (ssl == NULL) {
96+
fprintf(stderr, "unable to get ssl object\n");
97+
goto cleanup;
98+
}
99+
100+
/* servAddr setup */
101+
memset(&servAddr, 0, sizeof(servAddr));
102+
servAddr.sin_family = AF_INET;
103+
servAddr.sin_port = htons(SERV_PORT);
104+
if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) {
105+
perror("inet_pton()");
106+
goto cleanup;
107+
}
108+
109+
if (wolfSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr))
110+
!= WOLFSSL_SUCCESS) {
111+
fprintf(stderr, "wolfSSL_dtls_set_peer failed\n");
112+
goto cleanup;
113+
}
114+
115+
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
116+
perror("socket()");
117+
goto cleanup;
118+
}
119+
120+
/* Set the file descriptor for ssl */
121+
if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
122+
fprintf(stderr, "cannot set socket file descriptor\n");
123+
goto cleanup;
124+
}
125+
126+
/* Perform SSL connection */
127+
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
128+
err = wolfSSL_get_error(ssl, 0);
129+
fprintf(stderr, "err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err));
130+
fprintf(stderr, "wolfSSL_connect failed\n");
131+
goto cleanup;
132+
}
133+
134+
showConnInfo(ssl);
135+
136+
/*****************************************************************************/
137+
/* Code for sending datagram to server */
138+
while (1) {
139+
if (fgets(sendLine, MAXLINE, stdin) == NULL)
140+
break;
141+
142+
if (strncmp(sendLine, "end", 3) == 0)
143+
break;
144+
145+
/* Send sendLine to the server */
146+
if (wolfSSL_write(ssl, sendLine, strlen(sendLine)) != strlen(sendLine)) {
147+
err = wolfSSL_get_error(ssl, 0);
148+
fprintf(stderr, "err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err));
149+
fprintf(stderr, "wolfSSL_write failed\n");
150+
goto cleanup;
151+
}
152+
153+
/* n is the # of bytes received */
154+
n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1);
155+
156+
if (n > 0) {
157+
/* Add a terminating character to the generic server message */
158+
recvLine[n] = '\0';
159+
printf("%s\n", recvLine);
160+
}
161+
else {
162+
err = wolfSSL_get_error(ssl, 0);
163+
fprintf(stderr, "err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err));
164+
fprintf(stderr, "wolfSSL_read failed\n");
165+
goto cleanup;
166+
}
167+
}
168+
/* End code for sending datagram to server */
169+
/*****************************************************************************/
170+
171+
exitVal = 0;
172+
cleanup:
173+
if (ssl != NULL) {
174+
/* Attempt a full shutdown */
175+
ret = wolfSSL_shutdown(ssl);
176+
if (ret == WOLFSSL_SHUTDOWN_NOT_DONE)
177+
ret = wolfSSL_shutdown(ssl);
178+
if (ret != WOLFSSL_SUCCESS) {
179+
err = wolfSSL_get_error(ssl, 0);
180+
fprintf(stderr, "err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err));
181+
fprintf(stderr, "wolfSSL_shutdown failed\n");
182+
}
183+
wolfSSL_free(ssl);
184+
}
185+
if (sockfd != INVALID_SOCKET)
186+
close(sockfd);
187+
if (ctx != NULL)
188+
wolfSSL_CTX_free(ctx);
189+
wolfSSL_Cleanup();
190+
191+
return exitVal;
192+
}
193+

dtls/dtls-common.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* dtls-common.h
3+
*
4+
* Copyright (C) 2006-2022 wolfSSL Inc.
5+
*
6+
* This file is part of wolfSSL. (formerly known as CyaSSL)
7+
*
8+
* wolfSSL is free software; you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation; either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* wolfSSL is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21+
*
22+
* -----------------------------------------------------------------------------
23+
*
24+
* Define USE_DTLS12 to use DTLS 1.2 instead of DTLS 1.3
25+
*
26+
*/
27+
28+
#ifndef DTLS_COMMON_H_
29+
#define DTLS_COMMON_H_
30+
31+
#define INVALID_SOCKET -1
32+
#define MAXLINE 4096
33+
#define SERV_PORT 11111
34+
#define LOOP_LIMIT 5
35+
#define SFD_TIMEOUT 1
36+
37+
/* Loc short for "location" */
38+
const char caCertLoc[] = "../certs/ca-cert.pem";
39+
const char servCertLoc[] = "../certs/server-cert.pem";
40+
const char servKeyLoc[] = "../certs/server-key.pem";
41+
42+
static inline void showConnInfo(WOLFSSL* ssl) {
43+
printf("New connection established using %s %s\n",
44+
wolfSSL_get_version(ssl), wolfSSL_get_cipher(ssl));
45+
}
46+
47+
48+
#endif /* DTLS_COMMON_H_ */

dtls/server-dtls.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -175,25 +175,27 @@ int main(int argc, char** argv)
175175
printf("SSL_accept failed.\n");
176176
break;
177177
}
178-
if ((recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
179-
printf("heard %d bytes\n", recvLen);
178+
while (1) {
179+
if ((recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
180+
printf("heard %d bytes\n", recvLen);
180181

181-
buff[recvLen] = 0;
182-
printf("I heard this: \"%s\"\n", buff);
183-
}
184-
else if (recvLen < 0) {
185-
int readErr = wolfSSL_get_error(ssl, 0);
186-
if(readErr != SSL_ERROR_WANT_READ) {
187-
printf("SSL_read failed.\n");
188-
break;
182+
buff[recvLen] = 0;
183+
printf("I heard this: \"%s\"\n", buff);
184+
}
185+
else if (recvLen < 0) {
186+
int readErr = wolfSSL_get_error(ssl, 0);
187+
if(readErr != SSL_ERROR_WANT_READ) {
188+
printf("SSL_read failed.\n");
189+
goto error;
190+
}
191+
}
192+
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
193+
printf("wolfSSL_write fail.\n");
194+
goto error;
195+
}
196+
else {
197+
printf("Sending reply.\n");
189198
}
190-
}
191-
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
192-
printf("wolfSSL_write fail.\n");
193-
break;
194-
}
195-
else {
196-
printf("Sending reply.\n");
197199
}
198200

199201
printf("reply sent \"%s\"\n", ack);
@@ -207,8 +209,7 @@ int main(int argc, char** argv)
207209
printf("Client left cont to idle state\n");
208210
}
209211

210-
/* With the "continue" keywords, it is possible for the loop to exit *
211-
* without changing the value of cont */
212+
error:
212213
if (cleanup == 1) {
213214
wolfSSL_set_fd(ssl, 0);
214215
wolfSSL_shutdown(ssl);

0 commit comments

Comments
 (0)