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