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 25 #include "nx_secure_tls.h" 26 #include "nx_secure_x509.h" 27 #ifdef NX_SECURE_ENABLE_DTLS 28 #include "nx_secure_dtls.h" 29 #endif /* NX_SECURE_ENABLE_DTLS */ 30 31 /**************************************************************************/ 32 /* */ 33 /* FUNCTION RELEASE */ 34 /* */ 35 /* _nx_secure_tls_send_certificate_request PORTABLE C */ 36 /* 6.1 */ 37 /* AUTHOR */ 38 /* */ 39 /* Timothy Stapko, Microsoft Corporation */ 40 /* */ 41 /* DESCRIPTION */ 42 /* */ 43 /* This function populates an NX_PACKET with a CertificateRequest */ 44 /* message which is used to indicate to the remote client that we wish */ 45 /* to do a Client certificate verification. The Client should respond */ 46 /* with an appropriate certificate and CertificateVerify message. */ 47 /* */ 48 /* INPUT */ 49 /* */ 50 /* tls_session TLS control block */ 51 /* send_packet Packet to be filled */ 52 /* */ 53 /* OUTPUT */ 54 /* */ 55 /* status Completion status */ 56 /* */ 57 /* CALLS */ 58 /* */ 59 /* None */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* _nx_secure_tls_server_handshake TLS server state machine */ 64 /* */ 65 /* RELEASE HISTORY */ 66 /* */ 67 /* DATE NAME DESCRIPTION */ 68 /* */ 69 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */ 70 /* 09-30-2020 Timothy Stapko Modified comment(s), */ 71 /* resulting in version 6.1 */ 72 /* */ 73 /**************************************************************************/ _nx_secure_tls_send_certificate_request(NX_SECURE_TLS_SESSION * tls_session,NX_PACKET * send_packet)74UINT _nx_secure_tls_send_certificate_request(NX_SECURE_TLS_SESSION *tls_session, 75 NX_PACKET *send_packet) 76 { 77 UINT length; 78 UCHAR *packet_buffer; 79 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) 80 UINT ext_len_pos = 0; 81 UINT sighash_len = 0; 82 UINT i; 83 UINT sign_alg; 84 #endif 85 86 /* Structure: 87 * | 1 | <Cert types count> | 2 | <Sig algs length> | 88 * | Cert types count | Cert types (1 byte each) | Sig Hash algorithms length | Algorithms (2 bytes each) | 89 */ 90 91 if (((ULONG)(send_packet -> nx_packet_data_end) - (ULONG)(send_packet -> nx_packet_append_ptr)) < 11u) 92 { 93 94 /* Packet buffer is too small. */ 95 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL); 96 } 97 98 packet_buffer = send_packet -> nx_packet_append_ptr; 99 100 /* Use our length as an index into the buffer. */ 101 length = 0; 102 103 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) 104 105 if (tls_session -> nx_secure_tls_1_3) 106 { 107 108 /* Put context here. */ 109 packet_buffer[length] = 0; 110 length++; 111 112 /* Skip the extensions length. */ 113 ext_len_pos = length; 114 length += 2; 115 116 /* Add signature_algorithms extension. */ 117 packet_buffer[length] = (UCHAR)(NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS >> 8); 118 packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS); 119 length += 2; 120 121 /* Skip signature_algorithm length. */ 122 length += 2; 123 } 124 else 125 #endif 126 { 127 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE 128 if (tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count != 0) 129 { 130 /* If ECC is initialized, we support RSA and ECDSA signatures. */ 131 packet_buffer[length] = 0x2; 132 length += 1; 133 134 packet_buffer[length] = NX_SECURE_TLS_CERT_TYPE_RSA_SIGN; 135 length += 1; 136 137 packet_buffer[length] = NX_SECURE_TLS_CERT_TYPE_ECDSA_SIGN; 138 length += 1; 139 } 140 else 141 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */ 142 { 143 144 /* ECC is not initialized, we only support RSA signatures for now... */ 145 packet_buffer[length] = 0x1; 146 length += 1; 147 148 packet_buffer[length] = NX_SECURE_TLS_CERT_TYPE_RSA_SIGN; 149 length += 1; 150 } 151 } 152 153 #if (NX_SECURE_TLS_TLS_1_2_ENABLED) 154 /* TLS 1.2 CertificateRequest contains a list of signature algorithms that 155 is not included in earlier TLS versions. */ 156 #ifdef NX_SECURE_ENABLE_DTLS 157 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 || 158 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2) 159 #else 160 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2) 161 #endif /* NX_SECURE_ENABLE_DTLS */ 162 { 163 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE 164 if (tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count != 0) 165 { 166 167 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) 168 if (tls_session -> nx_secure_tls_1_3) 169 { 170 /* Skip length field. */ 171 length = length + 2; 172 173 /* Add supported signature algorithms. */ 174 for (i = 0; i < tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count; i++) 175 { 176 switch (tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups[i]) 177 { 178 case (NX_CRYPTO_EC_SECP256R1 & 0x00FF): 179 sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256; 180 break; 181 case (NX_CRYPTO_EC_SECP384R1 & 0x00FF): 182 sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA384; 183 break; 184 case (NX_CRYPTO_EC_SECP521R1 & 0x00FF): 185 sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512; 186 break; 187 default: 188 continue; 189 } 190 191 if (((ULONG)(send_packet -> nx_packet_data_end) - (ULONG)(send_packet -> nx_packet_append_ptr)) < (length + 2u)) 192 { 193 194 /* Packet buffer is too small. */ 195 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL); 196 } 197 198 packet_buffer[length] = (UCHAR)(sign_alg >> 8); 199 packet_buffer[length + 1] = (UCHAR)(sign_alg); 200 length = length + 2; 201 sighash_len = sighash_len + 2; 202 } 203 } 204 else 205 #endif 206 { 207 208 /* ECC is initialized. */ 209 /* Length of supported signature algorithms - each entry is 2 bytes so length 210 is number of entries * 2. */ 211 packet_buffer[length] = (UCHAR)0x0; 212 packet_buffer[length + 1] = (UCHAR)0x4; 213 length = length + 2; 214 215 /* Extract the signature algorithms. */ 216 packet_buffer[length] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_RSA_SHA256 >> 8); 217 packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_RSA_SHA256); 218 length = length + 2; 219 220 packet_buffer[length] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256 >> 8); 221 packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256); 222 length = length + 2; 223 } 224 } 225 else 226 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */ 227 { 228 /* Length of supported signature algorithms - each entry is 2 bytes so length 229 is number of entries * 2. */ 230 /* Note: We only support 1 one signature algorithm for now... */ 231 packet_buffer[length] = (UCHAR)0x0; 232 packet_buffer[length + 1] = (UCHAR)0x2; 233 length = length + 2; 234 235 /* Extract the signature algorithms. */ 236 packet_buffer[length] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_RSA_SHA256 >> 8); 237 packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_RSA_SHA256); 238 length = length + 2; 239 } 240 241 } 242 #endif 243 244 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) 245 if (tls_session -> nx_secure_tls_1_3) 246 { 247 248 /* Set extensions length and signature algorithm length. */ 249 packet_buffer[ext_len_pos] = (UCHAR)((sighash_len + 6) >> 8); 250 packet_buffer[ext_len_pos + 1] = (UCHAR)(sighash_len + 6); 251 packet_buffer[ext_len_pos + 4] = (UCHAR)((sighash_len + 2) >> 8); 252 packet_buffer[ext_len_pos + 5] = (UCHAR)(sighash_len + 2); 253 packet_buffer[ext_len_pos + 6] = (UCHAR)(sighash_len >> 8); 254 packet_buffer[ext_len_pos + 7] = (UCHAR)(sighash_len); 255 } 256 else 257 #endif 258 { 259 260 /* Distinguished names length - right now we do not support this. */ 261 packet_buffer[length] = (UCHAR)0x0; 262 packet_buffer[length + 1] = (UCHAR)0x0; 263 length = length + 2; 264 } 265 266 /* The remainder of the message is the Certificate Authorities list. It can be used 267 to select a certificate in a particular authorization chain. */ 268 269 /* Let the caller know how many bytes we wrote. */ 270 send_packet -> nx_packet_append_ptr = send_packet -> nx_packet_append_ptr + (length); 271 send_packet -> nx_packet_length = send_packet -> nx_packet_length + (length); 272 273 return(NX_SUCCESS); 274 } 275 276