1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Secure Component                                                 */
16 /**                                                                       */
17 /**    Transport Layer Security (TLS)                                     */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_SECURE_SOURCE_CODE
23 
24 #include "nx_secure_tls.h"
25 
26 /* We need to access the supported versions table located in nx_secure_tls_check_protocol_version.c. */
27 extern const NX_SECURE_VERSIONS_LIST nx_secure_supported_versions_list[];
28 
29 /**************************************************************************/
30 /*                                                                        */
31 /*  FUNCTION                                               RELEASE        */
32 /*                                                                        */
33 /*    _nx_secure_tls_newest_supported_version             PORTABLE C      */
34 /*                                                           6.1          */
35 /*  AUTHOR                                                                */
36 /*                                                                        */
37 /*    Timothy Stapko, Microsoft Corporation                               */
38 /*                                                                        */
39 /*  DESCRIPTION                                                           */
40 /*                                                                        */
41 /*    Return the newest currently supported and enabled TLS/DTLS protocol */
42 /*    version. This enables the backward-compatible TLS/DTLS handshake    */
43 /*    and forces the upgrade to the latest supported TLS/DTLS version.    */
44 /*                                                                        */
45 /*  INPUT                                                                 */
46 /*                                                                        */
47 /*    session_ptr                           TLS session                   */
48 /*    protocol_version                      Pointer to version variable   */
49 /*    id                                    TLS or DTLS                   */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    None                                                                */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    None                                                                */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    _nx_secure_dtls_send_clienthello      Send ClientHello              */
62 /*    _nx_secure_tls_process_clienthello    Process ClientHello           */
63 /*    _nx_secure_tls_send_clienthello       Send ClientHello              */
64 /*    _nx_secure_tls_protocol_version_get   Get current TLS version to use*/
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
71 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
72 /*                                            resulting in version 6.1    */
73 /*                                                                        */
74 /**************************************************************************/
_nx_secure_tls_newest_supported_version(NX_SECURE_TLS_SESSION * session_ptr,USHORT * protocol_version,UINT id)75 VOID _nx_secure_tls_newest_supported_version(NX_SECURE_TLS_SESSION *session_ptr,
76                                              USHORT *protocol_version, UINT id)
77 {
78 INT i;
79 
80     NX_PARAMETER_NOT_USED(session_ptr);
81 
82 #ifndef NX_SECURE_TLS_SERVER_DISABLED
83     if(session_ptr -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER &&
84        session_ptr -> nx_secure_tls_protocol_version_override != 0)
85     {
86         /* If this is a server and the user has overriden the protocol version,
87            THAT version is now the higest supported. */
88         (*protocol_version) = session_ptr -> nx_secure_tls_protocol_version_override;
89         return;
90     }
91 #endif
92     /* Table is in order of oldest to newest, so walk backward to get
93      * the newest version we support. */
94     for (i = (INT)(nx_secure_supported_versions_list[id].nx_secure_versions_list_count - 1); i >= 0; --i)
95     {
96         /* If the version is supported, return it. */
97         if (nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_is_supported)
98         {
99             (*protocol_version) = nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version;
100             return;
101         }
102     }
103 
104     /* If we get here, no versions of TLS have been enabled. Set protocol to 0 to indicate failure. */
105     (*protocol_version) = 0x0;
106     return;
107 }
108 
109 /**************************************************************************/
110 /*                                                                        */
111 /*  FUNCTION                                               RELEASE        */
112 /*                                                                        */
113 /*    _nx_secure_tls_highest_supported_version_negotiate     PORTABLE C   */
114 /*                                                           6.1          */
115 /*  AUTHOR                                                                */
116 /*                                                                        */
117 /*    Timothy Stapko, Microsoft Corporation                               */
118 /*                                                                        */
119 /*  DESCRIPTION                                                           */
120 /*                                                                        */
121 /*    Negotiate the highested supported and enabled TLS/DTLS protocol     */
122 /*    version, if the protocol version in clientHello is not supported    */
123 /*    by the server.                                                      */
124 /*                                                                        */
125 /*  INPUT                                                                 */
126 /*                                                                        */
127 /*    session_ptr                           TLS session                   */
128 /*    protocol_version                      Pointer to version variable   */
129 /*    id                                    TLS or DTLS                   */
130 /*                                                                        */
131 /*  OUTPUT                                                                */
132 /*                                                                        */
133 /*    None                                                                */
134 /*                                                                        */
135 /*  CALLS                                                                 */
136 /*                                                                        */
137 /*    None                                                                */
138 /*                                                                        */
139 /*  CALLED BY                                                             */
140 /*                                                                        */
141 /*    _nx_secure_dtls_process_clienthello   Send ClientHello              */
142 /*    _nx_secure_tls_process_clienthello    Process ClientHello           */
143 /*                                                                        */
144 /*  RELEASE HISTORY                                                       */
145 /*                                                                        */
146 /*    DATE              NAME                      DESCRIPTION             */
147 /*                                                                        */
148 /*  09-30-2020     Timothy Stapko           Initial Version 6.1           */
149 /*                                                                        */
150 /**************************************************************************/
_nx_secure_tls_highest_supported_version_negotiate(NX_SECURE_TLS_SESSION * session_ptr,USHORT * protocol_version,UINT id)151 void _nx_secure_tls_highest_supported_version_negotiate(NX_SECURE_TLS_SESSION *session_ptr,
152                                              USHORT *protocol_version, UINT id)
153 {
154 INT i;
155 USHORT highest_version = 0;
156 USHORT lowest_version = 0xFF;
157 USHORT highest_version_not_greater_than_client_version = 0;
158 
159     NX_PARAMETER_NOT_USED(session_ptr);
160 
161 #ifndef NX_SECURE_TLS_SERVER_DISABLED
162     if(session_ptr -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER &&
163        session_ptr -> nx_secure_tls_negotiated_highest_protocol_version != 0)
164     {
165         /* If this is a server and the user has the negotiated highest version,
166            return it directly. */
167         (*protocol_version) = session_ptr -> nx_secure_tls_negotiated_highest_protocol_version;
168         return;
169     }
170 #endif
171 
172     /* Find the highest and the lowest supported server version. */
173 
174     for (i = (INT)(nx_secure_supported_versions_list[id].nx_secure_versions_list_count - 1); i >= 0; --i)
175     {
176         /* If the version is supported, return it. */
177         if (nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_is_supported)
178         {
179             if (highest_version < nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version)
180             {
181                 highest_version = nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version;
182             }
183 
184             if (lowest_version > nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version)
185             {
186                 lowest_version = nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version;
187             }
188 
189             if (!highest_version_not_greater_than_client_version &&
190                 (*protocol_version) >= nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version)
191             {
192                 highest_version_not_greater_than_client_version = nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version;
193             }
194 
195         }
196     }
197 
198     /* No versions of TLS have been enabled. Set protocol to 0 to indicate failure. */
199     if (highest_version == 0)
200     {
201         (*protocol_version) = 0;
202         session_ptr -> nx_secure_tls_negotiated_highest_protocol_version = 0;
203         return;
204     }
205 
206     /* According to RFC 5246 E.1,
207        if protocol_version > highest_version, set protocol_version to highest_version to indicate to send "server_hello" with highest_version;
208        if lowest_version < protocol_version < highest_version, set protocol_version to the highest server version not greater than protocol_version;
209        if protocol_version < lowest_version, set protocol_version to 0 to indicate to send a "protocol_version" alert message.
210     */
211 
212     if ((*protocol_version) > highest_version)
213     {
214         (*protocol_version) = highest_version;
215     }
216     else
217     {
218         if ((*protocol_version) < highest_version && (*protocol_version) > lowest_version)
219         {
220             (*protocol_version) = highest_version_not_greater_than_client_version;
221         }
222         else
223         {
224             (*protocol_version) = 0;
225         }
226     }
227 
228     session_ptr -> nx_secure_tls_negotiated_highest_protocol_version = (*protocol_version);
229     return;
230 }
231 
232 
233 
234