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 #include "nx_secure_x509.h"
26 #ifdef NX_SECURE_ENABLE_DTLS
27 #include "nx_secure_dtls.h"
28 #endif /* NX_SECURE_ENABLE_DTLS */
29 
30 /**************************************************************************/
31 /*                                                                        */
32 /*  FUNCTION                                               RELEASE        */
33 /*                                                                        */
34 /*    _nx_secure_tls_process_certificate_request          PORTABLE C      */
35 /*                                                           6.2.1        */
36 /*  AUTHOR                                                                */
37 /*                                                                        */
38 /*    Timothy Stapko, Microsoft Corporation                               */
39 /*                                                                        */
40 /*  DESCRIPTION                                                           */
41 /*                                                                        */
42 /*    This function processes an incoming TLS Certificate request         */
43 /*    message, typically sent by a TLS Server to request a client         */
44 /*    certificate for authentication.                                     */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    tls_session                           TLS control block             */
49 /*    packet_buffer                         Pointer to message data       */
50 /*    message_length                        Length of message data (bytes)*/
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                Completion status             */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _nx_secure_x509_local_device_certificate_get                        */
59 /*                                          Get the local certificate     */
60 /*                                                                        */
61 /*  CALLED BY                                                             */
62 /*                                                                        */
63 /*    _nx_secure_dtls_client_handshake      DTLS client state machine     */
64 /*    _nx_secure_tls_client_handshake       TLS client state machine      */
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 /*  07-29-2022     Yuxin Zhou               Modified comment(s), improved */
74 /*                                            buffer length verification, */
75 /*                                            resulting in version 6.1.12 */
76 /*  03-08-2023     Yanwu Cai                Modified comment(s),          */
77 /*                                            fixed compiler errors when  */
78 /*                                            x509 is disabled,           */
79 /*                                            resulting in version 6.2.1  */
80 /*                                                                        */
81 /**************************************************************************/
_nx_secure_tls_process_certificate_request(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length)82 UINT _nx_secure_tls_process_certificate_request(NX_SECURE_TLS_SESSION *tls_session,
83                                                 UCHAR *packet_buffer, UINT message_length)
84 {
85 #ifndef NX_SECURE_DISABLE_X509
86 UINT  length;
87 UINT  cert_types_length;
88 UCHAR cert_type;
89 UINT  i;
90 NX_SECURE_X509_CERT *local_certificate = NX_NULL;
91 UCHAR expected_cert_type = 0;
92 UINT  status;
93 
94 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
95 UINT sign_algs_length;
96 UINT sign_alg;
97 UINT expected_sign_alg = 0;
98 #endif
99 
100 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
101 UINT extension_total_length;
102 UINT extension_length;
103 UINT extension_type;
104 #endif
105 
106     /* Structure:
107      * |       1            |    <Cert types count>    |             2              |  <Sig algs length>        |
108      * |  Cert types count  | Cert types (1 byte each) | Sig Hash algorithms length | Algorithms (2 bytes each) |
109      */
110 
111     /* Use our length as an index into the buffer. */
112     length = 0;
113 
114     /* Get the local certificate. */
115     if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate != NX_NULL)
116     {
117         local_certificate = tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate;
118     }
119     else
120     {
121         /* Get reference to local device certificate. NX_NULL is passed for name to get default entry. */
122         status = _nx_secure_x509_local_device_certificate_get(&tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store,
123                                                                 NX_NULL, &local_certificate);
124         if (status != NX_SUCCESS)
125         {
126             local_certificate = NX_NULL;
127         }
128     }
129 
130     if (local_certificate != NX_NULL)
131     {
132 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
133         if (tls_session -> nx_secure_tls_1_3)
134         {
135             tls_session -> nx_secure_tls_signature_algorithm = 0;
136 
137             /* TLS1.3 uses RSASSA-PSS instead of RSASSA-PKCS. RSASSA-PSS is not supported now. */
138             if (local_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_RSA)
139             {
140                 return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_TYPE);
141             }
142 
143             /* In TLS 1.3, the signing curve is constrained.  */
144             switch (local_certificate -> nx_secure_x509_private_key.ec_private_key.nx_secure_ec_named_curve)
145             {
146             case NX_CRYPTO_EC_SECP256R1:
147                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256;
148                 break;
149             case NX_CRYPTO_EC_SECP384R1:
150                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA384;
151                 break;
152             case NX_CRYPTO_EC_SECP521R1:
153                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512;
154                 break;
155             default:
156                 return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG);
157             }
158         }
159         else
160 #endif
161         {
162             if (local_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_RSA)
163             {
164                 expected_cert_type = NX_SECURE_TLS_CERT_TYPE_RSA_SIGN;
165 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
166                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_RSA_SHA256;
167 #endif
168             }
169 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
170             else if (local_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
171             {
172                 expected_cert_type = NX_SECURE_TLS_CERT_TYPE_ECDSA_SIGN;
173 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
174                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256;
175 #endif
176             }
177 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
178         }
179     }
180 
181 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
182     /*
183       struct {
184           opaque certificate_request_context<0..2^8-1>;
185           Extension extensions<2..2^16-1>;
186       } CertificateRequest;
187     */
188     if (tls_session -> nx_secure_tls_1_3)
189     {
190 
191         if (message_length < 1 || (UINT)packet_buffer[0] + 3 > message_length)
192         {
193             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
194         }
195 
196         /* Skip certificate request context.  */
197         length = length + 1 + packet_buffer[length];
198 
199         extension_total_length = (UINT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
200         length += 2;
201 
202         /* Make sure what we extracted makes sense. */
203         if ((length + extension_total_length) > message_length)
204         {
205             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
206         }
207 
208         /* Find SignatureAlgorithms extension.  */
209         /* Note: Other extensions will be processed in the future.  */
210         while (length < message_length)
211         {
212             extension_type = (UINT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
213             length += 2;
214 
215             extension_length = (UINT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
216             length += 2;
217 
218             if (extension_type == NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS)
219             {
220                 break;
221             }
222 
223             length += extension_length;
224         }
225 
226         if (length >= message_length)
227         {
228             return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG);
229         }
230     }
231     else
232 #endif
233     {
234 
235         /* Extract the count of certificate types from the incoming data. */
236         cert_types_length = packet_buffer[length];
237         length += 1;
238 
239         /* Make sure what we extracted makes sense. */
240         if (cert_types_length + 1 > message_length)
241         {
242             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
243         }
244 
245 
246         cert_type = NX_SECURE_TLS_CERT_TYPE_NONE;
247         for (i = 0; i < cert_types_length; ++i)
248         {
249             if (packet_buffer[length] == expected_cert_type)
250             {
251                 /* We found a type we support. */
252                 cert_type = packet_buffer[length];
253             }
254             length += 1;
255         }
256 
257         /* Make sure our certificate type is one we support. */
258         if (cert_type != expected_cert_type)
259         {
260             return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_TYPE);
261         }
262     }
263 
264 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
265     /* TLS 1.2 CertificateRequest contains a list of signature algorithms that
266        is not included in earlier TLS versions. */
267 #ifdef NX_SECURE_ENABLE_DTLS
268     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
269         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
270 #else
271     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
272 #endif /* NX_SECURE_ENABLE_DTLS */
273     {
274         if (length + 2 > message_length)
275         {
276             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
277         }
278 
279         /* Extract the count of algorithms from the incoming data. */
280         sign_algs_length = (UINT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
281         length = length + 2;
282 
283         /* Make sure what we extracted makes sense. */
284         if ((length + sign_algs_length) > message_length)
285         {
286             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
287         }
288 
289         /* Extract the signature algorithms. */
290         sign_alg = NX_SECURE_TLS_HASH_ALGORITHM_NONE;
291         for (i = 0; i < sign_algs_length; i += 2)
292         {
293             /* Look for a type we support. */
294             if ((UINT)((packet_buffer[length] << 8) + packet_buffer[length + 1]) == expected_sign_alg)
295             {
296                 sign_alg = (UINT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
297                 break;
298             }
299             length = length + 2;
300         }
301 
302         /* Make sure we are using the right signature algorithm! */
303         if (sign_alg != expected_sign_alg)
304         {
305             return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG);
306         }
307 
308 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
309         if (tls_session -> nx_secure_tls_1_3)
310         {
311             tls_session -> nx_secure_tls_signature_algorithm = sign_alg;
312         }
313 #endif
314     }
315 #endif
316 
317     /* The remainder of the message is the Certificate Authorities list. It can be used
318        to select a certificate in a particular authorization chain. In general, if there
319        is only one device certificate we will send that one and if the server doesn't like
320        it the connection will be dropped. */
321 
322 #ifdef NX_SECURE_TLS_CLIENT_DISABLED
323     /* If TLS Client is disabled and we have processed a CertificateRequest, something is wrong... */
324     tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_ERROR;
325 
326     return(NX_SECURE_TLS_INVALID_STATE);
327 #else
328     /* Set our state to indicate we received a certificate request. */
329     tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_CERTIFICATE_REQUEST;
330 
331     return(NX_SUCCESS);
332 #endif
333 #else
334     NX_PARAMETER_NOT_USED(tls_session);
335     NX_PARAMETER_NOT_USED(packet_buffer);
336     NX_PARAMETER_NOT_USED(message_length);
337 
338     return(NX_NOT_SUPPORTED);
339 #endif /* NX_SECURE_DISABLE_X509 */
340 }
341 
342