OLD | NEW |
| (Empty) |
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 /* Check if we can properly return the length of data written and that | |
31 * we're not asked to return more information than we know how to provide. | |
32 */ | |
33 if (!info || len < sizeof inf.length || len > sizeof inf) { | |
34 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
35 return SECFailure; | |
36 } | |
37 | |
38 ss = ssl_FindSocket(fd); | |
39 if (!ss) { | |
40 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo", | |
41 SSL_GETPID(), fd)); | |
42 return SECFailure; | |
43 } | |
44 | |
45 memset(&inf, 0, sizeof inf); | |
46 inf.length = PR_MIN(sizeof inf, len); | |
47 | |
48 if (ss->opt.useSecurity && ss->enoughFirstHsDone) { | |
49 sid = ss->sec.ci.sid; | |
50 inf.protocolVersion = ss->version; | |
51 inf.authKeyBits = ss->sec.authKeyBits; | |
52 inf.keaKeyBits = ss->sec.keaKeyBits; | |
53 if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */ | |
54 inf.cipherSuite = ss->sec.cipherType | 0xff00; | |
55 inf.compressionMethod = ssl_compression_null; | |
56 inf.compressionMethodName = "N/A"; | |
57 } else if (ss->ssl3.initialized) { /* SSL3 and TLS */ | |
58 ssl_GetSpecReadLock(ss); | |
59 /* XXX The cipher suite should be in the specs and this | |
60 * function should get it from cwSpec rather than from the "hs". | |
61 * See bug 275744 comment 69 and bug 766137. | |
62 */ | |
63 inf.cipherSuite = ss->ssl3.hs.cipher_suite; | |
64 inf.compressionMethod = ss->ssl3.cwSpec->compression_method; | |
65 ssl_ReleaseSpecReadLock(ss); | |
66 inf.compressionMethodName = | |
67 ssl_GetCompressionMethodName(inf.compressionMethod); | |
68 } | |
69 if (sid) { | |
70 inf.creationTime = sid->creationTime; | |
71 inf.lastAccessTime = sid->lastAccessTime; | |
72 inf.expirationTime = sid->expirationTime; | |
73 inf.extendedMasterSecretUsed = | |
74 (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 || | |
75 sid->u.ssl3.keys.extendedMasterSecretUsed) | |
76 ? PR_TRUE | |
77 : PR_FALSE; | |
78 | |
79 if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */ | |
80 inf.sessionIDLength = SSL2_SESSIONID_BYTES; | |
81 memcpy(inf.sessionID, sid->u.ssl2.sessionID, | |
82 SSL2_SESSIONID_BYTES); | |
83 } else { | |
84 unsigned int sidLen = sid->u.ssl3.sessionIDLength; | |
85 sidLen = PR_MIN(sidLen, sizeof inf.sessionID); | |
86 inf.sessionIDLength = sidLen; | |
87 memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen); | |
88 } | |
89 } | |
90 } | |
91 | |
92 memcpy(info, &inf, inf.length); | |
93 | |
94 return SECSuccess; | |
95 } | |
96 | |
97 SECStatus | |
98 SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, | |
99 SSLPreliminaryChannelInfo *info, | |
100 PRUintn len) | |
101 { | |
102 sslSocket *ss; | |
103 SSLPreliminaryChannelInfo inf; | |
104 | |
105 /* Check if we can properly return the length of data written and that | |
106 * we're not asked to return more information than we know how to provide. | |
107 */ | |
108 if (!info || len < sizeof inf.length || len > sizeof inf) { | |
109 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
110 return SECFailure; | |
111 } | |
112 | |
113 ss = ssl_FindSocket(fd); | |
114 if (!ss) { | |
115 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPreliminaryChannelInfo", | |
116 SSL_GETPID(), fd)); | |
117 return SECFailure; | |
118 } | |
119 | |
120 if (ss->version < SSL_LIBRARY_VERSION_3_0) { | |
121 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION); | |
122 return SECFailure; | |
123 } | |
124 | |
125 memset(&inf, 0, sizeof(inf)); | |
126 inf.length = PR_MIN(sizeof(inf), len); | |
127 | |
128 inf.valuesSet = ss->ssl3.hs.preliminaryInfo; | |
129 inf.protocolVersion = ss->version; | |
130 inf.cipherSuite = ss->ssl3.hs.cipher_suite; | |
131 | |
132 memcpy(info, &inf, inf.length); | |
133 return SECSuccess; | |
134 } | |
135 | |
136 #define CS(x) x, #x | |
137 #define CK(x) x | 0xff00, #x | |
138 | |
139 #define S_DSA "DSA", ssl_auth_dsa | |
140 #define S_RSA "RSA", ssl_auth_rsa | |
141 #define S_KEA "KEA", ssl_auth_kea | |
142 #define S_ECDSA "ECDSA", ssl_auth_ecdsa | |
143 | |
144 #define K_DHE "DHE", kt_dh | |
145 #define K_RSA "RSA", kt_rsa | |
146 #define K_KEA "KEA", kt_kea | |
147 #define K_ECDH "ECDH", kt_ecdh | |
148 #define K_ECDHE "ECDHE", kt_ecdh | |
149 | |
150 #define C_SEED "SEED", calg_seed | |
151 #define C_CAMELLIA "CAMELLIA", calg_camellia | |
152 #define C_AES "AES", calg_aes | |
153 #define C_RC4 "RC4", calg_rc4 | |
154 #define C_RC2 "RC2", calg_rc2 | |
155 #define C_DES "DES", calg_des | |
156 #define C_3DES "3DES", calg_3des | |
157 #define C_NULL "NULL", calg_null | |
158 #define C_SJ "SKIPJACK", calg_sj | |
159 #define C_AESGCM "AES-GCM", calg_aes_gcm | |
160 #define C_CHACHA20 "CHACHA20POLY1305", calg_chacha20 | |
161 | |
162 #define B_256 256, 256, 256 | |
163 #define B_128 128, 128, 128 | |
164 #define B_3DES 192, 156, 112 | |
165 #define B_SJ 96, 80, 80 | |
166 #define B_DES 64, 56, 56 | |
167 #define B_56 128, 56, 56 | |
168 #define B_40 128, 40, 40 | |
169 #define B_0 0, 0, 0 | |
170 | |
171 #define M_AEAD_128 "AEAD", ssl_mac_aead, 128 | |
172 #define M_SHA256 "SHA256", ssl_hmac_sha256, 256 | |
173 #define M_SHA "SHA1", ssl_mac_sha, 160 | |
174 #define M_MD5 "MD5", ssl_mac_md5, 128 | |
175 #define M_NULL "NULL", ssl_mac_null, 0 | |
176 | |
177 /* clang-format off */ | |
178 static const SSLCipherSuiteInfo suiteInfo[] = { | |
179 /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <M
AC> <FIPS> */ | |
180 {0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128,
M_AEAD_128, 1, 0, 0 }, | |
181 {0,CS(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_DHE, C_CHACHA20,
B_256, M_AEAD_128, 0, 0, 0 }, | |
182 | |
183 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_25
6, M_SHA, 0, 0, 0 }, | |
184 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_25
6, M_SHA, 0, 0, 0 }, | |
185 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_
SHA256, 1, 0, 0 }, | |
186 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_
SHA, 1, 0, 0 }, | |
187 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_
SHA, 1, 0, 0 }, | |
188 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_
SHA256, 1, 0, 0 }, | |
189 {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_25
6, M_SHA, 0, 0, 0 }, | |
190 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_
SHA256, 1, 0, 0 }, | |
191 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_
SHA, 1, 0, 0 }, | |
192 | |
193 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_12
8, M_SHA, 0, 0, 0 }, | |
194 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_12
8, M_SHA, 0, 0, 0 }, | |
195 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_
SHA, 0, 0, 0 }, | |
196 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_
SHA256, 1, 0, 0 }, | |
197 {0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128,
M_AEAD_128, 1, 0, 0 }, | |
198 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_
SHA, 1, 0, 0 }, | |
199 {0,CS(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128,
M_AEAD_128, 1, 0, 0 }, | |
200 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_
SHA, 1, 0, 0 }, | |
201 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_
SHA256, 1, 0, 0 }, | |
202 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_
SHA, 1, 0, 0 }, | |
203 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_12
8, M_SHA, 0, 0, 0 }, | |
204 {0,CS(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_
SHA, 0, 0, 0 }, | |
205 {0,CS(TLS_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_
MD5, 0, 0, 0 }, | |
206 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_RSA, C_AES, B_128, M_
SHA256, 1, 0, 0 }, | |
207 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_
SHA, 1, 0, 0 }, | |
208 | |
209 {0,CS(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_
SHA, 1, 0, 0 }, | |
210 {0,CS(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_
SHA, 1, 0, 0 }, | |
211 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_
SHA, 1, 0, 1 }, | |
212 {0,CS(TLS_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_
SHA, 1, 0, 0 }, | |
213 | |
214 {0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_
SHA, 0, 0, 0 }, | |
215 {0,CS(TLS_DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_
SHA, 0, 0, 0 }, | |
216 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_
SHA, 0, 0, 1 }, | |
217 {0,CS(TLS_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_
SHA, 0, 0, 0 }, | |
218 | |
219 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_
SHA, 0, 1, 0 }, | |
220 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_
SHA, 0, 1, 0 }, | |
221 {0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_
MD5, 0, 1, 0 }, | |
222 {0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_
MD5, 0, 1, 0 }, | |
223 {0,CS(TLS_RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL,B_0, M_
SHA256, 0, 1, 0 }, | |
224 {0,CS(TLS_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_
SHA, 0, 1, 0 }, | |
225 {0,CS(TLS_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_
MD5, 0, 1, 0 }, | |
226 | |
227 #ifndef NSS_DISABLE_ECC | |
228 /* ECC cipher suites */ | |
229 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_12
8, M_AEAD_128, 1, 0, 0 }, | |
230 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM,
B_128, M_AEAD_128, 1, 0, 0 }, | |
231 | |
232 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0,
M_SHA, 0, 0, 0 }, | |
233 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128,
M_SHA, 0, 0, 0 }, | |
234 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DE
S, M_SHA, 1, 0, 0 }, | |
235 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128,
M_SHA, 1, 0, 0 }, | |
236 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256,
M_SHA, 1, 0, 0 }, | |
237 | |
238 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0,
M_SHA, 0, 0, 0 }, | |
239 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128
, M_SHA, 0, 0, 0 }, | |
240 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3D
ES, M_SHA, 1, 0, 0 }, | |
241 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128
, M_SHA, 1, 0, 0 }, | |
242 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_1
28, M_SHA256, 1, 0, 0 }, | |
243 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256
, M_SHA, 1, 0, 0 }, | |
244 {0,CS(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256), S_ECDSA, K_ECDHE, C_CH
ACHA20, B_256, M_AEAD_128, 0, 0, 0 }, | |
245 | |
246 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_
SHA, 0, 0, 0 }, | |
247 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M
_SHA, 0, 0, 0 }, | |
248 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES,
M_SHA, 1, 0, 0 }, | |
249 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M
_SHA, 1, 0, 0 }, | |
250 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M
_SHA, 1, 0, 0 }, | |
251 | |
252 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M
_SHA, 0, 0, 0 }, | |
253 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128,
M_SHA, 0, 0, 0 }, | |
254 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES
, M_SHA, 1, 0, 0 }, | |
255 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128,
M_SHA, 1, 0, 0 }, | |
256 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128,
M_SHA256, 1, 0, 0 }, | |
257 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256,
M_SHA, 1, 0, 0 }, | |
258 {0,CS(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_ECDHE, C_CHACHA
20, B_256, M_AEAD_128, 0, 0, 0 }, | |
259 #endif /* NSS_DISABLE_ECC */ | |
260 | |
261 /* SSL 2 table */ | |
262 {0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_
MD5, 0, 0, 0 }, | |
263 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_
MD5, 0, 0, 0 }, | |
264 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5), S_RSA, K_RSA, C_3DES,B_3DES,M_
MD5, 0, 0, 0 }, | |
265 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5), S_RSA, K_RSA, C_DES, B_DES, M_
MD5, 0, 0, 0 }, | |
266 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC4, B_40, M_
MD5, 0, 1, 0 }, | |
267 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC2, B_40, M_
MD5, 0, 1, 0 } | |
268 }; | |
269 /* clang-format on */ | |
270 | |
271 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0])) | |
272 | |
273 SECStatus | |
274 SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, | |
275 SSLCipherSuiteInfo *info, PRUintn len) | |
276 { | |
277 unsigned int i; | |
278 | |
279 /* Check if we can properly return the length of data written and that | |
280 * we're not asked to return more information than we know how to provide. | |
281 */ | |
282 if (!info || len < sizeof suiteInfo[0].length || | |
283 len > sizeof suiteInfo[0]) { | |
284 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
285 return SECFailure; | |
286 } | |
287 len = PR_MIN(len, sizeof suiteInfo[0]); | |
288 for (i = 0; i < NUM_SUITEINFOS; i++) { | |
289 if (suiteInfo[i].cipherSuite == cipherSuite) { | |
290 memcpy(info, &suiteInfo[i], len); | |
291 info->length = len; | |
292 return SECSuccess; | |
293 } | |
294 } | |
295 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
296 return SECFailure; | |
297 } | |
298 | |
299 /* This function might be a candidate to be public. | |
300 * Disables all export ciphers in the default set of enabled ciphers. | |
301 */ | |
302 SECStatus | |
303 SSL_DisableDefaultExportCipherSuites(void) | |
304 { | |
305 const SSLCipherSuiteInfo *pInfo = suiteInfo; | |
306 unsigned int i; | |
307 | |
308 for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) { | |
309 if (pInfo->isExportable) { | |
310 PORT_CheckSuccess(SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FA
LSE)); | |
311 } | |
312 } | |
313 return SECSuccess; | |
314 } | |
315 | |
316 /* This function might be a candidate to be public, | |
317 * except that it takes an sslSocket pointer as an argument. | |
318 * A Public version would take a PRFileDesc pointer. | |
319 * Disables all export ciphers in the default set of enabled ciphers. | |
320 */ | |
321 SECStatus | |
322 SSL_DisableExportCipherSuites(PRFileDesc *fd) | |
323 { | |
324 const SSLCipherSuiteInfo *pInfo = suiteInfo; | |
325 unsigned int i; | |
326 | |
327 for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) { | |
328 if (pInfo->isExportable) { | |
329 PORT_CheckSuccess(SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE
)); | |
330 } | |
331 } | |
332 return SECSuccess; | |
333 } | |
334 | |
335 /* Tells us if the named suite is exportable | |
336 * returns false for unknown suites. | |
337 */ | |
338 PRBool | |
339 SSL_IsExportCipherSuite(PRUint16 cipherSuite) | |
340 { | |
341 unsigned int i; | |
342 for (i = 0; i < NUM_SUITEINFOS; i++) { | |
343 if (suiteInfo[i].cipherSuite == cipherSuite) { | |
344 return (PRBool)(suiteInfo[i].isExportable); | |
345 } | |
346 } | |
347 return PR_FALSE; | |
348 } | |
349 | |
350 SECItem * | |
351 SSL_GetNegotiatedHostInfo(PRFileDesc *fd) | |
352 { | |
353 SECItem *sniName = NULL; | |
354 sslSocket *ss; | |
355 char *name = NULL; | |
356 | |
357 ss = ssl_FindSocket(fd); | |
358 if (!ss) { | |
359 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo", | |
360 SSL_GETPID(), fd)); | |
361 return NULL; | |
362 } | |
363 | |
364 if (ss->sec.isServer) { | |
365 if (ss->version > SSL_LIBRARY_VERSION_3_0 && | |
366 ss->ssl3.initialized) { /* TLS */ | |
367 SECItem *crsName; | |
368 ssl_GetSpecReadLock(ss); /*********************************/ | |
369 crsName = &ss->ssl3.cwSpec->srvVirtName; | |
370 if (crsName->data) { | |
371 sniName = SECITEM_DupItem(crsName); | |
372 } | |
373 ssl_ReleaseSpecReadLock(ss); /*----------------------------*/ | |
374 } | |
375 return sniName; | |
376 } | |
377 name = SSL_RevealURL(fd); | |
378 if (name) { | |
379 sniName = PORT_ZNew(SECItem); | |
380 if (!sniName) { | |
381 PORT_Free(name); | |
382 return NULL; | |
383 } | |
384 sniName->data = (void *)name; | |
385 sniName->len = PORT_Strlen(name); | |
386 } | |
387 return sniName; | |
388 } | |
389 | |
390 SECStatus | |
391 SSL_ExportKeyingMaterial(PRFileDesc *fd, | |
392 const char *label, unsigned int labelLen, | |
393 PRBool hasContext, | |
394 const unsigned char *context, unsigned int contextLen, | |
395 unsigned char *out, unsigned int outLen) | |
396 { | |
397 sslSocket *ss; | |
398 unsigned char *val = NULL; | |
399 unsigned int valLen, i; | |
400 SECStatus rv = SECFailure; | |
401 | |
402 ss = ssl_FindSocket(fd); | |
403 if (!ss) { | |
404 SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial", | |
405 SSL_GETPID(), fd)); | |
406 return SECFailure; | |
407 } | |
408 | |
409 ssl_GetRecvBufLock(ss); | |
410 ssl_GetSSL3HandshakeLock(ss); | |
411 | |
412 if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) { | |
413 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION); | |
414 ssl_ReleaseSSL3HandshakeLock(ss); | |
415 ssl_ReleaseRecvBufLock(ss); | |
416 return SECFailure; | |
417 } | |
418 | |
419 /* construct PRF arguments */ | |
420 valLen = SSL3_RANDOM_LENGTH * 2; | |
421 if (hasContext) { | |
422 valLen += 2 /* PRUint16 length */ + contextLen; | |
423 } | |
424 val = PORT_Alloc(valLen); | |
425 if (!val) { | |
426 ssl_ReleaseSSL3HandshakeLock(ss); | |
427 ssl_ReleaseRecvBufLock(ss); | |
428 return SECFailure; | |
429 } | |
430 i = 0; | |
431 PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); | |
432 i += SSL3_RANDOM_LENGTH; | |
433 PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH); | |
434 i += SSL3_RANDOM_LENGTH; | |
435 if (hasContext) { | |
436 val[i++] = contextLen >> 8; | |
437 val[i++] = contextLen; | |
438 PORT_Memcpy(val + i, context, contextLen); | |
439 i += contextLen; | |
440 } | |
441 PORT_Assert(i == valLen); | |
442 | |
443 /* Allow TLS keying material to be exported sooner, when the master | |
444 * secret is available and we have sent ChangeCipherSpec. | |
445 */ | |
446 ssl_GetSpecReadLock(ss); | |
447 if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) { | |
448 PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); | |
449 rv = SECFailure; | |
450 } else { | |
451 rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val, | |
452 valLen, out, outLen); | |
453 } | |
454 ssl_ReleaseSpecReadLock(ss); | |
455 ssl_ReleaseSSL3HandshakeLock(ss); | |
456 ssl_ReleaseRecvBufLock(ss); | |
457 | |
458 PORT_ZFree(val, valLen); | |
459 return rv; | |
460 } | |
OLD | NEW |