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 #ifdef NX_SECURE_ENABLE_DTLS
26 #include "nx_secure_dtls.h"
27 #endif /* NX_SECURE_ENABLE_DTLS */
28
29 /* This table is used to determine the legacy TLS versions currently enabled and supported. */
30 static const NX_SECURE_TLS_VERSIONS nx_secure_tls_supported_versions[] =
31 {
32 {NX_SECURE_TLS_VERSION_SSL_3_0, NX_SECURE_TLS_SSL_3_0_ENABLED}, /* SSLv3 */
33 {NX_SECURE_TLS_VERSION_TLS_1_0, NX_SECURE_TLS_TLS_1_0_ENABLED}, /* TLS 1.0 */
34 {NX_SECURE_TLS_VERSION_TLS_1_1, NX_SECURE_TLS_TLS_1_1_ENABLED}, /* TLS 1.1 */
35 {NX_SECURE_TLS_VERSION_TLS_1_2, NX_SECURE_TLS_TLS_1_2_ENABLED}, /* TLS 1.2 */
36 /* This array contains legacy versions only so TLS 1.3 is not included. */
37 };
38
39 #ifdef NX_SECURE_ENABLE_DTLS
40 /* This table is used to determine the DTLS versions currently enabled and supported. */
41 static const NX_SECURE_TLS_VERSIONS nx_secure_dtls_supported_versions[] =
42 {
43 {NX_SECURE_DTLS_VERSION_1_0, NX_SECURE_TLS_TLS_1_1_ENABLED}, /* DTLS 1.0 */
44 {NX_SECURE_DTLS_VERSION_1_2, NX_SECURE_TLS_TLS_1_2_ENABLED}, /* DTLS 1.2 */
45 };
46 #endif /* NX_SECURE_ENABLE_DTLS */
47
48 /* Supported version list for TLS and DTLS. */
49 NX_SECURE_VERSIONS_LIST nx_secure_supported_versions_list[] =
50 {
51 {nx_secure_tls_supported_versions, sizeof(nx_secure_tls_supported_versions) / sizeof(NX_SECURE_TLS_VERSIONS)},
52 #ifdef NX_SECURE_ENABLE_DTLS
53 {nx_secure_dtls_supported_versions, sizeof(nx_secure_dtls_supported_versions) / sizeof(NX_SECURE_TLS_VERSIONS)},
54 #endif /* NX_SECURE_ENABLE_DTLS */
55 };
56
57
58 /**************************************************************************/
59 /* */
60 /* FUNCTION RELEASE */
61 /* */
62 /* _nx_secure_tls_check_protocol_version PORTABLE C */
63 /* 6.1 */
64 /* AUTHOR */
65 /* */
66 /* Timothy Stapko, Microsoft Corporation */
67 /* */
68 /* DESCRIPTION */
69 /* */
70 /* This function checks the protocol version in received TLS/DTLS */
71 /* headers against the established TLS/DTLS session version. */
72 /* */
73 /* The function also uses a compile-time constant table to see if the */
74 /* version provided in the initial Hello messages is currently */
75 /* supported and enabled in the TLS/DTLS stack. If the version is not */
76 /* recognized or not supported, an error is returned. */
77 /* */
78 /* INPUT */
79 /* */
80 /* tls_session TLS session */
81 /* protocol_version Received TLS version */
82 /* id TLS or DTLS */
83 /* */
84 /* OUTPUT */
85 /* */
86 /* status Enabled status of version */
87 /* */
88 /* CALLS */
89 /* */
90 /* None */
91 /* */
92 /* CALLED BY */
93 /* */
94 /* _nx_secure_dtls_process_header Process record header */
95 /* _nx_secure_tls_process_clienthello Process ClientHello */
96 /* _nx_secure_tls_process_header Process record header */
97 /* _nx_secure_tls_process_serverhello Process ServerHello */
98 /* */
99 /* RELEASE HISTORY */
100 /* */
101 /* DATE NAME DESCRIPTION */
102 /* */
103 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
104 /* 09-30-2020 Timothy Stapko Modified comment(s), */
105 /* resulting in version 6.1 */
106 /* */
107 /**************************************************************************/
_nx_secure_tls_check_protocol_version(NX_SECURE_TLS_SESSION * tls_session,USHORT protocol_version,UINT id)108 UINT _nx_secure_tls_check_protocol_version(NX_SECURE_TLS_SESSION *tls_session,
109 USHORT protocol_version, UINT id)
110 {
111 UINT i;
112
113 /* See if this is an established TLS session with a negotiated TLS version. */
114 if (tls_session -> nx_secure_tls_protocol_version != 0)
115 {
116 /* If the session already has a protocol version, it means the version was already
117 * determined, and if we get a different version in a received record, we have a problem. */
118 if (tls_session -> nx_secure_tls_protocol_version == protocol_version)
119 {
120 /* Version is good, return success. */
121 return(NX_SUCCESS);
122 }
123
124 #if !defined(NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE) && !defined(NX_SECURE_TLS_CLIENT_DISABLED)
125 if ((tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER) ||
126 (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_IDLE))
127 #endif /* !defined(NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE) && !defined(NX_SECURE_TLS_CLIENT_DISABLED) */
128 {
129
130 /* We have an established session, but the incoming version does not match! This is
131 a fatal error. */
132 return(NX_SECURE_TLS_PROTOCOL_VERSION_CHANGED);
133 }
134 }
135
136 /* See if the application has overridden the protocol version. */
137 if (tls_session -> nx_secure_tls_protocol_version_override != 0)
138 {
139 /* If the override is euqal to the supplied version, we're all good. */
140 if (tls_session -> nx_secure_tls_protocol_version_override == protocol_version)
141 {
142 return(NX_SUCCESS);
143 }
144
145 /* Supplied version doesn't match the override, allow the stack to re-negotiate
146 to the selected version by returning "unsupported version" even if we do support
147 the supplied version. */
148 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
149 }
150
151 /* Loop through the supported versions to see if the passed-in version is one that is enabled. */
152 for (i = 0; i < nx_secure_supported_versions_list[id].nx_secure_versions_list_count; ++i)
153 {
154 if (protocol_version == nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version)
155 {
156 /* We have a match. See if it is supported. */
157 if (nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_is_supported)
158 {
159 /* Supported version. Return success. */
160 return(NX_SUCCESS);
161 }
162 else
163 {
164 /* Recognized the version, but it is not enabled or supported. */
165 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
166 }
167 }
168 }
169
170 /* This error indicates an incorrect TLS record or possible attack. */
171 return(NX_SECURE_TLS_UNKNOWN_TLS_VERSION);
172 }
173
174