1 /* This case tests reconnection when TLS connection fail. */
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "fx_api.h"
5 #include    "nx_web_http_client.h"
6 #include    "nx_web_http_server.h"
7 
8 extern void test_control_return(UINT);
9 
10 #if !defined(NX_DISABLE_IPV4) && defined(NX_WEB_HTTPS_ENABLE)
11 
12 #include "test_device_cert.c"
13 #include "test_ca_cert.c"
14 #define ca_cert_der test_ca_cert_der
15 #define ca_cert_der_len test_ca_cert_der_len
16 
17 #define     DEMO_STACK_SIZE         4096
18 
19 /* Set up FileX and file memory resources. */
20 static CHAR             ram_disk_memory[4096];
21 static FX_MEDIA         ram_disk;
22 static UCHAR            media_memory[4096];
23 
24 static UCHAR            server_stack[16000];
25 
26 /* Define device drivers.  */
27 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
28 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
29 
30 /* Set up the HTTP client global variables. */
31 
32 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
33 
34 static TX_THREAD           client_thread;
35 static NX_PACKET_POOL      client_pool;
36 static NX_IP               client_ip;
37 static UINT                error_counter;
38 
39 /* Set up the HTTP server global variables */
40 
41 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
42 
43 static NX_WEB_HTTP_SERVER  my_server;
44 static NX_PACKET_POOL      server_pool;
45 static TX_THREAD           server_thread;
46 static NX_IP               server_ip;
47 static NXD_ADDRESS         server_ip_address;
48 static UINT                http_server_start = 0;
49 static UINT                http_client_stop = 0;
50 
51 static void thread_client_entry(ULONG thread_input);
52 static void thread_server_entry(ULONG thread_input);
53 
54 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
55 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
56 
57 static UINT https_server_start = 0;
58 static UINT https_client_stop = 0;
59 static UINT loop = 2;
60 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
61 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
62 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
63 static UCHAR tls_packet_buffer[18500];
64 static NX_SECURE_X509_CERT certificate;
65 static NX_SECURE_X509_CERT trusted_certificate;
66 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
67 static UCHAR remote_cert_buffer[2000];
68 static UCHAR remote_issuer_buffer[2000];
69 
70 static UINT tls_setup_callback(NX_SECURE_TLS_SESSION *tls_session);
71 
72 static UINT  authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
73                                   CHAR *resource, CHAR **name, CHAR **password, CHAR **realm);
74 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr);
75 
76 #ifdef CTEST
test_application_define(void * first_unused_memory)77 VOID test_application_define(void *first_unused_memory)
78 #else
79 void    netx_web_secure_reconnect_test_application_define(void *first_unused_memory)
80 #endif
81 {
82 CHAR    *pointer;
83 UINT    status;
84 
85 
86     error_counter = 0;
87 
88     /* Setup the working pointer.  */
89     pointer =  (CHAR *) first_unused_memory;
90 
91     /* Create a helper thread for the server. */
92     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
93                      pointer, DEMO_STACK_SIZE,
94                      3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
95 
96     pointer =  pointer + DEMO_STACK_SIZE;
97 
98     /* Initialize the NetX system.  */
99     nx_system_initialize();
100 
101     /* Create the server packet pool.  */
102     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
103                                     pointer, SERVER_PACKET_SIZE*8);
104     pointer = pointer + SERVER_PACKET_SIZE * 8;
105     if (status)
106         error_counter++;
107 
108     /* Create an IP instance.  */
109     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
110                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
111                           pointer, 4096, 1);
112     pointer =  pointer + 4096;
113     if (status)
114         error_counter++;
115 
116     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
117     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
118     pointer = pointer + 1024;
119     if (status)
120         error_counter++;
121 
122 
123      /* Enable TCP traffic.  */
124     status = nx_tcp_enable(&server_ip);
125     if (status)
126         error_counter++;
127 
128     /* Create the HTTP Client thread. */
129     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
130                               pointer, DEMO_STACK_SIZE,
131                               3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
132     pointer =  pointer + DEMO_STACK_SIZE;
133     if (status)
134         error_counter++;
135 
136     /* Create the Client packet pool.  */
137     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
138                                     pointer, CLIENT_PACKET_SIZE*8);
139     pointer = pointer + CLIENT_PACKET_SIZE * 8;
140     if (status)
141         error_counter++;
142 
143     /* Create an IP instance.  */
144     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
145                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
146                           pointer, 2048, 1);
147     pointer =  pointer + 2048;
148     if (status)
149         error_counter++;
150 
151     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
152     pointer =  pointer + 2048;
153     if (status)
154         error_counter++;
155 
156      /* Enable TCP traffic.  */
157     status = nx_tcp_enable(&client_ip);
158     if (status)
159         error_counter++;
160 }
161 
162 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_SECURE_TLS_SESSION * tls_session)163 static UINT tls_setup_callback(NX_SECURE_TLS_SESSION *tls_session)
164 {
165 UINT status;
166 
167 
168     /* Initialize and create TLS session.  */
169     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
170 
171     /* Check status.  */
172     if (status)
173     {
174         return(status);
175     }
176 
177     /* Allocate space for packet reassembly.  */
178     status = nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer, sizeof(tls_packet_buffer));
179 
180     /* Check status.  */
181     if (status)
182     {
183         return(status);
184     }
185 
186     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
187     ca_cert_der[0] = ca_cert_der[0] + 1; /* Modify the cert data to make TLS connection fail. */
188     nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
189     nx_secure_tls_trusted_certificate_add(tls_session, &trusted_certificate);
190 
191     /* Need to allocate space for the certificate coming in from the remote host.  */
192     nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
193     nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
194 
195     return(NX_SUCCESS);
196 }
197 
thread_client_entry(ULONG thread_input)198 void thread_client_entry(ULONG thread_input)
199 {
200 UINT            i;
201 UINT            status;
202 NX_TCP_SOCKET   client_socket;
203 NX_SECURE_TLS_SESSION client_tls_session;
204 
205     /* Give IP task and driver a chance to initialize the system.  */
206     tx_thread_sleep(NX_IP_PERIODIC_RATE);
207 
208     /* Set server IP address.  */
209     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
210     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
211 
212     /* First loop test HTTP, second loop test HTTPS.  */
213 
214     /* Wait HTTPS server started.  */
215     while(!https_server_start)
216     {
217         tx_thread_sleep(NX_IP_PERIODIC_RATE);
218     }
219 
220     status =  nx_tcp_socket_create(&client_ip, &client_socket, "client socket",
221                                    NX_WEB_HTTP_TYPE_OF_SERVICE,  NX_WEB_HTTP_FRAGMENT_OPTION, NX_WEB_HTTP_TIME_TO_LIVE,
222                                    1536, NX_NULL, NX_NULL);
223     if (status)
224         error_counter++;
225 
226     status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_WAIT_FOREVER);
227     if (status)
228         error_counter++;
229 
230     for (i = 0; i < loop; i++)
231     {
232         status = nxd_tcp_client_socket_connect(&client_socket, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT, NX_IP_PERIODIC_RATE);
233         if (status)
234             error_counter++;
235 
236         tls_setup_callback(&client_tls_session);
237 
238         status = nx_secure_tls_session_start(&client_tls_session, &client_socket, NX_IP_PERIODIC_RATE);
239 
240         if (status)
241         {
242 
243             nx_secure_tls_session_end(&client_tls_session, NX_NO_WAIT);
244             nx_secure_tls_session_delete(&client_tls_session);
245 
246             nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT);
247         }
248         else
249         {
250             error_counter++;
251         }
252     }
253 
254     nx_tcp_client_socket_unbind(&client_socket);
255     nx_tcp_socket_delete(&client_socket);
256 
257     /* Set the flag.  */
258     https_client_stop = 1;
259 }
260 
261 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)262 void    thread_server_entry(ULONG thread_input)
263 {
264 UINT            status;
265 FX_FILE         my_file;
266 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
267 
268 
269     /* Print out test information banner.  */
270     printf("NetX Test:   Web Secure Reconnect Test.................................");
271 
272     /* Check for earlier error.  */
273     if(error_counter)
274     {
275         printf("ERROR!\n");
276         test_control_return(1);
277     }
278 
279     fx_media_format(&ram_disk,
280                     _fx_ram_driver,               // Driver entry
281                     ram_disk_memory,              // RAM disk memory pointer
282                     media_memory,                 // Media buffer pointer
283                     sizeof(media_memory),         // Media buffer size
284                     "MY_RAM_DISK",                // Volume Name
285                     1,                            // Number of FATs
286                     32,                           // Directory Entries
287                     0,                            // Hidden sectors
288                     256,                          // Total sectors
289                     512,                          // Sector size
290                     8,                            // Sectors per cluster
291                     1,                            // Heads
292                     1);                           // Sectors per track
293 
294     /* Open the RAM disk.  */
295     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
296     status += fx_file_create(&ram_disk, "TEST.TXT");
297     status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
298     status += fx_file_write(&my_file, "https server", 12);
299     status += fx_file_close(&my_file);
300     if(status)
301         error_counter++;
302 
303     /* Give NetX a chance to initialize the system.  */
304     tx_thread_sleep(NX_IP_PERIODIC_RATE);
305 
306     server_port = NX_WEB_HTTPS_SERVER_PORT;
307 
308     /* Create the HTTP Server. */
309     status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
310                                        &server_stack, sizeof(server_stack), &server_pool,
311                                        NX_NULL, NX_NULL);
312     if (status)
313         error_counter++;
314 
315     /* Initialize device certificate (used for all sessions in HTTPS server).  */
316     memset(&certificate, 0, sizeof(certificate));
317     nx_secure_x509_certificate_initialize(&certificate, test_device_cert_der, test_device_cert_der_len, NX_NULL, 0, test_device_cert_key_der, test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
318 
319         /* Setup TLS session data for the TCP server.  */
320     status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
321                                                  crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
322                                                  &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
323     if (status)
324         error_counter++;
325 
326     /* OK to start the HTTP Server.  */
327     status = nx_web_http_server_start(&my_server);
328     if (status)
329         error_counter++;
330 
331     https_server_start = 1;
332 
333     /* Wait HTTPS test finished.  */
334     while (!https_client_stop)
335     {
336         tx_thread_sleep(NX_IP_PERIODIC_RATE);
337     }
338 
339     status = nx_web_http_server_delete(&my_server);
340     if (status)
341         error_counter++;
342 
343     /* Check if there is packet leak. */
344     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
345     {
346         error_counter++;
347     }
348 
349     if(error_counter)
350     {
351         printf("ERROR!\n");
352         test_control_return(1);
353     }
354     else
355     {
356         printf("SUCCESS!\n");
357         test_control_return(0);
358     }
359 }
360 #else
361 #ifdef CTEST
test_application_define(void * first_unused_memory)362 VOID test_application_define(void *first_unused_memory)
363 #else
364 void    netx_web_secure_reconnect_test_application_define(void *first_unused_memory)
365 #endif
366 {
367 
368     /* Print out test information banner.  */
369     printf("NetX Test:   Web Secure Reconnect Test.................................N/A\n");
370 
371     test_control_return(3);
372 }
373 #endif
374 
375