1 /* server-tls.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
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-1335, USA
20 */
21
22
23 /* wolfSSL */
24 #include <wolfssl/wolfcrypt/settings.h>
25 #include <wolfssl/ssl.h>
26 #include <addrinfo.h>
27
28 #define DEFAULT_PORT 11111
29
30 #define CERT_FILE "../certs/server-cert.pem"
31 #define KEY_FILE "../certs/server-key.pem"
32
33
34
main()35 int main()
36 {
37 int sockfd;
38 int connd;
39 struct sockaddr_in servAddr;
40 struct sockaddr_in clientAddr;
41 socklen_t size = sizeof(clientAddr);
42 char buff[256];
43 size_t len;
44 int shutdown = 0;
45 int ret;
46 const char* reply = "I hear ya fa shizzle!\n";
47
48 /* declare wolfSSL objects */
49 WOLFSSL_CTX* ctx;
50 WOLFSSL* ssl;
51
52
53
54 /* Initialize wolfSSL */
55 wolfSSL_Init();
56
57
58
59 /* Create a socket that uses an internet IPv4 address,
60 * Sets the socket to be stream based (TCP),
61 * 0 means choose the default protocol. */
62 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
63 fprintf(stderr, "ERROR: failed to create the socket\n");
64 return -1;
65 }
66
67
68
69 /* Create and initialize WOLFSSL_CTX */
70 if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) {
71 fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
72 return -1;
73 }
74
75 /* Load server certificates into WOLFSSL_CTX */
76 if (wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)
77 != SSL_SUCCESS) {
78 fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
79 CERT_FILE);
80 return -1;
81 }
82
83 /* Load server key into WOLFSSL_CTX */
84 if (wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM)
85 != SSL_SUCCESS) {
86 fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
87 KEY_FILE);
88 return -1;
89 }
90
91
92
93 /* Initialize the server address struct with zeros */
94 memset(&servAddr, 0, sizeof(servAddr));
95
96 /* Fill in the server address */
97 servAddr.sin_family = AF_INET; /* using IPv4 */
98 servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
99 servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */
100
101
102
103 /* Bind the server socket to our port */
104 if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) {
105 fprintf(stderr, "ERROR: failed to bind\n");
106 return -1;
107 }
108
109 /* Listen for a new connection, allow 5 pending connections */
110 if (listen(sockfd, 5) == -1) {
111 fprintf(stderr, "ERROR: failed to listen\n");
112 return -1;
113 }
114
115
116
117 /* Continue to accept clients until shutdown is issued */
118 while (!shutdown) {
119 printf("Waiting for a connection...\n");
120
121 /* Accept client connections */
122 if ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size))
123 == -1) {
124 fprintf(stderr, "ERROR: failed to accept the connection\n\n");
125 return -1;
126 }
127
128 /* Create a WOLFSSL object */
129 if ((ssl = wolfSSL_new(ctx)) == NULL) {
130 fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
131 return -1;
132 }
133
134 /* Attach wolfSSL to the socket */
135 wolfSSL_set_fd(ssl, connd);
136
137 /* Establish TLS connection */
138 ret = wolfSSL_accept(ssl);
139 if (ret != SSL_SUCCESS) {
140 fprintf(stderr, "wolfSSL_accept error = %d\n",
141 wolfSSL_get_error(ssl, ret));
142 return -1;
143 }
144
145
146 printf("Client connected successfully\n");
147
148
149
150 /* Read the client data into our buff array */
151 memset(buff, 0, sizeof(buff));
152 if (wolfSSL_read(ssl, buff, sizeof(buff)-1) == -1) {
153 fprintf(stderr, "ERROR: failed to read\n");
154 return -1;
155 }
156
157 /* Print to stdout any data the client sends */
158 printf("Client: %s\n", buff);
159
160 /* Check for server shutdown command */
161 if (strncmp(buff, "shutdown", 8) == 0) {
162 printf("Shutdown command issued!\n");
163 shutdown = 1;
164 }
165
166
167
168 /* Write our reply into buff */
169 memset(buff, 0, sizeof(buff));
170 memcpy(buff, reply, strlen(reply));
171 len = strnlen(buff, sizeof(buff));
172
173 /* Reply back to the client */
174 if (wolfSSL_write(ssl, buff, len) != len) {
175 fprintf(stderr, "ERROR: failed to write\n");
176 return -1;
177 }
178
179
180
181 /* Cleanup after this connection */
182 wolfSSL_free(ssl); /* Free the wolfSSL object */
183 close(connd); /* Close the connection to the client */
184 }
185
186 printf("Shutdown complete\n");
187
188
189
190 /* Cleanup and return */
191 wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
192 wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
193 close(sockfd); /* Close the socket listening for clients */
194 return 0; /* Return reporting a success */
195 }