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