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