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