]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/examples/server/server.c
Add FreeRTOS-Plus directory with new directory structure so it matches the FreeRTOS...
[freertos] / FreeRTOS-Plus / Source / CyaSSL / examples / server / server.c
1 /* server.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL 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  * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <cyassl/openssl/ssl.h>
27 #include <cyassl/test.h>
28
29
30 #ifdef CYASSL_CALLBACKS
31     int srvHandShakeCB(HandShakeInfo*);
32     int srvTimeoutCB(TimeoutInfo*);
33     Timeval srvTo;
34 #endif
35
36 #if defined(NON_BLOCKING) || defined(CYASSL_CALLBACKS)
37     void NonBlockingSSL_Accept(SSL* ssl)
38     {
39     #ifndef CYASSL_CALLBACKS
40         int ret = SSL_accept(ssl);
41     #else
42         int ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB, srvTo);
43     #endif
44         int error = SSL_get_error(ssl, 0);
45         while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
46                                       error == SSL_ERROR_WANT_WRITE)) {
47             printf("... server would block\n");
48             #ifdef USE_WINDOWS_API 
49                 Sleep(1000);
50             #else
51                 sleep(1);
52             #endif
53             #ifndef CYASSL_CALLBACKS
54                 ret = SSL_accept(ssl);
55             #else
56                 ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB,srvTo);
57             #endif
58             error = SSL_get_error(ssl, 0);
59         }
60         if (ret != SSL_SUCCESS)
61             err_sys("SSL_accept failed");
62     }
63 #endif
64
65
66 static void Usage(void)
67 {
68     printf("server "    LIBCYASSL_VERSION_STRING
69            " NOTE: All files relative to CyaSSL home dir\n");
70     printf("-?          Help, print this usage\n");
71     printf("-p <num>    Port to listen on, default %d\n", yasslPort);
72     printf("-v <num>    SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
73                                  SERVER_DEFAULT_VERSION);
74     printf("-l <str>    Cipher list\n");
75     printf("-c <file>   Certificate file,           default %s\n", svrCert);
76     printf("-k <file>   Key file,                   default %s\n", svrKey);
77     printf("-A <file>   Certificate Authority file, default %s\n", cliCert);
78     printf("-d          Disable client cert check\n");
79     printf("-b          Bind to any interface instead of localhost only\n");
80     printf("-s          Use pre Shared keys\n");
81     printf("-u          Use UDP DTLS\n");
82 }
83
84
85 THREAD_RETURN CYASSL_THREAD server_test(void* args)
86 {
87     SOCKET_T sockfd   = 0;
88     int      clientfd = 0;
89
90     SSL_METHOD* method = 0;
91     SSL_CTX*    ctx    = 0;
92     SSL*        ssl    = 0;
93
94     char   msg[] = "I hear you fa shizzle!";
95     char   input[1024];
96     int    idx;
97     int    ch;
98     int    version = SERVER_DEFAULT_VERSION;
99     int    doCliCertCheck = 1;
100     int    useAnyAddr = 0;
101     int    port = yasslPort;
102     int    usePsk = 0;
103     int    doDTLS = 0;
104     int    useNtruKey = 0;
105     char*  cipherList = NULL;
106     char*  verifyCert = (char*)cliCert;
107     char*  ourCert    = (char*)svrCert;
108     char*  ourKey     = (char*)svrKey;
109     int    argc = ((func_args*)args)->argc;
110     char** argv = ((func_args*)args)->argv;
111
112     ((func_args*)args)->return_code = -1; /* error state */
113
114     while ((ch = mygetopt(argc, argv, "?dbsnup:v:l:A:c:k:")) != -1) {
115         switch (ch) {
116             case '?' :
117                 Usage();
118                 exit(EXIT_SUCCESS);
119
120             case 'd' :
121                 doCliCertCheck = 0;
122                 break;
123
124             case 'b' :
125                 useAnyAddr = 1;
126                 break;
127
128             case 's' :
129                 usePsk = 1;
130                 break;
131
132             case 'n' :
133                 useNtruKey = 1;
134                 break;
135
136             case 'u' :
137                 doDTLS  = 1;
138                 version = -1;  /* DTLS flag */
139                 break;
140
141             case 'p' :
142                 port = atoi(myoptarg);
143                 break;
144
145             case 'v' :
146                 version = atoi(myoptarg);
147                 if (version < 0 || version > 3) {
148                     Usage();
149                     exit(MY_EX_USAGE);
150                 }
151                 if (doDTLS)
152                     version = -1;  /* stay with DTLS */
153                 break;
154
155             case 'l' :
156                 cipherList = myoptarg;
157                 break;
158
159             case 'A' :
160                 verifyCert = myoptarg;
161                 break;
162
163             case 'c' :
164                 ourCert = myoptarg;
165                 break;
166
167             case 'k' :
168                 ourKey = myoptarg;
169                 break;
170
171             default:
172                 Usage();
173                 exit(MY_EX_USAGE);
174         }
175     }
176
177     argc -= myoptind;
178     argv += myoptind;
179     myoptind = 0;      /* reset for test cases */
180
181     switch (version) {
182         case 0:
183             method = SSLv3_server_method();
184             break;
185
186         case 1:
187             method = TLSv1_server_method();
188             break;
189
190         case 2:
191             method = TLSv1_1_server_method();
192             break;
193
194         case 3:
195             method = TLSv1_2_server_method();
196             break;
197
198 #ifdef CYASSL_DTLS
199         case -1:
200             method = DTLSv1_server_method();
201             break;
202 #endif
203
204         default:
205             err_sys("Bad SSL version");
206     }
207
208     if (method == NULL)
209         err_sys("unable to get method");
210
211     ctx = SSL_CTX_new(method);
212     if (ctx == NULL)
213         err_sys("unable to get ctx");
214
215     if (cipherList)
216         if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
217             err_sys("can't set cipher list");
218
219     if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
220                                      != SSL_SUCCESS)
221         err_sys("can't load server cert file, check file and run from"
222                 " CyaSSL home dir");
223
224
225 #ifdef HAVE_NTRU
226     if (useNtruKey) {
227         if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
228                                                != SSL_SUCCESS)
229             err_sys("can't load ntru key file, "
230                     "Please run from CyaSSL home dir");
231     }
232 #endif
233
234     if (!useNtruKey) {
235         if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
236                                          != SSL_SUCCESS)
237             err_sys("can't load server cert file, check file and run from"
238                 " CyaSSL home dir");
239     }
240
241 #ifndef NO_PSK
242     if (usePsk) {
243         SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
244         SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
245         if (cipherList == NULL)
246             if (SSL_CTX_set_cipher_list(ctx,"PSK-AES256-CBC-SHA") !=SSL_SUCCESS)
247                 err_sys("can't set cipher list");
248     }
249 #endif
250
251     /* if not using PSK, verify peer with certs */
252     if (doCliCertCheck && usePsk == 0) {
253         SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
254                                 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
255         if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
256             err_sys("can't load ca file, Please run from CyaSSL home dir");
257     }
258
259 #ifdef OPENSSL_EXTRA
260     SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
261 #endif
262
263 #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
264     /* don't use EDH, can't sniff tmp keys */
265     if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS)
266         err_sys("can't set cipher list");
267 #endif
268
269     ssl = SSL_new(ctx);
270     if (ssl == NULL)
271         err_sys("unable to get SSL");
272
273 #ifdef HAVE_CRL
274     CyaSSL_EnableCRL(ssl, 0);
275     CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
276                                                      CYASSL_CRL_START_MON);
277     CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
278 #endif
279     tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
280     if (!doDTLS) 
281         CloseSocket(sockfd);
282
283     SSL_set_fd(ssl, clientfd);
284 #ifdef NO_PSK
285     #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
286         CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
287     #else
288         SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
289     #endif
290 #endif
291
292 #ifdef NON_BLOCKING
293     tcp_set_nonblocking(&clientfd);
294     NonBlockingSSL_Accept(ssl);
295 #else
296     #ifndef CYASSL_CALLBACKS
297         if (SSL_accept(ssl) != SSL_SUCCESS) {
298             int err = SSL_get_error(ssl, 0);
299             char buffer[80];
300             printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
301             err_sys("SSL_accept failed");
302         }
303     #else
304         NonBlockingSSL_Accept(ssl);
305     #endif
306 #endif
307     showPeer(ssl);
308
309     idx = SSL_read(ssl, input, sizeof(input));
310     if (idx > 0) {
311         input[idx] = 0;
312         printf("Client message: %s\n", input);
313     }
314     
315     if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
316         err_sys("SSL_write failed");
317
318     SSL_shutdown(ssl);
319     SSL_free(ssl);
320     SSL_CTX_free(ctx);
321     
322     CloseSocket(clientfd);
323     ((func_args*)args)->return_code = 0;
324     return 0;
325 }
326
327
328 /* so overall tests can pull in test function */
329 #ifndef NO_MAIN_DRIVER
330
331     int main(int argc, char** argv)
332     {
333         func_args args;
334
335         StartTCP();
336
337         args.argc = argc;
338         args.argv = argv;
339
340         CyaSSL_Init();
341 #ifdef DEBUG_CYASSL
342         CyaSSL_Debugging_ON();
343 #endif
344         if (CurrentDir("server") || CurrentDir("build"))
345             ChangeDirBack(2);
346    
347         server_test(&args);
348         CyaSSL_Cleanup();
349
350         return args.return_code;
351     }
352
353     int myoptind = 0;
354     char* myoptarg = NULL;
355
356 #endif /* NO_MAIN_DRIVER */
357
358
359 #ifdef CYASSL_CALLBACKS
360
361     int srvHandShakeCB(HandShakeInfo* info)
362     {
363
364         return 0;
365     }
366
367
368     int srvTimeoutCB(TimeoutInfo* info)
369     {
370
371         return 0;
372     }
373
374 #endif
375
376