tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }