Skip to content

Commit f707ad8

Browse files
authored
Merge pull request #446 from anhu/posthsauth_example
New examples for post-handshake authentication.
2 parents de246ca + 7f96232 commit f707ad8

5 files changed

Lines changed: 560 additions & 2 deletions

File tree

tls/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,41 @@ kex=P-256
13781378
0
13791379
```
13801380

1381+
## TLS Example with Post-Handshake Authentication
1382+
1383+
See `client-tls-posthsauth.c` and `server-tls-posthsauth.c`. These server and client applications show how to do a handshake without the server authenticating the client. Then after the handshake is complete, the server requests authentication and the client authenticates itself to the server. This is mutual authentication with a faster handshake because the client authentication is done later. This can lead to a better user experience if there are conditions where the client need not be authenticated.
1384+
1385+
To get a better understanding of what is going on, see the comments that start with "POSTHSAUTH:".
1386+
1387+
Of course, to use this example, you must enable post-handshake authentication. For the purposes of verifying that post-handshake authentication is actually happening, you can enable debugging messages.
1388+
1389+
Build and install wolfSSL like so:
1390+
1391+
```
1392+
$ ./autogen.sh
1393+
$ ./configure --enable-debug --enable-postauth
1394+
$ make all
1395+
$ sudo make install
1396+
```
1397+
1398+
Modify `client-tls-posthsauth.c` and `server-tls-posthsauth.c` so that they call `wolfSSL_Debugging_ON()`.
1399+
1400+
Build them like so:
1401+
1402+
```
1403+
make client-tls-posthsauth server-tls-posthsaut
1404+
```
1405+
1406+
Execute them like so:
1407+
1408+
```
1409+
./server-tls-posthsauth
1410+
```
1411+
1412+
```
1413+
./server-tls-posthsauth 127.0.0.1
1414+
```
1415+
13811416
## Support
13821417

13831418
Please contact wolfSSL at support@wolfssl.com with any questions, bug fixes,

tls/client-tls-posthsauth.c

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/* client-tls-postauth.c
2+
*
3+
* Copyright (C) 2006-2024 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+
/* the usual suspects */
23+
#include <stdlib.h>
24+
#include <stdio.h>
25+
#include <string.h>
26+
27+
/* socket includes */
28+
#include <sys/socket.h>
29+
#include <arpa/inet.h>
30+
#include <netinet/in.h>
31+
#include <unistd.h>
32+
33+
/* wolfSSL */
34+
#ifndef WOLFSSL_USER_SETTINGS
35+
#include <wolfssl/options.h>
36+
#endif
37+
#include <wolfssl/ssl.h>
38+
#include <wolfssl/wolfio.h>
39+
#include <wolfssl/wolfcrypt/error-crypt.h>
40+
41+
#if defined(WOLFSSL_POST_HANDSHAKE_AUTH) && defined(WOLFSSL_TLS13)
42+
#define DEFAULT_PORT 11111
43+
44+
#define CERT_FILE "../certs/client-cert.pem"
45+
#define KEY_FILE "../certs/client-key.pem"
46+
#define CA_FILE "../certs/ca-cert.pem"
47+
48+
int main(int argc, char** argv)
49+
{
50+
int ret = 0;
51+
int sockfd = SOCKET_INVALID;
52+
struct sockaddr_in servAddr;
53+
char buff[256];
54+
size_t len;
55+
56+
/* declare wolfSSL objects */
57+
WOLFSSL_CTX* ctx = NULL;
58+
WOLFSSL* ssl = NULL;
59+
60+
/* Check for proper calling convention */
61+
if (argc != 2) {
62+
printf("usage: %s <IPv4 address>\n", argv[0]);
63+
return 0;
64+
}
65+
66+
/* Create a socket that uses an internet IPv4 address,
67+
* Sets the socket to be stream based (TCP),
68+
* 0 means choose the default protocol. */
69+
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
70+
fprintf(stderr, "ERROR: failed to create the socket\n");
71+
ret = -1; goto exit;
72+
}
73+
74+
/* Initialize the server address struct with zeros */
75+
memset(&servAddr, 0, sizeof(servAddr));
76+
77+
/* Fill in the server address */
78+
servAddr.sin_family = AF_INET; /* using IPv4 */
79+
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
80+
81+
/* Get the server IPv4 address from the command line call */
82+
if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) != 1) {
83+
fprintf(stderr, "ERROR: invalid address\n");
84+
ret = -1; goto exit;
85+
}
86+
87+
/* Connect to the server */
88+
if ((ret = connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)))
89+
== -1) {
90+
fprintf(stderr, "ERROR: failed to connect\n");
91+
goto exit;
92+
}
93+
94+
/*---------------------------------*/
95+
/* Start of wolfSSL initialization and configuration */
96+
/*---------------------------------*/
97+
#if 0
98+
wolfSSL_Debugging_ON();
99+
#endif
100+
101+
/* Initialize wolfSSL */
102+
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
103+
fprintf(stderr, "ERROR: Failed to initialize the library\n");
104+
goto exit;
105+
}
106+
107+
/* Create and initialize WOLFSSL_CTX */
108+
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())) == NULL) {
109+
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
110+
ret = -1; goto exit;
111+
}
112+
113+
/* Load client certificate into WOLFSSL_CTX */
114+
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM))
115+
!= WOLFSSL_SUCCESS) {
116+
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
117+
CERT_FILE);
118+
goto exit;
119+
}
120+
121+
/* Load client key into WOLFSSL_CTX */
122+
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM))
123+
!= WOLFSSL_SUCCESS) {
124+
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
125+
KEY_FILE);
126+
goto exit;
127+
}
128+
129+
/* Load CA certificate into WOLFSSL_CTX */
130+
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL))
131+
!= WOLFSSL_SUCCESS) {
132+
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
133+
CA_FILE);
134+
goto exit;
135+
}
136+
137+
/* POSTHSAUTH: Prepare for post-handshake authentication. */
138+
if ((ret = wolfSSL_CTX_allow_post_handshake_auth(ctx)) != 0) {
139+
fprintf(stderr, "ERROR: failed to allow post hand-shake auth.\n");
140+
goto exit;
141+
}
142+
143+
/* Create a WOLFSSL object */
144+
if ((ssl = wolfSSL_new(ctx)) == NULL) {
145+
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
146+
ret = -1; goto exit;
147+
}
148+
149+
/* Attach wolfSSL to the socket */
150+
if ((ret = wolfSSL_set_fd(ssl, sockfd)) != WOLFSSL_SUCCESS) {
151+
fprintf(stderr, "ERROR: Failed to set the file descriptor\n");
152+
goto exit;
153+
}
154+
155+
/* Connect to wolfSSL on the server side */
156+
if ((ret = wolfSSL_connect(ssl)) != WOLFSSL_SUCCESS) {
157+
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
158+
goto exit;
159+
}
160+
161+
/* Get a message for the server from stdin */
162+
printf("Message for server: ");
163+
memset(buff, 0, sizeof(buff));
164+
if (fgets(buff, sizeof(buff), stdin) == NULL) {
165+
fprintf(stderr, "ERROR: failed to get message for server\n");
166+
ret = -1; goto exit;
167+
}
168+
len = strnlen(buff, sizeof(buff));
169+
170+
/* Send the message to the server */
171+
if ((ret = wolfSSL_write(ssl, buff, len)) != len) {
172+
fprintf(stderr, "ERROR: failed to write entire message\n");
173+
fprintf(stderr, "%d bytes of %d bytes were sent", ret, (int) len);
174+
goto exit;
175+
}
176+
177+
/* Read the server data into our buff array */
178+
memset(buff, 0, sizeof(buff));
179+
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) < 0) {
180+
fprintf(stderr, "ERROR: failed to read\n");
181+
goto exit;
182+
}
183+
184+
/* Print to stdout any data the server sends */
185+
printf("Server: %s\n", buff);
186+
187+
/* POSTHSAUTH: Send the second message to the server. This message is now
188+
* authenticated. */
189+
memset(buff, 0, sizeof(buff));
190+
memcpy(buff, "Hello again from the client\n", 28);
191+
len = strnlen(buff, sizeof(buff));
192+
193+
if ((ret = wolfSSL_write(ssl, buff, len)) != len) {
194+
fprintf(stderr, "ERROR: failed to write entire message\n");
195+
fprintf(stderr, "%d bytes of %d bytes were sent", ret, (int) len);
196+
goto exit;
197+
}
198+
199+
/* Return reporting a success */
200+
ret = 0;
201+
202+
exit:
203+
/* Cleanup and return */
204+
if (sockfd != SOCKET_INVALID)
205+
close(sockfd); /* Close the connection to the server */
206+
if (ssl)
207+
wolfSSL_free(ssl); /* Free the wolfSSL object */
208+
if (ctx)
209+
wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
210+
wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
211+
return ret;
212+
}
213+
#else
214+
int main() {
215+
fprintf(stderr, "Please configure with --enable-postauth or compile with "
216+
"WOLFSSL_POST_HANDSHAKE_AUTH defined. Do not disable "
217+
"TLS 1.3.\n");
218+
return 0;
219+
}
220+
#endif /* WOLFSSL_POST_HANDSHAKE_AUTH && WOLFSSL_TLS13 */

tls/client-tls13.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
#include <unistd.h>
3232

3333
/* wolfSSL */
34-
#include <wolfssl/options.h>
34+
#ifndef WOLFSSL_USER_SETTINGS
35+
#include <wolfssl/options.h>
36+
#endif
3537
#include <wolfssl/ssl.h>
3638
#include <wolfssl/wolfio.h>
3739
#include <wolfssl/wolfcrypt/error-crypt.h>

0 commit comments

Comments
 (0)