sslinfo.c (25407B)
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 #include "pk11pub.h" 6 #include "ssl.h" 7 #include "sslimpl.h" 8 #include "sslproto.h" 9 #include "tls13hkdf.h" 10 #include "tls13psk.h" 11 #include "tls13subcerts.h" 12 13 SECStatus 14 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) 15 { 16 sslSocket *ss; 17 SSLChannelInfo inf; 18 sslSessionID *sid; 19 20 /* Check if we can properly return the length of data written and that 21 * we're not asked to return more information than we know how to provide. 22 */ 23 if (!info || len < sizeof inf.length || len > sizeof inf) { 24 PORT_SetError(SEC_ERROR_INVALID_ARGS); 25 return SECFailure; 26 } 27 28 ss = ssl_FindSocket(fd); 29 if (!ss) { 30 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo", 31 SSL_GETPID(), fd)); 32 return SECFailure; 33 } 34 35 memset(&inf, 0, sizeof inf); 36 inf.length = PR_MIN(sizeof inf, len); 37 38 if (ss->opt.useSecurity && ss->enoughFirstHsDone) { 39 SSLCipherSuiteInfo cinfo; 40 SECStatus rv; 41 42 sid = ss->sec.ci.sid; 43 inf.protocolVersion = ss->version; 44 inf.authKeyBits = ss->sec.authKeyBits; 45 inf.keaKeyBits = ss->sec.keaKeyBits; 46 47 ssl_GetSpecReadLock(ss); 48 /* XXX The cipher suite should be in the specs and this 49 * function should get it from cwSpec rather than from the "hs". 50 * See bug 275744 comment 69 and bug 766137. 51 */ 52 inf.cipherSuite = ss->ssl3.hs.cipher_suite; 53 ssl_ReleaseSpecReadLock(ss); 54 inf.compressionMethod = ssl_compression_null; 55 inf.compressionMethodName = "NULL"; 56 57 /* Fill in the cipher details from the cipher suite. */ 58 rv = SSL_GetCipherSuiteInfo(inf.cipherSuite, 59 &cinfo, sizeof(cinfo)); 60 if (rv != SECSuccess) { 61 return SECFailure; /* Error code already set. */ 62 } 63 inf.symCipher = cinfo.symCipher; 64 inf.macAlgorithm = cinfo.macAlgorithm; 65 /* Get these fromm |ss->sec| because that is accurate 66 * even with TLS 1.3 disaggregated cipher suites. */ 67 inf.keaType = ss->sec.keaType; 68 inf.originalKeaGroup = ss->sec.originalKeaGroup 69 ? ss->sec.originalKeaGroup->name 70 : ssl_grp_none; 71 inf.keaGroup = ss->sec.keaGroup 72 ? ss->sec.keaGroup->name 73 : ssl_grp_none; 74 inf.keaKeyBits = ss->sec.keaKeyBits; 75 inf.authType = ss->sec.authType; 76 inf.authKeyBits = ss->sec.authKeyBits; 77 inf.signatureScheme = ss->sec.signatureScheme; 78 /* If this is a resumed session, signatureScheme isn't set in ss->sec. 79 * Use the signature scheme from the previous handshake. */ 80 if (inf.signatureScheme == ssl_sig_none && sid->sigScheme) { 81 inf.signatureScheme = sid->sigScheme; 82 } 83 inf.resumed = ss->statelessResume || ss->ssl3.hs.isResuming; 84 if (inf.resumed) { 85 inf.pskType = ssl_psk_resume; 86 } else if (inf.authType == ssl_auth_psk) { 87 inf.pskType = ssl_psk_external; 88 } else { 89 inf.pskType = ssl_psk_none; 90 } 91 inf.peerDelegCred = tls13_IsVerifyingWithDelegatedCredential(ss); 92 inf.echAccepted = ss->ssl3.hs.echAccepted; 93 94 if (sid) { 95 unsigned int sidLen; 96 97 inf.creationTime = sid->creationTime / PR_USEC_PER_SEC; 98 inf.lastAccessTime = sid->lastAccessTime / PR_USEC_PER_SEC; 99 inf.expirationTime = sid->expirationTime / PR_USEC_PER_SEC; 100 inf.extendedMasterSecretUsed = 101 (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 || 102 sid->u.ssl3.keys.extendedMasterSecretUsed) 103 ? PR_TRUE 104 : PR_FALSE; 105 106 inf.earlyDataAccepted = 107 (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted || 108 ss->ssl3.hs.zeroRttState == ssl_0rtt_done); 109 sidLen = sid->u.ssl3.sessionIDLength; 110 sidLen = PR_MIN(sidLen, sizeof inf.sessionID); 111 inf.sessionIDLength = sidLen; 112 memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen); 113 inf.isFIPS = ssl_isFIPS(ss); 114 } 115 } 116 117 memcpy(info, &inf, inf.length); 118 119 return SECSuccess; 120 } 121 122 SECStatus 123 SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, 124 SSLPreliminaryChannelInfo *info, 125 PRUintn len) 126 { 127 sslSocket *ss; 128 SSLPreliminaryChannelInfo inf; 129 130 /* Check if we can properly return the length of data written and that 131 * we're not asked to return more information than we know how to provide. 132 */ 133 if (!info || len < sizeof inf.length || len > sizeof inf) { 134 PORT_SetError(SEC_ERROR_INVALID_ARGS); 135 return SECFailure; 136 } 137 138 ss = ssl_FindSocket(fd); 139 if (!ss) { 140 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPreliminaryChannelInfo", 141 SSL_GETPID(), fd)); 142 return SECFailure; 143 } 144 145 /* All fields MUST be zero initialized! */ 146 memset(&inf, 0, sizeof(inf)); 147 inf.length = PR_MIN(sizeof(inf), len); 148 149 inf.valuesSet = ss->ssl3.hs.preliminaryInfo; 150 inf.protocolVersion = ss->version; 151 inf.cipherSuite = ss->ssl3.hs.cipher_suite; 152 inf.canSendEarlyData = !ss->sec.isServer && 153 (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || 154 ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted); 155 /* We shouldn't be able to send early data if the handshake is done. */ 156 PORT_Assert(!ss->firstHsDone || !inf.canSendEarlyData); 157 158 if (ss->sec.ci.sid) { 159 PRUint32 ticketMaxEarlyData = 160 ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size; 161 162 /* Resumption token info. */ 163 inf.ticketSupportsEarlyData = (ticketMaxEarlyData > 0); 164 165 if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || 166 ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { 167 if (ss->statelessResume) { 168 inf.maxEarlyDataSize = ticketMaxEarlyData; 169 } else if (ss->psk) { 170 /* We may have cleared the handshake list, so check the socket. 171 * This is permissable since we only support one EPSK at a time. */ 172 inf.maxEarlyDataSize = ss->psk->maxEarlyData; 173 } 174 } 175 } 176 inf.zeroRttCipherSuite = ss->ssl3.hs.zeroRttSuite; 177 178 inf.peerDelegCred = tls13_IsVerifyingWithDelegatedCredential(ss); 179 inf.authKeyBits = ss->sec.authKeyBits; 180 inf.signatureScheme = ss->sec.signatureScheme; 181 inf.echAccepted = ss->ssl3.hs.echAccepted; 182 /* Only expose this if the application should use it for verification. */ 183 inf.echPublicName = (inf.echAccepted == PR_FALSE) ? ss->ssl3.hs.echPublicName : NULL; 184 185 memcpy(info, &inf, inf.length); 186 return SECSuccess; 187 } 188 189 /* name */ 190 #define CS_(x) x, #x 191 #define CS(x) CS_(TLS_##x) 192 193 /* legacy values for authAlgorithm */ 194 #define S_DSA "DSA", ssl_auth_dsa 195 /* S_RSA is incorrect for signature-based suites */ 196 /* ECDH suites incorrectly report S_RSA or S_ECDSA */ 197 #define S_RSA "RSA", ssl_auth_rsa_decrypt 198 #define S_ECDSA "ECDSA", ssl_auth_ecdsa 199 #define S_PSK "PSK", ssl_auth_psk 200 #define S_ANY "TLS 1.3", ssl_auth_tls13_any 201 202 /* real authentication algorithm */ 203 #define A_DSA ssl_auth_dsa 204 #define A_RSAD ssl_auth_rsa_decrypt 205 #define A_RSAS ssl_auth_rsa_sign 206 #define A_ECDSA ssl_auth_ecdsa 207 #define A_ECDH_R ssl_auth_ecdh_rsa 208 #define A_ECDH_E ssl_auth_ecdh_ecdsa 209 #define A_PSK ssl_auth_psk 210 /* Report ssl_auth_null for export suites that can't decide between 211 * ssl_auth_rsa_sign and ssl_auth_rsa_decrypt. */ 212 #define A_EXP ssl_auth_null 213 #define A_ANY ssl_auth_tls13_any 214 215 /* key exchange */ 216 #define K_DHE "DHE", ssl_kea_dh 217 #define K_RSA "RSA", ssl_kea_rsa 218 #define K_KEA "KEA", ssl_kea_kea 219 #define K_ECDH "ECDH", ssl_kea_ecdh 220 #define K_ECDHE "ECDHE", ssl_kea_ecdh 221 #define K_ECDHE_PSK "ECDHE-PSK", ssl_kea_ecdh_psk 222 #define K_DHE_PSK "DHE-PSK", ssl_kea_dh_psk 223 #define K_ANY "TLS 1.3", ssl_kea_tls13_any 224 225 /* record protection cipher */ 226 #define C_SEED "SEED", ssl_calg_seed 227 #define C_CAMELLIA "CAMELLIA", ssl_calg_camellia 228 #define C_AES "AES", ssl_calg_aes 229 #define C_RC4 "RC4", ssl_calg_rc4 230 #define C_RC2 "RC2", ssl_calg_rc2 231 #define C_DES "DES", ssl_calg_des 232 #define C_3DES "3DES", ssl_calg_3des 233 #define C_NULL "NULL", ssl_calg_null 234 #define C_SJ "SKIPJACK", ssl_calg_sj 235 #define C_AESGCM "AES-GCM", ssl_calg_aes_gcm 236 #define C_CHACHA20 "CHACHA20POLY1305", ssl_calg_chacha20 237 238 /* "block cipher" sizes */ 239 #define B_256 256, 256, 256 240 #define B_128 128, 128, 128 241 #define B_3DES 192, 156, 112 242 #define B_SJ 96, 80, 80 243 #define B_DES 64, 56, 56 244 #define B_56 128, 56, 56 245 #define B_40 128, 40, 40 246 #define B_0 0, 0, 0 247 248 /* "mac algorithm" and size */ 249 #define M_AEAD_128 "AEAD", ssl_mac_aead, 128 250 #define M_SHA384 "SHA384", ssl_hmac_sha384, 384 251 #define M_SHA256 "SHA256", ssl_hmac_sha256, 256 252 #define M_SHA "SHA1", ssl_mac_sha, 160 253 #define M_MD5 "MD5", ssl_mac_md5, 128 254 #define M_NULL "NULL", ssl_mac_null, 0 255 256 /* flags: FIPS, exportable, nonstandard, reserved */ 257 #define F_FIPS_STD 1, 0, 0, 0 258 #define F_FIPS_NSTD 1, 0, 1, 0 259 #define F_NFIPS_STD 0, 0, 0, 0 260 #define F_NFIPS_NSTD 0, 0, 1, 0 /* i.e., trash */ 261 #define F_EXPORT 0, 1, 0, 0 /* i.e., trash */ 262 263 // RFC 5705 264 #define MAX_CONTEXT_LEN PR_UINT16_MAX - 1 265 266 static const SSLCipherSuiteInfo suiteInfo[] = { 267 /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */ 268 { 0, CS_(TLS_AES_128_GCM_SHA256), S_ANY, K_ANY, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_ANY, ssl_hash_sha256 }, 269 { 0, CS_(TLS_CHACHA20_POLY1305_SHA256), S_ANY, K_ANY, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_ANY, ssl_hash_sha256 }, 270 { 0, CS_(TLS_AES_256_GCM_SHA384), S_ANY, K_ANY, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_ANY, ssl_hash_sha384 }, 271 272 { 0, CS(RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_RSAD, ssl_hash_sha256 }, 273 { 0, CS(DHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_DHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_RSAS, ssl_hash_sha256 }, 274 275 { 0, CS(DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, F_NFIPS_STD, A_RSAS, ssl_hash_none }, 276 { 0, CS(DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, F_NFIPS_STD, A_DSA, ssl_hash_none }, 277 { 0, CS(DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, F_FIPS_STD, A_RSAS, ssl_hash_sha256 }, 278 { 0, CS(DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAS, ssl_hash_none }, 279 { 0, CS(DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_DSA, ssl_hash_none }, 280 { 0, CS(DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, F_FIPS_STD, A_DSA, ssl_hash_sha256 }, 281 { 0, CS(RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, F_NFIPS_STD, A_RSAD, ssl_hash_none }, 282 { 0, CS(RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, F_FIPS_STD, A_RSAD, ssl_hash_sha256 }, 283 { 0, CS(RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAD, ssl_hash_none }, 284 285 { 0, CS(DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, F_NFIPS_STD, A_RSAS, ssl_hash_none }, 286 { 0, CS(DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, F_NFIPS_STD, A_DSA, ssl_hash_none }, 287 { 0, CS(DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_DSA, ssl_hash_none }, 288 { 0, CS(DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAS, ssl_hash_sha256 }, 289 { 0, CS(DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_RSAS, ssl_hash_sha256 }, 290 { 0, CS(DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_RSAS, ssl_hash_none }, 291 { 0, CS(DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_DSA, ssl_hash_sha256 }, 292 { 0, CS(DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_DSA, ssl_hash_none }, 293 { 0, CS(DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_DSA, ssl_hash_sha256 }, 294 { 0, CS(RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED, B_128, M_SHA, F_FIPS_STD, A_RSAD, ssl_hash_none }, 295 { 0, CS(RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, F_NFIPS_STD, A_RSAD, ssl_hash_none }, 296 { 0, CS(RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_RSAD, ssl_hash_none }, 297 { 0, CS(RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, F_NFIPS_STD, A_RSAD, ssl_hash_none }, 298 { 0, CS(RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_RSA, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAD, ssl_hash_sha256 }, 299 { 0, CS(RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, F_FIPS_STD, A_RSAD, ssl_hash_none }, 300 301 { 0, CS(DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_RSAS, ssl_hash_none }, 302 { 0, CS(DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_DSA, ssl_hash_none }, 303 { 0, CS(RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_RSAD, ssl_hash_none }, 304 305 { 0, CS(DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, F_NFIPS_STD, A_RSAS, ssl_hash_none }, 306 { 0, CS(DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, F_NFIPS_STD, A_DSA, ssl_hash_none }, 307 { 0, CS(RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, F_NFIPS_STD, A_RSAD, ssl_hash_none }, 308 309 { 0, CS(RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL, B_0, M_SHA256, F_EXPORT, A_RSAD, ssl_hash_sha256 }, 310 { 0, CS(RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL, B_0, M_SHA, F_EXPORT, A_RSAD, ssl_hash_none }, 311 { 0, CS(RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL, B_0, M_MD5, F_EXPORT, A_RSAD, ssl_hash_none }, 312 313 /* ECC cipher suites */ 314 { 0, CS(ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_RSAS, ssl_hash_sha256 }, 315 { 0, CS(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_ECDSA, ssl_hash_sha256 }, 316 { 0, CS(ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_ECDH_E, ssl_hash_none }, 317 { 0, CS(ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_ECDH_E, ssl_hash_none }, 318 { 0, CS(ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_ECDH_E, ssl_hash_none }, 319 { 0, CS(ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, F_FIPS_STD, A_ECDH_E, ssl_hash_none }, 320 { 0, CS(ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, F_FIPS_STD, A_ECDH_E, ssl_hash_none }, 321 322 { 0, CS(ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_ECDSA, ssl_hash_none }, 323 { 0, CS(ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_ECDSA, ssl_hash_none }, 324 { 0, CS(ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_ECDSA, ssl_hash_none }, 325 { 0, CS(ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_ECDSA, ssl_hash_none }, 326 { 0, CS(ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_ECDSA, ssl_hash_sha256 }, 327 { 0, CS(ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_ECDSA, ssl_hash_none }, 328 { 0, CS(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256), S_ECDSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_ECDSA, ssl_hash_sha256 }, 329 330 { 0, CS(ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_ECDH_R, ssl_hash_none }, 331 { 0, CS(ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_ECDH_R, ssl_hash_none }, 332 { 0, CS(ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_ECDH_R, ssl_hash_none }, 333 { 0, CS(ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, F_FIPS_STD, A_ECDH_R, ssl_hash_none }, 334 { 0, CS(ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, F_FIPS_STD, A_ECDH_R, ssl_hash_none }, 335 336 { 0, CS(ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_RSAS, ssl_hash_none }, 337 { 0, CS(ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_RSAS, ssl_hash_none }, 338 { 0, CS(ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_RSAS, ssl_hash_none }, 339 { 0, CS(ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_RSAS, ssl_hash_none }, 340 { 0, CS(ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAS, ssl_hash_sha256 }, 341 { 0, CS(ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAS, ssl_hash_none }, 342 { 0, CS(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_RSAS, ssl_hash_sha256 }, 343 { 0, CS(ECDHE_RSA_WITH_AES_256_CBC_SHA384), S_RSA, K_ECDHE, C_AES, B_256, M_SHA384, F_FIPS_STD, A_RSAS, ssl_hash_sha384 }, 344 { 0, CS(ECDHE_ECDSA_WITH_AES_256_CBC_SHA384), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA384, F_FIPS_STD, A_ECDSA, ssl_hash_sha384 }, 345 { 0, CS(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384), S_ECDSA, K_ECDHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_ECDSA, ssl_hash_sha384 }, 346 { 0, CS(ECDHE_RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_ECDHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAS, ssl_hash_sha384 }, 347 348 { 0, CS(DHE_DSS_WITH_AES_256_GCM_SHA384), S_DSA, K_DHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_DSA, ssl_hash_sha384 }, 349 { 0, CS(DHE_RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_DHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAS, ssl_hash_sha384 }, 350 { 0, CS(RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_RSA, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAD, ssl_hash_sha384 }, 351 }; 352 353 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0])) 354 355 SECStatus 356 SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, 357 SSLCipherSuiteInfo *info, PRUintn len) 358 { 359 unsigned int i; 360 361 /* Check if we can properly return the length of data written and that 362 * we're not asked to return more information than we know how to provide. 363 */ 364 if (!info || len < sizeof suiteInfo[0].length || 365 len > sizeof suiteInfo[0]) { 366 PORT_SetError(SEC_ERROR_INVALID_ARGS); 367 return SECFailure; 368 } 369 len = PR_MIN(len, sizeof suiteInfo[0]); 370 for (i = 0; i < NUM_SUITEINFOS; i++) { 371 if (suiteInfo[i].cipherSuite == cipherSuite) { 372 memcpy(info, &suiteInfo[i], len); 373 info->length = len; 374 return SECSuccess; 375 } 376 } 377 378 PORT_SetError(SEC_ERROR_INVALID_ARGS); 379 return SECFailure; 380 } 381 382 SECItem * 383 SSL_GetNegotiatedHostInfo(PRFileDesc *fd) 384 { 385 SECItem *sniName = NULL; 386 sslSocket *ss; 387 char *name = NULL; 388 389 ss = ssl_FindSocket(fd); 390 if (!ss) { 391 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo", 392 SSL_GETPID(), fd)); 393 return NULL; 394 } 395 396 if (ss->sec.isServer) { 397 if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* TLS */ 398 SECItem *crsName; 399 ssl_GetSpecReadLock(ss); /*********************************/ 400 crsName = &ss->ssl3.hs.srvVirtName; 401 if (crsName->data) { 402 sniName = SECITEM_DupItem(crsName); 403 } 404 ssl_ReleaseSpecReadLock(ss); /*----------------------------*/ 405 } 406 return sniName; 407 } 408 name = SSL_RevealURL(fd); 409 if (name) { 410 sniName = PORT_ZNew(SECItem); 411 if (!sniName) { 412 PORT_Free(name); 413 return NULL; 414 } 415 sniName->data = (void *)name; 416 sniName->len = PORT_Strlen(name); 417 } 418 return sniName; 419 } 420 421 /* 422 * HKDF-Expand-Label(Derive-Secret(Secret, label, ""), 423 * "exporter", Hash(context_value), key_length) 424 */ 425 static SECStatus 426 tls13_Exporter(sslSocket *ss, PK11SymKey *secret, 427 const char *label, unsigned int labelLen, 428 const unsigned char *context, unsigned int contextLen, 429 unsigned char *out, unsigned int outLen) 430 { 431 SSL3Hashes contextHash; 432 PK11SymKey *innerSecret = NULL; 433 SECStatus rv; 434 435 static const char *kExporterInnerLabel = "exporter"; 436 437 if (!secret) { 438 PORT_SetError(SEC_ERROR_INVALID_ARGS); 439 return SECFailure; 440 } 441 442 SSLHashType hashAlg; 443 /* Early export requires a PSK. As in 0-RTT, default 444 * to the first PSK if no suite is negotiated yet. */ 445 if (secret == ss->ssl3.hs.earlyExporterSecret && !ss->ssl3.hs.suite_def) { 446 if (PR_CLIST_IS_EMPTY(&ss->ssl3.hs.psks)) { 447 PORT_SetError(SEC_ERROR_INVALID_ARGS); 448 return SECFailure; 449 } 450 hashAlg = ((sslPsk *)PR_LIST_HEAD(&ss->ssl3.hs.psks))->hash; 451 } else { 452 hashAlg = tls13_GetHash(ss); 453 } 454 455 /* Pre-hash the context. */ 456 rv = tls13_ComputeHash(ss, &contextHash, context, contextLen, hashAlg); 457 if (rv != SECSuccess) { 458 return rv; 459 } 460 461 rv = tls13_DeriveSecretNullHash(ss, secret, label, labelLen, 462 &innerSecret, hashAlg); 463 if (rv != SECSuccess) { 464 return rv; 465 } 466 467 rv = tls13_HkdfExpandLabelRaw(innerSecret, 468 hashAlg, 469 contextHash.u.raw, contextHash.len, 470 kExporterInnerLabel, 471 strlen(kExporterInnerLabel), 472 ss->protocolVariant, out, outLen); 473 PK11_FreeSymKey(innerSecret); 474 return rv; 475 } 476 477 SECStatus 478 SSL_ExportKeyingMaterial(PRFileDesc *fd, 479 const char *label, unsigned int labelLen, 480 PRBool hasContext, 481 const unsigned char *context, unsigned int contextLen, 482 unsigned char *out, unsigned int outLen) 483 { 484 sslSocket *ss; 485 unsigned char *val = NULL; 486 unsigned int valLen, i; 487 SECStatus rv = SECFailure; 488 489 ss = ssl_FindSocket(fd); 490 if (!ss) { 491 SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial", 492 SSL_GETPID(), fd)); 493 return SECFailure; 494 } 495 496 if (!label || !labelLen || !out || !outLen || 497 (hasContext && (!context || !contextLen))) { 498 PORT_SetError(SEC_ERROR_INVALID_ARGS); 499 return SECFailure; 500 } 501 502 if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { 503 return tls13_Exporter(ss, ss->ssl3.hs.exporterSecret, 504 label, labelLen, 505 context, hasContext ? contextLen : 0, 506 out, outLen); 507 } 508 509 if (hasContext && contextLen > MAX_CONTEXT_LEN) { 510 PORT_SetError(SEC_ERROR_INVALID_ARGS); 511 return SECFailure; 512 } 513 514 /* construct PRF arguments */ 515 valLen = SSL3_RANDOM_LENGTH * 2; 516 if (hasContext) { 517 valLen += 2 /* PRUint16 length */ + contextLen; 518 } 519 val = PORT_Alloc(valLen); 520 if (!val) { 521 return SECFailure; 522 } 523 i = 0; 524 PORT_Memcpy(val + i, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH); 525 i += SSL3_RANDOM_LENGTH; 526 PORT_Memcpy(val + i, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH); 527 i += SSL3_RANDOM_LENGTH; 528 if (hasContext) { 529 val[i++] = contextLen >> 8; 530 val[i++] = contextLen; 531 PORT_Memcpy(val + i, context, contextLen); 532 i += contextLen; 533 } 534 PORT_Assert(i == valLen); 535 536 /* Allow TLS keying material to be exported sooner, when the master 537 * secret is available and we have sent ChangeCipherSpec. 538 */ 539 ssl_GetSpecReadLock(ss); 540 if (!ss->ssl3.cwSpec->masterSecret) { 541 PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); 542 rv = SECFailure; 543 } else { 544 rv = ssl3_TLSPRFWithMasterSecret(ss, ss->ssl3.cwSpec, label, labelLen, 545 val, valLen, out, outLen); 546 } 547 ssl_ReleaseSpecReadLock(ss); 548 549 PORT_ZFree(val, valLen); 550 return rv; 551 } 552 553 SECStatus 554 SSL_ExportEarlyKeyingMaterial(PRFileDesc *fd, 555 const char *label, unsigned int labelLen, 556 const unsigned char *context, 557 unsigned int contextLen, 558 unsigned char *out, unsigned int outLen) 559 { 560 sslSocket *ss; 561 562 ss = ssl_FindSocket(fd); 563 if (!ss) { 564 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_ExportEarlyKeyingMaterial", 565 SSL_GETPID(), fd)); 566 return SECFailure; 567 } 568 569 if (!label || !labelLen || !out || !outLen || 570 (!context && contextLen)) { 571 PORT_SetError(SEC_ERROR_INVALID_ARGS); 572 return SECFailure; 573 } 574 575 return tls13_Exporter(ss, ss->ssl3.hs.earlyExporterSecret, 576 label, labelLen, context, contextLen, 577 out, outLen); 578 }