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