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