Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #include "ssl.h"
5 #include "sslimpl.h"
6 #include "sslproto.h"
8 static const char *
9 ssl_GetCompressionMethodName(SSLCompressionMethod compression)
10 {
11 switch (compression) {
12 case ssl_compression_null:
13 return "NULL";
14 #ifdef NSS_ENABLE_ZLIB
15 case ssl_compression_deflate:
16 return "DEFLATE";
17 #endif
18 default:
19 return "???";
20 }
21 }
23 SECStatus
24 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
25 {
26 sslSocket * ss;
27 SSLChannelInfo inf;
28 sslSessionID * sid;
30 if (!info || len < sizeof inf.length) {
31 PORT_SetError(SEC_ERROR_INVALID_ARGS);
32 return SECFailure;
33 }
35 ss = ssl_FindSocket(fd);
36 if (!ss) {
37 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
38 SSL_GETPID(), fd));
39 return SECFailure;
40 }
42 memset(&inf, 0, sizeof inf);
43 inf.length = PR_MIN(sizeof inf, len);
45 if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
46 sid = ss->sec.ci.sid;
47 inf.protocolVersion = ss->version;
48 inf.authKeyBits = ss->sec.authKeyBits;
49 inf.keaKeyBits = ss->sec.keaKeyBits;
50 if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
51 inf.cipherSuite = ss->sec.cipherType | 0xff00;
52 inf.compressionMethod = ssl_compression_null;
53 inf.compressionMethodName = "N/A";
54 } else if (ss->ssl3.initialized) { /* SSL3 and TLS */
55 ssl_GetSpecReadLock(ss);
56 /* XXX The cipher suite should be in the specs and this
57 * function should get it from cwSpec rather than from the "hs".
58 * See bug 275744 comment 69 and bug 766137.
59 */
60 inf.cipherSuite = ss->ssl3.hs.cipher_suite;
61 inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
62 ssl_ReleaseSpecReadLock(ss);
63 inf.compressionMethodName =
64 ssl_GetCompressionMethodName(inf.compressionMethod);
65 }
66 if (sid) {
67 inf.creationTime = sid->creationTime;
68 inf.lastAccessTime = sid->lastAccessTime;
69 inf.expirationTime = sid->expirationTime;
70 if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
71 inf.sessionIDLength = SSL2_SESSIONID_BYTES;
72 memcpy(inf.sessionID, sid->u.ssl2.sessionID,
73 SSL2_SESSIONID_BYTES);
74 } else {
75 unsigned int sidLen = sid->u.ssl3.sessionIDLength;
76 sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
77 inf.sessionIDLength = sidLen;
78 memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
79 }
80 }
81 }
83 memcpy(info, &inf, inf.length);
85 return SECSuccess;
86 }
89 #define CS(x) x, #x
90 #define CK(x) x | 0xff00, #x
92 #define S_DSA "DSA", ssl_auth_dsa
93 #define S_RSA "RSA", ssl_auth_rsa
94 #define S_KEA "KEA", ssl_auth_kea
95 #define S_ECDSA "ECDSA", ssl_auth_ecdsa
97 #define K_DHE "DHE", kt_dh
98 #define K_RSA "RSA", kt_rsa
99 #define K_KEA "KEA", kt_kea
100 #define K_ECDH "ECDH", kt_ecdh
101 #define K_ECDHE "ECDHE", kt_ecdh
103 #define C_SEED "SEED", calg_seed
104 #define C_CAMELLIA "CAMELLIA", calg_camellia
105 #define C_AES "AES", calg_aes
106 #define C_RC4 "RC4", calg_rc4
107 #define C_RC2 "RC2", calg_rc2
108 #define C_DES "DES", calg_des
109 #define C_3DES "3DES", calg_3des
110 #define C_NULL "NULL", calg_null
111 #define C_SJ "SKIPJACK", calg_sj
112 #define C_AESGCM "AES-GCM", calg_aes_gcm
114 #define B_256 256, 256, 256
115 #define B_128 128, 128, 128
116 #define B_3DES 192, 156, 112
117 #define B_SJ 96, 80, 80
118 #define B_DES 64, 56, 56
119 #define B_56 128, 56, 56
120 #define B_40 128, 40, 40
121 #define B_0 0, 0, 0
123 #define M_AEAD_128 "AEAD", ssl_mac_aead, 128
124 #define M_SHA256 "SHA256", ssl_hmac_sha256, 256
125 #define M_SHA "SHA1", ssl_mac_sha, 160
126 #define M_MD5 "MD5", ssl_mac_md5, 128
127 #define M_NULL "NULL", ssl_mac_null, 0
129 static const SSLCipherSuiteInfo suiteInfo[] = {
130 /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
131 {0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
133 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
134 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
135 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, },
136 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
137 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
138 {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
139 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 0, 0, },
140 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
142 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
143 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
144 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
145 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
146 {0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
147 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
148 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
149 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
150 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
151 {0,CS(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
152 {0,CS(TLS_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
153 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_RSA, C_AES, B_128, M_SHA256, 1, 0, 0, },
154 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
156 {0,CS(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
157 {0,CS(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
158 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
159 {0,CS(TLS_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
161 {0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
162 {0,CS(TLS_DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
163 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 1, },
164 {0,CS(TLS_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0, },
166 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_SHA, 0, 1, 0, },
167 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0, },
168 {0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
169 {0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, },
170 {0,CS(TLS_RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL,B_0, M_SHA256, 0, 1, 0, },
171 {0,CS(TLS_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
172 {0,CS(TLS_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
174 #ifndef NSS_DISABLE_ECC
175 /* ECC cipher suites */
176 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
177 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
179 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
180 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
181 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
182 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
183 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
185 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
186 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
187 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
188 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
189 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
190 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
192 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
193 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
194 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
195 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
196 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
198 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
199 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
200 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
201 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
202 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
203 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
204 #endif /* NSS_DISABLE_ECC */
206 /* SSL 2 table */
207 {0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
208 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0, },
209 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5), S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0, },
210 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5), S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0, },
211 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
212 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, }
213 };
215 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
218 SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
219 SSLCipherSuiteInfo *info, PRUintn len)
220 {
221 unsigned int i;
223 len = PR_MIN(len, sizeof suiteInfo[0]);
224 if (!info || len < sizeof suiteInfo[0].length) {
225 PORT_SetError(SEC_ERROR_INVALID_ARGS);
226 return SECFailure;
227 }
228 for (i = 0; i < NUM_SUITEINFOS; i++) {
229 if (suiteInfo[i].cipherSuite == cipherSuite) {
230 memcpy(info, &suiteInfo[i], len);
231 info->length = len;
232 return SECSuccess;
233 }
234 }
235 PORT_SetError(SEC_ERROR_INVALID_ARGS);
236 return SECFailure;
237 }
239 /* This function might be a candidate to be public.
240 * Disables all export ciphers in the default set of enabled ciphers.
241 */
242 SECStatus
243 SSL_DisableDefaultExportCipherSuites(void)
244 {
245 const SSLCipherSuiteInfo * pInfo = suiteInfo;
246 unsigned int i;
247 SECStatus rv;
249 for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
250 if (pInfo->isExportable) {
251 rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE);
252 PORT_Assert(rv == SECSuccess);
253 }
254 }
255 return SECSuccess;
256 }
258 /* This function might be a candidate to be public,
259 * except that it takes an sslSocket pointer as an argument.
260 * A Public version would take a PRFileDesc pointer.
261 * Disables all export ciphers in the default set of enabled ciphers.
262 */
263 SECStatus
264 SSL_DisableExportCipherSuites(PRFileDesc * fd)
265 {
266 const SSLCipherSuiteInfo * pInfo = suiteInfo;
267 unsigned int i;
268 SECStatus rv;
270 for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
271 if (pInfo->isExportable) {
272 rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE);
273 PORT_Assert(rv == SECSuccess);
274 }
275 }
276 return SECSuccess;
277 }
279 /* Tells us if the named suite is exportable
280 * returns false for unknown suites.
281 */
282 PRBool
283 SSL_IsExportCipherSuite(PRUint16 cipherSuite)
284 {
285 unsigned int i;
286 for (i = 0; i < NUM_SUITEINFOS; i++) {
287 if (suiteInfo[i].cipherSuite == cipherSuite) {
288 return (PRBool)(suiteInfo[i].isExportable);
289 }
290 }
291 return PR_FALSE;
292 }
294 SECItem*
295 SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
296 {
297 SECItem *sniName = NULL;
298 sslSocket *ss;
299 char *name = NULL;
301 ss = ssl_FindSocket(fd);
302 if (!ss) {
303 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
304 SSL_GETPID(), fd));
305 return NULL;
306 }
308 if (ss->sec.isServer) {
309 if (ss->version > SSL_LIBRARY_VERSION_3_0 &&
310 ss->ssl3.initialized) { /* TLS */
311 SECItem *crsName;
312 ssl_GetSpecReadLock(ss); /*********************************/
313 crsName = &ss->ssl3.cwSpec->srvVirtName;
314 if (crsName->data) {
315 sniName = SECITEM_DupItem(crsName);
316 }
317 ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
318 }
319 return sniName;
320 }
321 name = SSL_RevealURL(fd);
322 if (name) {
323 sniName = PORT_ZNew(SECItem);
324 if (!sniName) {
325 PORT_Free(name);
326 return NULL;
327 }
328 sniName->data = (void*)name;
329 sniName->len = PORT_Strlen(name);
330 }
331 return sniName;
332 }
334 SECStatus
335 SSL_ExportKeyingMaterial(PRFileDesc *fd,
336 const char *label, unsigned int labelLen,
337 PRBool hasContext,
338 const unsigned char *context, unsigned int contextLen,
339 unsigned char *out, unsigned int outLen)
340 {
341 sslSocket *ss;
342 unsigned char *val = NULL;
343 unsigned int valLen, i;
344 SECStatus rv = SECFailure;
346 ss = ssl_FindSocket(fd);
347 if (!ss) {
348 SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
349 SSL_GETPID(), fd));
350 return SECFailure;
351 }
353 if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
354 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
355 return SECFailure;
356 }
358 /* construct PRF arguments */
359 valLen = SSL3_RANDOM_LENGTH * 2;
360 if (hasContext) {
361 valLen += 2 /* PRUint16 length */ + contextLen;
362 }
363 val = PORT_Alloc(valLen);
364 if (!val) {
365 return SECFailure;
366 }
367 i = 0;
368 PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
369 i += SSL3_RANDOM_LENGTH;
370 PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
371 i += SSL3_RANDOM_LENGTH;
372 if (hasContext) {
373 val[i++] = contextLen >> 8;
374 val[i++] = contextLen;
375 PORT_Memcpy(val + i, context, contextLen);
376 i += contextLen;
377 }
378 PORT_Assert(i == valLen);
380 /* Allow TLS keying material to be exported sooner, when the master
381 * secret is available and we have sent ChangeCipherSpec.
382 */
383 ssl_GetSpecReadLock(ss);
384 if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
385 PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
386 rv = SECFailure;
387 } else {
388 rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
389 valLen, out, outLen);
390 }
391 ssl_ReleaseSpecReadLock(ss);
393 PORT_ZFree(val, valLen);
394 return rv;
395 }