1 #include "tls_test_frame.h"
2 
3 /* Global demo emaphore. */
4 extern TLS_TEST_SEMAPHORE* demo_semaphore;
5 
6 /* Define the ThreadX and NetX object control blocks...  */
7 NX_PACKET_POOL    pool_0;
8 NX_IP             ip_0;
9 
10 NX_TCP_SOCKET tcp_socket;
11 NX_SECURE_TLS_SESSION tls_session;
12 NX_SECURE_X509_CERT certificate;
13 NX_SECURE_X509_CERT remote_certificate, remote_issuer;
14 NX_SECURE_X509_CERT trusted_certificate;
15 
16 UCHAR tls_packet_buffer[4000];
17 
18 /* Define the IP thread's stack area.  */
19 ULONG             ip_thread_stack[3 * 1024 / sizeof(ULONG)];
20 
21 /* Define packet pool for the demonstration.  */
22 #define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 32)
23 ULONG             packet_pool_area[NX_PACKET_POOL_SIZE/sizeof(ULONG) + 64 / sizeof(ULONG)];
24 
25 /* Define the ARP cache area.  */
26 ULONG             arp_space_area[512 / sizeof(ULONG)];
27 
28 /* Define the demo thread.  */
29 ULONG             demo_thread_stack[6 * 1024 / sizeof(ULONG)];
30 TX_THREAD         demo_thread;
31 void              server_thread_entry(ULONG thread_input);
32 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
33 UCHAR remote_cert_buffer[2000];
34 UCHAR remote_issuer_buffer[2000];
35 NX_SECURE_X509_CERT device_issuer_certificate;
36 NX_SECURE_X509_CERT remote_certificate, remote_issuer;
37 CHAR crypto_metadata[30000];
38 /*
39  * max_total_metadata_size = 8928 :
40  *  max_public_cipher_metasize (sizeof(NX_ECJPAKE)) = 2688
41  *  2 * max_session_cipher_metadata_size (2 * sizeof(NX_AES)) = 2 * 540 = 1080
42  *  max_hash_mac_metadata_size (sizeof(NX_CRYPTO_RSA)) = 2608
43  *  max_handshake_hash_metadata_size (sizeof(NX_MD5) + sizeof(NX_SHA1) + sizeof(NX_SHA256)) = 88 + 412 + 360 = 860
44  *  max_handshake_hash_scratch_size (sizeof(NX_MD5) + sizeof(NX_SHA1)) = 500
45  *  max_tls_prf_metadata_size (sizeof(NX_SECURE_TLS_PRF)) = 1192
46  */
47 
48 #include "ica_test_device_cert.c"
49 #include "ica_test_ica_cert.c"
50 
51 CHAR *html_data =  "HTTP/1.1 200 OK\r\n" \
52         "Date: Fri, 15 Sep 2016 23:59:59 GMT\r\n" \
53         "Content-Type: text/html\r\n" \
54         "Content-Length: 200\r\n\r\n" \
55         "<html>\r\n"\
56         "<body>\r\n"\
57         "<b>Hello NetX Secure User!</b>\r\n"\
58         "This is a simple webpage\r\n"\
59         "served up using NetX Secure!\r\n"\
60         "</body>\r\n"\
61         "</html>\r\n";
62 
63 /* Define the pointer of current instance control block. */
64 static TLS_TEST_INSTANCE* demo_instance_ptr;
65 
66 /* Define external references.  */
67 VOID    _nx_pcap_network_driver(NX_IP_DRIVER *driver_req_ptr);
68 
69 /*  Instance one test entry. */
demo_server_entry(TLS_TEST_INSTANCE * instance_ptr)70 INT demo_server_entry(TLS_TEST_INSTANCE* instance_ptr)
71 {
72 
73 #ifndef NX_SECURE_TLS_SERVER_DISABLED
74 
75     /* Get instance pointer. */
76     demo_instance_ptr = instance_ptr;
77 
78     /* Enter the ThreadX kernel.  */
79     tx_kernel_enter();
80 
81 #else /* ifndef NX_SECURE_TLS_SERVER_DISABLED */
82 
83     exit(TLS_TEST_NOT_AVAILABLE);
84 
85 #endif /* ifndef NX_SECURE_TLS_SERVER_DISABLED */
86 
87 }
88 
89 /* Define what the initial system looks like.  */
tx_application_define(void * first_unused_memory)90 void    tx_application_define(void *first_unused_memory)
91 {
92     ULONG gateway_ipv4_address;
93     UINT  status;
94 
95     /* Initialize the NetX system.  */
96     nx_system_initialize();
97 
98     /* Create a packet pool.  */
99     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536,  (ULONG*)(((int)packet_pool_area + 64) & ~63) , NX_PACKET_POOL_SIZE);
100     show_error_message_if_fail( status == NX_SUCCESS);
101 
102     /* Create an IP instance.  */
103     status = nx_ip_create(&ip_0, "NetX IP Instance 0", TLS_TEST_IP_ADDRESS_NUMBER, 0xFFFFFF00UL, &pool_0, _nx_pcap_network_driver, (UCHAR*)ip_thread_stack, sizeof(ip_thread_stack), 1);
104 print_error_message( "ip address number: %lu", TLS_TEST_IP_ADDRESS_NUMBER);
105     show_error_message_if_fail( status == NX_SUCCESS);
106 
107     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
108     status =  nx_arp_enable(&ip_0, (void *)arp_space_area, sizeof(arp_space_area));
109     show_error_message_if_fail( status == NX_SUCCESS);
110 
111     /* Enable TCP traffic.  */
112     status =  nx_tcp_enable(&ip_0);
113     show_error_message_if_fail( status == NX_SUCCESS);
114 
115     /* Enable UDP traffic.  */
116     status =  nx_udp_enable(&ip_0);
117     show_error_message_if_fail( status == NX_SUCCESS);
118 
119     /* Enable ICMP.  */
120     status =  nx_icmp_enable(&ip_0);
121     show_error_message_if_fail( status == NX_SUCCESS);
122 
123     status =  nx_ip_fragment_enable(&ip_0);
124     show_error_message_if_fail( status == NX_SUCCESS);
125 
126     tx_thread_create(&demo_thread, "demo thread", server_thread_entry, 0, demo_thread_stack, sizeof(demo_thread_stack), 16, 16, 4, TX_AUTO_START);
127 }
128 
129 /* TLS Server example application thread. */
server_thread_entry(ULONG thread_input)130 void server_thread_entry(ULONG thread_input)
131 {
132     INT i = 0, status = 0;
133     ULONG actual_status;
134     NX_PACKET *receive_packet;
135     NX_PACKET *send_packet;
136     UCHAR receive_buffer[100];
137     ULONG bytes;
138 
139     /* Ensure the IP instance has been initialized.  */
140     status =  nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE);
141     show_error_message_if_fail( NX_SUCCESS == status);
142 
143     /* Create a socket.  */
144     status =  nx_tcp_socket_create(&ip_0, &tcp_socket, "Server Socket",
145                                    NX_IP_NORMAL, NX_FRAGMENT_OKAY /*NX_DONT_FRAGMENT*/, NX_IP_TIME_TO_LIVE, 8192,
146                                    NX_NULL, NX_NULL);
147     show_error_message_if_fail( NX_SUCCESS == status);
148 
149     status =  nx_secure_tls_session_create(&tls_session,
150                                        &nx_crypto_tls_ciphers,
151                                        crypto_metadata,
152                                        sizeof(crypto_metadata));
153     show_error_message_if_fail( NX_SUCCESS == status);
154 
155     /* Allocate space for packet reassembly. */
156     status = nx_secure_tls_session_packet_buffer_set(&tls_session, tls_packet_buffer, sizeof(tls_packet_buffer));
157     show_error_message_if_fail( NX_SUCCESS == status);
158 
159     // Initialize our certificates
160     nx_secure_tls_remote_certificate_allocate(&tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
161     nx_secure_tls_remote_certificate_allocate(&tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
162 
163     memset(&certificate, 0, sizeof(certificate));
164     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);
165     nx_secure_tls_local_certificate_add(&tls_session, &certificate);
166 
167     // Initialize the Intermediate CA certificate - it does not have a private RSA key
168     nx_secure_x509_certificate_initialize(&device_issuer_certificate, ica_cert_der, ica_cert_der_len, NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
169     nx_secure_tls_local_certificate_add(&tls_session, &device_issuer_certificate);
170 
171     /* Setup this thread to listen.  */
172     status =  nx_tcp_server_socket_listen(&ip_0, DEVICE_SERVER_PORT, &tcp_socket, 5, NX_NULL);
173     show_error_message_if_fail( NX_SUCCESS == status);
174 
175     for ( ; i < 3; i++)
176     {
177         /* Post semaphore before accept sockets. */
178         print_error_message("Connection %d: server is prepared. Post the semaphore.\n", i);
179         tls_test_semaphore_post(demo_semaphore);
180 
181         /* Accept a client socket connection.  */
182         print_error_message("Connection %d: wait for connections.\n", i);
183         status = nx_tcp_server_socket_accept(&tcp_socket, NX_WAIT_FOREVER);
184         print_error_message("Connection %d: server accept.\n", i);
185         exit_if_fail( NX_SUCCESS == status, 1);
186 
187         /* Start the TLS Session now that we have a connected socket. */
188         status = nx_secure_tls_session_start(&tls_session, &tcp_socket, NX_WAIT_FOREVER);
189         exit_if_fail( NX_SUCCESS == status, 2);
190 
191         /* Receive the HTTP request, and print it out. */
192         status = nx_secure_tls_session_receive(&tls_session, &receive_packet, NX_WAIT_FOREVER);
193         exit_if_fail( NX_SUCCESS == status, 3);
194 
195         /* Show received data. */
196         nx_packet_data_extract_offset(receive_packet, 0, receive_buffer, 100, &bytes);
197         receive_buffer[bytes] = 0;
198         print_error_message("Received data: %s\n", receive_buffer);
199 
200         /* Allocate a return packet and send our HTML data back to the client. */
201         status = nx_secure_tls_packet_allocate(&tls_session, &pool_0, &send_packet, NX_WAIT_FOREVER);
202         exit_if_fail( NX_SUCCESS == status, 4);
203 
204         /* Send the prepared html page. */
205         status = nx_packet_data_append(send_packet, html_data, strlen(html_data), &pool_0, NX_WAIT_FOREVER);
206         exit_if_fail( NX_SUCCESS == status, 5);
207 
208         /* TLS send the HTML/HTTPS data back to the client. */
209         status = nx_secure_tls_session_send(&tls_session, send_packet, NX_IP_PERIODIC_RATE);
210         /* Exit the test process directly without release packet. */
211         exit_if_fail( NX_SUCCESS == status, 6);
212 
213         /* End the TLS session. This is required to properly shut down the TLS connection. */
214         status = nx_secure_tls_session_end(&tls_session, NX_IP_PERIODIC_RATE * 3);
215         /*exit_if_fail( NX_SUCCESS == status, 7);*/
216 
217         /* Disconnect the TCP socket, closing the connection. */
218         status =  nx_tcp_socket_disconnect(&tcp_socket, NX_IP_PERIODIC_RATE * 3);
219         /*exit_if_fail( NX_SUCCESS == status, 8);*/
220 
221         /* Unaccept the server socket.  */
222         status =  nx_tcp_server_socket_unaccept(&tcp_socket);
223         exit_if_fail( NX_SUCCESS == status, 9);
224 
225         print_error_message("Connection %d: server unaccept, sleeping...\n", i);
226         /*tx_thread_sleep( 500);*/
227 
228         /* Setup server socket for listening again.  */
229         status =  nx_tcp_server_socket_relisten(&ip_0, DEVICE_SERVER_PORT, &tcp_socket);
230         exit_if_fail( NX_SUCCESS == status, 10);
231     }
232     exit(0);
233 }
234