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/. */
9 ssl_GetCompressionMethodName(SSLCompressionMethod compression
)
11 switch (compression
) {
12 case ssl_compression_null
:
14 #ifdef NSS_ENABLE_ZLIB
15 case ssl_compression_deflate
:
24 SSL_GetChannelInfo(PRFileDesc
*fd
, SSLChannelInfo
*info
, PRUintn len
)
30 if (!info
|| len
< sizeof inf
.length
) {
31 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
35 ss
= ssl_FindSocket(fd
);
37 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
42 memset(&inf
, 0, sizeof inf
);
43 inf
.length
= PR_MIN(sizeof inf
, len
);
45 if (ss
->opt
.useSecurity
&& ss
->enoughFirstHsDone
) {
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.
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
);
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
);
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
);
83 memcpy(info
, &inf
, inf
.length
);
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
113 #define C_CHACHA20 "CHACHA20POLY1305", calg_chacha20
115 #define B_256 256, 256, 256
116 #define B_128 128, 128, 128
117 #define B_3DES 192, 156, 112
118 #define B_SJ 96, 80, 80
119 #define B_DES 64, 56, 56
120 #define B_56 128, 56, 56
121 #define B_40 128, 40, 40
124 #define M_AEAD_128 "AEAD", ssl_mac_aead, 128
125 #define M_SHA256 "SHA256", ssl_hmac_sha256, 256
126 #define M_SHA "SHA1", ssl_mac_sha, 160
127 #define M_MD5 "MD5", ssl_mac_md5, 128
128 #define M_NULL "NULL", ssl_mac_null, 0
130 static const SSLCipherSuiteInfo suiteInfo
[] = {
131 /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
132 {0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256
), S_RSA
, K_RSA
, C_AESGCM
, B_128
, M_AEAD_128
, 1, 0, 0, },
134 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
), S_RSA
, K_DHE
, C_CAMELLIA
, B_256
, M_SHA
, 0, 0, 0, },
135 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
), S_DSA
, K_DHE
, C_CAMELLIA
, B_256
, M_SHA
, 0, 0, 0, },
136 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
), S_RSA
, K_DHE
, C_AES
, B_256
, M_SHA256
, 1, 0, 0, },
137 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_DHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
138 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA
), S_DSA
, K_DHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
139 {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
), S_RSA
, K_RSA
, C_CAMELLIA
, B_256
, M_SHA
, 0, 0, 0, },
140 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256
), S_RSA
, K_RSA
, C_AES
, B_256
, M_SHA256
, 1, 0, 0, },
141 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_RSA
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
143 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
), S_RSA
, K_DHE
, C_CAMELLIA
, B_128
, M_SHA
, 0, 0, 0, },
144 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
), S_DSA
, K_DHE
, C_CAMELLIA
, B_128
, M_SHA
, 0, 0, 0, },
145 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA
), S_DSA
, K_DHE
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
146 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
), S_RSA
, K_DHE
, C_AES
, B_128
, M_SHA256
, 1, 0, 0, },
147 {0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
), S_RSA
, K_DHE
, C_AESGCM
, B_128
, M_AEAD_128
, 1, 0, 0, },
148 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_DHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
149 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA
), S_DSA
, K_DHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
150 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA
), S_RSA
, K_RSA
, C_SEED
,B_128
, M_SHA
, 1, 0, 0, },
151 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
), S_RSA
, K_RSA
, C_CAMELLIA
, B_128
, M_SHA
, 0, 0, 0, },
152 {0,CS(TLS_RSA_WITH_RC4_128_SHA
), S_RSA
, K_RSA
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
153 {0,CS(TLS_RSA_WITH_RC4_128_MD5
), S_RSA
, K_RSA
, C_RC4
, B_128
, M_MD5
, 0, 0, 0, },
154 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA256
), S_RSA
, K_RSA
, C_AES
, B_128
, M_SHA256
, 1, 0, 0, },
155 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_RSA
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
157 {0,CS(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_DHE
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 0, },
158 {0,CS(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
), S_DSA
, K_DHE
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 0, },
159 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_RSA
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 1, },
160 {0,CS(TLS_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_RSA
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 0, },
162 {0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA
), S_RSA
, K_DHE
, C_DES
, B_DES
, M_SHA
, 0, 0, 0, },
163 {0,CS(TLS_DHE_DSS_WITH_DES_CBC_SHA
), S_DSA
, K_DHE
, C_DES
, B_DES
, M_SHA
, 0, 0, 0, },
164 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_SHA
, 0, 0, 1, },
165 {0,CS(TLS_RSA_WITH_DES_CBC_SHA
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_SHA
, 0, 0, 0, },
167 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA
), S_RSA
, K_RSA
, C_RC4
, B_56
, M_SHA
, 0, 1, 0, },
168 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_SHA
, 0, 1, 0, },
169 {0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5
), S_RSA
, K_RSA
, C_RC4
, B_40
, M_MD5
, 0, 1, 0, },
170 {0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
), S_RSA
, K_RSA
, C_RC2
, B_40
, M_MD5
, 0, 1, 0, },
171 {0,CS(TLS_RSA_WITH_NULL_SHA256
), S_RSA
, K_RSA
, C_NULL
,B_0
, M_SHA256
, 0, 1, 0, },
172 {0,CS(TLS_RSA_WITH_NULL_SHA
), S_RSA
, K_RSA
, C_NULL
,B_0
, M_SHA
, 0, 1, 0, },
173 {0,CS(TLS_RSA_WITH_NULL_MD5
), S_RSA
, K_RSA
, C_NULL
,B_0
, M_MD5
, 0, 1, 0, },
175 #ifndef NSS_DISABLE_ECC
176 /* ECC cipher suites */
177 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
), S_RSA
, K_ECDHE
, C_AESGCM
, B_128
, M_AEAD_128
, 1, 0, 0, },
178 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
), S_ECDSA
, K_ECDHE
, C_AESGCM
, B_128
, M_AEAD_128
, 1, 0, 0, },
180 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA
), S_ECDSA
, K_ECDH
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
181 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA
), S_ECDSA
, K_ECDH
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
182 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
), S_ECDSA
, K_ECDH
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
183 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
), S_ECDSA
, K_ECDH
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
184 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
), S_ECDSA
, K_ECDH
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
186 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA
), S_ECDSA
, K_ECDHE
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
187 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
), S_ECDSA
, K_ECDHE
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
188 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
), S_ECDSA
, K_ECDHE
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
189 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
), S_ECDSA
, K_ECDHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
190 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
), S_ECDSA
, K_ECDHE
, C_AES
, B_128
, M_SHA256
, 1, 0, 0, },
191 {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_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
),S_ECDSA
,K_ECDHE
,C_CHACHA20
,B_256
,M_AEAD_128
,0, 0, 0, },
194 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA
), S_RSA
, K_ECDH
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
195 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA
), S_RSA
, K_ECDH
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
196 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_ECDH
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
197 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_ECDH
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
198 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_ECDH
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
199 {0,CS(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
), S_RSA
,K_ECDHE
,C_CHACHA20
,B_256
,M_AEAD_128
, 0, 0, 0, },
201 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA
), S_RSA
, K_ECDHE
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
202 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA
), S_RSA
, K_ECDHE
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
203 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_ECDHE
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
204 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_ECDHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
205 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
), S_RSA
, K_ECDHE
, C_AES
, B_128
, M_SHA256
, 1, 0, 0, },
206 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_ECDHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
207 #endif /* NSS_DISABLE_ECC */
210 {0,CK(SSL_CK_RC4_128_WITH_MD5
), S_RSA
, K_RSA
, C_RC4
, B_128
, M_MD5
, 0, 0, 0, },
211 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5
), S_RSA
, K_RSA
, C_RC2
, B_128
, M_MD5
, 0, 0, 0, },
212 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5
), S_RSA
, K_RSA
, C_3DES
,B_3DES
,M_MD5
, 0, 0, 0, },
213 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_MD5
, 0, 0, 0, },
214 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5
), S_RSA
, K_RSA
, C_RC4
, B_40
, M_MD5
, 0, 1, 0, },
215 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5
), S_RSA
, K_RSA
, C_RC2
, B_40
, M_MD5
, 0, 1, 0, }
218 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
221 SECStatus
SSL_GetCipherSuiteInfo(PRUint16 cipherSuite
,
222 SSLCipherSuiteInfo
*info
, PRUintn len
)
226 len
= PR_MIN(len
, sizeof suiteInfo
[0]);
227 if (!info
|| len
< sizeof suiteInfo
[0].length
) {
228 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
231 for (i
= 0; i
< NUM_SUITEINFOS
; i
++) {
232 if (suiteInfo
[i
].cipherSuite
== cipherSuite
) {
233 memcpy(info
, &suiteInfo
[i
], len
);
238 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
242 /* This function might be a candidate to be public.
243 * Disables all export ciphers in the default set of enabled ciphers.
246 SSL_DisableDefaultExportCipherSuites(void)
248 const SSLCipherSuiteInfo
* pInfo
= suiteInfo
;
252 for (i
= 0; i
< NUM_SUITEINFOS
; ++i
, ++pInfo
) {
253 if (pInfo
->isExportable
) {
254 rv
= SSL_CipherPrefSetDefault(pInfo
->cipherSuite
, PR_FALSE
);
255 PORT_Assert(rv
== SECSuccess
);
261 /* This function might be a candidate to be public,
262 * except that it takes an sslSocket pointer as an argument.
263 * A Public version would take a PRFileDesc pointer.
264 * Disables all export ciphers in the default set of enabled ciphers.
267 SSL_DisableExportCipherSuites(PRFileDesc
* fd
)
269 const SSLCipherSuiteInfo
* pInfo
= suiteInfo
;
273 for (i
= 0; i
< NUM_SUITEINFOS
; ++i
, ++pInfo
) {
274 if (pInfo
->isExportable
) {
275 rv
= SSL_CipherPrefSet(fd
, pInfo
->cipherSuite
, PR_FALSE
);
276 PORT_Assert(rv
== SECSuccess
);
282 /* Tells us if the named suite is exportable
283 * returns false for unknown suites.
286 SSL_IsExportCipherSuite(PRUint16 cipherSuite
)
289 for (i
= 0; i
< NUM_SUITEINFOS
; i
++) {
290 if (suiteInfo
[i
].cipherSuite
== cipherSuite
) {
291 return (PRBool
)(suiteInfo
[i
].isExportable
);
298 SSL_GetNegotiatedHostInfo(PRFileDesc
*fd
)
300 SECItem
*sniName
= NULL
;
304 ss
= ssl_FindSocket(fd
);
306 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
311 if (ss
->sec
.isServer
) {
312 if (ss
->version
> SSL_LIBRARY_VERSION_3_0
&&
313 ss
->ssl3
.initialized
) { /* TLS */
315 ssl_GetSpecReadLock(ss
); /*********************************/
316 crsName
= &ss
->ssl3
.cwSpec
->srvVirtName
;
318 sniName
= SECITEM_DupItem(crsName
);
320 ssl_ReleaseSpecReadLock(ss
); /*----------------------------*/
324 name
= SSL_RevealURL(fd
);
326 sniName
= PORT_ZNew(SECItem
);
331 sniName
->data
= (void*)name
;
332 sniName
->len
= PORT_Strlen(name
);
338 SSL_ExportKeyingMaterial(PRFileDesc
*fd
,
339 const char *label
, unsigned int labelLen
,
341 const unsigned char *context
, unsigned int contextLen
,
342 unsigned char *out
, unsigned int outLen
)
345 unsigned char *val
= NULL
;
346 unsigned int valLen
, i
;
347 SECStatus rv
= SECFailure
;
349 ss
= ssl_FindSocket(fd
);
351 SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
356 ssl_GetRecvBufLock(ss
);
357 ssl_GetSSL3HandshakeLock(ss
);
359 if (ss
->version
< SSL_LIBRARY_VERSION_3_1_TLS
) {
360 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION
);
361 ssl_ReleaseSSL3HandshakeLock(ss
);
362 ssl_ReleaseRecvBufLock(ss
);
366 /* construct PRF arguments */
367 valLen
= SSL3_RANDOM_LENGTH
* 2;
369 valLen
+= 2 /* PRUint16 length */ + contextLen
;
371 val
= PORT_Alloc(valLen
);
373 ssl_ReleaseSSL3HandshakeLock(ss
);
374 ssl_ReleaseRecvBufLock(ss
);
379 PORT_Memcpy(val
+ i
, &ss
->ssl3
.hs
.client_random
.rand
, SSL3_RANDOM_LENGTH
);
380 i
+= SSL3_RANDOM_LENGTH
;
381 PORT_Memcpy(val
+ i
, &ss
->ssl3
.hs
.server_random
.rand
, SSL3_RANDOM_LENGTH
);
382 i
+= SSL3_RANDOM_LENGTH
;
385 val
[i
++] = contextLen
>> 8;
386 val
[i
++] = contextLen
;
387 PORT_Memcpy(val
+ i
, context
, contextLen
);
390 PORT_Assert(i
== valLen
);
392 /* Allow TLS keying material to be exported sooner, when the master
393 * secret is available and we have sent ChangeCipherSpec.
395 ssl_GetSpecReadLock(ss
);
396 if (!ss
->ssl3
.cwSpec
->master_secret
&& !ss
->ssl3
.cwSpec
->msItem
.len
) {
397 PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED
);
400 rv
= ssl3_TLSPRFWithMasterSecret(ss
->ssl3
.cwSpec
, label
, labelLen
, val
,
401 valLen
, out
, outLen
);
403 ssl_ReleaseSpecReadLock(ss
);
404 ssl_ReleaseSSL3HandshakeLock(ss
);
405 ssl_ReleaseRecvBufLock(ss
);
407 PORT_ZFree(val
, valLen
);