1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Secure Component */
17 /** */
18 /** Transport Layer Security (TLS) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SECURE_SOURCE_CODE
24
25 #include "nx_secure_tls.h"
26
27 /**************************************************************************/
28 /* */
29 /* FUNCTION RELEASE */
30 /* */
31 /* _nx_secure_tls_session_end PORTABLE C */
32 /* 6.1 */
33 /* AUTHOR */
34 /* */
35 /* Timothy Stapko, Microsoft Corporation */
36 /* */
37 /* DESCRIPTION */
38 /* */
39 /* This function ends an active TLS session by sending the TLS */
40 /* CloseNotify alert to the remote host, then waiting for the response */
41 /* CloseNotify before returning. */
42 /* */
43 /* INPUT */
44 /* */
45 /* tls_session TLS control block */
46 /* wait_option Indicates how long the caller */
47 /* should wait for the response */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* status Completion status */
52 /* */
53 /* CALLS */
54 /* */
55 /* _nx_secure_tls_packet_allocate Allocate internal TLS packet */
56 /* _nx_secure_tls_send_alert Generate the CloseNotify */
57 /* _nx_secure_tls_send_record Send the CloseNotify */
58 /* _nx_secure_tls_session_reset Clear out the session */
59 /* nx_secure_tls_packet_release Release packet */
60 /* tx_mutex_get Get protection mutex */
61 /* tx_mutex_put Put protection mutex */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* Application Code */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
72 /* 09-30-2020 Timothy Stapko Modified comment(s), */
73 /* supported chained packet, */
74 /* resulting in version 6.1 */
75 /* */
76 /**************************************************************************/
_nx_secure_tls_session_end(NX_SECURE_TLS_SESSION * tls_session,UINT wait_option)77 UINT _nx_secure_tls_session_end(NX_SECURE_TLS_SESSION *tls_session, UINT wait_option)
78 {
79 UINT status;
80 UINT error_return;
81 UINT send_close_notify;
82 NX_PACKET *send_packet;
83 NX_PACKET *tmp_ptr;
84
85 /* Get the protection. */
86 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
87
88 /* Release packets in queue. */
89 while (tls_session -> nx_secure_record_queue_header)
90 {
91 tmp_ptr = tls_session -> nx_secure_record_queue_header;
92 tls_session -> nx_secure_record_queue_header = tmp_ptr -> nx_packet_queue_next;
93 tmp_ptr -> nx_packet_queue_next = NX_NULL;
94 nx_secure_tls_packet_release(tmp_ptr);
95 }
96 if (tls_session -> nx_secure_record_decrypted_packet)
97 {
98 nx_secure_tls_packet_release(tls_session -> nx_secure_record_decrypted_packet);
99 tls_session -> nx_secure_record_decrypted_packet = NX_NULL;
100 }
101
102 /* See if we want to send a CloseNotify alert, or if there was an error, don't send
103 a CloseNotify, just reset the TLS session. */
104 send_close_notify = 0;
105
106 #ifndef NX_SECURE_TLS_SERVER_DISABLED
107 /* Only send a CloseNotify if the handshake was finished. */
108 if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER)
109 {
110 send_close_notify = tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED;
111 }
112 #endif
113
114 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
115 if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_CLIENT)
116 {
117 send_close_notify = tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HANDSHAKE_FINISHED;
118 }
119 #endif
120
121 if (send_close_notify)
122 {
123 /* Release the protection before suspending on nx_packet_allocate. */
124 tx_mutex_put(&_nx_secure_tls_protection);
125
126 /* Allocate a packet for our close-notify alert. */
127 status = _nx_secure_tls_packet_allocate(tls_session, tls_session -> nx_secure_tls_packet_pool, &send_packet, wait_option);
128
129 /* Check for errors in allocating packet. */
130 if (status != NX_SUCCESS)
131 {
132 /* Save the return status before resetting the TLS session. */
133 error_return = status;
134
135 /* Reset the TLS state so this socket can be reused. */
136 status = _nx_secure_tls_session_reset(tls_session);
137
138
139 if(status != NX_SUCCESS)
140 {
141 return(status);
142 }
143
144 return(error_return);
145 }
146
147 /* Get the protection after nx_packet_allocate. */
148 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
149
150 /* A close-notify alert shuts down the TLS session cleanly. */
151 _nx_secure_tls_send_alert(tls_session, send_packet, NX_SECURE_TLS_ALERT_CLOSE_NOTIFY, NX_SECURE_TLS_ALERT_LEVEL_WARNING);
152
153 /* Finally, send the alert record to the remote host. */
154 status = _nx_secure_tls_send_record(tls_session, send_packet, NX_SECURE_TLS_ALERT, wait_option);
155
156 if (status)
157 {
158 /* Release the packet on send errors. */
159 nx_secure_tls_packet_release(send_packet);
160
161 /* Release the protection. */
162 tx_mutex_put(&_nx_secure_tls_protection);
163
164 /* Save the return status before resetting the TLS session. */
165 error_return = status;
166
167 /* Reset the TLS state so this socket can be reused. */
168 status = _nx_secure_tls_session_reset(tls_session);
169
170
171 if(status != NX_SUCCESS)
172 {
173 return(status);
174 }
175
176 return(error_return);
177 }
178 }
179
180 /* Release the protection. */
181 tx_mutex_put(&_nx_secure_tls_protection);
182
183 /* Reset the TLS state so this socket can be reused. */
184 status = _nx_secure_tls_session_reset(tls_session);
185
186 return(status);
187 }
188
189