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 }