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