|
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" |
|
7 |
|
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 } |
|
22 |
|
23 SECStatus |
|
24 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) |
|
25 { |
|
26 sslSocket * ss; |
|
27 SSLChannelInfo inf; |
|
28 sslSessionID * sid; |
|
29 |
|
30 if (!info || len < sizeof inf.length) { |
|
31 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
32 return SECFailure; |
|
33 } |
|
34 |
|
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 } |
|
41 |
|
42 memset(&inf, 0, sizeof inf); |
|
43 inf.length = PR_MIN(sizeof inf, len); |
|
44 |
|
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 } |
|
82 |
|
83 memcpy(info, &inf, inf.length); |
|
84 |
|
85 return SECSuccess; |
|
86 } |
|
87 |
|
88 |
|
89 #define CS(x) x, #x |
|
90 #define CK(x) x | 0xff00, #x |
|
91 |
|
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 |
|
96 |
|
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 |
|
102 |
|
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 |
|
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 |
|
122 |
|
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 |
|
128 |
|
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, }, |
|
132 |
|
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, }, |
|
141 |
|
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, }, |
|
155 |
|
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, }, |
|
160 |
|
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, }, |
|
165 |
|
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, }, |
|
173 |
|
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, }, |
|
178 |
|
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, }, |
|
184 |
|
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, }, |
|
191 |
|
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, }, |
|
197 |
|
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 */ |
|
205 |
|
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 }; |
|
214 |
|
215 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0])) |
|
216 |
|
217 |
|
218 SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, |
|
219 SSLCipherSuiteInfo *info, PRUintn len) |
|
220 { |
|
221 unsigned int i; |
|
222 |
|
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 } |
|
238 |
|
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; |
|
248 |
|
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 } |
|
257 |
|
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; |
|
269 |
|
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 } |
|
278 |
|
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 } |
|
293 |
|
294 SECItem* |
|
295 SSL_GetNegotiatedHostInfo(PRFileDesc *fd) |
|
296 { |
|
297 SECItem *sniName = NULL; |
|
298 sslSocket *ss; |
|
299 char *name = NULL; |
|
300 |
|
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 } |
|
307 |
|
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 } |
|
333 |
|
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; |
|
345 |
|
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 } |
|
352 |
|
353 if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) { |
|
354 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION); |
|
355 return SECFailure; |
|
356 } |
|
357 |
|
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); |
|
379 |
|
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); |
|
392 |
|
393 PORT_ZFree(val, valLen); |
|
394 return rv; |
|
395 } |