Coverage Report

Created: 2018-09-25 14:53

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