File: | security/nss/lib/ssl/ssl3con.c |
Location: | line 8329, column 2 |
Description: | Value stored to 'haveSpecWriteLock' is never read |
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * SSL3 Protocol |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
8 | |
9 | /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ |
10 | |
11 | #include "cert.h" |
12 | #include "ssl.h" |
13 | #include "cryptohi.h" /* for DSAU_ stuff */ |
14 | #include "keyhi.h" |
15 | #include "secder.h" |
16 | #include "secitem.h" |
17 | #include "sechash.h" |
18 | |
19 | #include "sslimpl.h" |
20 | #include "sslproto.h" |
21 | #include "sslerr.h" |
22 | #include "prtime.h" |
23 | #include "prinrval.h" |
24 | #include "prerror.h" |
25 | #include "pratom.h" |
26 | #include "prthread.h" |
27 | |
28 | #include "pk11func.h" |
29 | #include "secmod.h" |
30 | #ifndef NO_PKCS11_BYPASS1 |
31 | #include "blapi.h" |
32 | #endif |
33 | |
34 | #include <stdio.h> |
35 | #ifdef NSS_ENABLE_ZLIB |
36 | #include "zlib.h" |
37 | #endif |
38 | |
39 | #ifndef PK11_SETATTRS |
40 | #define PK11_SETATTRS(x,id,v,l)(x)->type = (id); (x)->pValue=(v); (x)->ulValueLen = (l); (x)->type = (id); \ |
41 | (x)->pValue=(v); (x)->ulValueLen = (l); |
42 | #endif |
43 | |
44 | static SECStatus ssl3_AuthCertificate(sslSocket *ss); |
45 | static void ssl3_CleanupPeerCerts(sslSocket *ss); |
46 | static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, |
47 | PK11SlotInfo * serverKeySlot); |
48 | static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); |
49 | static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss); |
50 | static SECStatus ssl3_HandshakeFailure( sslSocket *ss); |
51 | static SECStatus ssl3_InitState( sslSocket *ss); |
52 | static SECStatus ssl3_SendCertificate( sslSocket *ss); |
53 | static SECStatus ssl3_SendCertificateStatus( sslSocket *ss); |
54 | static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); |
55 | static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); |
56 | static SECStatus ssl3_SendNextProto( sslSocket *ss); |
57 | static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); |
58 | static SECStatus ssl3_SendServerHello( sslSocket *ss); |
59 | static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); |
60 | static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss); |
61 | static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, |
62 | const unsigned char *b, |
63 | unsigned int l); |
64 | static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags); |
65 | static int ssl3_OIDToTLSHashAlgorithm(SECOidTag oid); |
66 | |
67 | static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, |
68 | int maxOutputLen, const unsigned char *input, |
69 | int inputLen); |
70 | #ifndef NO_PKCS11_BYPASS1 |
71 | static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt, |
72 | unsigned char *out, int *outlen, int maxout, |
73 | const unsigned char *in, int inlen, |
74 | const unsigned char *additionalData, |
75 | int additionalDataLen); |
76 | #endif |
77 | |
78 | #define MAX_SEND_BUF_LENGTH32000 32000 /* watch for 16-bit integer overflow */ |
79 | #define MIN_SEND_BUF_LENGTH4000 4000 |
80 | |
81 | /* This list of SSL3 cipher suites is sorted in descending order of |
82 | * precedence (desirability). It only includes cipher suites we implement. |
83 | * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites |
84 | * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c) |
85 | * |
86 | * Important: See bug 946147 before enabling, reordering, or adding any cipher |
87 | * suites to this list. |
88 | */ |
89 | static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED61] = { |
90 | /* cipher_suite policy enabled isPresent */ |
91 | |
92 | #ifdef NSS_ENABLE_ECC1 |
93 | { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA2560xC02B, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
94 | { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA2560xC02F, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
95 | /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around |
96 | * bug 946147. |
97 | */ |
98 | { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA0xC00A, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
99 | { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA0xC009, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
100 | { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA0xC013, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
101 | { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA2560xC023, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
102 | { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA2560xC027, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
103 | { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA0xC014, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
104 | { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA0xC008, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
105 | { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA0xC012, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
106 | { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA0xC007, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
107 | { TLS_ECDHE_RSA_WITH_RC4_128_SHA0xC011, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
108 | #endif /* NSS_ENABLE_ECC */ |
109 | |
110 | { TLS_DHE_RSA_WITH_AES_128_GCM_SHA2560x009E, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
111 | { TLS_DHE_RSA_WITH_AES_128_CBC_SHA0x0033, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
112 | { TLS_DHE_DSS_WITH_AES_128_CBC_SHA0x0032, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
113 | { TLS_DHE_RSA_WITH_AES_128_CBC_SHA2560x0067, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
114 | { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA0x0045, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
115 | { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA0x0044, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
116 | { TLS_DHE_RSA_WITH_AES_256_CBC_SHA0x0039, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
117 | { TLS_DHE_DSS_WITH_AES_256_CBC_SHA0x0038, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
118 | { TLS_DHE_RSA_WITH_AES_256_CBC_SHA2560x006B, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
119 | { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA0x0088, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
120 | { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA0x0087, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
121 | { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA0x0016, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
122 | { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA0x0013, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
123 | { TLS_DHE_DSS_WITH_RC4_128_SHA0x0066, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
124 | |
125 | #ifdef NSS_ENABLE_ECC1 |
126 | { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA0xC004, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
127 | { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA0xC00E, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
128 | { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA0xC005, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
129 | { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA0xC00F, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
130 | { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA0xC003, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
131 | { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA0xC00D, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
132 | { TLS_ECDH_ECDSA_WITH_RC4_128_SHA0xC002, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
133 | { TLS_ECDH_RSA_WITH_RC4_128_SHA0xC00C, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
134 | #endif /* NSS_ENABLE_ECC */ |
135 | |
136 | /* RSA */ |
137 | { TLS_RSA_WITH_AES_128_GCM_SHA2560x009C, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
138 | { TLS_RSA_WITH_AES_128_CBC_SHA0x002F, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
139 | { TLS_RSA_WITH_AES_128_CBC_SHA2560x003C, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
140 | { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA0x0041, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
141 | { TLS_RSA_WITH_AES_256_CBC_SHA0x0035, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
142 | { TLS_RSA_WITH_AES_256_CBC_SHA2560x003D, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
143 | { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA0x0084, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
144 | { TLS_RSA_WITH_SEED_CBC_SHA0x0096, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
145 | { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA0xfeff, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
146 | { SSL_RSA_WITH_3DES_EDE_CBC_SHA0x000a, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
147 | { SSL_RSA_WITH_RC4_128_SHA0x0005, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
148 | { SSL_RSA_WITH_RC4_128_MD50x0004, SSL_ALLOWED1, PR_TRUE1, PR_FALSE0}, |
149 | |
150 | /* 56-bit DES "domestic" cipher suites */ |
151 | { SSL_DHE_RSA_WITH_DES_CBC_SHA0x0015, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
152 | { SSL_DHE_DSS_WITH_DES_CBC_SHA0x0012, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
153 | { SSL_RSA_FIPS_WITH_DES_CBC_SHA0xfefe, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
154 | { SSL_RSA_WITH_DES_CBC_SHA0x0009, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
155 | |
156 | /* export ciphersuites with 1024-bit public key exchange keys */ |
157 | { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA0x0064, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
158 | { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA0x0062, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
159 | |
160 | /* export ciphersuites with 512-bit public key exchange keys */ |
161 | { SSL_RSA_EXPORT_WITH_RC4_40_MD50x0003, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
162 | { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD50x0006, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
163 | |
164 | /* ciphersuites with no encryption */ |
165 | #ifdef NSS_ENABLE_ECC1 |
166 | { TLS_ECDHE_ECDSA_WITH_NULL_SHA0xC006, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
167 | { TLS_ECDHE_RSA_WITH_NULL_SHA0xC010, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
168 | { TLS_ECDH_RSA_WITH_NULL_SHA0xC00B, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
169 | { TLS_ECDH_ECDSA_WITH_NULL_SHA0xC001, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
170 | #endif /* NSS_ENABLE_ECC */ |
171 | { SSL_RSA_WITH_NULL_SHA0x0002, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
172 | { TLS_RSA_WITH_NULL_SHA2560x003B, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
173 | { SSL_RSA_WITH_NULL_MD50x0001, SSL_ALLOWED1, PR_FALSE0, PR_FALSE0}, |
174 | }; |
175 | |
176 | /* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order. |
177 | */ |
178 | #ifdef DEBUG1 |
179 | void ssl3_CheckCipherSuiteOrderConsistency() |
180 | { |
181 | unsigned int i; |
182 | |
183 | /* Note that SSL_ImplementedCiphers has more elements than cipherSuites |
184 | * because it SSL_ImplementedCiphers includes SSL 2.0 cipher suites. |
185 | */ |
186 | PORT_Assert(SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites))((SSL_NumImplementedCiphers >= (sizeof(cipherSuites)/sizeof ((cipherSuites)[0])))?((void)0):PR_Assert("SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites)" ,"ssl3con.c",186)); |
187 | |
188 | for (i = 0; i < PR_ARRAY_SIZE(cipherSuites)(sizeof(cipherSuites)/sizeof((cipherSuites)[0])); ++i) { |
189 | PORT_Assert(SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite)((SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite)? ((void)0):PR_Assert("SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite" ,"ssl3con.c",189)); |
190 | } |
191 | } |
192 | #endif |
193 | |
194 | /* This list of SSL3 compression methods is sorted in descending order of |
195 | * precedence (desirability). It only includes compression methods we |
196 | * implement. |
197 | */ |
198 | static const /*SSLCompressionMethod*/ PRUint8 compressions [] = { |
199 | #ifdef NSS_ENABLE_ZLIB |
200 | ssl_compression_deflate, |
201 | #endif |
202 | ssl_compression_null |
203 | }; |
204 | |
205 | static const int compressionMethodsCount = |
206 | sizeof(compressions) / sizeof(compressions[0]); |
207 | |
208 | /* compressionEnabled returns true iff the compression algorithm is enabled |
209 | * for the given SSL socket. */ |
210 | static PRBool |
211 | compressionEnabled(sslSocket *ss, SSLCompressionMethod compression) |
212 | { |
213 | switch (compression) { |
214 | case ssl_compression_null: |
215 | return PR_TRUE1; /* Always enabled */ |
216 | #ifdef NSS_ENABLE_ZLIB |
217 | case ssl_compression_deflate: |
218 | return ss->opt.enableDeflate; |
219 | #endif |
220 | default: |
221 | return PR_FALSE0; |
222 | } |
223 | } |
224 | |
225 | static const /*SSL3ClientCertificateType */ PRUint8 certificate_types [] = { |
226 | ct_RSA_sign, |
227 | #ifdef NSS_ENABLE_ECC1 |
228 | ct_ECDSA_sign, |
229 | #endif /* NSS_ENABLE_ECC */ |
230 | ct_DSS_sign, |
231 | }; |
232 | |
233 | /* This block is the contents of the supported_signature_algorithms field of |
234 | * our TLS 1.2 CertificateRequest message, in wire format. See |
235 | * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 |
236 | * |
237 | * This block contains only sha256 entries because we only support TLS 1.2 |
238 | * CertificateVerify messages that use the handshake hash. */ |
239 | static const PRUint8 supported_signature_algorithms[] = { |
240 | tls_hash_sha256, tls_sig_rsa, |
241 | #ifdef NSS_ENABLE_ECC1 |
242 | tls_hash_sha256, tls_sig_ecdsa, |
243 | #endif |
244 | tls_hash_sha256, tls_sig_dsa, |
245 | }; |
246 | |
247 | #define EXPORT_RSA_KEY_LENGTH64 64 /* bytes */ |
248 | |
249 | |
250 | /* This global item is used only in servers. It is is initialized by |
251 | ** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest(). |
252 | */ |
253 | CERTDistNames *ssl3_server_ca_list = NULL((void*)0); |
254 | static SSL3Statistics ssl3stats; |
255 | |
256 | /* indexed by SSL3BulkCipher */ |
257 | static const ssl3BulkCipherDef bulk_cipher_defs[] = { |
258 | /* |--------- Lengths --------| */ |
259 | /* cipher calg k s type i b t n */ |
260 | /* e e v l a o */ |
261 | /* y c | o g n */ |
262 | /* | r | c | c */ |
263 | /* | e | k | e */ |
264 | /* | t | | | | */ |
265 | {cipher_null, calg_nullssl_calg_null, 0, 0, type_stream, 0, 0, 0, 0}, |
266 | {cipher_rc4, calg_rc4ssl_calg_rc4, 16,16, type_stream, 0, 0, 0, 0}, |
267 | {cipher_rc4_40, calg_rc4ssl_calg_rc4, 16, 5, type_stream, 0, 0, 0, 0}, |
268 | {cipher_rc4_56, calg_rc4ssl_calg_rc4, 16, 7, type_stream, 0, 0, 0, 0}, |
269 | {cipher_rc2, calg_rc2ssl_calg_rc2, 16,16, type_block, 8, 8, 0, 0}, |
270 | {cipher_rc2_40, calg_rc2ssl_calg_rc2, 16, 5, type_block, 8, 8, 0, 0}, |
271 | {cipher_des, calg_desssl_calg_des, 8, 8, type_block, 8, 8, 0, 0}, |
272 | {cipher_3des, calg_3desssl_calg_3des, 24,24, type_block, 8, 8, 0, 0}, |
273 | {cipher_des40, calg_desssl_calg_des, 8, 5, type_block, 8, 8, 0, 0}, |
274 | {cipher_idea, calg_ideassl_calg_idea, 16,16, type_block, 8, 8, 0, 0}, |
275 | {cipher_aes_128, calg_aesssl_calg_aes, 16,16, type_block, 16,16, 0, 0}, |
276 | {cipher_aes_256, calg_aesssl_calg_aes, 32,32, type_block, 16,16, 0, 0}, |
277 | {cipher_camellia_128, calg_camelliassl_calg_camellia, 16,16, type_block, 16,16, 0, 0}, |
278 | {cipher_camellia_256, calg_camelliassl_calg_camellia, 32,32, type_block, 16,16, 0, 0}, |
279 | {cipher_seed, calg_seedssl_calg_seed, 16,16, type_block, 16,16, 0, 0}, |
280 | {cipher_aes_128_gcm, calg_aes_gcmssl_calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8}, |
281 | {cipher_missing, calg_nullssl_calg_null, 0, 0, type_stream, 0, 0, 0, 0}, |
282 | }; |
283 | |
284 | static const ssl3KEADef kea_defs[] = |
285 | { /* indexed by SSL3KeyExchangeAlgorithm */ |
286 | /* kea exchKeyType signKeyType is_limited limit tls_keygen */ |
287 | {kea_null, kt_nullssl_kea_null, sign_nullssl_sign_null, PR_FALSE0, 0, PR_FALSE0}, |
288 | {kea_rsa, kt_rsassl_kea_rsa, sign_rsassl_sign_rsa, PR_FALSE0, 0, PR_FALSE0}, |
289 | {kea_rsa_export, kt_rsassl_kea_rsa, sign_rsassl_sign_rsa, PR_TRUE1, 512, PR_FALSE0}, |
290 | {kea_rsa_export_1024,kt_rsassl_kea_rsa, sign_rsassl_sign_rsa, PR_TRUE1, 1024, PR_FALSE0}, |
291 | {kea_dh_dss, kt_dhssl_kea_dh, sign_dsassl_sign_dsa, PR_FALSE0, 0, PR_FALSE0}, |
292 | {kea_dh_dss_export, kt_dhssl_kea_dh, sign_dsassl_sign_dsa, PR_TRUE1, 512, PR_FALSE0}, |
293 | {kea_dh_rsa, kt_dhssl_kea_dh, sign_rsassl_sign_rsa, PR_FALSE0, 0, PR_FALSE0}, |
294 | {kea_dh_rsa_export, kt_dhssl_kea_dh, sign_rsassl_sign_rsa, PR_TRUE1, 512, PR_FALSE0}, |
295 | {kea_dhe_dss, kt_dhssl_kea_dh, sign_dsassl_sign_dsa, PR_FALSE0, 0, PR_FALSE0}, |
296 | {kea_dhe_dss_export, kt_dhssl_kea_dh, sign_dsassl_sign_dsa, PR_TRUE1, 512, PR_FALSE0}, |
297 | {kea_dhe_rsa, kt_dhssl_kea_dh, sign_rsassl_sign_rsa, PR_FALSE0, 0, PR_FALSE0}, |
298 | {kea_dhe_rsa_export, kt_dhssl_kea_dh, sign_rsassl_sign_rsa, PR_TRUE1, 512, PR_FALSE0}, |
299 | {kea_dh_anon, kt_dhssl_kea_dh, sign_nullssl_sign_null, PR_FALSE0, 0, PR_FALSE0}, |
300 | {kea_dh_anon_export, kt_dhssl_kea_dh, sign_nullssl_sign_null, PR_TRUE1, 512, PR_FALSE0}, |
301 | {kea_rsa_fips, kt_rsassl_kea_rsa, sign_rsassl_sign_rsa, PR_FALSE0, 0, PR_TRUE1 }, |
302 | #ifdef NSS_ENABLE_ECC1 |
303 | {kea_ecdh_ecdsa, kt_ecdhssl_kea_ecdh, sign_ecdsassl_sign_ecdsa, PR_FALSE0, 0, PR_FALSE0}, |
304 | {kea_ecdhe_ecdsa, kt_ecdhssl_kea_ecdh, sign_ecdsassl_sign_ecdsa, PR_FALSE0, 0, PR_FALSE0}, |
305 | {kea_ecdh_rsa, kt_ecdhssl_kea_ecdh, sign_rsassl_sign_rsa, PR_FALSE0, 0, PR_FALSE0}, |
306 | {kea_ecdhe_rsa, kt_ecdhssl_kea_ecdh, sign_rsassl_sign_rsa, PR_FALSE0, 0, PR_FALSE0}, |
307 | {kea_ecdh_anon, kt_ecdhssl_kea_ecdh, sign_nullssl_sign_null, PR_FALSE0, 0, PR_FALSE0}, |
308 | #endif /* NSS_ENABLE_ECC */ |
309 | }; |
310 | |
311 | /* must use ssl_LookupCipherSuiteDef to access */ |
312 | static const ssl3CipherSuiteDef cipher_suite_defs[] = |
313 | { |
314 | /* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */ |
315 | |
316 | {SSL_NULL_WITH_NULL_NULL0x0000, cipher_null, mac_nullssl_mac_null, kea_null}, |
317 | {SSL_RSA_WITH_NULL_MD50x0001, cipher_null, mac_md5ssl_mac_md5, kea_rsa}, |
318 | {SSL_RSA_WITH_NULL_SHA0x0002, cipher_null, mac_shassl_mac_sha, kea_rsa}, |
319 | {TLS_RSA_WITH_NULL_SHA2560x003B, cipher_null, hmac_sha256ssl_hmac_sha256, kea_rsa}, |
320 | {SSL_RSA_EXPORT_WITH_RC4_40_MD50x0003,cipher_rc4_40, mac_md5ssl_mac_md5, kea_rsa_export}, |
321 | {SSL_RSA_WITH_RC4_128_MD50x0004, cipher_rc4, mac_md5ssl_mac_md5, kea_rsa}, |
322 | {SSL_RSA_WITH_RC4_128_SHA0x0005, cipher_rc4, mac_shassl_mac_sha, kea_rsa}, |
323 | {SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD50x0006, |
324 | cipher_rc2_40, mac_md5ssl_mac_md5, kea_rsa_export}, |
325 | #if 0 /* not implemented */ |
326 | {SSL_RSA_WITH_IDEA_CBC_SHA0x0007, cipher_idea, mac_shassl_mac_sha, kea_rsa}, |
327 | {SSL_RSA_EXPORT_WITH_DES40_CBC_SHA0x0008, |
328 | cipher_des40, mac_shassl_mac_sha, kea_rsa_export}, |
329 | #endif |
330 | {SSL_RSA_WITH_DES_CBC_SHA0x0009, cipher_des, mac_shassl_mac_sha, kea_rsa}, |
331 | {SSL_RSA_WITH_3DES_EDE_CBC_SHA0x000a, cipher_3des, mac_shassl_mac_sha, kea_rsa}, |
332 | {SSL_DHE_DSS_WITH_DES_CBC_SHA0x0012, cipher_des, mac_shassl_mac_sha, kea_dhe_dss}, |
333 | {SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA0x0013, |
334 | cipher_3des, mac_shassl_mac_sha, kea_dhe_dss}, |
335 | {TLS_DHE_DSS_WITH_RC4_128_SHA0x0066, cipher_rc4, mac_shassl_mac_sha, kea_dhe_dss}, |
336 | #if 0 /* not implemented */ |
337 | {SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA0x000b, |
338 | cipher_des40, mac_shassl_mac_sha, kea_dh_dss_export}, |
339 | {SSL_DH_DSS_DES_CBC_SHA, cipher_des, mac_shassl_mac_sha, kea_dh_dss}, |
340 | {SSL_DH_DSS_3DES_CBC_SHA, cipher_3des, mac_shassl_mac_sha, kea_dh_dss}, |
341 | {SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA0x000e, |
342 | cipher_des40, mac_shassl_mac_sha, kea_dh_rsa_export}, |
343 | {SSL_DH_RSA_DES_CBC_SHA, cipher_des, mac_shassl_mac_sha, kea_dh_rsa}, |
344 | {SSL_DH_RSA_3DES_CBC_SHA, cipher_3des, mac_shassl_mac_sha, kea_dh_rsa}, |
345 | {SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA0x0011, |
346 | cipher_des40, mac_shassl_mac_sha, kea_dh_dss_export}, |
347 | {SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA0x0014, |
348 | cipher_des40, mac_shassl_mac_sha, kea_dh_rsa_export}, |
349 | #endif |
350 | {SSL_DHE_RSA_WITH_DES_CBC_SHA0x0015, cipher_des, mac_shassl_mac_sha, kea_dhe_rsa}, |
351 | {SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA0x0016, |
352 | cipher_3des, mac_shassl_mac_sha, kea_dhe_rsa}, |
353 | #if 0 |
354 | {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5ssl_mac_md5, kea_dh_anon_export}, |
355 | {SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA0x0019, |
356 | cipher_des40, mac_shassl_mac_sha, kea_dh_anon_export}, |
357 | {SSL_DH_ANON_DES_CBC_SHA, cipher_des, mac_shassl_mac_sha, kea_dh_anon}, |
358 | {SSL_DH_ANON_3DES_CBC_SHA, cipher_3des, mac_shassl_mac_sha, kea_dh_anon}, |
359 | #endif |
360 | |
361 | |
362 | /* New TLS cipher suites */ |
363 | {TLS_RSA_WITH_AES_128_CBC_SHA0x002F, cipher_aes_128, mac_shassl_mac_sha, kea_rsa}, |
364 | {TLS_RSA_WITH_AES_128_CBC_SHA2560x003C, cipher_aes_128, hmac_sha256ssl_hmac_sha256, kea_rsa}, |
365 | {TLS_DHE_DSS_WITH_AES_128_CBC_SHA0x0032, cipher_aes_128, mac_shassl_mac_sha, kea_dhe_dss}, |
366 | {TLS_DHE_RSA_WITH_AES_128_CBC_SHA0x0033, cipher_aes_128, mac_shassl_mac_sha, kea_dhe_rsa}, |
367 | {TLS_DHE_RSA_WITH_AES_128_CBC_SHA2560x0067, cipher_aes_128, hmac_sha256ssl_hmac_sha256, kea_dhe_rsa}, |
368 | {TLS_RSA_WITH_AES_256_CBC_SHA0x0035, cipher_aes_256, mac_shassl_mac_sha, kea_rsa}, |
369 | {TLS_RSA_WITH_AES_256_CBC_SHA2560x003D, cipher_aes_256, hmac_sha256ssl_hmac_sha256, kea_rsa}, |
370 | {TLS_DHE_DSS_WITH_AES_256_CBC_SHA0x0038, cipher_aes_256, mac_shassl_mac_sha, kea_dhe_dss}, |
371 | {TLS_DHE_RSA_WITH_AES_256_CBC_SHA0x0039, cipher_aes_256, mac_shassl_mac_sha, kea_dhe_rsa}, |
372 | {TLS_DHE_RSA_WITH_AES_256_CBC_SHA2560x006B, cipher_aes_256, hmac_sha256ssl_hmac_sha256, kea_dhe_rsa}, |
373 | #if 0 |
374 | {TLS_DH_DSS_WITH_AES_128_CBC_SHA0x0030, cipher_aes_128, mac_shassl_mac_sha, kea_dh_dss}, |
375 | {TLS_DH_RSA_WITH_AES_128_CBC_SHA0x0031, cipher_aes_128, mac_shassl_mac_sha, kea_dh_rsa}, |
376 | {TLS_DH_ANON_WITH_AES_128_CBC_SHA0x0034, cipher_aes_128, mac_shassl_mac_sha, kea_dh_anon}, |
377 | {TLS_DH_DSS_WITH_AES_256_CBC_SHA0x0036, cipher_aes_256, mac_shassl_mac_sha, kea_dh_dss}, |
378 | {TLS_DH_RSA_WITH_AES_256_CBC_SHA0x0037, cipher_aes_256, mac_shassl_mac_sha, kea_dh_rsa}, |
379 | {TLS_DH_ANON_WITH_AES_256_CBC_SHA0x003A, cipher_aes_256, mac_shassl_mac_sha, kea_dh_anon}, |
380 | #endif |
381 | |
382 | {TLS_RSA_WITH_SEED_CBC_SHA0x0096, cipher_seed, mac_shassl_mac_sha, kea_rsa}, |
383 | |
384 | {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA0x0041, cipher_camellia_128, mac_shassl_mac_sha, kea_rsa}, |
385 | {TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA0x0044, |
386 | cipher_camellia_128, mac_shassl_mac_sha, kea_dhe_dss}, |
387 | {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA0x0045, |
388 | cipher_camellia_128, mac_shassl_mac_sha, kea_dhe_rsa}, |
389 | {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA0x0084, cipher_camellia_256, mac_shassl_mac_sha, kea_rsa}, |
390 | {TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA0x0087, |
391 | cipher_camellia_256, mac_shassl_mac_sha, kea_dhe_dss}, |
392 | {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA0x0088, |
393 | cipher_camellia_256, mac_shassl_mac_sha, kea_dhe_rsa}, |
394 | |
395 | {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA0x0062, |
396 | cipher_des, mac_shassl_mac_sha,kea_rsa_export_1024}, |
397 | {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA0x0064, |
398 | cipher_rc4_56, mac_shassl_mac_sha,kea_rsa_export_1024}, |
399 | |
400 | {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA0xfeff, cipher_3des, mac_shassl_mac_sha, kea_rsa_fips}, |
401 | {SSL_RSA_FIPS_WITH_DES_CBC_SHA0xfefe, cipher_des, mac_shassl_mac_sha, kea_rsa_fips}, |
402 | |
403 | {TLS_DHE_RSA_WITH_AES_128_GCM_SHA2560x009E, cipher_aes_128_gcm, mac_aeadssl_mac_aead, kea_dhe_rsa}, |
404 | {TLS_RSA_WITH_AES_128_GCM_SHA2560x009C, cipher_aes_128_gcm, mac_aeadssl_mac_aead, kea_rsa}, |
405 | {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA2560xC02F, cipher_aes_128_gcm, mac_aeadssl_mac_aead, kea_ecdhe_rsa}, |
406 | {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA2560xC02B, cipher_aes_128_gcm, mac_aeadssl_mac_aead, kea_ecdhe_ecdsa}, |
407 | |
408 | #ifdef NSS_ENABLE_ECC1 |
409 | {TLS_ECDH_ECDSA_WITH_NULL_SHA0xC001, cipher_null, mac_shassl_mac_sha, kea_ecdh_ecdsa}, |
410 | {TLS_ECDH_ECDSA_WITH_RC4_128_SHA0xC002, cipher_rc4, mac_shassl_mac_sha, kea_ecdh_ecdsa}, |
411 | {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA0xC003, cipher_3des, mac_shassl_mac_sha, kea_ecdh_ecdsa}, |
412 | {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA0xC004, cipher_aes_128, mac_shassl_mac_sha, kea_ecdh_ecdsa}, |
413 | {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA0xC005, cipher_aes_256, mac_shassl_mac_sha, kea_ecdh_ecdsa}, |
414 | |
415 | {TLS_ECDHE_ECDSA_WITH_NULL_SHA0xC006, cipher_null, mac_shassl_mac_sha, kea_ecdhe_ecdsa}, |
416 | {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA0xC007, cipher_rc4, mac_shassl_mac_sha, kea_ecdhe_ecdsa}, |
417 | {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA0xC008, cipher_3des, mac_shassl_mac_sha, kea_ecdhe_ecdsa}, |
418 | {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA0xC009, cipher_aes_128, mac_shassl_mac_sha, kea_ecdhe_ecdsa}, |
419 | {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA2560xC023, cipher_aes_128, hmac_sha256ssl_hmac_sha256, kea_ecdhe_ecdsa}, |
420 | {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA0xC00A, cipher_aes_256, mac_shassl_mac_sha, kea_ecdhe_ecdsa}, |
421 | |
422 | {TLS_ECDH_RSA_WITH_NULL_SHA0xC00B, cipher_null, mac_shassl_mac_sha, kea_ecdh_rsa}, |
423 | {TLS_ECDH_RSA_WITH_RC4_128_SHA0xC00C, cipher_rc4, mac_shassl_mac_sha, kea_ecdh_rsa}, |
424 | {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA0xC00D, cipher_3des, mac_shassl_mac_sha, kea_ecdh_rsa}, |
425 | {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA0xC00E, cipher_aes_128, mac_shassl_mac_sha, kea_ecdh_rsa}, |
426 | {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA0xC00F, cipher_aes_256, mac_shassl_mac_sha, kea_ecdh_rsa}, |
427 | |
428 | {TLS_ECDHE_RSA_WITH_NULL_SHA0xC010, cipher_null, mac_shassl_mac_sha, kea_ecdhe_rsa}, |
429 | {TLS_ECDHE_RSA_WITH_RC4_128_SHA0xC011, cipher_rc4, mac_shassl_mac_sha, kea_ecdhe_rsa}, |
430 | {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA0xC012, cipher_3des, mac_shassl_mac_sha, kea_ecdhe_rsa}, |
431 | {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA0xC013, cipher_aes_128, mac_shassl_mac_sha, kea_ecdhe_rsa}, |
432 | {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA2560xC027, cipher_aes_128, hmac_sha256ssl_hmac_sha256, kea_ecdhe_rsa}, |
433 | {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA0xC014, cipher_aes_256, mac_shassl_mac_sha, kea_ecdhe_rsa}, |
434 | |
435 | #if 0 |
436 | {TLS_ECDH_anon_WITH_NULL_SHA0xC015, cipher_null, mac_shassl_mac_sha, kea_ecdh_anon}, |
437 | {TLS_ECDH_anon_WITH_RC4_128_SHA0xC016, cipher_rc4, mac_shassl_mac_sha, kea_ecdh_anon}, |
438 | {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA0xC017, cipher_3des, mac_shassl_mac_sha, kea_ecdh_anon}, |
439 | {TLS_ECDH_anon_WITH_AES_128_CBC_SHA0xC018, cipher_aes_128, mac_shassl_mac_sha, kea_ecdh_anon}, |
440 | {TLS_ECDH_anon_WITH_AES_256_CBC_SHA0xC019, cipher_aes_256, mac_shassl_mac_sha, kea_ecdh_anon}, |
441 | #endif |
442 | #endif /* NSS_ENABLE_ECC */ |
443 | }; |
444 | |
445 | static const CK_MECHANISM_TYPE kea_alg_defs[] = { |
446 | 0x80000000L, |
447 | CKM_RSA_PKCS0x00000001, |
448 | CKM_DH_PKCS_DERIVE0x00000021, |
449 | CKM_KEA_KEY_DERIVE0x00001011, |
450 | CKM_ECDH1_DERIVE0x00001050 |
451 | }; |
452 | |
453 | typedef struct SSLCipher2MechStr { |
454 | SSLCipherAlgorithm calg; |
455 | CK_MECHANISM_TYPE cmech; |
456 | } SSLCipher2Mech; |
457 | |
458 | /* indexed by type SSLCipherAlgorithm */ |
459 | static const SSLCipher2Mech alg2Mech[] = { |
460 | /* calg, cmech */ |
461 | { calg_nullssl_calg_null , (CK_MECHANISM_TYPE)0x80000000L }, |
462 | { calg_rc4ssl_calg_rc4 , CKM_RC40x00000111 }, |
463 | { calg_rc2ssl_calg_rc2 , CKM_RC2_CBC0x00000102 }, |
464 | { calg_desssl_calg_des , CKM_DES_CBC0x00000122 }, |
465 | { calg_3desssl_calg_3des , CKM_DES3_CBC0x00000133 }, |
466 | { calg_ideassl_calg_idea , CKM_IDEA_CBC0x00000342 }, |
467 | { calg_fortezzassl_calg_fortezza , CKM_SKIPJACK_CBC640x00001002 }, |
468 | { calg_aesssl_calg_aes , CKM_AES_CBC0x00001082 }, |
469 | { calg_camelliassl_calg_camellia , CKM_CAMELLIA_CBC0x00000552 }, |
470 | { calg_seedssl_calg_seed , CKM_SEED_CBC0x00000652 }, |
471 | { calg_aes_gcmssl_calg_aes_gcm , CKM_AES_GCM0x00001087 }, |
472 | /* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */ |
473 | }; |
474 | |
475 | #define mmech_invalid(CK_MECHANISM_TYPE)0x80000000L (CK_MECHANISM_TYPE)0x80000000L |
476 | #define mmech_md50x00000380 CKM_SSL3_MD5_MAC0x00000380 |
477 | #define mmech_sha0x00000381 CKM_SSL3_SHA1_MAC0x00000381 |
478 | #define mmech_md5_hmac0x00000211 CKM_MD5_HMAC0x00000211 |
479 | #define mmech_sha_hmac0x00000221 CKM_SHA_1_HMAC0x00000221 |
480 | #define mmech_sha256_hmac0x00000251 CKM_SHA256_HMAC0x00000251 |
481 | |
482 | static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ |
483 | /* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */ |
484 | /* mac mmech pad_size mac_size */ |
485 | { mac_nullssl_mac_null, mmech_invalid(CK_MECHANISM_TYPE)0x80000000L, 0, 0 }, |
486 | { mac_md5ssl_mac_md5, mmech_md50x00000380, 48, MD5_LENGTH16 }, |
487 | { mac_shassl_mac_sha, mmech_sha0x00000381, 40, SHA1_LENGTH20}, |
488 | {hmac_md5ssl_hmac_md5, mmech_md5_hmac0x00000211, 0, MD5_LENGTH16 }, |
489 | {hmac_shassl_hmac_sha, mmech_sha_hmac0x00000221, 0, SHA1_LENGTH20}, |
490 | {hmac_sha256ssl_hmac_sha256, mmech_sha256_hmac0x00000251, 0, SHA256_LENGTH32}, |
491 | { mac_aeadssl_mac_aead, mmech_invalid(CK_MECHANISM_TYPE)0x80000000L, 0, 0 }, |
492 | }; |
493 | |
494 | /* indexed by SSL3BulkCipher */ |
495 | const char * const ssl3_cipherName[] = { |
496 | "NULL", |
497 | "RC4", |
498 | "RC4-40", |
499 | "RC4-56", |
500 | "RC2-CBC", |
501 | "RC2-CBC-40", |
502 | "DES-CBC", |
503 | "3DES-EDE-CBC", |
504 | "DES-CBC-40", |
505 | "IDEA-CBC", |
506 | "AES-128", |
507 | "AES-256", |
508 | "Camellia-128", |
509 | "Camellia-256", |
510 | "SEED-CBC", |
511 | "AES-128-GCM", |
512 | "missing" |
513 | }; |
514 | |
515 | #ifdef NSS_ENABLE_ECC1 |
516 | /* The ECCWrappedKeyInfo structure defines how various pieces of |
517 | * information are laid out within wrappedSymmetricWrappingkey |
518 | * for ECDH key exchange. Since wrappedSymmetricWrappingkey is |
519 | * a 512-byte buffer (see sslimpl.h), the variable length field |
520 | * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes. |
521 | * |
522 | * XXX For now, NSS only supports named elliptic curves of size 571 bits |
523 | * or smaller. The public value will fit within 145 bytes and EC params |
524 | * will fit within 12 bytes. We'll need to revisit this when NSS |
525 | * supports arbitrary curves. |
526 | */ |
527 | #define MAX_EC_WRAPPED_KEY_BUFLEN504 504 |
528 | |
529 | typedef struct ECCWrappedKeyInfoStr { |
530 | PRUint16 size; /* EC public key size in bits */ |
531 | PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */ |
532 | PRUint16 pubValueLen; /* length (in bytes) of EC public value */ |
533 | PRUint16 wrappedKeyLen; /* length (in bytes) of the wrapped key */ |
534 | PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN504]; /* this buffer contains the */ |
535 | /* EC public-key params, the EC public value and the wrapped key */ |
536 | } ECCWrappedKeyInfo; |
537 | #endif /* NSS_ENABLE_ECC */ |
538 | |
539 | #if defined(TRACE) |
540 | |
541 | static char * |
542 | ssl3_DecodeHandshakeType(int msgType) |
543 | { |
544 | char * rv; |
545 | static char line[40]; |
546 | |
547 | switch(msgType) { |
548 | case hello_request: rv = "hello_request (0)"; break; |
549 | case client_hello: rv = "client_hello (1)"; break; |
550 | case server_hello: rv = "server_hello (2)"; break; |
551 | case hello_verify_request: rv = "hello_verify_request (3)"; break; |
552 | case certificate: rv = "certificate (11)"; break; |
553 | case server_key_exchange: rv = "server_key_exchange (12)"; break; |
554 | case certificate_request: rv = "certificate_request (13)"; break; |
555 | case server_hello_done: rv = "server_hello_done (14)"; break; |
556 | case certificate_verify: rv = "certificate_verify (15)"; break; |
557 | case client_key_exchange: rv = "client_key_exchange (16)"; break; |
558 | case finished: rv = "finished (20)"; break; |
559 | default: |
560 | sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType); |
561 | rv = line; |
562 | } |
563 | return rv; |
564 | } |
565 | |
566 | static char * |
567 | ssl3_DecodeContentType(int msgType) |
568 | { |
569 | char * rv; |
570 | static char line[40]; |
571 | |
572 | switch(msgType) { |
573 | case content_change_cipher_spec: |
574 | rv = "change_cipher_spec (20)"; break; |
575 | case content_alert: rv = "alert (21)"; break; |
576 | case content_handshake: rv = "handshake (22)"; break; |
577 | case content_application_data: |
578 | rv = "application_data (23)"; break; |
579 | default: |
580 | sprintf(line, "*UNKNOWN* record type! (%d)", msgType); |
581 | rv = line; |
582 | } |
583 | return rv; |
584 | } |
585 | |
586 | #endif |
587 | |
588 | SSL3Statistics * |
589 | SSL_GetStatistics(void) |
590 | { |
591 | return &ssl3stats; |
592 | } |
593 | |
594 | typedef struct tooLongStr { |
595 | #if defined(IS_LITTLE_ENDIAN1) |
596 | PRInt32 low; |
597 | PRInt32 high; |
598 | #else |
599 | PRInt32 high; |
600 | PRInt32 low; |
601 | #endif |
602 | } tooLong; |
603 | |
604 | void SSL_AtomicIncrementLong(long * x) |
605 | { |
606 | if ((sizeof *x) == sizeof(PRInt32)) { |
607 | PR_ATOMIC_INCREMENT((PRInt32 *)x)__sync_add_and_fetch((PRInt32 *)x, 1); |
608 | } else { |
609 | tooLong * tl = (tooLong *)x; |
610 | if (PR_ATOMIC_INCREMENT(&tl->low)__sync_add_and_fetch(&tl->low, 1) == 0) |
611 | PR_ATOMIC_INCREMENT(&tl->high)__sync_add_and_fetch(&tl->high, 1); |
612 | } |
613 | } |
614 | |
615 | static PRBool |
616 | ssl3_CipherSuiteAllowedForVersionRange( |
617 | ssl3CipherSuite cipherSuite, |
618 | const SSLVersionRange *vrange) |
619 | { |
620 | switch (cipherSuite) { |
621 | /* See RFC 4346 A.5. Export cipher suites must not be used in TLS 1.1 or |
622 | * later. This set of cipher suites is similar to, but different from, the |
623 | * set of cipher suites considered exportable by SSL_IsExportCipherSuite. |
624 | */ |
625 | case SSL_RSA_EXPORT_WITH_RC4_40_MD50x0003: |
626 | case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD50x0006: |
627 | /* SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented |
628 | * SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented |
629 | * SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented |
630 | * SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented |
631 | * SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented |
632 | * SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5: never implemented |
633 | * SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA: never implemented |
634 | */ |
635 | return vrange->min <= SSL_LIBRARY_VERSION_TLS_1_00x0301; |
636 | case TLS_DHE_RSA_WITH_AES_256_CBC_SHA2560x006B: |
637 | case TLS_RSA_WITH_AES_256_CBC_SHA2560x003D: |
638 | case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA2560xC023: |
639 | case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA2560xC02B: |
640 | case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA2560xC027: |
641 | case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA2560xC02F: |
642 | case TLS_DHE_RSA_WITH_AES_128_CBC_SHA2560x0067: |
643 | case TLS_DHE_RSA_WITH_AES_128_GCM_SHA2560x009E: |
644 | case TLS_RSA_WITH_AES_128_CBC_SHA2560x003C: |
645 | case TLS_RSA_WITH_AES_128_GCM_SHA2560x009C: |
646 | case TLS_RSA_WITH_NULL_SHA2560x003B: |
647 | return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_20x0303; |
648 | default: |
649 | return PR_TRUE1; |
650 | } |
651 | } |
652 | |
653 | /* return pointer to ssl3CipherSuiteDef for suite, or NULL */ |
654 | /* XXX This does a linear search. A binary search would be better. */ |
655 | static const ssl3CipherSuiteDef * |
656 | ssl_LookupCipherSuiteDef(ssl3CipherSuite suite) |
657 | { |
658 | int cipher_suite_def_len = |
659 | sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]); |
660 | int i; |
661 | |
662 | for (i = 0; i < cipher_suite_def_len; i++) { |
663 | if (cipher_suite_defs[i].cipher_suite == suite) |
664 | return &cipher_suite_defs[i]; |
665 | } |
666 | PORT_Assert(PR_FALSE)((0)?((void)0):PR_Assert("PR_FALSE","ssl3con.c",666)); /* We should never get here. */ |
667 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
668 | return NULL((void*)0); |
669 | } |
670 | |
671 | /* Find the cipher configuration struct associate with suite */ |
672 | /* XXX This does a linear search. A binary search would be better. */ |
673 | static ssl3CipherSuiteCfg * |
674 | ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites) |
675 | { |
676 | int i; |
677 | |
678 | for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED61; i++) { |
679 | if (suites[i].cipher_suite == suite) |
680 | return &suites[i]; |
681 | } |
682 | /* return NULL and let the caller handle it. */ |
683 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
684 | return NULL((void*)0); |
685 | } |
686 | |
687 | |
688 | /* Initialize the suite->isPresent value for config_match |
689 | * Returns count of enabled ciphers supported by extant tokens, |
690 | * regardless of policy or user preference. |
691 | * If this returns zero, the user cannot do SSL v3. |
692 | */ |
693 | int |
694 | ssl3_config_match_init(sslSocket *ss) |
695 | { |
696 | ssl3CipherSuiteCfg * suite; |
697 | const ssl3CipherSuiteDef *cipher_def; |
698 | SSLCipherAlgorithm cipher_alg; |
699 | CK_MECHANISM_TYPE cipher_mech; |
700 | SSL3KEAType exchKeyType; |
701 | int i; |
702 | int numPresent = 0; |
703 | int numEnabled = 0; |
704 | PRBool isServer; |
705 | sslServerCerts *svrAuth; |
706 | |
707 | PORT_Assert(ss)((ss)?((void)0):PR_Assert("ss","ssl3con.c",707)); |
708 | if (!ss) { |
709 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
710 | return 0; |
711 | } |
712 | if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)((&ss->vrange)->min == 0)) { |
713 | return 0; |
714 | } |
715 | isServer = (PRBool)(ss->sec.isServer != 0); |
716 | |
717 | for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED61; i++) { |
718 | suite = &ss->cipherSuites[i]; |
719 | if (suite->enabled) { |
720 | ++numEnabled; |
721 | /* We need the cipher defs to see if we have a token that can handle |
722 | * this cipher. It isn't part of the static definition. |
723 | */ |
724 | cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite); |
725 | if (!cipher_def) { |
726 | suite->isPresent = PR_FALSE0; |
727 | continue; |
728 | } |
729 | cipher_alg = bulk_cipher_defs[cipher_def->bulk_cipher_alg].calg; |
730 | PORT_Assert( alg2Mech[cipher_alg].calg == cipher_alg)((alg2Mech[cipher_alg].calg == cipher_alg)?((void)0):PR_Assert ("alg2Mech[cipher_alg].calg == cipher_alg","ssl3con.c",730)); |
731 | cipher_mech = alg2Mech[cipher_alg].cmech; |
732 | exchKeyType = |
733 | kea_defs[cipher_def->key_exchange_alg].exchKeyType; |
734 | #ifndef NSS_ENABLE_ECC1 |
735 | svrAuth = ss->serverCerts + exchKeyType; |
736 | #else |
737 | /* XXX SSLKEAType isn't really a good choice for |
738 | * indexing certificates. It doesn't work for |
739 | * (EC)DHE-* ciphers. Here we use a hack to ensure |
740 | * that the server uses an RSA cert for (EC)DHE-RSA. |
741 | */ |
742 | switch (cipher_def->key_exchange_alg) { |
743 | case kea_ecdhe_rsa: |
744 | #if NSS_SERVER_DHE_IMPLEMENTED |
745 | /* XXX NSS does not yet implement the server side of _DHE_ |
746 | * cipher suites. Correcting the computation for svrAuth, |
747 | * as the case below does, causes NSS SSL servers to begin to |
748 | * negotiate cipher suites they do not implement. So, until |
749 | * server side _DHE_ is implemented, keep this disabled. |
750 | */ |
751 | case kea_dhe_rsa: |
752 | #endif |
753 | svrAuth = ss->serverCerts + kt_rsassl_kea_rsa; |
754 | break; |
755 | case kea_ecdh_ecdsa: |
756 | case kea_ecdh_rsa: |
757 | /* |
758 | * XXX We ought to have different indices for |
759 | * ECDSA- and RSA-signed EC certificates so |
760 | * we could support both key exchange mechanisms |
761 | * simultaneously. For now, both of them use |
762 | * whatever is in the certificate slot for kt_ecdh |
763 | */ |
764 | default: |
765 | svrAuth = ss->serverCerts + exchKeyType; |
766 | break; |
767 | } |
768 | #endif /* NSS_ENABLE_ECC */ |
769 | |
770 | /* Mark the suites that are backed by real tokens, certs and keys */ |
771 | suite->isPresent = (PRBool) |
772 | (((exchKeyType == kt_nullssl_kea_null) || |
773 | ((!isServer || (svrAuth->serverKeyPair && |
774 | svrAuth->SERVERKEYserverKeyPair->privKey && |
775 | svrAuth->serverCertChain)) && |
776 | PK11_TokenExists(kea_alg_defs[exchKeyType]))) && |
777 | ((cipher_alg == calg_nullssl_calg_null) || PK11_TokenExists(cipher_mech))); |
778 | if (suite->isPresent) |
779 | ++numPresent; |
780 | } |
781 | } |
782 | PORT_Assert(numPresent > 0 || numEnabled == 0)((numPresent > 0 || numEnabled == 0)?((void)0):PR_Assert("numPresent > 0 || numEnabled == 0" ,"ssl3con.c",782)); |
783 | if (numPresent <= 0) { |
784 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_CIPHERS_SUPPORTED); |
785 | } |
786 | return numPresent; |
787 | } |
788 | |
789 | |
790 | /* return PR_TRUE if suite matches policy, enabled state and is applicable to |
791 | * the given version range. */ |
792 | /* It would be a REALLY BAD THING (tm) if we ever permitted the use |
793 | ** of a cipher that was NOT_ALLOWED. So, if this is ever called with |
794 | ** policy == SSL_NOT_ALLOWED, report no match. |
795 | */ |
796 | /* adjust suite enabled to the availability of a token that can do the |
797 | * cipher suite. */ |
798 | static PRBool |
799 | config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled, |
800 | const SSLVersionRange *vrange) |
801 | { |
802 | PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE)((policy != 0 && enabled != 0)?((void)0):PR_Assert("policy != SSL_NOT_ALLOWED && enabled != PR_FALSE" ,"ssl3con.c",802)); |
803 | if (policy == SSL_NOT_ALLOWED0 || !enabled) |
804 | return PR_FALSE0; |
805 | return (PRBool)(suite->enabled && |
806 | suite->isPresent && |
807 | suite->policy != SSL_NOT_ALLOWED0 && |
808 | suite->policy <= policy && |
809 | ssl3_CipherSuiteAllowedForVersionRange( |
810 | suite->cipher_suite, vrange)); |
811 | } |
812 | |
813 | /* return number of cipher suites that match policy, enabled state and are |
814 | * applicable for the configured protocol version range. */ |
815 | /* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */ |
816 | static int |
817 | count_cipher_suites(sslSocket *ss, int policy, PRBool enabled) |
818 | { |
819 | int i, count = 0; |
820 | |
821 | if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)((&ss->vrange)->min == 0)) { |
822 | return 0; |
823 | } |
824 | for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED61; i++) { |
825 | if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange)) |
826 | count++; |
827 | } |
828 | if (count <= 0) { |
829 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SSL_DISABLED); |
830 | } |
831 | return count; |
832 | } |
833 | |
834 | /* |
835 | * Null compression, mac and encryption functions |
836 | */ |
837 | |
838 | static SECStatus |
839 | Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen, |
840 | const unsigned char *input, int inputLen) |
841 | { |
842 | if (inputLen > maxOutputLen) { |
843 | *outputLen = 0; /* Match PK11_CipherOp in setting outputLen */ |
844 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OUTPUT_LEN); |
845 | return SECFailure; |
846 | } |
847 | *outputLen = inputLen; |
848 | if (input != output) |
849 | PORT_Memcpymemcpy(output, input, inputLen); |
850 | return SECSuccess; |
851 | } |
852 | |
853 | /* |
854 | * SSL3 Utility functions |
855 | */ |
856 | |
857 | /* allowLargerPeerVersion controls whether the function will select the |
858 | * highest enabled SSL version or fail when peerVersion is greater than the |
859 | * highest enabled version. |
860 | * |
861 | * If allowLargerPeerVersion is true, peerVersion is the peer's highest |
862 | * enabled version rather than the peer's selected version. |
863 | */ |
864 | SECStatus |
865 | ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion, |
866 | PRBool allowLargerPeerVersion) |
867 | { |
868 | if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)((&ss->vrange)->min == 0)) { |
869 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SSL_DISABLED); |
870 | return SECFailure; |
871 | } |
872 | |
873 | if (peerVersion < ss->vrange.min || |
874 | (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) { |
875 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_CYPHER_OVERLAP); |
876 | return SECFailure; |
877 | } |
878 | |
879 | ss->version = PR_MIN(peerVersion, ss->vrange.max)((peerVersion)<(ss->vrange.max)?(peerVersion):(ss->vrange .max)); |
880 | PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version))((ssl3_VersionIsSupported(ss->protocolVariant, ss->version ))?((void)0):PR_Assert("ssl3_VersionIsSupported(ss->protocolVariant, ss->version)" ,"ssl3con.c",880)); |
881 | |
882 | return SECSuccess; |
883 | } |
884 | |
885 | static SECStatus |
886 | ssl3_GetNewRandom(SSL3Random *random) |
887 | { |
888 | SECStatus rv; |
889 | |
890 | /* first 4 bytes are reserverd for time */ |
891 | rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH32); |
892 | if (rv != SECSuccess) { |
893 | ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); |
894 | } |
895 | return rv; |
896 | } |
897 | |
898 | /* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */ |
899 | SECStatus |
900 | ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, |
901 | PRBool isTLS) |
902 | { |
903 | SECStatus rv = SECFailure; |
904 | PRBool doDerEncode = PR_FALSE0; |
905 | int signatureLen; |
906 | SECItem hashItem; |
907 | |
908 | buf->data = NULL((void*)0); |
909 | |
910 | switch (key->keyType) { |
911 | case rsaKey: |
912 | hashItem.data = hash->u.raw; |
913 | hashItem.len = hash->len; |
914 | break; |
915 | case dsaKey: |
916 | doDerEncode = isTLS; |
917 | /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
918 | * In that case, we use just the SHA1 part. */ |
919 | if (hash->hashAlg == SEC_OID_UNKNOWN) { |
920 | hashItem.data = hash->u.s.sha; |
921 | hashItem.len = sizeof(hash->u.s.sha); |
922 | } else { |
923 | hashItem.data = hash->u.raw; |
924 | hashItem.len = hash->len; |
925 | } |
926 | break; |
927 | #ifdef NSS_ENABLE_ECC1 |
928 | case ecKey: |
929 | doDerEncode = PR_TRUE1; |
930 | /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
931 | * In that case, we use just the SHA1 part. */ |
932 | if (hash->hashAlg == SEC_OID_UNKNOWN) { |
933 | hashItem.data = hash->u.s.sha; |
934 | hashItem.len = sizeof(hash->u.s.sha); |
935 | } else { |
936 | hashItem.data = hash->u.raw; |
937 | hashItem.len = hash->len; |
938 | } |
939 | break; |
940 | #endif /* NSS_ENABLE_ECC */ |
941 | default: |
942 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); |
943 | goto done; |
944 | } |
945 | PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "hash(es) to be signed" , hashItem.data, hashItem.len); |
946 | |
947 | if (hash->hashAlg == SEC_OID_UNKNOWN) { |
948 | signatureLen = PK11_SignatureLen(key); |
949 | if (signatureLen <= 0) { |
950 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); |
951 | goto done; |
952 | } |
953 | |
954 | buf->len = (unsigned)signatureLen; |
955 | buf->data = (unsigned char *)PORT_AllocPORT_Alloc_Util(signatureLen); |
956 | if (!buf->data) |
957 | goto done; /* error code was set. */ |
958 | |
959 | rv = PK11_Sign(key, buf, &hashItem); |
960 | } else { |
961 | rv = SGN_Digest(key, hash->hashAlg, buf, &hashItem); |
962 | } |
963 | if (rv != SECSuccess) { |
964 | ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE); |
965 | } else if (doDerEncode) { |
966 | SECItem derSig = {siBuffer, NULL((void*)0), 0}; |
967 | |
968 | /* This also works for an ECDSA signature */ |
969 | rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len); |
970 | if (rv == SECSuccess) { |
971 | PORT_FreePORT_Free_Util(buf->data); /* discard unencoded signature. */ |
972 | *buf = derSig; /* give caller encoded signature. */ |
973 | } else if (derSig.data) { |
974 | PORT_FreePORT_Free_Util(derSig.data); |
975 | } |
976 | } |
977 | |
978 | PRINT_BUF(60, (NULL, "signed hashes", (unsigned char*)buf->data, buf->len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "signed hashes" , (unsigned char*)buf->data, buf->len); |
979 | done: |
980 | if (rv != SECSuccess && buf->data) { |
981 | PORT_FreePORT_Free_Util(buf->data); |
982 | buf->data = NULL((void*)0); |
983 | } |
984 | return rv; |
985 | } |
986 | |
987 | /* Called from ssl3_HandleServerKeyExchange, ssl3_HandleCertificateVerify */ |
988 | SECStatus |
989 | ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, |
990 | SECItem *buf, PRBool isTLS, void *pwArg) |
991 | { |
992 | SECKEYPublicKey * key; |
993 | SECItem * signature = NULL((void*)0); |
994 | SECStatus rv; |
995 | SECItem hashItem; |
996 | SECOidTag encAlg; |
997 | SECOidTag hashAlg; |
998 | |
999 | |
1000 | PRINT_BUF(60, (NULL, "check signed hashes",if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "check signed hashes" , buf->data, buf->len) |
1001 | buf->data, buf->len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "check signed hashes" , buf->data, buf->len); |
1002 | |
1003 | key = CERT_ExtractPublicKey(cert); |
1004 | if (key == NULL((void*)0)) { |
1005 | ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
1006 | return SECFailure; |
1007 | } |
1008 | |
1009 | hashAlg = hash->hashAlg; |
1010 | switch (key->keyType) { |
1011 | case rsaKey: |
1012 | encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION; |
1013 | hashItem.data = hash->u.raw; |
1014 | hashItem.len = hash->len; |
1015 | break; |
1016 | case dsaKey: |
1017 | encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; |
1018 | /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
1019 | * In that case, we use just the SHA1 part. */ |
1020 | if (hash->hashAlg == SEC_OID_UNKNOWN) { |
1021 | hashItem.data = hash->u.s.sha; |
1022 | hashItem.len = sizeof(hash->u.s.sha); |
1023 | } else { |
1024 | hashItem.data = hash->u.raw; |
1025 | hashItem.len = hash->len; |
1026 | } |
1027 | /* Allow DER encoded DSA signatures in SSL 3.0 */ |
1028 | if (isTLS || buf->len != SECKEY_SignatureLen(key)) { |
1029 | signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key)); |
1030 | if (!signature) { |
1031 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
1032 | return SECFailure; |
1033 | } |
1034 | buf = signature; |
1035 | } |
1036 | break; |
1037 | |
1038 | #ifdef NSS_ENABLE_ECC1 |
1039 | case ecKey: |
1040 | encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; |
1041 | /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash. |
1042 | * In that case, we use just the SHA1 part. |
1043 | * ECDSA signatures always encode the integers r and s using ASN.1 |
1044 | * (unlike DSA where ASN.1 encoding is used with TLS but not with |
1045 | * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA. |
1046 | */ |
1047 | if (hash->hashAlg == SEC_OID_UNKNOWN) { |
1048 | hashAlg = SEC_OID_SHA1; |
1049 | hashItem.data = hash->u.s.sha; |
1050 | hashItem.len = sizeof(hash->u.s.sha); |
1051 | } else { |
1052 | hashItem.data = hash->u.raw; |
1053 | hashItem.len = hash->len; |
1054 | } |
1055 | break; |
1056 | #endif /* NSS_ENABLE_ECC */ |
1057 | |
1058 | default: |
1059 | SECKEY_DestroyPublicKey(key); |
1060 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_UNSUPPORTED_KEYALG); |
1061 | return SECFailure; |
1062 | } |
1063 | |
1064 | PRINT_BUF(60, (NULL, "hash(es) to be verified",if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "hash(es) to be verified" , hashItem.data, hashItem.len) |
1065 | hashItem.data, hashItem.len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "hash(es) to be verified" , hashItem.data, hashItem.len); |
1066 | |
1067 | if (hashAlg == SEC_OID_UNKNOWN || key->keyType == dsaKey) { |
1068 | /* VFY_VerifyDigestDirect requires DSA signatures to be DER-encoded. |
1069 | * DSA signatures are DER-encoded in TLS but not in SSL3 and the code |
1070 | * above always removes the DER encoding of DSA signatures when |
1071 | * present. Thus DSA signatures are always verified with PK11_Verify. |
1072 | */ |
1073 | rv = PK11_Verify(key, buf, &hashItem, pwArg); |
1074 | } else { |
1075 | rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg, |
1076 | pwArg); |
1077 | } |
1078 | SECKEY_DestroyPublicKey(key); |
1079 | if (signature) { |
1080 | SECITEM_FreeItemSECITEM_FreeItem_Util(signature, PR_TRUE1); |
1081 | } |
1082 | if (rv != SECSuccess) { |
1083 | ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
1084 | } |
1085 | return rv; |
1086 | } |
1087 | |
1088 | |
1089 | /* Caller must set hiLevel error code. */ |
1090 | /* Called from ssl3_ComputeExportRSAKeyHash |
1091 | * ssl3_ComputeDHKeyHash |
1092 | * which are called from ssl3_HandleServerKeyExchange. |
1093 | * |
1094 | * hashAlg: either the OID for a hash algorithm or SEC_OID_UNKNOWN to specify |
1095 | * the pre-1.2, MD5/SHA1 combination hash. |
1096 | */ |
1097 | SECStatus |
1098 | ssl3_ComputeCommonKeyHash(SECOidTag hashAlg, |
1099 | PRUint8 * hashBuf, unsigned int bufLen, |
1100 | SSL3Hashes *hashes, PRBool bypassPKCS11) |
1101 | { |
1102 | SECStatus rv = SECSuccess; |
1103 | |
1104 | #ifndef NO_PKCS11_BYPASS1 |
1105 | if (bypassPKCS11) { |
1106 | if (hashAlg == SEC_OID_UNKNOWN) { |
1107 | MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen); |
1108 | SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen); |
1109 | hashes->len = MD5_LENGTH16 + SHA1_LENGTH20; |
1110 | } else if (hashAlg == SEC_OID_SHA1) { |
1111 | SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen); |
1112 | hashes->len = SHA1_LENGTH20; |
1113 | } else if (hashAlg == SEC_OID_SHA256) { |
1114 | SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen); |
1115 | hashes->len = SHA256_LENGTH32; |
1116 | } else if (hashAlg == SEC_OID_SHA384) { |
1117 | SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen); |
1118 | hashes->len = SHA384_LENGTH48; |
1119 | } else if (hashAlg == SEC_OID_SHA512) { |
1120 | SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen); |
1121 | hashes->len = SHA512_LENGTH64; |
1122 | } else { |
1123 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
1124 | return SECFailure; |
1125 | } |
1126 | } else |
1127 | #endif |
1128 | { |
1129 | if (hashAlg == SEC_OID_UNKNOWN) { |
1130 | rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen); |
1131 | if (rv != SECSuccess) { |
1132 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
1133 | rv = SECFailure; |
1134 | goto done; |
1135 | } |
1136 | |
1137 | rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen); |
1138 | if (rv != SECSuccess) { |
1139 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
1140 | rv = SECFailure; |
1141 | } |
1142 | hashes->len = MD5_LENGTH16 + SHA1_LENGTH20; |
1143 | } else { |
1144 | hashes->len = HASH_ResultLenByOidTag(hashAlg); |
1145 | if (hashes->len > sizeof(hashes->u.raw)) { |
1146 | ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
1147 | rv = SECFailure; |
1148 | goto done; |
1149 | } |
1150 | rv = PK11_HashBuf(hashAlg, hashes->u.raw, hashBuf, bufLen); |
1151 | if (rv != SECSuccess) { |
1152 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
1153 | rv = SECFailure; |
1154 | } |
1155 | } |
1156 | } |
1157 | hashes->hashAlg = hashAlg; |
1158 | |
1159 | done: |
1160 | return rv; |
1161 | } |
1162 | |
1163 | /* Caller must set hiLevel error code. |
1164 | ** Called from ssl3_SendServerKeyExchange and |
1165 | ** ssl3_HandleServerKeyExchange. |
1166 | */ |
1167 | static SECStatus |
1168 | ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg, |
1169 | SECItem modulus, SECItem publicExponent, |
1170 | SSL3Random *client_rand, SSL3Random *server_rand, |
1171 | SSL3Hashes *hashes, PRBool bypassPKCS11) |
1172 | { |
1173 | PRUint8 * hashBuf; |
1174 | PRUint8 * pBuf; |
1175 | SECStatus rv = SECSuccess; |
1176 | unsigned int bufLen; |
1177 | PRUint8 buf[2*SSL3_RANDOM_LENGTH32 + 2 + 4096/8 + 2 + 4096/8]; |
1178 | |
1179 | bufLen = 2*SSL3_RANDOM_LENGTH32 + 2 + modulus.len + 2 + publicExponent.len; |
1180 | if (bufLen <= sizeof buf) { |
1181 | hashBuf = buf; |
1182 | } else { |
1183 | hashBuf = PORT_AllocPORT_Alloc_Util(bufLen); |
1184 | if (!hashBuf) { |
1185 | return SECFailure; |
1186 | } |
1187 | } |
1188 | |
1189 | memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH32); |
1190 | pBuf = hashBuf + SSL3_RANDOM_LENGTH32; |
1191 | memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH32); |
1192 | pBuf += SSL3_RANDOM_LENGTH32; |
1193 | pBuf[0] = (PRUint8)(modulus.len >> 8); |
1194 | pBuf[1] = (PRUint8)(modulus.len); |
1195 | pBuf += 2; |
1196 | memcpy(pBuf, modulus.data, modulus.len); |
1197 | pBuf += modulus.len; |
1198 | pBuf[0] = (PRUint8)(publicExponent.len >> 8); |
1199 | pBuf[1] = (PRUint8)(publicExponent.len); |
1200 | pBuf += 2; |
1201 | memcpy(pBuf, publicExponent.data, publicExponent.len); |
1202 | pBuf += publicExponent.len; |
1203 | PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen)(((unsigned int)(pBuf - hashBuf) == bufLen)?((void)0):PR_Assert ("(unsigned int)(pBuf - hashBuf) == bufLen","ssl3con.c",1203) ); |
1204 | |
1205 | rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, |
1206 | bypassPKCS11); |
1207 | |
1208 | PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: " , hashBuf, bufLen); |
1209 | if (hashAlg == SEC_OID_UNKNOWN) { |
1210 | PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result",if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: MD5 result" , hashes->u.s.md5, 16) |
1211 | hashes->u.s.md5, MD5_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: MD5 result" , hashes->u.s.md5, 16); |
1212 | PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result",if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: SHA1 result" , hashes->u.s.sha, 20) |
1213 | hashes->u.s.sha, SHA1_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: SHA1 result" , hashes->u.s.sha, 20); |
1214 | } else { |
1215 | PRINT_BUF(95, (NULL, "RSAkey hash: result",if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: result" , hashes->u.raw, hashes->len) |
1216 | hashes->u.raw, hashes->len))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "RSAkey hash: result" , hashes->u.raw, hashes->len); |
1217 | } |
1218 | |
1219 | if (hashBuf != buf && hashBuf != NULL((void*)0)) |
1220 | PORT_FreePORT_Free_Util(hashBuf); |
1221 | return rv; |
1222 | } |
1223 | |
1224 | /* Caller must set hiLevel error code. */ |
1225 | /* Called from ssl3_HandleServerKeyExchange. */ |
1226 | static SECStatus |
1227 | ssl3_ComputeDHKeyHash(SECOidTag hashAlg, |
1228 | SECItem dh_p, SECItem dh_g, SECItem dh_Ys, |
1229 | SSL3Random *client_rand, SSL3Random *server_rand, |
1230 | SSL3Hashes *hashes, PRBool bypassPKCS11) |
1231 | { |
1232 | PRUint8 * hashBuf; |
1233 | PRUint8 * pBuf; |
1234 | SECStatus rv = SECSuccess; |
1235 | unsigned int bufLen; |
1236 | PRUint8 buf[2*SSL3_RANDOM_LENGTH32 + 2 + 4096/8 + 2 + 4096/8]; |
1237 | |
1238 | bufLen = 2*SSL3_RANDOM_LENGTH32 + 2 + dh_p.len + 2 + dh_g.len + 2 + dh_Ys.len; |
1239 | if (bufLen <= sizeof buf) { |
1240 | hashBuf = buf; |
1241 | } else { |
1242 | hashBuf = PORT_AllocPORT_Alloc_Util(bufLen); |
1243 | if (!hashBuf) { |
1244 | return SECFailure; |
1245 | } |
1246 | } |
1247 | |
1248 | memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH32); |
1249 | pBuf = hashBuf + SSL3_RANDOM_LENGTH32; |
1250 | memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH32); |
1251 | pBuf += SSL3_RANDOM_LENGTH32; |
1252 | pBuf[0] = (PRUint8)(dh_p.len >> 8); |
1253 | pBuf[1] = (PRUint8)(dh_p.len); |
1254 | pBuf += 2; |
1255 | memcpy(pBuf, dh_p.data, dh_p.len); |
1256 | pBuf += dh_p.len; |
1257 | pBuf[0] = (PRUint8)(dh_g.len >> 8); |
1258 | pBuf[1] = (PRUint8)(dh_g.len); |
1259 | pBuf += 2; |
1260 | memcpy(pBuf, dh_g.data, dh_g.len); |
1261 | pBuf += dh_g.len; |
1262 | pBuf[0] = (PRUint8)(dh_Ys.len >> 8); |
1263 | pBuf[1] = (PRUint8)(dh_Ys.len); |
1264 | pBuf += 2; |
1265 | memcpy(pBuf, dh_Ys.data, dh_Ys.len); |
1266 | pBuf += dh_Ys.len; |
1267 | PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen)(((unsigned int)(pBuf - hashBuf) == bufLen)?((void)0):PR_Assert ("(unsigned int)(pBuf - hashBuf) == bufLen","ssl3con.c",1267) ); |
1268 | |
1269 | rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, |
1270 | bypassPKCS11); |
1271 | |
1272 | PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: " , hashBuf, bufLen); |
1273 | if (hashAlg == SEC_OID_UNKNOWN) { |
1274 | PRINT_BUF(95, (NULL, "DHkey hash: MD5 result",if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: MD5 result" , hashes->u.s.md5, 16) |
1275 | hashes->u.s.md5, MD5_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: MD5 result" , hashes->u.s.md5, 16); |
1276 | PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result",if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: SHA1 result" , hashes->u.s.sha, 20) |
1277 | hashes->u.s.sha, SHA1_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: SHA1 result" , hashes->u.s.sha, 20); |
1278 | } else { |
1279 | PRINT_BUF(95, (NULL, "DHkey hash: result",if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: result" , hashes->u.raw, hashes->len) |
1280 | hashes->u.raw, hashes->len))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "DHkey hash: result" , hashes->u.raw, hashes->len); |
1281 | } |
1282 | |
1283 | if (hashBuf != buf && hashBuf != NULL((void*)0)) |
1284 | PORT_FreePORT_Free_Util(hashBuf); |
1285 | return rv; |
1286 | } |
1287 | |
1288 | static void |
1289 | ssl3_BumpSequenceNumber(SSL3SequenceNumber *num) |
1290 | { |
1291 | num->low++; |
1292 | if (num->low == 0) |
1293 | num->high++; |
1294 | } |
1295 | |
1296 | /* Called twice, only from ssl3_DestroyCipherSpec (immediately below). */ |
1297 | static void |
1298 | ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat) |
1299 | { |
1300 | if (mat->write_key != NULL((void*)0)) { |
1301 | PK11_FreeSymKey(mat->write_key); |
1302 | mat->write_key = NULL((void*)0); |
1303 | } |
1304 | if (mat->write_mac_key != NULL((void*)0)) { |
1305 | PK11_FreeSymKey(mat->write_mac_key); |
1306 | mat->write_mac_key = NULL((void*)0); |
1307 | } |
1308 | if (mat->write_mac_context != NULL((void*)0)) { |
1309 | PK11_DestroyContext(mat->write_mac_context, PR_TRUE1); |
1310 | mat->write_mac_context = NULL((void*)0); |
1311 | } |
1312 | } |
1313 | |
1314 | /* Called from ssl3_SendChangeCipherSpecs() and |
1315 | ** ssl3_HandleChangeCipherSpecs() |
1316 | ** ssl3_DestroySSL3Info |
1317 | ** Caller must hold SpecWriteLock. |
1318 | */ |
1319 | void |
1320 | ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName) |
1321 | { |
1322 | PRBool freeit = (PRBool)(!spec->bypassCiphers); |
1323 | /* PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */ |
1324 | if (spec->destroy) { |
1325 | spec->destroy(spec->encodeContext, freeit); |
1326 | spec->destroy(spec->decodeContext, freeit); |
1327 | spec->encodeContext = NULL((void*)0); /* paranoia */ |
1328 | spec->decodeContext = NULL((void*)0); |
1329 | } |
1330 | if (spec->destroyCompressContext && spec->compressContext) { |
1331 | spec->destroyCompressContext(spec->compressContext, 1); |
1332 | spec->compressContext = NULL((void*)0); |
1333 | } |
1334 | if (spec->destroyDecompressContext && spec->decompressContext) { |
1335 | spec->destroyDecompressContext(spec->decompressContext, 1); |
1336 | spec->decompressContext = NULL((void*)0); |
1337 | } |
1338 | if (freeSrvName && spec->srvVirtName.data) { |
1339 | SECITEM_FreeItemSECITEM_FreeItem_Util(&spec->srvVirtName, PR_FALSE0); |
1340 | } |
1341 | if (spec->master_secret != NULL((void*)0)) { |
1342 | PK11_FreeSymKey(spec->master_secret); |
1343 | spec->master_secret = NULL((void*)0); |
1344 | } |
1345 | spec->msItem.data = NULL((void*)0); |
1346 | spec->msItem.len = 0; |
1347 | ssl3_CleanupKeyMaterial(&spec->client); |
1348 | ssl3_CleanupKeyMaterial(&spec->server); |
1349 | spec->bypassCiphers = PR_FALSE0; |
1350 | spec->destroy=NULL((void*)0); |
1351 | spec->destroyCompressContext = NULL((void*)0); |
1352 | spec->destroyDecompressContext = NULL((void*)0); |
1353 | } |
1354 | |
1355 | /* Fill in the pending cipher spec with info from the selected ciphersuite. |
1356 | ** This is as much initialization as we can do without having key material. |
1357 | ** Called from ssl3_HandleServerHello(), ssl3_SendServerHello() |
1358 | ** Caller must hold the ssl3 handshake lock. |
1359 | ** Acquires & releases SpecWriteLock. |
1360 | */ |
1361 | static SECStatus |
1362 | ssl3_SetupPendingCipherSpec(sslSocket *ss) |
1363 | { |
1364 | ssl3CipherSpec * pwSpec; |
1365 | ssl3CipherSpec * cwSpec; |
1366 | ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite; |
1367 | SSL3MACAlgorithm mac; |
1368 | SSL3BulkCipher cipher; |
1369 | SSL3KeyExchangeAlgorithm kea; |
1370 | const ssl3CipherSuiteDef *suite_def; |
1371 | PRBool isTLS; |
1372 | |
1373 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",1373)); |
1374 | |
1375 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; /*******************************/ |
1376 | |
1377 | pwSpec = ss->ssl3.pwSpec; |
1378 | PORT_Assert(pwSpec == ss->ssl3.prSpec)((pwSpec == ss->ssl3.prSpec)?((void)0):PR_Assert("pwSpec == ss->ssl3.prSpec" ,"ssl3con.c",1378)); |
1379 | |
1380 | /* This hack provides maximal interoperability with SSL 3 servers. */ |
1381 | cwSpec = ss->ssl3.cwSpec; |
1382 | if (cwSpec->mac_def->mac == mac_nullssl_mac_null) { |
1383 | /* SSL records are not being MACed. */ |
1384 | cwSpec->version = ss->version; |
1385 | } |
1386 | |
1387 | pwSpec->version = ss->version; |
1388 | isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
1389 | |
1390 | SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x" , getpid(), ss->fd, suite) |
1391 | SSL_GETPID(), ss->fd, suite))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x" , getpid(), ss->fd, suite); |
1392 | |
1393 | suite_def = ssl_LookupCipherSuiteDef(suite); |
1394 | if (suite_def == NULL((void*)0)) { |
1395 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
1396 | return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */ |
1397 | } |
1398 | |
1399 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
1400 | /* Double-check that we did not pick an RC4 suite */ |
1401 | PORT_Assert((suite_def->bulk_cipher_alg != cipher_rc4) &&(((suite_def->bulk_cipher_alg != cipher_rc4) && (suite_def ->bulk_cipher_alg != cipher_rc4_40) && (suite_def-> bulk_cipher_alg != cipher_rc4_56))?((void)0):PR_Assert("(suite_def->bulk_cipher_alg != cipher_rc4) && (suite_def->bulk_cipher_alg != cipher_rc4_40) && (suite_def->bulk_cipher_alg != cipher_rc4_56)" ,"ssl3con.c",1403)) |
1402 | (suite_def->bulk_cipher_alg != cipher_rc4_40) &&(((suite_def->bulk_cipher_alg != cipher_rc4) && (suite_def ->bulk_cipher_alg != cipher_rc4_40) && (suite_def-> bulk_cipher_alg != cipher_rc4_56))?((void)0):PR_Assert("(suite_def->bulk_cipher_alg != cipher_rc4) && (suite_def->bulk_cipher_alg != cipher_rc4_40) && (suite_def->bulk_cipher_alg != cipher_rc4_56)" ,"ssl3con.c",1403)) |
1403 | (suite_def->bulk_cipher_alg != cipher_rc4_56))(((suite_def->bulk_cipher_alg != cipher_rc4) && (suite_def ->bulk_cipher_alg != cipher_rc4_40) && (suite_def-> bulk_cipher_alg != cipher_rc4_56))?((void)0):PR_Assert("(suite_def->bulk_cipher_alg != cipher_rc4) && (suite_def->bulk_cipher_alg != cipher_rc4_40) && (suite_def->bulk_cipher_alg != cipher_rc4_56)" ,"ssl3con.c",1403)); |
1404 | } |
1405 | |
1406 | cipher = suite_def->bulk_cipher_alg; |
1407 | kea = suite_def->key_exchange_alg; |
1408 | mac = suite_def->mac_alg; |
1409 | if (mac <= ssl_mac_sha && mac != ssl_mac_null && isTLS) |
1410 | mac += 2; |
1411 | |
1412 | ss->ssl3.hs.suite_def = suite_def; |
1413 | ss->ssl3.hs.kea_def = &kea_defs[kea]; |
1414 | PORT_Assert(ss->ssl3.hs.kea_def->kea == kea)((ss->ssl3.hs.kea_def->kea == kea)?((void)0):PR_Assert( "ss->ssl3.hs.kea_def->kea == kea","ssl3con.c",1414)); |
1415 | |
1416 | pwSpec->cipher_def = &bulk_cipher_defs[cipher]; |
1417 | PORT_Assert(pwSpec->cipher_def->cipher == cipher)((pwSpec->cipher_def->cipher == cipher)?((void)0):PR_Assert ("pwSpec->cipher_def->cipher == cipher","ssl3con.c",1417 )); |
1418 | |
1419 | pwSpec->mac_def = &mac_defs[mac]; |
1420 | PORT_Assert(pwSpec->mac_def->mac == mac)((pwSpec->mac_def->mac == mac)?((void)0):PR_Assert("pwSpec->mac_def->mac == mac" ,"ssl3con.c",1420)); |
1421 | |
1422 | ss->sec.keyBits = pwSpec->cipher_def->key_size * BPB8; |
1423 | ss->sec.secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB8; |
1424 | ss->sec.cipherType = cipher; |
1425 | |
1426 | pwSpec->encodeContext = NULL((void*)0); |
1427 | pwSpec->decodeContext = NULL((void*)0); |
1428 | |
1429 | pwSpec->mac_size = pwSpec->mac_def->mac_size; |
1430 | |
1431 | pwSpec->compression_method = ss->ssl3.hs.compression; |
1432 | pwSpec->compressContext = NULL((void*)0); |
1433 | pwSpec->decompressContext = NULL((void*)0); |
1434 | |
1435 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /*******************************/ |
1436 | return SECSuccess; |
1437 | } |
1438 | |
1439 | #ifdef NSS_ENABLE_ZLIB |
1440 | #define SSL3_DEFLATE_CONTEXT_SIZE sizeof(z_stream) |
1441 | |
1442 | static SECStatus |
1443 | ssl3_MapZlibError(int zlib_error) |
1444 | { |
1445 | switch (zlib_error) { |
1446 | case Z_OK: |
1447 | return SECSuccess; |
1448 | default: |
1449 | return SECFailure; |
1450 | } |
1451 | } |
1452 | |
1453 | static SECStatus |
1454 | ssl3_DeflateInit(void *void_context) |
1455 | { |
1456 | z_stream *context = void_context; |
1457 | context->zalloc = NULL((void*)0); |
1458 | context->zfree = NULL((void*)0); |
1459 | context->opaque = NULL((void*)0); |
1460 | |
1461 | return ssl3_MapZlibError(deflateInit(context, Z_DEFAULT_COMPRESSION)); |
1462 | } |
1463 | |
1464 | static SECStatus |
1465 | ssl3_InflateInit(void *void_context) |
1466 | { |
1467 | z_stream *context = void_context; |
1468 | context->zalloc = NULL((void*)0); |
1469 | context->zfree = NULL((void*)0); |
1470 | context->opaque = NULL((void*)0); |
1471 | context->next_in = NULL((void*)0); |
1472 | context->avail_in = 0; |
1473 | |
1474 | return ssl3_MapZlibError(inflateInit(context)); |
1475 | } |
1476 | |
1477 | static SECStatus |
1478 | ssl3_DeflateCompress(void *void_context, unsigned char *out, int *out_len, |
1479 | int maxout, const unsigned char *in, int inlen) |
1480 | { |
1481 | z_stream *context = void_context; |
1482 | |
1483 | if (!inlen) { |
1484 | *out_len = 0; |
1485 | return SECSuccess; |
1486 | } |
1487 | |
1488 | context->next_in = (unsigned char*) in; |
1489 | context->avail_in = inlen; |
1490 | context->next_out = out; |
1491 | context->avail_out = maxout; |
1492 | if (deflate(context, Z_SYNC_FLUSH) != Z_OK) { |
1493 | return SECFailure; |
1494 | } |
1495 | if (context->avail_out == 0) { |
1496 | /* We ran out of space! */ |
1497 | SSL_TRC(3, ("%d: SSL3[%d] Ran out of buffer while compressing",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] Ran out of buffer while compressing" , getpid()) |
1498 | SSL_GETPID()))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] Ran out of buffer while compressing" , getpid()); |
1499 | return SECFailure; |
1500 | } |
1501 | |
1502 | *out_len = maxout - context->avail_out; |
1503 | return SECSuccess; |
1504 | } |
1505 | |
1506 | static SECStatus |
1507 | ssl3_DeflateDecompress(void *void_context, unsigned char *out, int *out_len, |
1508 | int maxout, const unsigned char *in, int inlen) |
1509 | { |
1510 | z_stream *context = void_context; |
1511 | |
1512 | if (!inlen) { |
1513 | *out_len = 0; |
1514 | return SECSuccess; |
1515 | } |
1516 | |
1517 | context->next_in = (unsigned char*) in; |
1518 | context->avail_in = inlen; |
1519 | context->next_out = out; |
1520 | context->avail_out = maxout; |
1521 | if (inflate(context, Z_SYNC_FLUSH) != Z_OK) { |
1522 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_DECOMPRESSION_FAILURE); |
1523 | return SECFailure; |
1524 | } |
1525 | |
1526 | *out_len = maxout - context->avail_out; |
1527 | return SECSuccess; |
1528 | } |
1529 | |
1530 | static SECStatus |
1531 | ssl3_DestroyCompressContext(void *void_context, PRBool unused) |
1532 | { |
1533 | deflateEnd(void_context); |
1534 | PORT_FreePORT_Free_Util(void_context); |
1535 | return SECSuccess; |
1536 | } |
1537 | |
1538 | static SECStatus |
1539 | ssl3_DestroyDecompressContext(void *void_context, PRBool unused) |
1540 | { |
1541 | inflateEnd(void_context); |
1542 | PORT_FreePORT_Free_Util(void_context); |
1543 | return SECSuccess; |
1544 | } |
1545 | |
1546 | #endif /* NSS_ENABLE_ZLIB */ |
1547 | |
1548 | /* Initialize the compression functions and contexts for the given |
1549 | * CipherSpec. */ |
1550 | static SECStatus |
1551 | ssl3_InitCompressionContext(ssl3CipherSpec *pwSpec) |
1552 | { |
1553 | /* Setup the compression functions */ |
1554 | switch (pwSpec->compression_method) { |
1555 | case ssl_compression_null: |
1556 | pwSpec->compressor = NULL((void*)0); |
1557 | pwSpec->decompressor = NULL((void*)0); |
1558 | pwSpec->compressContext = NULL((void*)0); |
1559 | pwSpec->decompressContext = NULL((void*)0); |
1560 | pwSpec->destroyCompressContext = NULL((void*)0); |
1561 | pwSpec->destroyDecompressContext = NULL((void*)0); |
1562 | break; |
1563 | #ifdef NSS_ENABLE_ZLIB |
1564 | case ssl_compression_deflate: |
1565 | pwSpec->compressor = ssl3_DeflateCompress; |
1566 | pwSpec->decompressor = ssl3_DeflateDecompress; |
1567 | pwSpec->compressContext = PORT_AllocPORT_Alloc_Util(SSL3_DEFLATE_CONTEXT_SIZE); |
1568 | pwSpec->decompressContext = PORT_AllocPORT_Alloc_Util(SSL3_DEFLATE_CONTEXT_SIZE); |
1569 | pwSpec->destroyCompressContext = ssl3_DestroyCompressContext; |
1570 | pwSpec->destroyDecompressContext = ssl3_DestroyDecompressContext; |
1571 | ssl3_DeflateInit(pwSpec->compressContext); |
1572 | ssl3_InflateInit(pwSpec->decompressContext); |
1573 | break; |
1574 | #endif /* NSS_ENABLE_ZLIB */ |
1575 | default: |
1576 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","ssl3con.c",1576)); |
1577 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
1578 | return SECFailure; |
1579 | } |
1580 | |
1581 | return SECSuccess; |
1582 | } |
1583 | |
1584 | #ifndef NO_PKCS11_BYPASS1 |
1585 | /* Initialize encryption contexts for pending spec. |
1586 | * MAC contexts are set up when computing the mac, not here. |
1587 | * Master Secret already is derived in spec->msItem |
1588 | * Caller holds Spec write lock. |
1589 | */ |
1590 | static SECStatus |
1591 | ssl3_InitPendingContextsBypass(sslSocket *ss) |
1592 | { |
1593 | ssl3CipherSpec * pwSpec; |
1594 | const ssl3BulkCipherDef *cipher_def; |
1595 | void * serverContext = NULL((void*)0); |
1596 | void * clientContext = NULL((void*)0); |
1597 | BLapiInitContextFunc initFn = (BLapiInitContextFunc)NULL((void*)0); |
1598 | int mode = 0; |
1599 | unsigned int optArg1 = 0; |
1600 | unsigned int optArg2 = 0; |
1601 | PRBool server_encrypts = ss->sec.isServer; |
1602 | SSLCipherAlgorithm calg; |
1603 | SECStatus rv; |
1604 | |
1605 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",1605)); |
1606 | PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss))((ss->opt.noLocks || (NSSRWLock_HaveWriteLock_Util((ss)-> specLock)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)" ,"ssl3con.c",1606)); |
1607 | PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec)((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",1607) ); |
1608 | |
1609 | pwSpec = ss->ssl3.pwSpec; |
1610 | cipher_def = pwSpec->cipher_def; |
1611 | |
1612 | calg = cipher_def->calg; |
1613 | |
1614 | if (calg == ssl_calg_aes_gcm) { |
1615 | pwSpec->encode = NULL((void*)0); |
1616 | pwSpec->decode = NULL((void*)0); |
1617 | pwSpec->destroy = NULL((void*)0); |
1618 | pwSpec->encodeContext = NULL((void*)0); |
1619 | pwSpec->decodeContext = NULL((void*)0); |
1620 | pwSpec->aead = ssl3_AESGCMBypass; |
1621 | ssl3_InitCompressionContext(pwSpec); |
1622 | return SECSuccess; |
1623 | } |
1624 | |
1625 | serverContext = pwSpec->server.cipher_context; |
1626 | clientContext = pwSpec->client.cipher_context; |
1627 | |
1628 | switch (calg) { |
1629 | case ssl_calg_null: |
1630 | pwSpec->encode = Null_Cipher; |
1631 | pwSpec->decode = Null_Cipher; |
1632 | pwSpec->destroy = NULL((void*)0); |
1633 | goto success; |
1634 | |
1635 | case ssl_calg_rc4: |
1636 | initFn = (BLapiInitContextFunc)RC4_InitContext; |
1637 | pwSpec->encode = (SSLCipher) RC4_Encrypt; |
1638 | pwSpec->decode = (SSLCipher) RC4_Decrypt; |
1639 | pwSpec->destroy = (SSLDestroy) RC4_DestroyContext; |
1640 | break; |
1641 | case ssl_calg_rc2: |
1642 | initFn = (BLapiInitContextFunc)RC2_InitContext; |
1643 | mode = NSS_RC2_CBC1; |
1644 | optArg1 = cipher_def->key_size; |
1645 | pwSpec->encode = (SSLCipher) RC2_Encrypt; |
1646 | pwSpec->decode = (SSLCipher) RC2_Decrypt; |
1647 | pwSpec->destroy = (SSLDestroy) RC2_DestroyContext; |
1648 | break; |
1649 | case ssl_calg_des: |
1650 | initFn = (BLapiInitContextFunc)DES_InitContext; |
1651 | mode = NSS_DES_CBC1; |
1652 | optArg1 = server_encrypts; |
1653 | pwSpec->encode = (SSLCipher) DES_Encrypt; |
1654 | pwSpec->decode = (SSLCipher) DES_Decrypt; |
1655 | pwSpec->destroy = (SSLDestroy) DES_DestroyContext; |
1656 | break; |
1657 | case ssl_calg_3des: |
1658 | initFn = (BLapiInitContextFunc)DES_InitContext; |
1659 | mode = NSS_DES_EDE3_CBC3; |
1660 | optArg1 = server_encrypts; |
1661 | pwSpec->encode = (SSLCipher) DES_Encrypt; |
1662 | pwSpec->decode = (SSLCipher) DES_Decrypt; |
1663 | pwSpec->destroy = (SSLDestroy) DES_DestroyContext; |
1664 | break; |
1665 | case ssl_calg_aes: |
1666 | initFn = (BLapiInitContextFunc)AES_InitContext; |
1667 | mode = NSS_AES_CBC1; |
1668 | optArg1 = server_encrypts; |
1669 | optArg2 = AES_BLOCK_SIZE16; |
1670 | pwSpec->encode = (SSLCipher) AES_Encrypt; |
1671 | pwSpec->decode = (SSLCipher) AES_Decrypt; |
1672 | pwSpec->destroy = (SSLDestroy) AES_DestroyContext; |
1673 | break; |
1674 | |
1675 | case ssl_calg_camellia: |
1676 | initFn = (BLapiInitContextFunc)Camellia_InitContext; |
1677 | mode = NSS_CAMELLIA_CBC1; |
1678 | optArg1 = server_encrypts; |
1679 | optArg2 = CAMELLIA_BLOCK_SIZE16; |
1680 | pwSpec->encode = (SSLCipher) Camellia_Encrypt; |
1681 | pwSpec->decode = (SSLCipher) Camellia_Decrypt; |
1682 | pwSpec->destroy = (SSLDestroy) Camellia_DestroyContext; |
1683 | break; |
1684 | |
1685 | case ssl_calg_seed: |
1686 | initFn = (BLapiInitContextFunc)SEED_InitContext; |
1687 | mode = NSS_SEED_CBC1; |
1688 | optArg1 = server_encrypts; |
1689 | optArg2 = SEED_BLOCK_SIZE16; |
1690 | pwSpec->encode = (SSLCipher) SEED_Encrypt; |
1691 | pwSpec->decode = (SSLCipher) SEED_Decrypt; |
1692 | pwSpec->destroy = (SSLDestroy) SEED_DestroyContext; |
1693 | break; |
1694 | |
1695 | case ssl_calg_idea: |
1696 | case ssl_calg_fortezza : |
1697 | default: |
1698 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","ssl3con.c",1698)); |
1699 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
1700 | goto bail_out; |
1701 | } |
1702 | rv = (*initFn)(serverContext, |
1703 | pwSpec->server.write_key_item.data, |
1704 | pwSpec->server.write_key_item.len, |
1705 | pwSpec->server.write_iv_item.data, |
1706 | mode, optArg1, optArg2); |
1707 | if (rv != SECSuccess) { |
1708 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","ssl3con.c",1708)); |
1709 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
1710 | goto bail_out; |
1711 | } |
1712 | |
1713 | switch (calg) { |
1714 | case ssl_calg_des: |
1715 | case ssl_calg_3des: |
1716 | case ssl_calg_aes: |
1717 | case ssl_calg_camellia: |
1718 | case ssl_calg_seed: |
1719 | /* For block ciphers, if the server is encrypting, then the client |
1720 | * is decrypting, and vice versa. |
1721 | */ |
1722 | optArg1 = !optArg1; |
1723 | break; |
1724 | /* kill warnings. */ |
1725 | case ssl_calg_null: |
1726 | case ssl_calg_rc4: |
1727 | case ssl_calg_rc2: |
1728 | case ssl_calg_idea: |
1729 | case ssl_calg_fortezza: |
1730 | case ssl_calg_aes_gcm: |
1731 | break; |
1732 | } |
1733 | |
1734 | rv = (*initFn)(clientContext, |
1735 | pwSpec->client.write_key_item.data, |
1736 | pwSpec->client.write_key_item.len, |
1737 | pwSpec->client.write_iv_item.data, |
1738 | mode, optArg1, optArg2); |
1739 | if (rv != SECSuccess) { |
1740 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","ssl3con.c",1740)); |
1741 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
1742 | goto bail_out; |
1743 | } |
1744 | |
1745 | pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext; |
1746 | pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext; |
1747 | |
1748 | ssl3_InitCompressionContext(pwSpec); |
1749 | |
1750 | success: |
1751 | return SECSuccess; |
1752 | |
1753 | bail_out: |
1754 | return SECFailure; |
1755 | } |
1756 | #endif |
1757 | |
1758 | /* This function should probably be moved to pk11wrap and be named |
1759 | * PK11_ParamFromIVAndEffectiveKeyBits |
1760 | */ |
1761 | static SECItem * |
1762 | ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits) |
1763 | { |
1764 | SECItem * param = PK11_ParamFromIV(mtype, iv); |
1765 | if (param && param->data && param->len >= sizeof(CK_RC2_PARAMS)) { |
1766 | switch (mtype) { |
1767 | case CKM_RC2_KEY_GEN0x00000100: |
1768 | case CKM_RC2_ECB0x00000101: |
1769 | case CKM_RC2_CBC0x00000102: |
1770 | case CKM_RC2_MAC0x00000103: |
1771 | case CKM_RC2_MAC_GENERAL0x00000104: |
1772 | case CKM_RC2_CBC_PAD0x00000105: |
1773 | *(CK_RC2_PARAMS *)param->data = ulEffectiveBits; |
1774 | default: break; |
1775 | } |
1776 | } |
1777 | return param; |
1778 | } |
1779 | |
1780 | /* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data |
1781 | * which is included in the MAC or AEAD additional data) to |out| and returns |
1782 | * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the |
1783 | * definition of the AEAD additional data. |
1784 | * |
1785 | * TLS pseudo-header includes the record's version field, SSL's doesn't. Which |
1786 | * pseudo-header defintiion to use should be decided based on the version of |
1787 | * the protocol that was negotiated when the cipher spec became current, NOT |
1788 | * based on the version value in the record itself, and the decision is passed |
1789 | * to this function as the |includesVersion| argument. But, the |version| |
1790 | * argument should be the record's version value. |
1791 | */ |
1792 | static unsigned int |
1793 | ssl3_BuildRecordPseudoHeader(unsigned char *out, |
1794 | SSL3SequenceNumber seq_num, |
1795 | SSL3ContentType type, |
1796 | PRBool includesVersion, |
1797 | SSL3ProtocolVersion version, |
1798 | PRBool isDTLS, |
1799 | int length) |
1800 | { |
1801 | out[0] = (unsigned char)(seq_num.high >> 24); |
1802 | out[1] = (unsigned char)(seq_num.high >> 16); |
1803 | out[2] = (unsigned char)(seq_num.high >> 8); |
1804 | out[3] = (unsigned char)(seq_num.high >> 0); |
1805 | out[4] = (unsigned char)(seq_num.low >> 24); |
1806 | out[5] = (unsigned char)(seq_num.low >> 16); |
1807 | out[6] = (unsigned char)(seq_num.low >> 8); |
1808 | out[7] = (unsigned char)(seq_num.low >> 0); |
1809 | out[8] = type; |
1810 | |
1811 | /* SSL3 MAC doesn't include the record's version field. */ |
1812 | if (!includesVersion) { |
1813 | out[9] = MSB(length)((unsigned char) (((unsigned)(length)) >> 8)); |
1814 | out[10] = LSB(length)((unsigned char) ((length) & 0xff)); |
1815 | return 11; |
1816 | } |
1817 | |
1818 | /* TLS MAC and AEAD additional data include version. */ |
1819 | if (isDTLS) { |
1820 | SSL3ProtocolVersion dtls_version; |
1821 | |
1822 | dtls_version = dtls_TLSVersionToDTLSVersion(version); |
1823 | out[9] = MSB(dtls_version)((unsigned char) (((unsigned)(dtls_version)) >> 8)); |
1824 | out[10] = LSB(dtls_version)((unsigned char) ((dtls_version) & 0xff)); |
1825 | } else { |
1826 | out[9] = MSB(version)((unsigned char) (((unsigned)(version)) >> 8)); |
1827 | out[10] = LSB(version)((unsigned char) ((version) & 0xff)); |
1828 | } |
1829 | out[11] = MSB(length)((unsigned char) (((unsigned)(length)) >> 8)); |
1830 | out[12] = LSB(length)((unsigned char) ((length) & 0xff)); |
1831 | return 13; |
1832 | } |
1833 | |
1834 | static SECStatus |
1835 | ssl3_AESGCM(ssl3KeyMaterial *keys, |
1836 | PRBool doDecrypt, |
1837 | unsigned char *out, |
1838 | int *outlen, |
1839 | int maxout, |
1840 | const unsigned char *in, |
1841 | int inlen, |
1842 | const unsigned char *additionalData, |
1843 | int additionalDataLen) |
1844 | { |
1845 | SECItem param; |
1846 | SECStatus rv = SECFailure; |
1847 | unsigned char nonce[12]; |
1848 | unsigned int uOutLen; |
1849 | CK_GCM_PARAMS gcmParams; |
1850 | |
1851 | static const int tagSize = 16; |
1852 | static const int explicitNonceLen = 8; |
1853 | |
1854 | /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the |
1855 | * nonce is formed. */ |
1856 | memcpy(nonce, keys->write_iv, 4); |
1857 | if (doDecrypt) { |
1858 | memcpy(nonce + 4, in, explicitNonceLen); |
1859 | in += explicitNonceLen; |
1860 | inlen -= explicitNonceLen; |
1861 | *outlen = 0; |
1862 | } else { |
1863 | if (maxout < explicitNonceLen) { |
1864 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INPUT_LEN); |
1865 | return SECFailure; |
1866 | } |
1867 | /* Use the 64-bit sequence number as the explicit nonce. */ |
1868 | memcpy(nonce + 4, additionalData, explicitNonceLen); |
1869 | memcpy(out, additionalData, explicitNonceLen); |
1870 | out += explicitNonceLen; |
1871 | maxout -= explicitNonceLen; |
1872 | *outlen = explicitNonceLen; |
1873 | } |
1874 | |
1875 | param.type = siBuffer; |
1876 | param.data = (unsigned char *) &gcmParams; |
1877 | param.len = sizeof(gcmParams); |
1878 | gcmParams.pIv = nonce; |
1879 | gcmParams.ulIvLen = sizeof(nonce); |
1880 | gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */ |
1881 | gcmParams.ulAADLen = additionalDataLen; |
1882 | gcmParams.ulTagBits = tagSize * 8; |
1883 | |
1884 | if (doDecrypt) { |
1885 | rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM0x00001087, ¶m, out, &uOutLen, |
1886 | maxout, in, inlen); |
1887 | } else { |
1888 | rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM0x00001087, ¶m, out, &uOutLen, |
1889 | maxout, in, inlen); |
1890 | } |
1891 | *outlen += (int) uOutLen; |
1892 | |
1893 | return rv; |
1894 | } |
1895 | |
1896 | #ifndef NO_PKCS11_BYPASS1 |
1897 | static SECStatus |
1898 | ssl3_AESGCMBypass(ssl3KeyMaterial *keys, |
1899 | PRBool doDecrypt, |
1900 | unsigned char *out, |
1901 | int *outlen, |
1902 | int maxout, |
1903 | const unsigned char *in, |
1904 | int inlen, |
1905 | const unsigned char *additionalData, |
1906 | int additionalDataLen) |
1907 | { |
1908 | SECStatus rv = SECFailure; |
1909 | unsigned char nonce[12]; |
1910 | unsigned int uOutLen; |
1911 | AESContext *cx; |
1912 | CK_GCM_PARAMS gcmParams; |
1913 | |
1914 | static const int tagSize = 16; |
1915 | static const int explicitNonceLen = 8; |
1916 | |
1917 | /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the |
1918 | * nonce is formed. */ |
1919 | PORT_Assert(keys->write_iv_item.len == 4)((keys->write_iv_item.len == 4)?((void)0):PR_Assert("keys->write_iv_item.len == 4" ,"ssl3con.c",1919)); |
1920 | if (keys->write_iv_item.len != 4) { |
1921 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
1922 | return SECFailure; |
1923 | } |
1924 | memcpy(nonce, keys->write_iv_item.data, 4); |
1925 | if (doDecrypt) { |
1926 | memcpy(nonce + 4, in, explicitNonceLen); |
1927 | in += explicitNonceLen; |
1928 | inlen -= explicitNonceLen; |
1929 | *outlen = 0; |
1930 | } else { |
1931 | if (maxout < explicitNonceLen) { |
1932 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INPUT_LEN); |
1933 | return SECFailure; |
1934 | } |
1935 | /* Use the 64-bit sequence number as the explicit nonce. */ |
1936 | memcpy(nonce + 4, additionalData, explicitNonceLen); |
1937 | memcpy(out, additionalData, explicitNonceLen); |
1938 | out += explicitNonceLen; |
1939 | maxout -= explicitNonceLen; |
1940 | *outlen = explicitNonceLen; |
1941 | } |
1942 | |
1943 | gcmParams.pIv = nonce; |
1944 | gcmParams.ulIvLen = sizeof(nonce); |
1945 | gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */ |
1946 | gcmParams.ulAADLen = additionalDataLen; |
1947 | gcmParams.ulTagBits = tagSize * 8; |
1948 | |
1949 | cx = (AESContext *)keys->cipher_context; |
1950 | rv = AES_InitContext(cx, keys->write_key_item.data, |
1951 | keys->write_key_item.len, |
1952 | (unsigned char *)&gcmParams, NSS_AES_GCM4, !doDecrypt, |
1953 | AES_BLOCK_SIZE16); |
1954 | if (rv != SECSuccess) { |
1955 | return rv; |
1956 | } |
1957 | if (doDecrypt) { |
1958 | rv = AES_Decrypt(cx, out, &uOutLen, maxout, in, inlen); |
1959 | } else { |
1960 | rv = AES_Encrypt(cx, out, &uOutLen, maxout, in, inlen); |
1961 | } |
1962 | AES_DestroyContext(cx, PR_FALSE0); |
1963 | *outlen += (int) uOutLen; |
1964 | |
1965 | return rv; |
1966 | } |
1967 | #endif |
1968 | |
1969 | /* Initialize encryption and MAC contexts for pending spec. |
1970 | * Master Secret already is derived. |
1971 | * Caller holds Spec write lock. |
1972 | */ |
1973 | static SECStatus |
1974 | ssl3_InitPendingContextsPKCS11(sslSocket *ss) |
1975 | { |
1976 | ssl3CipherSpec * pwSpec; |
1977 | const ssl3BulkCipherDef *cipher_def; |
1978 | PK11Context * serverContext = NULL((void*)0); |
1979 | PK11Context * clientContext = NULL((void*)0); |
1980 | SECItem * param; |
1981 | CK_MECHANISM_TYPE mechanism; |
1982 | CK_MECHANISM_TYPE mac_mech; |
1983 | CK_ULONG macLength; |
1984 | CK_ULONG effKeyBits; |
1985 | SECItem iv; |
1986 | SECItem mac_param; |
1987 | SSLCipherAlgorithm calg; |
1988 | |
1989 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",1989)); |
1990 | PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss))((ss->opt.noLocks || (NSSRWLock_HaveWriteLock_Util((ss)-> specLock)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)" ,"ssl3con.c",1990)); |
1991 | PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec)((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",1991) ); |
1992 | |
1993 | pwSpec = ss->ssl3.pwSpec; |
1994 | cipher_def = pwSpec->cipher_def; |
1995 | macLength = pwSpec->mac_size; |
1996 | calg = cipher_def->calg; |
1997 | PORT_Assert(alg2Mech[calg].calg == calg)((alg2Mech[calg].calg == calg)?((void)0):PR_Assert("alg2Mech[calg].calg == calg" ,"ssl3con.c",1997)); |
1998 | |
1999 | pwSpec->client.write_mac_context = NULL((void*)0); |
2000 | pwSpec->server.write_mac_context = NULL((void*)0); |
2001 | |
2002 | if (calg == calg_aes_gcmssl_calg_aes_gcm) { |
2003 | pwSpec->encode = NULL((void*)0); |
2004 | pwSpec->decode = NULL((void*)0); |
2005 | pwSpec->destroy = NULL((void*)0); |
2006 | pwSpec->encodeContext = NULL((void*)0); |
2007 | pwSpec->decodeContext = NULL((void*)0); |
2008 | pwSpec->aead = ssl3_AESGCM; |
2009 | return SECSuccess; |
2010 | } |
2011 | |
2012 | /* |
2013 | ** Now setup the MAC contexts, |
2014 | ** crypto contexts are setup below. |
2015 | */ |
2016 | |
2017 | mac_mech = pwSpec->mac_def->mmech; |
2018 | mac_param.data = (unsigned char *)&macLength; |
2019 | mac_param.len = sizeof(macLength); |
2020 | mac_param.type = 0; |
2021 | |
2022 | pwSpec->client.write_mac_context = PK11_CreateContextBySymKey( |
2023 | mac_mech, CKA_SIGN0x00000108, pwSpec->client.write_mac_key, &mac_param); |
2024 | if (pwSpec->client.write_mac_context == NULL((void*)0)) { |
2025 | ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); |
2026 | goto fail; |
2027 | } |
2028 | pwSpec->server.write_mac_context = PK11_CreateContextBySymKey( |
2029 | mac_mech, CKA_SIGN0x00000108, pwSpec->server.write_mac_key, &mac_param); |
2030 | if (pwSpec->server.write_mac_context == NULL((void*)0)) { |
2031 | ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); |
2032 | goto fail; |
2033 | } |
2034 | |
2035 | /* |
2036 | ** Now setup the crypto contexts. |
2037 | */ |
2038 | |
2039 | if (calg == calg_nullssl_calg_null) { |
2040 | pwSpec->encode = Null_Cipher; |
2041 | pwSpec->decode = Null_Cipher; |
2042 | pwSpec->destroy = NULL((void*)0); |
2043 | return SECSuccess; |
2044 | } |
2045 | mechanism = alg2Mech[calg].cmech; |
2046 | effKeyBits = cipher_def->key_size * BPB8; |
2047 | |
2048 | /* |
2049 | * build the server context |
2050 | */ |
2051 | iv.data = pwSpec->server.write_iv; |
2052 | iv.len = cipher_def->iv_size; |
2053 | param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits); |
2054 | if (param == NULL((void*)0)) { |
2055 | ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); |
2056 | goto fail; |
2057 | } |
2058 | serverContext = PK11_CreateContextBySymKey(mechanism, |
2059 | (ss->sec.isServer ? CKA_ENCRYPT0x00000104 : CKA_DECRYPT0x00000105), |
2060 | pwSpec->server.write_key, param); |
2061 | iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); |
2062 | if (iv.data) |
2063 | PORT_Memcpymemcpy(pwSpec->server.write_iv, iv.data, iv.len); |
2064 | SECITEM_FreeItemSECITEM_FreeItem_Util(param, PR_TRUE1); |
2065 | if (serverContext == NULL((void*)0)) { |
2066 | ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); |
2067 | goto fail; |
2068 | } |
2069 | |
2070 | /* |
2071 | * build the client context |
2072 | */ |
2073 | iv.data = pwSpec->client.write_iv; |
2074 | iv.len = cipher_def->iv_size; |
2075 | |
2076 | param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits); |
2077 | if (param == NULL((void*)0)) { |
2078 | ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); |
2079 | goto fail; |
2080 | } |
2081 | clientContext = PK11_CreateContextBySymKey(mechanism, |
2082 | (ss->sec.isServer ? CKA_DECRYPT0x00000105 : CKA_ENCRYPT0x00000104), |
2083 | pwSpec->client.write_key, param); |
2084 | iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); |
2085 | if (iv.data) |
2086 | PORT_Memcpymemcpy(pwSpec->client.write_iv, iv.data, iv.len); |
2087 | SECITEM_FreeItemSECITEM_FreeItem_Util(param,PR_TRUE1); |
2088 | if (clientContext == NULL((void*)0)) { |
2089 | ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); |
2090 | goto fail; |
2091 | } |
2092 | pwSpec->encode = (SSLCipher) PK11_CipherOp; |
2093 | pwSpec->decode = (SSLCipher) PK11_CipherOp; |
2094 | pwSpec->destroy = (SSLDestroy) PK11_DestroyContext; |
2095 | |
2096 | pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext; |
2097 | pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext; |
2098 | |
2099 | serverContext = NULL((void*)0); |
2100 | clientContext = NULL((void*)0); |
2101 | |
2102 | ssl3_InitCompressionContext(pwSpec); |
2103 | |
2104 | return SECSuccess; |
2105 | |
2106 | fail: |
2107 | if (serverContext != NULL((void*)0)) PK11_DestroyContext(serverContext, PR_TRUE1); |
2108 | if (clientContext != NULL((void*)0)) PK11_DestroyContext(clientContext, PR_TRUE1); |
2109 | if (pwSpec->client.write_mac_context != NULL((void*)0)) { |
2110 | PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE1); |
2111 | pwSpec->client.write_mac_context = NULL((void*)0); |
2112 | } |
2113 | if (pwSpec->server.write_mac_context != NULL((void*)0)) { |
2114 | PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE1); |
2115 | pwSpec->server.write_mac_context = NULL((void*)0); |
2116 | } |
2117 | |
2118 | return SECFailure; |
2119 | } |
2120 | |
2121 | /* Complete the initialization of all keys, ciphers, MACs and their contexts |
2122 | * for the pending Cipher Spec. |
2123 | * Called from: ssl3_SendClientKeyExchange (for Full handshake) |
2124 | * ssl3_HandleRSAClientKeyExchange (for Full handshake) |
2125 | * ssl3_HandleServerHello (for session restart) |
2126 | * ssl3_HandleClientHello (for session restart) |
2127 | * Sets error code, but caller probably should override to disambiguate. |
2128 | * NULL pms means re-use old master_secret. |
2129 | * |
2130 | * This code is common to the bypass and PKCS11 execution paths. |
2131 | * For the bypass case, pms is NULL. |
2132 | */ |
2133 | SECStatus |
2134 | ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms) |
2135 | { |
2136 | ssl3CipherSpec * pwSpec; |
2137 | ssl3CipherSpec * cwSpec; |
2138 | SECStatus rv; |
2139 | |
2140 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",2140)); |
2141 | |
2142 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; /**************************************/ |
2143 | |
2144 | PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec)((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",2144) ); |
2145 | |
2146 | pwSpec = ss->ssl3.pwSpec; |
2147 | cwSpec = ss->ssl3.cwSpec; |
2148 | |
2149 | if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) { |
2150 | rv = ssl3_DeriveMasterSecret(ss, pms); |
2151 | if (rv != SECSuccess) { |
2152 | goto done; /* err code set by ssl3_DeriveMasterSecret */ |
2153 | } |
2154 | } |
2155 | #ifndef NO_PKCS11_BYPASS1 |
2156 | if (ss->opt.bypassPKCS11 && pwSpec->msItem.len && pwSpec->msItem.data) { |
2157 | /* Double Bypass succeeded in extracting the master_secret */ |
2158 | const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
2159 | PRBool isTLS = (PRBool)(kea_def->tls_keygen || |
2160 | (pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300)); |
2161 | pwSpec->bypassCiphers = PR_TRUE1; |
2162 | rv = ssl3_KeyAndMacDeriveBypass( pwSpec, |
2163 | (const unsigned char *)&ss->ssl3.hs.client_random, |
2164 | (const unsigned char *)&ss->ssl3.hs.server_random, |
2165 | isTLS, |
2166 | (PRBool)(kea_def->is_limited)); |
2167 | if (rv == SECSuccess) { |
2168 | rv = ssl3_InitPendingContextsBypass(ss); |
2169 | } |
2170 | } else |
2171 | #endif |
2172 | if (pwSpec->master_secret) { |
2173 | rv = ssl3_DeriveConnectionKeysPKCS11(ss); |
2174 | if (rv == SECSuccess) { |
2175 | rv = ssl3_InitPendingContextsPKCS11(ss); |
2176 | } |
2177 | } else { |
2178 | PORT_Assert(pwSpec->master_secret)((pwSpec->master_secret)?((void)0):PR_Assert("pwSpec->master_secret" ,"ssl3con.c",2178)); |
2179 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
2180 | rv = SECFailure; |
2181 | } |
2182 | if (rv != SECSuccess) { |
2183 | goto done; |
2184 | } |
2185 | |
2186 | /* Generic behaviors -- common to all crypto methods */ |
2187 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
2188 | pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = 0; |
2189 | } else { |
2190 | if (cwSpec->epoch == PR_UINT16_MAX65535U) { |
2191 | /* The problem here is that we have rehandshaked too many |
2192 | * times (you are not allowed to wrap the epoch). The |
2193 | * spec says you should be discarding the connection |
2194 | * and start over, so not much we can do here. */ |
2195 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
2196 | rv = SECFailure; |
2197 | goto done; |
2198 | } |
2199 | /* The sequence number has the high 16 bits as the epoch. */ |
2200 | pwSpec->epoch = cwSpec->epoch + 1; |
2201 | pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = |
2202 | pwSpec->epoch << 16; |
2203 | |
2204 | dtls_InitRecvdRecords(&pwSpec->recvdRecords); |
2205 | } |
2206 | pwSpec->read_seq_num.low = pwSpec->write_seq_num.low = 0; |
2207 | |
2208 | done: |
2209 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /******************************/ |
2210 | if (rv != SECSuccess) |
2211 | ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
2212 | return rv; |
2213 | } |
2214 | |
2215 | /* |
2216 | * 60 bytes is 3 times the maximum length MAC size that is supported. |
2217 | */ |
2218 | static const unsigned char mac_pad_1 [60] = { |
2219 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2220 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2221 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2222 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2223 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2224 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2225 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, |
2226 | 0x36, 0x36, 0x36, 0x36 |
2227 | }; |
2228 | static const unsigned char mac_pad_2 [60] = { |
2229 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2230 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2231 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2232 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2233 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2234 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2235 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, |
2236 | 0x5c, 0x5c, 0x5c, 0x5c |
2237 | }; |
2238 | |
2239 | /* Called from: ssl3_SendRecord() |
2240 | ** Caller must already hold the SpecReadLock. (wish we could assert that!) |
2241 | */ |
2242 | static SECStatus |
2243 | ssl3_ComputeRecordMAC( |
2244 | ssl3CipherSpec * spec, |
2245 | PRBool useServerMacKey, |
2246 | const unsigned char *header, |
2247 | unsigned int headerLen, |
2248 | const SSL3Opaque * input, |
2249 | int inputLength, |
2250 | unsigned char * outbuf, |
2251 | unsigned int * outLength) |
2252 | { |
2253 | const ssl3MACDef * mac_def; |
2254 | SECStatus rv; |
2255 | |
2256 | PRINT_BUF(95, (NULL, "frag hash1: header", header, headerLen))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "frag hash1: header" , header, headerLen); |
2257 | PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "frag hash1: input" , input, inputLength); |
2258 | |
2259 | mac_def = spec->mac_def; |
2260 | if (mac_def->mac == mac_nullssl_mac_null) { |
2261 | *outLength = 0; |
2262 | return SECSuccess; |
2263 | } |
2264 | #ifndef NO_PKCS11_BYPASS1 |
2265 | if (spec->bypassCiphers) { |
2266 | /* bypass version */ |
2267 | const SECHashObject *hashObj = NULL((void*)0); |
2268 | unsigned int pad_bytes = 0; |
2269 | PRUint64 write_mac_context[MAX_MAC_CONTEXT_LLONGS(400 / 8)]; |
2270 | |
2271 | switch (mac_def->mac) { |
2272 | case ssl_mac_null: |
2273 | *outLength = 0; |
2274 | return SECSuccess; |
2275 | case ssl_mac_md5: |
2276 | pad_bytes = 48; |
2277 | hashObj = HASH_GetRawHashObject(HASH_AlgMD5); |
2278 | break; |
2279 | case ssl_mac_sha: |
2280 | pad_bytes = 40; |
2281 | hashObj = HASH_GetRawHashObject(HASH_AlgSHA1); |
2282 | break; |
2283 | case ssl_hmac_md5: /* used with TLS */ |
2284 | hashObj = HASH_GetRawHashObject(HASH_AlgMD5); |
2285 | break; |
2286 | case ssl_hmac_sha: /* used with TLS */ |
2287 | hashObj = HASH_GetRawHashObject(HASH_AlgSHA1); |
2288 | break; |
2289 | case ssl_hmac_sha256: /* used with TLS */ |
2290 | hashObj = HASH_GetRawHashObject(HASH_AlgSHA256); |
2291 | break; |
2292 | default: |
2293 | break; |
2294 | } |
2295 | if (!hashObj) { |
2296 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","ssl3con.c",2296)); |
2297 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
2298 | return SECFailure; |
2299 | } |
2300 | |
2301 | if (spec->version <= SSL_LIBRARY_VERSION_3_00x0300) { |
2302 | unsigned int tempLen; |
2303 | unsigned char temp[MAX_MAC_LENGTH64]; |
2304 | |
2305 | /* compute "inner" part of SSL3 MAC */ |
2306 | hashObj->begin(write_mac_context); |
2307 | if (useServerMacKey) |
2308 | hashObj->update(write_mac_context, |
2309 | spec->server.write_mac_key_item.data, |
2310 | spec->server.write_mac_key_item.len); |
2311 | else |
2312 | hashObj->update(write_mac_context, |
2313 | spec->client.write_mac_key_item.data, |
2314 | spec->client.write_mac_key_item.len); |
2315 | hashObj->update(write_mac_context, mac_pad_1, pad_bytes); |
2316 | hashObj->update(write_mac_context, header, headerLen); |
2317 | hashObj->update(write_mac_context, input, inputLength); |
2318 | hashObj->end(write_mac_context, temp, &tempLen, sizeof temp); |
2319 | |
2320 | /* compute "outer" part of SSL3 MAC */ |
2321 | hashObj->begin(write_mac_context); |
2322 | if (useServerMacKey) |
2323 | hashObj->update(write_mac_context, |
2324 | spec->server.write_mac_key_item.data, |
2325 | spec->server.write_mac_key_item.len); |
2326 | else |
2327 | hashObj->update(write_mac_context, |
2328 | spec->client.write_mac_key_item.data, |
2329 | spec->client.write_mac_key_item.len); |
2330 | hashObj->update(write_mac_context, mac_pad_2, pad_bytes); |
2331 | hashObj->update(write_mac_context, temp, tempLen); |
2332 | hashObj->end(write_mac_context, outbuf, outLength, spec->mac_size); |
2333 | rv = SECSuccess; |
2334 | } else { /* is TLS */ |
2335 | #define cx ((HMACContext *)write_mac_context) |
2336 | if (useServerMacKey) { |
2337 | rv = HMAC_Init(cx, hashObj, |
2338 | spec->server.write_mac_key_item.data, |
2339 | spec->server.write_mac_key_item.len, PR_FALSE0); |
2340 | } else { |
2341 | rv = HMAC_Init(cx, hashObj, |
2342 | spec->client.write_mac_key_item.data, |
2343 | spec->client.write_mac_key_item.len, PR_FALSE0); |
2344 | } |
2345 | if (rv == SECSuccess) { |
2346 | HMAC_Begin(cx); |
2347 | HMAC_Update(cx, header, headerLen); |
2348 | HMAC_Update(cx, input, inputLength); |
2349 | rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size); |
2350 | HMAC_Destroy(cx, PR_FALSE0); |
2351 | } |
2352 | #undef cx |
2353 | } |
2354 | } else |
2355 | #endif |
2356 | { |
2357 | PK11Context *mac_context = |
2358 | (useServerMacKey ? spec->server.write_mac_context |
2359 | : spec->client.write_mac_context); |
2360 | rv = PK11_DigestBegin(mac_context); |
2361 | rv |= PK11_DigestOp(mac_context, header, headerLen); |
2362 | rv |= PK11_DigestOp(mac_context, input, inputLength); |
2363 | rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size); |
2364 | } |
2365 | |
2366 | PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size)((rv != SECSuccess || *outLength == (unsigned)spec->mac_size )?((void)0):PR_Assert("rv != SECSuccess || *outLength == (unsigned)spec->mac_size" ,"ssl3con.c",2366)); |
2367 | |
2368 | PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "frag hash2: result" , outbuf, *outLength); |
2369 | |
2370 | if (rv != SECSuccess) { |
2371 | rv = SECFailure; |
2372 | ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); |
2373 | } |
2374 | return rv; |
2375 | } |
2376 | |
2377 | /* Called from: ssl3_HandleRecord() |
2378 | * Caller must already hold the SpecReadLock. (wish we could assert that!) |
2379 | * |
2380 | * On entry: |
2381 | * originalLen >= inputLen >= MAC size |
2382 | */ |
2383 | static SECStatus |
2384 | ssl3_ComputeRecordMACConstantTime( |
2385 | ssl3CipherSpec * spec, |
2386 | PRBool useServerMacKey, |
2387 | const unsigned char *header, |
2388 | unsigned int headerLen, |
2389 | const SSL3Opaque * input, |
2390 | int inputLen, |
2391 | int originalLen, |
2392 | unsigned char * outbuf, |
2393 | unsigned int * outLen) |
2394 | { |
2395 | CK_MECHANISM_TYPE macType; |
2396 | CK_NSS_MAC_CONSTANT_TIME_PARAMS params; |
2397 | SECItem param, inputItem, outputItem; |
2398 | SECStatus rv; |
2399 | PK11SymKey * key; |
2400 | |
2401 | PORT_Assert(inputLen >= spec->mac_size)((inputLen >= spec->mac_size)?((void)0):PR_Assert("inputLen >= spec->mac_size" ,"ssl3con.c",2401)); |
2402 | PORT_Assert(originalLen >= inputLen)((originalLen >= inputLen)?((void)0):PR_Assert("originalLen >= inputLen" ,"ssl3con.c",2402)); |
2403 | |
2404 | if (spec->bypassCiphers) { |
2405 | /* This function doesn't support PKCS#11 bypass. We fallback on the |
2406 | * non-constant time version. */ |
2407 | goto fallback; |
2408 | } |
2409 | |
2410 | if (spec->mac_def->mac == mac_nullssl_mac_null) { |
2411 | *outLen = 0; |
2412 | return SECSuccess; |
2413 | } |
2414 | |
2415 | macType = CKM_NSS_HMAC_CONSTANT_TIME((0x80000000|0x4E534350) + 19); |
2416 | if (spec->version <= SSL_LIBRARY_VERSION_3_00x0300) { |
2417 | macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME((0x80000000|0x4E534350) + 20); |
2418 | } |
2419 | |
2420 | params.macAlg = spec->mac_def->mmech; |
2421 | params.ulBodyTotalLen = originalLen; |
2422 | params.pHeader = (unsigned char *) header; /* const cast */ |
2423 | params.ulHeaderLen = headerLen; |
2424 | |
2425 | param.data = (unsigned char*) ¶ms; |
2426 | param.len = sizeof(params); |
2427 | param.type = 0; |
2428 | |
2429 | inputItem.data = (unsigned char *) input; |
2430 | inputItem.len = inputLen; |
2431 | inputItem.type = 0; |
2432 | |
2433 | outputItem.data = outbuf; |
2434 | outputItem.len = *outLen; |
2435 | outputItem.type = 0; |
2436 | |
2437 | key = spec->server.write_mac_key; |
2438 | if (!useServerMacKey) { |
2439 | key = spec->client.write_mac_key; |
2440 | } |
2441 | |
2442 | rv = PK11_SignWithSymKey(key, macType, ¶m, &outputItem, &inputItem); |
2443 | if (rv != SECSuccess) { |
2444 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_INVALID_ALGORITHM) { |
2445 | goto fallback; |
2446 | } |
2447 | |
2448 | *outLen = 0; |
2449 | rv = SECFailure; |
2450 | ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); |
2451 | return rv; |
2452 | } |
2453 | |
2454 | PORT_Assert(outputItem.len == (unsigned)spec->mac_size)((outputItem.len == (unsigned)spec->mac_size)?((void)0):PR_Assert ("outputItem.len == (unsigned)spec->mac_size","ssl3con.c", 2454)); |
2455 | *outLen = outputItem.len; |
2456 | |
2457 | return rv; |
2458 | |
2459 | fallback: |
2460 | /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the |
2461 | * length already. */ |
2462 | inputLen -= spec->mac_size; |
2463 | return ssl3_ComputeRecordMAC(spec, useServerMacKey, header, headerLen, |
2464 | input, inputLen, outbuf, outLen); |
2465 | } |
2466 | |
2467 | static PRBool |
2468 | ssl3_ClientAuthTokenPresent(sslSessionID *sid) { |
2469 | PK11SlotInfo *slot = NULL((void*)0); |
2470 | PRBool isPresent = PR_TRUE1; |
2471 | |
2472 | /* we only care if we are doing client auth */ |
2473 | if (!sid || !sid->u.ssl3.clAuthValid) { |
2474 | return PR_TRUE1; |
2475 | } |
2476 | |
2477 | /* get the slot */ |
2478 | slot = SECMOD_LookupSlot(sid->u.ssl3.clAuthModuleID, |
2479 | sid->u.ssl3.clAuthSlotID); |
2480 | if (slot == NULL((void*)0) || |
2481 | !PK11_IsPresent(slot) || |
2482 | sid->u.ssl3.clAuthSeries != PK11_GetSlotSeries(slot) || |
2483 | sid->u.ssl3.clAuthSlotID != PK11_GetSlotID(slot) || |
2484 | sid->u.ssl3.clAuthModuleID != PK11_GetModuleID(slot) || |
2485 | (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL((void*)0)))) { |
2486 | isPresent = PR_FALSE0; |
2487 | } |
2488 | if (slot) { |
2489 | PK11_FreeSlot(slot); |
2490 | } |
2491 | return isPresent; |
2492 | } |
2493 | |
2494 | /* Caller must hold the spec read lock. */ |
2495 | SECStatus |
2496 | ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, |
2497 | PRBool isServer, |
2498 | PRBool isDTLS, |
2499 | PRBool capRecordVersion, |
2500 | SSL3ContentType type, |
2501 | const SSL3Opaque * pIn, |
2502 | PRUint32 contentLen, |
2503 | sslBuffer * wrBuf) |
2504 | { |
2505 | const ssl3BulkCipherDef * cipher_def; |
2506 | SECStatus rv; |
2507 | PRUint32 macLen = 0; |
2508 | PRUint32 fragLen; |
2509 | PRUint32 p1Len, p2Len, oddLen = 0; |
2510 | PRUint16 headerLen; |
2511 | int ivLen = 0; |
2512 | int cipherBytes = 0; |
2513 | unsigned char pseudoHeader[13]; |
2514 | unsigned int pseudoHeaderLen; |
2515 | |
2516 | cipher_def = cwSpec->cipher_def; |
2517 | headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH13 : SSL3_RECORD_HEADER_LENGTH5; |
2518 | |
2519 | if (cipher_def->type == type_block && |
2520 | cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_10x0302) { |
2521 | /* Prepend the per-record explicit IV using technique 2b from |
2522 | * RFC 4346 section 6.2.3.2: The IV is a cryptographically |
2523 | * strong random number XORed with the CBC residue from the previous |
2524 | * record. |
2525 | */ |
2526 | ivLen = cipher_def->iv_size; |
2527 | if (ivLen > wrBuf->space - headerLen) { |
2528 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
2529 | return SECFailure; |
2530 | } |
2531 | rv = PK11_GenerateRandom(wrBuf->buf + headerLen, ivLen); |
2532 | if (rv != SECSuccess) { |
2533 | ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); |
2534 | return rv; |
2535 | } |
2536 | rv = cwSpec->encode( cwSpec->encodeContext, |
2537 | wrBuf->buf + headerLen, |
2538 | &cipherBytes, /* output and actual outLen */ |
2539 | ivLen, /* max outlen */ |
2540 | wrBuf->buf + headerLen, |
2541 | ivLen); /* input and inputLen*/ |
2542 | if (rv != SECSuccess || cipherBytes != ivLen) { |
2543 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_ENCRYPTION_FAILURE); |
2544 | return SECFailure; |
2545 | } |
2546 | } |
2547 | |
2548 | if (cwSpec->compressor) { |
2549 | int outlen; |
2550 | rv = cwSpec->compressor( |
2551 | cwSpec->compressContext, |
2552 | wrBuf->buf + headerLen + ivLen, &outlen, |
2553 | wrBuf->space - headerLen - ivLen, pIn, contentLen); |
2554 | if (rv != SECSuccess) |
2555 | return rv; |
2556 | pIn = wrBuf->buf + headerLen + ivLen; |
2557 | contentLen = outlen; |
2558 | } |
2559 | |
2560 | pseudoHeaderLen = ssl3_BuildRecordPseudoHeader( |
2561 | pseudoHeader, cwSpec->write_seq_num, type, |
2562 | cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_00x0301, cwSpec->version, |
2563 | isDTLS, contentLen); |
2564 | PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader))((pseudoHeaderLen <= sizeof(pseudoHeader))?((void)0):PR_Assert ("pseudoHeaderLen <= sizeof(pseudoHeader)","ssl3con.c",2564 )); |
2565 | if (cipher_def->type == type_aead) { |
2566 | const int nonceLen = cipher_def->explicit_nonce_size; |
2567 | const int tagLen = cipher_def->tag_size; |
2568 | |
2569 | if (headerLen + nonceLen + contentLen + tagLen > wrBuf->space) { |
2570 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
2571 | return SECFailure; |
2572 | } |
2573 | |
2574 | cipherBytes = contentLen; |
2575 | rv = cwSpec->aead( |
2576 | isServer ? &cwSpec->server : &cwSpec->client, |
2577 | PR_FALSE0, /* do encrypt */ |
2578 | wrBuf->buf + headerLen, /* output */ |
2579 | &cipherBytes, /* out len */ |
2580 | wrBuf->space - headerLen, /* max out */ |
2581 | pIn, contentLen, /* input */ |
2582 | pseudoHeader, pseudoHeaderLen); |
2583 | if (rv != SECSuccess) { |
2584 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_ENCRYPTION_FAILURE); |
2585 | return SECFailure; |
2586 | } |
2587 | } else { |
2588 | /* |
2589 | * Add the MAC |
2590 | */ |
2591 | rv = ssl3_ComputeRecordMAC(cwSpec, isServer, |
2592 | pseudoHeader, pseudoHeaderLen, pIn, contentLen, |
2593 | wrBuf->buf + headerLen + ivLen + contentLen, &macLen); |
2594 | if (rv != SECSuccess) { |
2595 | ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); |
2596 | return SECFailure; |
2597 | } |
2598 | p1Len = contentLen; |
2599 | p2Len = macLen; |
2600 | fragLen = contentLen + macLen; /* needs to be encrypted */ |
2601 | PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024)((fragLen <= 16384 + 1024)?((void)0):PR_Assert("fragLen <= MAX_FRAGMENT_LENGTH + 1024" ,"ssl3con.c",2601)); |
2602 | |
2603 | /* |
2604 | * Pad the text (if we're doing a block cipher) |
2605 | * then Encrypt it |
2606 | */ |
2607 | if (cipher_def->type == type_block) { |
2608 | unsigned char * pBuf; |
2609 | int padding_length; |
2610 | int i; |
2611 | |
2612 | oddLen = contentLen % cipher_def->block_size; |
2613 | /* Assume blockSize is a power of two */ |
2614 | padding_length = cipher_def->block_size - 1 - |
2615 | ((fragLen) & (cipher_def->block_size - 1)); |
2616 | fragLen += padding_length + 1; |
2617 | PORT_Assert((fragLen % cipher_def->block_size) == 0)(((fragLen % cipher_def->block_size) == 0)?((void)0):PR_Assert ("(fragLen % cipher_def->block_size) == 0","ssl3con.c",2617 )); |
2618 | |
2619 | /* Pad according to TLS rules (also acceptable to SSL3). */ |
2620 | pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1]; |
2621 | for (i = padding_length + 1; i > 0; --i) { |
2622 | *pBuf-- = padding_length; |
2623 | } |
2624 | /* now, if contentLen is not a multiple of block size, fix it */ |
2625 | p2Len = fragLen - p1Len; |
2626 | } |
2627 | if (p1Len < 256) { |
2628 | oddLen = p1Len; |
2629 | p1Len = 0; |
2630 | } else { |
2631 | p1Len -= oddLen; |
2632 | } |
2633 | if (oddLen) { |
2634 | p2Len += oddLen; |
2635 | PORT_Assert( (cipher_def->block_size < 2) || \(((cipher_def->block_size < 2) || (p2Len % cipher_def-> block_size) == 0)?((void)0):PR_Assert("(cipher_def->block_size < 2) || (p2Len % cipher_def->block_size) == 0" ,"ssl3con.c",2636)) |
2636 | (p2Len % cipher_def->block_size) == 0)(((cipher_def->block_size < 2) || (p2Len % cipher_def-> block_size) == 0)?((void)0):PR_Assert("(cipher_def->block_size < 2) || (p2Len % cipher_def->block_size) == 0" ,"ssl3con.c",2636)); |
2637 | memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len, |
2638 | oddLen); |
2639 | } |
2640 | if (p1Len > 0) { |
2641 | int cipherBytesPart1 = -1; |
2642 | rv = cwSpec->encode( cwSpec->encodeContext, |
2643 | wrBuf->buf + headerLen + ivLen, /* output */ |
2644 | &cipherBytesPart1, /* actual outlen */ |
2645 | p1Len, /* max outlen */ |
2646 | pIn, p1Len); /* input, and inputlen */ |
2647 | PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int) p1Len)((rv == SECSuccess && cipherBytesPart1 == (int) p1Len )?((void)0):PR_Assert("rv == SECSuccess && cipherBytesPart1 == (int) p1Len" ,"ssl3con.c",2647)); |
2648 | if (rv != SECSuccess || cipherBytesPart1 != (int) p1Len) { |
2649 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_ENCRYPTION_FAILURE); |
2650 | return SECFailure; |
2651 | } |
2652 | cipherBytes += cipherBytesPart1; |
2653 | } |
2654 | if (p2Len > 0) { |
2655 | int cipherBytesPart2 = -1; |
2656 | rv = cwSpec->encode( cwSpec->encodeContext, |
2657 | wrBuf->buf + headerLen + ivLen + p1Len, |
2658 | &cipherBytesPart2, /* output and actual outLen */ |
2659 | p2Len, /* max outlen */ |
2660 | wrBuf->buf + headerLen + ivLen + p1Len, |
2661 | p2Len); /* input and inputLen*/ |
2662 | PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len)((rv == SECSuccess && cipherBytesPart2 == (int) p2Len )?((void)0):PR_Assert("rv == SECSuccess && cipherBytesPart2 == (int) p2Len" ,"ssl3con.c",2662)); |
2663 | if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) { |
2664 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_ENCRYPTION_FAILURE); |
2665 | return SECFailure; |
2666 | } |
2667 | cipherBytes += cipherBytesPart2; |
2668 | } |
2669 | } |
2670 | |
2671 | PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024)((cipherBytes <= 16384 + 1024)?((void)0):PR_Assert("cipherBytes <= MAX_FRAGMENT_LENGTH + 1024" ,"ssl3con.c",2671)); |
2672 | |
2673 | wrBuf->len = cipherBytes + headerLen; |
2674 | wrBuf->buf[0] = type; |
2675 | if (isDTLS) { |
2676 | SSL3ProtocolVersion version; |
2677 | |
2678 | version = dtls_TLSVersionToDTLSVersion(cwSpec->version); |
2679 | wrBuf->buf[1] = MSB(version)((unsigned char) (((unsigned)(version)) >> 8)); |
2680 | wrBuf->buf[2] = LSB(version)((unsigned char) ((version) & 0xff)); |
2681 | wrBuf->buf[3] = (unsigned char)(cwSpec->write_seq_num.high >> 24); |
2682 | wrBuf->buf[4] = (unsigned char)(cwSpec->write_seq_num.high >> 16); |
2683 | wrBuf->buf[5] = (unsigned char)(cwSpec->write_seq_num.high >> 8); |
2684 | wrBuf->buf[6] = (unsigned char)(cwSpec->write_seq_num.high >> 0); |
2685 | wrBuf->buf[7] = (unsigned char)(cwSpec->write_seq_num.low >> 24); |
2686 | wrBuf->buf[8] = (unsigned char)(cwSpec->write_seq_num.low >> 16); |
2687 | wrBuf->buf[9] = (unsigned char)(cwSpec->write_seq_num.low >> 8); |
2688 | wrBuf->buf[10] = (unsigned char)(cwSpec->write_seq_num.low >> 0); |
2689 | wrBuf->buf[11] = MSB(cipherBytes)((unsigned char) (((unsigned)(cipherBytes)) >> 8)); |
2690 | wrBuf->buf[12] = LSB(cipherBytes)((unsigned char) ((cipherBytes) & 0xff)); |
2691 | } else { |
2692 | SSL3ProtocolVersion version = cwSpec->version; |
2693 | |
2694 | if (capRecordVersion) { |
2695 | version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version)((0x0301)<(version)?(0x0301):(version)); |
2696 | } |
2697 | wrBuf->buf[1] = MSB(version)((unsigned char) (((unsigned)(version)) >> 8)); |
2698 | wrBuf->buf[2] = LSB(version)((unsigned char) ((version) & 0xff)); |
2699 | wrBuf->buf[3] = MSB(cipherBytes)((unsigned char) (((unsigned)(cipherBytes)) >> 8)); |
2700 | wrBuf->buf[4] = LSB(cipherBytes)((unsigned char) ((cipherBytes) & 0xff)); |
2701 | } |
2702 | |
2703 | ssl3_BumpSequenceNumber(&cwSpec->write_seq_num); |
2704 | |
2705 | return SECSuccess; |
2706 | } |
2707 | |
2708 | /* Process the plain text before sending it. |
2709 | * Returns the number of bytes of plaintext that were successfully sent |
2710 | * plus the number of bytes of plaintext that were copied into the |
2711 | * output (write) buffer. |
2712 | * Returns SECFailure on a hard IO error, memory error, or crypto error. |
2713 | * Does NOT return SECWouldBlock. |
2714 | * |
2715 | * Notes on the use of the private ssl flags: |
2716 | * (no private SSL flags) |
2717 | * Attempt to make and send SSL records for all plaintext |
2718 | * If non-blocking and a send gets WOULD_BLOCK, |
2719 | * or if the pending (ciphertext) buffer is not empty, |
2720 | * then buffer remaining bytes of ciphertext into pending buf, |
2721 | * and continue to do that for all succssive records until all |
2722 | * bytes are used. |
2723 | * ssl_SEND_FLAG_FORCE_INTO_BUFFER |
2724 | * As above, except this suppresses all write attempts, and forces |
2725 | * all ciphertext into the pending ciphertext buffer. |
2726 | * ssl_SEND_FLAG_USE_EPOCH (for DTLS) |
2727 | * Forces the use of the provided epoch |
2728 | * ssl_SEND_FLAG_CAP_RECORD_VERSION |
2729 | * Caps the record layer version number of TLS ClientHello to { 3, 1 } |
2730 | * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore |
2731 | * ClientHello.client_version and use the record layer version number |
2732 | * (TLSPlaintext.version) instead when negotiating protocol versions. In |
2733 | * addition, if the record layer version number of ClientHello is { 3, 2 } |
2734 | * (TLS 1.1) or higher, these servers reset the TCP connections. Lastly, |
2735 | * some F5 BIG-IP servers hang if a record containing a ClientHello has a |
2736 | * version greater than { 3, 1 } and a length greater than 255. Set this |
2737 | * flag to work around such servers. |
2738 | */ |
2739 | PRInt32 |
2740 | ssl3_SendRecord( sslSocket * ss, |
2741 | DTLSEpoch epoch, /* DTLS only */ |
2742 | SSL3ContentType type, |
2743 | const SSL3Opaque * pIn, /* input buffer */ |
2744 | PRInt32 nIn, /* bytes of input */ |
2745 | PRInt32 flags) |
2746 | { |
2747 | sslBuffer * wrBuf = &ss->sec.writeBuf; |
2748 | SECStatus rv; |
2749 | PRInt32 totalSent = 0; |
2750 | PRBool capRecordVersion; |
2751 | |
2752 | SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] SendRecord type: %s nIn=%d" , getpid(), ss->fd, ssl3_DecodeContentType(type), nIn) |
2753 | SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] SendRecord type: %s nIn=%d" , getpid(), ss->fd, ssl3_DecodeContentType(type), nIn) |
2754 | nIn))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] SendRecord type: %s nIn=%d" , getpid(), ss->fd, ssl3_DecodeContentType(type), nIn); |
2755 | PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Send record (plain text)" , pIn, nIn); |
2756 | |
2757 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",2757)); |
2758 | |
2759 | capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION0x04000000) != 0); |
2760 | |
2761 | if (capRecordVersion) { |
2762 | /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the |
2763 | * TLS initial ClientHello. */ |
2764 | PORT_Assert(!IS_DTLS(ss))((!(ss->protocolVariant == ssl_variant_datagram))?((void)0 ):PR_Assert("!IS_DTLS(ss)","ssl3con.c",2764)); |
2765 | PORT_Assert(!ss->firstHsDone)((!ss->firstHsDone)?((void)0):PR_Assert("!ss->firstHsDone" ,"ssl3con.c",2765)); |
2766 | PORT_Assert(type == content_handshake)((type == content_handshake)?((void)0):PR_Assert("type == content_handshake" ,"ssl3con.c",2766)); |
2767 | PORT_Assert(ss->ssl3.hs.ws == wait_server_hello)((ss->ssl3.hs.ws == wait_server_hello)?((void)0):PR_Assert ("ss->ssl3.hs.ws == wait_server_hello","ssl3con.c",2767)); |
2768 | } |
2769 | |
2770 | if (ss->ssl3.initialized == PR_FALSE0) { |
2771 | /* This can happen on a server if the very first incoming record |
2772 | ** looks like a defective ssl3 record (e.g. too long), and we're |
2773 | ** trying to send an alert. |
2774 | */ |
2775 | PR_ASSERT(type == content_alert)((type == content_alert)?((void)0):PR_Assert("type == content_alert" ,"ssl3con.c",2775)); |
2776 | rv = ssl3_InitState(ss); |
2777 | if (rv != SECSuccess) { |
2778 | return SECFailure; /* ssl3_InitState has set the error code. */ |
2779 | } |
2780 | } |
2781 | |
2782 | /* check for Token Presence */ |
2783 | if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { |
2784 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
2785 | return SECFailure; |
2786 | } |
2787 | |
2788 | while (nIn > 0) { |
2789 | PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH)((nIn)<(16384)?(nIn):(16384)); |
2790 | unsigned int spaceNeeded; |
2791 | unsigned int numRecords; |
2792 | |
2793 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; /********************************/ |
2794 | |
2795 | if (nIn > 1 && ss->opt.cbcRandomIV && |
2796 | ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_10x0302 && |
2797 | type == content_application_data && |
2798 | ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { |
2799 | /* We will split the first byte of the record into its own record, |
2800 | * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h |
2801 | */ |
2802 | numRecords = 2; |
2803 | } else { |
2804 | numRecords = 1; |
2805 | } |
2806 | |
2807 | spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE100 + 0); |
2808 | if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_10x0302 && |
2809 | ss->ssl3.cwSpec->cipher_def->type == type_block) { |
2810 | spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size; |
2811 | } |
2812 | if (spaceNeeded > wrBuf->space) { |
2813 | rv = sslBuffer_Grow(wrBuf, spaceNeeded); |
2814 | if (rv != SECSuccess) { |
2815 | SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: SendRecord, tried to get %d bytes" , getpid(), ss->fd, spaceNeeded) |
2816 | SSL_GETPID(), ss->fd, spaceNeeded))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: SendRecord, tried to get %d bytes" , getpid(), ss->fd, spaceNeeded); |
2817 | goto spec_locked_loser; /* sslBuffer_Grow set error code. */ |
2818 | } |
2819 | } |
2820 | |
2821 | if (numRecords == 2) { |
2822 | sslBuffer secondRecord; |
2823 | |
2824 | rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
2825 | ss->sec.isServer, IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram), |
2826 | capRecordVersion, type, pIn, |
2827 | 1, wrBuf); |
2828 | if (rv != SECSuccess) |
2829 | goto spec_locked_loser; |
2830 | |
2831 | PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",if (ssl_trace >= (50)) ssl_PrintBuf (ss, "send (encrypted) record data [1/2]:" , wrBuf->buf, wrBuf->len) |
2832 | wrBuf->buf, wrBuf->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "send (encrypted) record data [1/2]:" , wrBuf->buf, wrBuf->len); |
2833 | |
2834 | secondRecord.buf = wrBuf->buf + wrBuf->len; |
2835 | secondRecord.len = 0; |
2836 | secondRecord.space = wrBuf->space - wrBuf->len; |
2837 | |
2838 | rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
2839 | ss->sec.isServer, IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram), |
2840 | capRecordVersion, type, |
2841 | pIn + 1, contentLen - 1, |
2842 | &secondRecord); |
2843 | if (rv == SECSuccess) { |
2844 | PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",if (ssl_trace >= (50)) ssl_PrintBuf (ss, "send (encrypted) record data [2/2]:" , secondRecord.buf, secondRecord.len) |
2845 | secondRecord.buf, secondRecord.len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "send (encrypted) record data [2/2]:" , secondRecord.buf, secondRecord.len); |
2846 | wrBuf->len += secondRecord.len; |
2847 | } |
2848 | } else { |
2849 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
2850 | rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
2851 | ss->sec.isServer, |
2852 | IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram), |
2853 | capRecordVersion, |
2854 | type, pIn, |
2855 | contentLen, wrBuf); |
2856 | } else { |
2857 | rv = dtls_CompressMACEncryptRecord(ss, epoch, |
2858 | !!(flags & ssl_SEND_FLAG_USE_EPOCH0x10000000), |
2859 | type, pIn, |
2860 | contentLen, wrBuf); |
2861 | } |
2862 | |
2863 | if (rv == SECSuccess) { |
2864 | PRINT_BUF(50, (ss, "send (encrypted) record data:",if (ssl_trace >= (50)) ssl_PrintBuf (ss, "send (encrypted) record data:" , wrBuf->buf, wrBuf->len) |
2865 | wrBuf->buf, wrBuf->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "send (encrypted) record data:" , wrBuf->buf, wrBuf->len); |
2866 | } |
2867 | } |
2868 | |
2869 | spec_locked_loser: |
2870 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; /************************************/ |
2871 | |
2872 | if (rv != SECSuccess) |
2873 | return SECFailure; |
2874 | |
2875 | pIn += contentLen; |
2876 | nIn -= contentLen; |
2877 | PORT_Assert( nIn >= 0 )((nIn >= 0)?((void)0):PR_Assert("nIn >= 0","ssl3con.c", 2877)); |
2878 | |
2879 | /* If there's still some previously saved ciphertext, |
2880 | * or the caller doesn't want us to send the data yet, |
2881 | * then add all our new ciphertext to the amount previously saved. |
2882 | */ |
2883 | if ((ss->pendingBuf.len > 0) || |
2884 | (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000)) { |
2885 | |
2886 | rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len); |
2887 | if (rv != SECSuccess) { |
2888 | /* presumably a memory error, SEC_ERROR_NO_MEMORY */ |
2889 | return SECFailure; |
2890 | } |
2891 | wrBuf->len = 0; /* All cipher text is saved away. */ |
2892 | |
2893 | if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000)) { |
2894 | PRInt32 sent; |
2895 | ss->handshakeBegun = 1; |
2896 | sent = ssl_SendSavedWriteData(ss); |
2897 | if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR(-5998L)) { |
2898 | ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); |
2899 | return SECFailure; |
2900 | } |
2901 | if (ss->pendingBuf.len) { |
2902 | flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000; |
2903 | } |
2904 | } |
2905 | } else if (wrBuf->len > 0) { |
2906 | PRInt32 sent; |
2907 | ss->handshakeBegun = 1; |
2908 | sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len, |
2909 | flags & ~ssl_SEND_FLAG_MASK0x7f000000); |
2910 | if (sent < 0) { |
2911 | if (PR_GetError() != PR_WOULD_BLOCK_ERROR(-5998L)) { |
2912 | ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); |
2913 | return SECFailure; |
2914 | } |
2915 | /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */ |
2916 | sent = 0; |
2917 | } |
2918 | wrBuf->len -= sent; |
2919 | if (wrBuf->len) { |
2920 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
2921 | /* DTLS just says no in this case. No buffering */ |
2922 | PR_SetError(PR_WOULD_BLOCK_ERROR(-5998L), 0); |
2923 | return SECFailure; |
2924 | } |
2925 | /* now take all the remaining unsent new ciphertext and |
2926 | * append it to the buffer of previously unsent ciphertext. |
2927 | */ |
2928 | rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); |
2929 | if (rv != SECSuccess) { |
2930 | /* presumably a memory error, SEC_ERROR_NO_MEMORY */ |
2931 | return SECFailure; |
2932 | } |
2933 | } |
2934 | } |
2935 | totalSent += contentLen; |
2936 | } |
2937 | return totalSent; |
2938 | } |
2939 | |
2940 | #define SSL3_PENDING_HIGH_WATER1024 1024 |
2941 | |
2942 | /* Attempt to send the content of "in" in an SSL application_data record. |
2943 | * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. |
2944 | */ |
2945 | int |
2946 | ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, |
2947 | PRInt32 len, PRInt32 flags) |
2948 | { |
2949 | PRInt32 totalSent = 0; |
2950 | PRInt32 discarded = 0; |
2951 | |
2952 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",2952)); |
2953 | /* These flags for internal use only */ |
2954 | PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH |((!(flags & (0x10000000 | 0x08000000)))?((void)0):PR_Assert ("!(flags & (ssl_SEND_FLAG_USE_EPOCH | ssl_SEND_FLAG_NO_RETRANSMIT))" ,"ssl3con.c",2955)) |
2955 | ssl_SEND_FLAG_NO_RETRANSMIT)))((!(flags & (0x10000000 | 0x08000000)))?((void)0):PR_Assert ("!(flags & (ssl_SEND_FLAG_USE_EPOCH | ssl_SEND_FLAG_NO_RETRANSMIT))" ,"ssl3con.c",2955)); |
2956 | if (len < 0 || !in) { |
2957 | PORT_SetErrorPORT_SetError_Util(PR_INVALID_ARGUMENT_ERROR(-5987L)); |
2958 | return SECFailure; |
2959 | } |
2960 | |
2961 | if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER1024 && |
2962 | !ssl_SocketIsBlocking(ss)) { |
2963 | PORT_Assert(!ssl_SocketIsBlocking(ss))((!ssl_SocketIsBlocking(ss))?((void)0):PR_Assert("!ssl_SocketIsBlocking(ss)" ,"ssl3con.c",2963)); |
2964 | PORT_SetErrorPORT_SetError_Util(PR_WOULD_BLOCK_ERROR(-5998L)); |
2965 | return SECFailure; |
2966 | } |
2967 | |
2968 | if (ss->appDataBuffered && len) { |
2969 | PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered))((in[0] == (unsigned char)(ss->appDataBuffered))?((void)0) :PR_Assert("in[0] == (unsigned char)(ss->appDataBuffered)" ,"ssl3con.c",2969)); |
2970 | if (in[0] != (unsigned char)(ss->appDataBuffered)) { |
2971 | PORT_SetErrorPORT_SetError_Util(PR_INVALID_ARGUMENT_ERROR(-5987L)); |
2972 | return SECFailure; |
2973 | } |
2974 | in++; |
2975 | len--; |
2976 | discarded = 1; |
2977 | } |
2978 | while (len > totalSent) { |
2979 | PRInt32 sent, toSend; |
2980 | |
2981 | if (totalSent > 0) { |
2982 | /* |
2983 | * The thread yield is intended to give the reader thread a |
2984 | * chance to get some cycles while the writer thread is in |
2985 | * the middle of a large application data write. (See |
2986 | * Bugzilla bug 127740, comment #1.) |
2987 | */ |
2988 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
2989 | PR_Sleep(PR_INTERVAL_NO_WAIT0UL); /* PR_Yield(); */ |
2990 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
2991 | } |
2992 | toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH)((len - totalSent)<(16384)?(len - totalSent):(16384)); |
2993 | /* |
2994 | * Note that the 0 epoch is OK because flags will never require |
2995 | * its use, as guaranteed by the PORT_Assert above. |
2996 | */ |
2997 | sent = ssl3_SendRecord(ss, 0, content_application_data, |
2998 | in + totalSent, toSend, flags); |
2999 | if (sent < 0) { |
3000 | if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR(-5998L)) { |
3001 | PORT_Assert(ss->lastWriteBlocked)((ss->lastWriteBlocked)?((void)0):PR_Assert("ss->lastWriteBlocked" ,"ssl3con.c",3001)); |
3002 | break; |
3003 | } |
3004 | return SECFailure; /* error code set by ssl3_SendRecord */ |
3005 | } |
3006 | totalSent += sent; |
3007 | if (ss->pendingBuf.len) { |
3008 | /* must be a non-blocking socket */ |
3009 | PORT_Assert(!ssl_SocketIsBlocking(ss))((!ssl_SocketIsBlocking(ss))?((void)0):PR_Assert("!ssl_SocketIsBlocking(ss)" ,"ssl3con.c",3009)); |
3010 | PORT_Assert(ss->lastWriteBlocked)((ss->lastWriteBlocked)?((void)0):PR_Assert("ss->lastWriteBlocked" ,"ssl3con.c",3010)); |
3011 | break; |
3012 | } |
3013 | } |
3014 | if (ss->pendingBuf.len) { |
3015 | /* Must be non-blocking. */ |
3016 | PORT_Assert(!ssl_SocketIsBlocking(ss))((!ssl_SocketIsBlocking(ss))?((void)0):PR_Assert("!ssl_SocketIsBlocking(ss)" ,"ssl3con.c",3016)); |
3017 | if (totalSent > 0) { |
3018 | ss->appDataBuffered = 0x100 | in[totalSent - 1]; |
3019 | } |
3020 | |
3021 | totalSent = totalSent + discarded - 1; |
3022 | if (totalSent <= 0) { |
3023 | PORT_SetErrorPORT_SetError_Util(PR_WOULD_BLOCK_ERROR(-5998L)); |
3024 | totalSent = SECFailure; |
3025 | } |
3026 | return totalSent; |
3027 | } |
3028 | ss->appDataBuffered = 0; |
3029 | return totalSent + discarded; |
3030 | } |
3031 | |
3032 | /* Attempt to send buffered handshake messages. |
3033 | * This function returns SECSuccess or SECFailure, never SECWouldBlock. |
3034 | * Always set sendBuf.len to 0, even when returning SECFailure. |
3035 | * |
3036 | * Depending on whether we are doing DTLS or not, this either calls |
3037 | * |
3038 | * - ssl3_FlushHandshakeMessages if non-DTLS |
3039 | * - dtls_FlushHandshakeMessages if DTLS |
3040 | * |
3041 | * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(), |
3042 | * ssl3_AppendHandshake(), ssl3_SendClientHello(), |
3043 | * ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(), |
3044 | * ssl3_SendFinished(), |
3045 | */ |
3046 | static SECStatus |
3047 | ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) |
3048 | { |
3049 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
3050 | return dtls_FlushHandshakeMessages(ss, flags); |
3051 | } else { |
3052 | return ssl3_FlushHandshakeMessages(ss, flags); |
3053 | } |
3054 | } |
3055 | |
3056 | /* Attempt to send the content of sendBuf buffer in an SSL handshake record. |
3057 | * This function returns SECSuccess or SECFailure, never SECWouldBlock. |
3058 | * Always set sendBuf.len to 0, even when returning SECFailure. |
3059 | * |
3060 | * Called from ssl3_FlushHandshake |
3061 | */ |
3062 | static SECStatus |
3063 | ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags) |
3064 | { |
3065 | static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000 | |
3066 | ssl_SEND_FLAG_CAP_RECORD_VERSION0x04000000; |
3067 | PRInt32 rv = SECSuccess; |
3068 | |
3069 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3069)); |
3070 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",3070)); |
3071 | |
3072 | if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) |
3073 | return rv; |
3074 | |
3075 | /* only these flags are allowed */ |
3076 | PORT_Assert(!(flags & ~allowedFlags))((!(flags & ~allowedFlags))?((void)0):PR_Assert("!(flags & ~allowedFlags)" ,"ssl3con.c",3076)); |
3077 | if ((flags & ~allowedFlags) != 0) { |
3078 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
3079 | rv = SECFailure; |
3080 | } else { |
3081 | rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf, |
3082 | ss->sec.ci.sendBuf.len, flags); |
3083 | } |
3084 | if (rv < 0) { |
3085 | int err = PORT_GetErrorPORT_GetError_Util(); |
3086 | PORT_Assert(err != PR_WOULD_BLOCK_ERROR)((err != (-5998L))?((void)0):PR_Assert("err != PR_WOULD_BLOCK_ERROR" ,"ssl3con.c",3086)); |
3087 | if (err == PR_WOULD_BLOCK_ERROR(-5998L)) { |
3088 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
3089 | } |
3090 | } else if (rv < ss->sec.ci.sendBuf.len) { |
3091 | /* short write should never happen */ |
3092 | PORT_Assert(rv >= ss->sec.ci.sendBuf.len)((rv >= ss->sec.ci.sendBuf.len)?((void)0):PR_Assert("rv >= ss->sec.ci.sendBuf.len" ,"ssl3con.c",3092)); |
3093 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
3094 | rv = SECFailure; |
3095 | } else { |
3096 | rv = SECSuccess; |
3097 | } |
3098 | |
3099 | /* Whether we succeeded or failed, toss the old handshake data. */ |
3100 | ss->sec.ci.sendBuf.len = 0; |
3101 | return rv; |
3102 | } |
3103 | |
3104 | /* |
3105 | * Called from ssl3_HandleAlert and from ssl3_HandleCertificate when |
3106 | * the remote client sends a negative response to our certificate request. |
3107 | * Returns SECFailure if the application has required client auth. |
3108 | * SECSuccess otherwise. |
3109 | */ |
3110 | static SECStatus |
3111 | ssl3_HandleNoCertificate(sslSocket *ss) |
3112 | { |
3113 | if (ss->sec.peerCert != NULL((void*)0)) { |
3114 | if (ss->sec.peerKey != NULL((void*)0)) { |
3115 | SECKEY_DestroyPublicKey(ss->sec.peerKey); |
3116 | ss->sec.peerKey = NULL((void*)0); |
3117 | } |
3118 | CERT_DestroyCertificate(ss->sec.peerCert); |
3119 | ss->sec.peerCert = NULL((void*)0); |
3120 | } |
3121 | ssl3_CleanupPeerCerts(ss); |
3122 | |
3123 | /* If the server has required client-auth blindly but doesn't |
3124 | * actually look at the certificate it won't know that no |
3125 | * certificate was presented so we shutdown the socket to ensure |
3126 | * an error. We only do this if we haven't already completed the |
3127 | * first handshake because if we're redoing the handshake we |
3128 | * know the server is paying attention to the certificate. |
3129 | */ |
3130 | if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS((PRBool)1)) || |
3131 | (!ss->firstHsDone && |
3132 | (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE((PRBool)2)))) { |
3133 | PRFileDesc * lower; |
3134 | |
3135 | if (ss->sec.uncache) |
3136 | ss->sec.uncache(ss->sec.ci.sid); |
3137 | SSL3_SendAlert(ss, alert_fatal, bad_certificate); |
3138 | |
3139 | lower = ss->fd->lower; |
3140 | #ifdef _WIN32 |
3141 | lower->methods->shutdown(lower, PR_SHUTDOWN_SEND); |
3142 | #else |
3143 | lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH); |
3144 | #endif |
3145 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_CERTIFICATE); |
3146 | return SECFailure; |
3147 | } |
3148 | return SECSuccess; |
3149 | } |
3150 | |
3151 | /************************************************************************ |
3152 | * Alerts |
3153 | */ |
3154 | |
3155 | /* |
3156 | ** Acquires both handshake and XmitBuf locks. |
3157 | ** Called from: ssl3_IllegalParameter <- |
3158 | ** ssl3_HandshakeFailure <- |
3159 | ** ssl3_HandleAlert <- ssl3_HandleRecord. |
3160 | ** ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord |
3161 | ** ssl3_ConsumeHandshakeVariable <- |
3162 | ** ssl3_HandleHelloRequest <- |
3163 | ** ssl3_HandleServerHello <- |
3164 | ** ssl3_HandleServerKeyExchange <- |
3165 | ** ssl3_HandleCertificateRequest <- |
3166 | ** ssl3_HandleServerHelloDone <- |
3167 | ** ssl3_HandleClientHello <- |
3168 | ** ssl3_HandleV2ClientHello <- |
3169 | ** ssl3_HandleCertificateVerify <- |
3170 | ** ssl3_HandleClientKeyExchange <- |
3171 | ** ssl3_HandleCertificate <- |
3172 | ** ssl3_HandleFinished <- |
3173 | ** ssl3_HandleHandshakeMessage <- |
3174 | ** ssl3_HandleRecord <- |
3175 | ** |
3176 | */ |
3177 | SECStatus |
3178 | SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) |
3179 | { |
3180 | PRUint8 bytes[2]; |
3181 | SECStatus rv; |
3182 | |
3183 | SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send alert record, level=%d desc=%d" , getpid(), ss->fd, level, desc) |
3184 | SSL_GETPID(), ss->fd, level, desc))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send alert record, level=%d desc=%d" , getpid(), ss->fd, level, desc); |
3185 | |
3186 | bytes[0] = level; |
3187 | bytes[1] = desc; |
3188 | |
3189 | ssl_GetSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",3189)); PR_EnterMonitor(((ss)->ssl3HandshakeLock )); } }; |
3190 | if (level == alert_fatal) { |
3191 | if (!ss->opt.noCache && ss->sec.ci.sid && ss->sec.uncache) { |
3192 | ss->sec.uncache(ss->sec.ci.sid); |
3193 | } |
3194 | } |
3195 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
3196 | rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000); |
3197 | if (rv == SECSuccess) { |
3198 | PRInt32 sent; |
3199 | sent = ssl3_SendRecord(ss, 0, content_alert, bytes, 2, |
3200 | desc == no_certificate |
3201 | ? ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000 : 0); |
3202 | rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
3203 | } |
3204 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
3205 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
3206 | return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */ |
3207 | } |
3208 | |
3209 | /* |
3210 | * Send illegal_parameter alert. Set generic error number. |
3211 | */ |
3212 | static SECStatus |
3213 | ssl3_IllegalParameter(sslSocket *ss) |
3214 | { |
3215 | (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
3216 | PORT_SetErrorPORT_SetError_Util(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT |
3217 | : SSL_ERROR_BAD_SERVER ); |
3218 | return SECFailure; |
3219 | } |
3220 | |
3221 | /* |
3222 | * Send handshake_Failure alert. Set generic error number. |
3223 | */ |
3224 | static SECStatus |
3225 | ssl3_HandshakeFailure(sslSocket *ss) |
3226 | { |
3227 | (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); |
3228 | PORT_SetErrorPORT_SetError_Util( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT |
3229 | : SSL_ERROR_BAD_SERVER ); |
3230 | return SECFailure; |
3231 | } |
3232 | |
3233 | static void |
3234 | ssl3_SendAlertForCertError(sslSocket * ss, PRErrorCode errCode) |
3235 | { |
3236 | SSL3AlertDescription desc = bad_certificate; |
3237 | PRBool isTLS = ss->version >= SSL_LIBRARY_VERSION_3_1_TLS0x0301; |
3238 | |
3239 | switch (errCode) { |
3240 | case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break; |
3241 | case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break; |
3242 | case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break; |
3243 | case SEC_ERROR_INADEQUATE_KEY_USAGE: |
3244 | case SEC_ERROR_INADEQUATE_CERT_TYPE: |
3245 | desc = certificate_unknown; break; |
3246 | case SEC_ERROR_UNTRUSTED_CERT: |
3247 | desc = isTLS ? access_denied : certificate_unknown; break; |
3248 | case SEC_ERROR_UNKNOWN_ISSUER: |
3249 | case SEC_ERROR_UNTRUSTED_ISSUER: |
3250 | desc = isTLS ? unknown_ca : certificate_unknown; break; |
3251 | case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: |
3252 | desc = isTLS ? unknown_ca : certificate_expired; break; |
3253 | |
3254 | case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: |
3255 | case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: |
3256 | case SEC_ERROR_CA_CERT_INVALID: |
3257 | case SEC_ERROR_BAD_SIGNATURE: |
3258 | default: desc = bad_certificate; break; |
3259 | } |
3260 | SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: peer certificate is no good: error=%d" , getpid(), ss->fd, errCode) |
3261 | SSL_GETPID(), ss->fd, errCode))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: peer certificate is no good: error=%d" , getpid(), ss->fd, errCode); |
3262 | |
3263 | (void) SSL3_SendAlert(ss, alert_fatal, desc); |
3264 | } |
3265 | |
3266 | |
3267 | /* |
3268 | * Send decode_error alert. Set generic error number. |
3269 | */ |
3270 | SECStatus |
3271 | ssl3_DecodeError(sslSocket *ss) |
3272 | { |
3273 | (void)SSL3_SendAlert(ss, alert_fatal, |
3274 | ss->version > SSL_LIBRARY_VERSION_3_00x0300 ? decode_error |
3275 | : illegal_parameter); |
3276 | PORT_SetErrorPORT_SetError_Util( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT |
3277 | : SSL_ERROR_BAD_SERVER ); |
3278 | return SECFailure; |
3279 | } |
3280 | |
3281 | /* Called from ssl3_HandleRecord. |
3282 | ** Caller must hold both RecvBuf and Handshake locks. |
3283 | */ |
3284 | static SECStatus |
3285 | ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) |
3286 | { |
3287 | SSL3AlertLevel level; |
3288 | SSL3AlertDescription desc; |
3289 | int error; |
3290 | |
3291 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",3291)); |
3292 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3292)); |
3293 | |
3294 | SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle alert record" , getpid(), ss->fd); |
3295 | |
3296 | if (buf->len != 2) { |
3297 | (void)ssl3_DecodeError(ss); |
3298 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ALERT); |
3299 | return SECFailure; |
3300 | } |
3301 | level = (SSL3AlertLevel)buf->buf[0]; |
3302 | desc = (SSL3AlertDescription)buf->buf[1]; |
3303 | buf->len = 0; |
3304 | SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",if (ssl_trace >= (5)) ssl_Trace ("%d: SSL3[%d] received alert, level = %d, description = %d" , getpid(), ss->fd, level, desc) |
3305 | SSL_GETPID(), ss->fd, level, desc))if (ssl_trace >= (5)) ssl_Trace ("%d: SSL3[%d] received alert, level = %d, description = %d" , getpid(), ss->fd, level, desc); |
3306 | |
3307 | switch (desc) { |
3308 | case close_notify: ss->recvdCloseNotify = 1; |
3309 | error = SSL_ERROR_CLOSE_NOTIFY_ALERT; break; |
3310 | case unexpected_message: error = SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT; |
3311 | break; |
3312 | case bad_record_mac: error = SSL_ERROR_BAD_MAC_ALERT; break; |
3313 | case decryption_failed_RESERVED: |
3314 | error = SSL_ERROR_DECRYPTION_FAILED_ALERT; |
3315 | break; |
3316 | case record_overflow: error = SSL_ERROR_RECORD_OVERFLOW_ALERT; break; |
3317 | case decompression_failure: error = SSL_ERROR_DECOMPRESSION_FAILURE_ALERT; |
3318 | break; |
3319 | case handshake_failure: error = SSL_ERROR_HANDSHAKE_FAILURE_ALERT; |
3320 | break; |
3321 | case no_certificate: error = SSL_ERROR_NO_CERTIFICATE; break; |
3322 | case bad_certificate: error = SSL_ERROR_BAD_CERT_ALERT; break; |
3323 | case unsupported_certificate:error = SSL_ERROR_UNSUPPORTED_CERT_ALERT;break; |
3324 | case certificate_revoked: error = SSL_ERROR_REVOKED_CERT_ALERT; break; |
3325 | case certificate_expired: error = SSL_ERROR_EXPIRED_CERT_ALERT; break; |
3326 | case certificate_unknown: error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT; |
3327 | break; |
3328 | case illegal_parameter: error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break; |
3329 | |
3330 | /* All alerts below are TLS only. */ |
3331 | case unknown_ca: error = SSL_ERROR_UNKNOWN_CA_ALERT; break; |
3332 | case access_denied: error = SSL_ERROR_ACCESS_DENIED_ALERT; break; |
3333 | case decode_error: error = SSL_ERROR_DECODE_ERROR_ALERT; break; |
3334 | case decrypt_error: error = SSL_ERROR_DECRYPT_ERROR_ALERT; break; |
3335 | case export_restriction: error = SSL_ERROR_EXPORT_RESTRICTION_ALERT; |
3336 | break; |
3337 | case protocol_version: error = SSL_ERROR_PROTOCOL_VERSION_ALERT; break; |
3338 | case insufficient_security: error = SSL_ERROR_INSUFFICIENT_SECURITY_ALERT; |
3339 | break; |
3340 | case internal_error: error = SSL_ERROR_INTERNAL_ERROR_ALERT; break; |
3341 | case user_canceled: error = SSL_ERROR_USER_CANCELED_ALERT; break; |
3342 | case no_renegotiation: error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break; |
3343 | |
3344 | /* Alerts for TLS client hello extensions */ |
3345 | case unsupported_extension: |
3346 | error = SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT; break; |
3347 | case certificate_unobtainable: |
3348 | error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break; |
3349 | case unrecognized_name: |
3350 | error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; break; |
3351 | case bad_certificate_status_response: |
3352 | error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break; |
3353 | case bad_certificate_hash_value: |
3354 | error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break; |
3355 | default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; |
3356 | } |
3357 | if (level == alert_fatal) { |
3358 | if (!ss->opt.noCache) { |
3359 | if (ss->sec.uncache) |
3360 | ss->sec.uncache(ss->sec.ci.sid); |
3361 | } |
3362 | if ((ss->ssl3.hs.ws == wait_server_hello) && |
3363 | (desc == handshake_failure)) { |
3364 | /* XXX This is a hack. We're assuming that any handshake failure |
3365 | * XXX on the client hello is a failure to match ciphers. |
3366 | */ |
3367 | error = SSL_ERROR_NO_CYPHER_OVERLAP; |
3368 | } |
3369 | PORT_SetErrorPORT_SetError_Util(error); |
3370 | return SECFailure; |
3371 | } |
3372 | if ((desc == no_certificate) && (ss->ssl3.hs.ws == wait_client_cert)) { |
3373 | /* I'm a server. I've requested a client cert. He hasn't got one. */ |
3374 | SECStatus rv; |
3375 | |
3376 | PORT_Assert(ss->sec.isServer)((ss->sec.isServer)?((void)0):PR_Assert("ss->sec.isServer" ,"ssl3con.c",3376)); |
3377 | ss->ssl3.hs.ws = wait_client_key; |
3378 | rv = ssl3_HandleNoCertificate(ss); |
3379 | return rv; |
3380 | } |
3381 | return SECSuccess; |
3382 | } |
3383 | |
3384 | /* |
3385 | * Change Cipher Specs |
3386 | * Called from ssl3_HandleServerHelloDone, |
3387 | * ssl3_HandleClientHello, |
3388 | * and ssl3_HandleFinished |
3389 | * |
3390 | * Acquires and releases spec write lock, to protect switching the current |
3391 | * and pending write spec pointers. |
3392 | */ |
3393 | |
3394 | static SECStatus |
3395 | ssl3_SendChangeCipherSpecs(sslSocket *ss) |
3396 | { |
3397 | PRUint8 change = change_cipher_spec_choice; |
3398 | ssl3CipherSpec * pwSpec; |
3399 | SECStatus rv; |
3400 | PRInt32 sent; |
3401 | |
3402 | SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send change_cipher_spec record" , getpid(), ss->fd) |
3403 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send change_cipher_spec record" , getpid(), ss->fd); |
3404 | |
3405 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",3405)); |
3406 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3406)); |
3407 | |
3408 | rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000); |
3409 | if (rv != SECSuccess) { |
3410 | return rv; /* error code set by ssl3_FlushHandshake */ |
3411 | } |
3412 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
3413 | sent = ssl3_SendRecord(ss, 0, content_change_cipher_spec, &change, 1, |
3414 | ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000); |
3415 | if (sent < 0) { |
3416 | return (SECStatus)sent; /* error code set by ssl3_SendRecord */ |
3417 | } |
3418 | } else { |
3419 | rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1); |
3420 | if (rv != SECSuccess) { |
3421 | return rv; |
3422 | } |
3423 | } |
3424 | |
3425 | /* swap the pending and current write specs. */ |
3426 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; /**************************************/ |
3427 | pwSpec = ss->ssl3.pwSpec; |
3428 | |
3429 | ss->ssl3.pwSpec = ss->ssl3.cwSpec; |
3430 | ss->ssl3.cwSpec = pwSpec; |
3431 | |
3432 | SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending" , getpid(), ss->fd ) |
3433 | SSL_GETPID(), ss->fd ))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending" , getpid(), ss->fd ); |
3434 | |
3435 | /* We need to free up the contexts, keys and certs ! */ |
3436 | /* If we are really through with the old cipher spec |
3437 | * (Both the read and write sides have changed) destroy it. |
3438 | */ |
3439 | if (ss->ssl3.prSpec == ss->ssl3.pwSpec) { |
3440 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
3441 | ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE0/*freeSrvName*/); |
3442 | } else { |
3443 | /* With DTLS, we need to set a holddown timer in case the final |
3444 | * message got lost */ |
3445 | ss->ssl3.hs.rtTimeoutMs = DTLS_FINISHED_TIMER_MS120000; |
3446 | dtls_StartTimer(ss, dtls_FinishedTimerCb); |
3447 | } |
3448 | } |
3449 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /**************************************/ |
3450 | |
3451 | return SECSuccess; |
3452 | } |
3453 | |
3454 | /* Called from ssl3_HandleRecord. |
3455 | ** Caller must hold both RecvBuf and Handshake locks. |
3456 | * |
3457 | * Acquires and releases spec write lock, to protect switching the current |
3458 | * and pending write spec pointers. |
3459 | */ |
3460 | static SECStatus |
3461 | ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) |
3462 | { |
3463 | ssl3CipherSpec * prSpec; |
3464 | SSL3WaitState ws = ss->ssl3.hs.ws; |
3465 | SSL3ChangeCipherSpecChoice change; |
3466 | |
3467 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",3467)); |
3468 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3468)); |
3469 | |
3470 | SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle change_cipher_spec record" , getpid(), ss->fd) |
3471 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle change_cipher_spec record" , getpid(), ss->fd); |
3472 | |
3473 | if (ws != wait_change_cipher) { |
3474 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
3475 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); |
3476 | return SECFailure; |
3477 | } |
3478 | |
3479 | if(buf->len != 1) { |
3480 | (void)ssl3_DecodeError(ss); |
3481 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER); |
3482 | return SECFailure; |
3483 | } |
3484 | change = (SSL3ChangeCipherSpecChoice)buf->buf[0]; |
3485 | if (change != change_cipher_spec_choice) { |
3486 | /* illegal_parameter is correct here for both SSL3 and TLS. */ |
3487 | (void)ssl3_IllegalParameter(ss); |
3488 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER); |
3489 | return SECFailure; |
3490 | } |
3491 | buf->len = 0; |
3492 | |
3493 | /* Swap the pending and current read specs. */ |
3494 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; /*************************************/ |
3495 | prSpec = ss->ssl3.prSpec; |
3496 | |
3497 | ss->ssl3.prSpec = ss->ssl3.crSpec; |
3498 | ss->ssl3.crSpec = prSpec; |
3499 | ss->ssl3.hs.ws = wait_finished; |
3500 | |
3501 | SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending" , getpid(), ss->fd ) |
3502 | SSL_GETPID(), ss->fd ))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending" , getpid(), ss->fd ); |
3503 | |
3504 | /* If we are really through with the old cipher prSpec |
3505 | * (Both the read and write sides have changed) destroy it. |
3506 | */ |
3507 | if (ss->ssl3.prSpec == ss->ssl3.pwSpec) { |
3508 | ssl3_DestroyCipherSpec(ss->ssl3.prSpec, PR_FALSE0/*freeSrvName*/); |
3509 | } |
3510 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /*************************************/ |
3511 | return SECSuccess; |
3512 | } |
3513 | |
3514 | /* This method uses PKCS11 to derive the MS from the PMS, where PMS |
3515 | ** is a PKCS11 symkey. This is used in all cases except the |
3516 | ** "triple bypass" with RSA key exchange. |
3517 | ** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec. |
3518 | */ |
3519 | static SECStatus |
3520 | ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) |
3521 | { |
3522 | ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; |
3523 | const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def; |
3524 | unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random; |
3525 | unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random; |
3526 | PRBool isTLS = (PRBool)(kea_def->tls_keygen || |
3527 | (pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300)); |
3528 | PRBool isTLS12= |
3529 | (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
3530 | /* |
3531 | * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH |
3532 | * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size |
3533 | * data into a 48-byte value. |
3534 | */ |
3535 | PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dhssl_kea_dh) || |
3536 | (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdhssl_kea_ecdh)); |
3537 | SECStatus rv = SECFailure; |
3538 | CK_MECHANISM_TYPE master_derive; |
3539 | CK_MECHANISM_TYPE key_derive; |
3540 | SECItem params; |
3541 | CK_FLAGS keyFlags; |
3542 | CK_VERSION pms_version; |
3543 | CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; |
3544 | |
3545 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3545)); |
3546 | PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss))((ss->opt.noLocks || (NSSRWLock_HaveWriteLock_Util((ss)-> specLock)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)" ,"ssl3con.c",3546)); |
3547 | PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec)((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",3547) ); |
3548 | if (isTLS12) { |
3549 | if(isDH) master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000|0x4E534350) + 24); |
3550 | else master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000|0x4E534350) + 22); |
3551 | key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000|0x4E534350) + 23); |
3552 | keyFlags = CKF_SIGN0x00000800 | CKF_VERIFY0x00002000; |
3553 | } else if (isTLS) { |
3554 | if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377; |
3555 | else master_derive = CKM_TLS_MASTER_KEY_DERIVE0x00000375; |
3556 | key_derive = CKM_TLS_KEY_AND_MAC_DERIVE0x00000376; |
3557 | keyFlags = CKF_SIGN0x00000800 | CKF_VERIFY0x00002000; |
3558 | } else { |
3559 | if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373; |
3560 | else master_derive = CKM_SSL3_MASTER_KEY_DERIVE0x00000371; |
3561 | key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372; |
3562 | keyFlags = 0; |
3563 | } |
3564 | |
3565 | if (pms || !pwSpec->master_secret) { |
3566 | if (isDH) { |
3567 | master_params.pVersion = NULL((void*)0); |
3568 | } else { |
3569 | master_params.pVersion = &pms_version; |
3570 | } |
3571 | master_params.RandomInfo.pClientRandom = cr; |
3572 | master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH32; |
3573 | master_params.RandomInfo.pServerRandom = sr; |
3574 | master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH32; |
3575 | |
3576 | params.data = (unsigned char *) &master_params; |
3577 | params.len = sizeof master_params; |
3578 | } |
3579 | |
3580 | if (pms != NULL((void*)0)) { |
3581 | #if defined(TRACE) |
3582 | if (ssl_trace >= 100) { |
3583 | SECStatus extractRV = PK11_ExtractKeyValue(pms); |
3584 | if (extractRV == SECSuccess) { |
3585 | SECItem * keyData = PK11_GetKeyData(pms); |
3586 | if (keyData && keyData->data && keyData->len) { |
3587 | ssl_PrintBuf(ss, "Pre-Master Secret", |
3588 | keyData->data, keyData->len); |
3589 | } |
3590 | } |
3591 | } |
3592 | #endif |
3593 | pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive, |
3594 | ¶ms, key_derive, CKA_DERIVE0x0000010C, 0, keyFlags); |
3595 | if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) { |
3596 | SSL3ProtocolVersion client_version; |
3597 | client_version = pms_version.major << 8 | pms_version.minor; |
3598 | |
3599 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
3600 | client_version = dtls_DTLSVersionToTLSVersion(client_version); |
3601 | } |
3602 | |
3603 | if (client_version != ss->clientHelloVersion) { |
3604 | /* Destroy it. Version roll-back detected. */ |
3605 | PK11_FreeSymKey(pwSpec->master_secret); |
3606 | pwSpec->master_secret = NULL((void*)0); |
3607 | } |
3608 | } |
3609 | if (pwSpec->master_secret == NULL((void*)0)) { |
3610 | /* Generate a faux master secret in the same slot as the old one. */ |
3611 | PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms); |
3612 | PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot); |
3613 | |
3614 | PK11_FreeSlot(slot); |
3615 | if (fpms != NULL((void*)0)) { |
3616 | pwSpec->master_secret = PK11_DeriveWithFlags(fpms, |
3617 | master_derive, ¶ms, key_derive, |
3618 | CKA_DERIVE0x0000010C, 0, keyFlags); |
3619 | PK11_FreeSymKey(fpms); |
3620 | } |
3621 | } |
3622 | } |
3623 | if (pwSpec->master_secret == NULL((void*)0)) { |
3624 | /* Generate a faux master secret from the internal slot. */ |
3625 | PK11SlotInfo * slot = PK11_GetInternalSlot(); |
3626 | PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot); |
3627 | |
3628 | PK11_FreeSlot(slot); |
3629 | if (fpms != NULL((void*)0)) { |
3630 | pwSpec->master_secret = PK11_DeriveWithFlags(fpms, |
3631 | master_derive, ¶ms, key_derive, |
3632 | CKA_DERIVE0x0000010C, 0, keyFlags); |
3633 | if (pwSpec->master_secret == NULL((void*)0)) { |
3634 | pwSpec->master_secret = fpms; /* use the fpms as the master. */ |
3635 | fpms = NULL((void*)0); |
3636 | } |
3637 | } |
3638 | if (fpms) { |
3639 | PK11_FreeSymKey(fpms); |
3640 | } |
3641 | } |
3642 | if (pwSpec->master_secret == NULL((void*)0)) { |
3643 | ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
3644 | return rv; |
3645 | } |
3646 | #ifndef NO_PKCS11_BYPASS1 |
3647 | if (ss->opt.bypassPKCS11) { |
3648 | SECItem * keydata; |
3649 | /* In hope of doing a "double bypass", |
3650 | * need to extract the master secret's value from the key object |
3651 | * and store it raw in the sslSocket struct. |
3652 | */ |
3653 | rv = PK11_ExtractKeyValue(pwSpec->master_secret); |
3654 | if (rv != SECSuccess) { |
3655 | return rv; |
3656 | } |
3657 | /* This returns the address of the secItem inside the key struct, |
3658 | * not a copy or a reference. So, there's no need to free it. |
3659 | */ |
3660 | keydata = PK11_GetKeyData(pwSpec->master_secret); |
3661 | if (keydata && keydata->len <= sizeof pwSpec->raw_master_secret) { |
3662 | memcpy(pwSpec->raw_master_secret, keydata->data, keydata->len); |
3663 | pwSpec->msItem.data = pwSpec->raw_master_secret; |
3664 | pwSpec->msItem.len = keydata->len; |
3665 | } else { |
3666 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
3667 | return SECFailure; |
3668 | } |
3669 | } |
3670 | #endif |
3671 | return SECSuccess; |
3672 | } |
3673 | |
3674 | |
3675 | /* |
3676 | * Derive encryption and MAC Keys (and IVs) from master secret |
3677 | * Sets a useful error code when returning SECFailure. |
3678 | * |
3679 | * Called only from ssl3_InitPendingCipherSpec(), |
3680 | * which in turn is called from |
3681 | * sendRSAClientKeyExchange (for Full handshake) |
3682 | * sendDHClientKeyExchange (for Full handshake) |
3683 | * ssl3_HandleClientKeyExchange (for Full handshake) |
3684 | * ssl3_HandleServerHello (for session restart) |
3685 | * ssl3_HandleClientHello (for session restart) |
3686 | * Caller MUST hold the specWriteLock, and SSL3HandshakeLock. |
3687 | * ssl3_InitPendingCipherSpec does that. |
3688 | * |
3689 | */ |
3690 | static SECStatus |
3691 | ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss) |
3692 | { |
3693 | ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; |
3694 | const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
3695 | unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random; |
3696 | unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random; |
3697 | PRBool isTLS = (PRBool)(kea_def->tls_keygen || |
3698 | (pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300)); |
3699 | PRBool isTLS12= |
3700 | (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
3701 | /* following variables used in PKCS11 path */ |
3702 | const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; |
3703 | PK11SlotInfo * slot = NULL((void*)0); |
3704 | PK11SymKey * symKey = NULL((void*)0); |
3705 | void * pwArg = ss->pkcs11PinArg; |
3706 | int keySize; |
3707 | CK_SSL3_KEY_MAT_PARAMS key_material_params; |
3708 | CK_SSL3_KEY_MAT_OUT returnedKeys; |
3709 | CK_MECHANISM_TYPE key_derive; |
3710 | CK_MECHANISM_TYPE bulk_mechanism; |
3711 | SSLCipherAlgorithm calg; |
3712 | SECItem params; |
3713 | PRBool skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_nullssl_calg_null); |
3714 | |
3715 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3715)); |
3716 | PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss))((ss->opt.noLocks || (NSSRWLock_HaveWriteLock_Util((ss)-> specLock)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)" ,"ssl3con.c",3716)); |
3717 | PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec)((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",3717) ); |
3718 | |
3719 | if (!pwSpec->master_secret) { |
3720 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
3721 | return SECFailure; |
3722 | } |
3723 | /* |
3724 | * generate the key material |
3725 | */ |
3726 | key_material_params.ulMacSizeInBits = pwSpec->mac_size * BPB8; |
3727 | key_material_params.ulKeySizeInBits = cipher_def->secret_key_size* BPB8; |
3728 | key_material_params.ulIVSizeInBits = cipher_def->iv_size * BPB8; |
3729 | if (cipher_def->type == type_block && |
3730 | pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_10x0302) { |
3731 | /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ |
3732 | key_material_params.ulIVSizeInBits = 0; |
3733 | memset(pwSpec->client.write_iv, 0, cipher_def->iv_size); |
3734 | memset(pwSpec->server.write_iv, 0, cipher_def->iv_size); |
3735 | } |
3736 | |
3737 | key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited); |
3738 | |
3739 | key_material_params.RandomInfo.pClientRandom = cr; |
3740 | key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH32; |
3741 | key_material_params.RandomInfo.pServerRandom = sr; |
3742 | key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH32; |
3743 | key_material_params.pReturnedKeyMaterial = &returnedKeys; |
3744 | |
3745 | returnedKeys.pIVClient = pwSpec->client.write_iv; |
3746 | returnedKeys.pIVServer = pwSpec->server.write_iv; |
3747 | keySize = cipher_def->key_size; |
3748 | |
3749 | if (skipKeysAndIVs) { |
3750 | keySize = 0; |
3751 | key_material_params.ulKeySizeInBits = 0; |
3752 | key_material_params.ulIVSizeInBits = 0; |
3753 | returnedKeys.pIVClient = NULL((void*)0); |
3754 | returnedKeys.pIVServer = NULL((void*)0); |
3755 | } |
3756 | |
3757 | calg = cipher_def->calg; |
3758 | PORT_Assert( alg2Mech[calg].calg == calg)((alg2Mech[calg].calg == calg)?((void)0):PR_Assert("alg2Mech[calg].calg == calg" ,"ssl3con.c",3758)); |
3759 | bulk_mechanism = alg2Mech[calg].cmech; |
3760 | |
3761 | params.data = (unsigned char *)&key_material_params; |
3762 | params.len = sizeof(key_material_params); |
3763 | |
3764 | if (isTLS12) { |
3765 | key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000|0x4E534350) + 23); |
3766 | } else if (isTLS) { |
3767 | key_derive = CKM_TLS_KEY_AND_MAC_DERIVE0x00000376; |
3768 | } else { |
3769 | key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372; |
3770 | } |
3771 | |
3772 | /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and |
3773 | * DERIVE by DEFAULT */ |
3774 | symKey = PK11_Derive(pwSpec->master_secret, key_derive, ¶ms, |
3775 | bulk_mechanism, CKA_ENCRYPT0x00000104, keySize); |
3776 | if (!symKey) { |
3777 | ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
3778 | return SECFailure; |
3779 | } |
3780 | /* we really should use the actual mac'ing mechanism here, but we |
3781 | * don't because these types are used to map keytype anyway and both |
3782 | * mac's map to the same keytype. |
3783 | */ |
3784 | slot = PK11_GetSlotFromKey(symKey); |
3785 | |
3786 | PK11_FreeSlot(slot); /* slot is held until the key is freed */ |
3787 | pwSpec->client.write_mac_key = |
3788 | PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, |
3789 | CKM_SSL3_SHA1_MAC0x00000381, returnedKeys.hClientMacSecret, PR_TRUE1, pwArg); |
3790 | if (pwSpec->client.write_mac_key == NULL((void*)0) ) { |
3791 | goto loser; /* loser sets err */ |
3792 | } |
3793 | pwSpec->server.write_mac_key = |
3794 | PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, |
3795 | CKM_SSL3_SHA1_MAC0x00000381, returnedKeys.hServerMacSecret, PR_TRUE1, pwArg); |
3796 | if (pwSpec->server.write_mac_key == NULL((void*)0) ) { |
3797 | goto loser; /* loser sets err */ |
3798 | } |
3799 | if (!skipKeysAndIVs) { |
3800 | pwSpec->client.write_key = |
3801 | PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, |
3802 | bulk_mechanism, returnedKeys.hClientKey, PR_TRUE1, pwArg); |
3803 | if (pwSpec->client.write_key == NULL((void*)0) ) { |
3804 | goto loser; /* loser sets err */ |
3805 | } |
3806 | pwSpec->server.write_key = |
3807 | PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive, |
3808 | bulk_mechanism, returnedKeys.hServerKey, PR_TRUE1, pwArg); |
3809 | if (pwSpec->server.write_key == NULL((void*)0) ) { |
3810 | goto loser; /* loser sets err */ |
3811 | } |
3812 | } |
3813 | PK11_FreeSymKey(symKey); |
3814 | return SECSuccess; |
3815 | |
3816 | |
3817 | loser: |
3818 | if (symKey) PK11_FreeSymKey(symKey); |
3819 | ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
3820 | return SECFailure; |
3821 | } |
3822 | |
3823 | /* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in |
3824 | * buffered messages in ss->ssl3.hs.messages. */ |
3825 | static SECStatus |
3826 | ssl3_InitHandshakeHashes(sslSocket *ss) |
3827 | { |
3828 | SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd))if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: start handshake hashes" , getpid(), ss->fd); |
3829 | |
3830 | PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown)((ss->ssl3.hs.hashType == handshake_hash_unknown)?((void)0 ):PR_Assert("ss->ssl3.hs.hashType == handshake_hash_unknown" ,"ssl3con.c",3830)); |
3831 | #ifndef NO_PKCS11_BYPASS1 |
3832 | if (ss->opt.bypassPKCS11) { |
3833 | PORT_Assert(!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone)((!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone )?((void)0):PR_Assert("!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone" ,"ssl3con.c",3833)); |
3834 | if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303) { |
3835 | /* If we ever support ciphersuites where the PRF hash isn't SHA-256 |
3836 | * then this will need to be updated. */ |
3837 | ss->ssl3.hs.sha_obj = HASH_GetRawHashObject(HASH_AlgSHA256); |
3838 | if (!ss->ssl3.hs.sha_obj) { |
3839 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
3840 | return SECFailure; |
3841 | } |
3842 | ss->ssl3.hs.sha_clone = (void (*)(void *, void *))SHA256_Clone; |
3843 | ss->ssl3.hs.hashType = handshake_hash_single; |
3844 | ss->ssl3.hs.sha_obj->begin(ss->ssl3.hs.sha_cx); |
3845 | } else { |
3846 | ss->ssl3.hs.hashType = handshake_hash_combo; |
3847 | MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx); |
3848 | SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx); |
3849 | } |
3850 | } else |
3851 | #endif |
3852 | { |
3853 | PORT_Assert(!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha)((!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha)?((void) 0):PR_Assert("!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha" ,"ssl3con.c",3853)); |
3854 | /* |
3855 | * note: We should probably lookup an SSL3 slot for these |
3856 | * handshake hashes in hopes that we wind up with the same slots |
3857 | * that the master secret will wind up in ... |
3858 | */ |
3859 | if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303) { |
3860 | /* If we ever support ciphersuites where the PRF hash isn't SHA-256 |
3861 | * then this will need to be updated. */ |
3862 | ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA256); |
3863 | if (ss->ssl3.hs.sha == NULL((void*)0)) { |
3864 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
3865 | return SECFailure; |
3866 | } |
3867 | ss->ssl3.hs.hashType = handshake_hash_single; |
3868 | |
3869 | if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) { |
3870 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
3871 | return SECFailure; |
3872 | } |
3873 | |
3874 | /* Create a backup SHA-1 hash for a potential client auth |
3875 | * signature. |
3876 | * |
3877 | * In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the |
3878 | * handshake hash function (SHA-256). If the server or the client |
3879 | * does not support SHA-256 as a signature hash, we can either |
3880 | * maintain a backup SHA-1 handshake hash or buffer all handshake |
3881 | * messages. |
3882 | */ |
3883 | if (!ss->sec.isServer) { |
3884 | ss->ssl3.hs.backupHashmd5 = PK11_CreateDigestContext(SEC_OID_SHA1); |
3885 | if (ss->ssl3.hs.backupHashmd5 == NULL((void*)0)) { |
3886 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
3887 | return SECFailure; |
3888 | } |
3889 | |
3890 | if (PK11_DigestBegin(ss->ssl3.hs.backupHashmd5) != SECSuccess) { |
3891 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
3892 | return SECFailure; |
3893 | } |
3894 | } |
3895 | } else { |
3896 | /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or |
3897 | * created successfully. */ |
3898 | ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5); |
3899 | if (ss->ssl3.hs.md5 == NULL((void*)0)) { |
3900 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
3901 | return SECFailure; |
3902 | } |
3903 | ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1); |
3904 | if (ss->ssl3.hs.sha == NULL((void*)0)) { |
3905 | PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE1); |
3906 | ss->ssl3.hs.md5 = NULL((void*)0); |
3907 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
3908 | return SECFailure; |
3909 | } |
3910 | ss->ssl3.hs.hashType = handshake_hash_combo; |
3911 | |
3912 | if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) { |
3913 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
3914 | return SECFailure; |
3915 | } |
3916 | if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) { |
3917 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
3918 | return SECFailure; |
3919 | } |
3920 | } |
3921 | } |
3922 | |
3923 | if (ss->ssl3.hs.messages.len > 0) { |
3924 | if (ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf, |
3925 | ss->ssl3.hs.messages.len) != |
3926 | SECSuccess) { |
3927 | return SECFailure; |
3928 | } |
3929 | PORT_FreePORT_Free_Util(ss->ssl3.hs.messages.buf); |
3930 | ss->ssl3.hs.messages.buf = NULL((void*)0); |
3931 | ss->ssl3.hs.messages.len = 0; |
3932 | ss->ssl3.hs.messages.space = 0; |
3933 | } |
3934 | |
3935 | return SECSuccess; |
3936 | } |
3937 | |
3938 | static SECStatus |
3939 | ssl3_RestartHandshakeHashes(sslSocket *ss) |
3940 | { |
3941 | SECStatus rv = SECSuccess; |
3942 | |
3943 | SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: reset handshake hashes" , getpid(), ss->fd ) |
3944 | SSL_GETPID(), ss->fd ))if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: reset handshake hashes" , getpid(), ss->fd ); |
3945 | ss->ssl3.hs.hashType = handshake_hash_unknown; |
3946 | ss->ssl3.hs.messages.len = 0; |
3947 | #ifndef NO_PKCS11_BYPASS1 |
3948 | ss->ssl3.hs.sha_obj = NULL((void*)0); |
3949 | ss->ssl3.hs.sha_clone = NULL((void*)0); |
3950 | #endif |
3951 | if (ss->ssl3.hs.md5) { |
3952 | PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE1); |
3953 | ss->ssl3.hs.md5 = NULL((void*)0); |
3954 | } |
3955 | if (ss->ssl3.hs.sha) { |
3956 | PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE1); |
3957 | ss->ssl3.hs.sha = NULL((void*)0); |
3958 | } |
3959 | return rv; |
3960 | } |
3961 | |
3962 | /* |
3963 | * Handshake messages |
3964 | */ |
3965 | /* Called from ssl3_InitHandshakeHashes() |
3966 | ** ssl3_AppendHandshake() |
3967 | ** ssl3_StartHandshakeHash() |
3968 | ** ssl3_HandleV2ClientHello() |
3969 | ** ssl3_HandleHandshakeMessage() |
3970 | ** Caller must hold the ssl3Handshake lock. |
3971 | */ |
3972 | static SECStatus |
3973 | ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, |
3974 | unsigned int l) |
3975 | { |
3976 | SECStatus rv = SECSuccess; |
3977 | |
3978 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",3978)); |
3979 | |
3980 | /* We need to buffer the handshake messages until we have established |
3981 | * which handshake hash function to use. */ |
3982 | if (ss->ssl3.hs.hashType == handshake_hash_unknown) { |
3983 | return sslBuffer_Append(&ss->ssl3.hs.messages, b, l); |
3984 | } |
3985 | |
3986 | PRINT_BUF(90, (NULL, "handshake hash input:", b, l))if (ssl_trace >= (90)) ssl_PrintBuf (((void*)0), "handshake hash input:" , b, l); |
3987 | |
3988 | #ifndef NO_PKCS11_BYPASS1 |
3989 | if (ss->opt.bypassPKCS11) { |
3990 | if (ss->ssl3.hs.hashType == handshake_hash_single) { |
3991 | ss->ssl3.hs.sha_obj->update(ss->ssl3.hs.sha_cx, b, l); |
3992 | } else { |
3993 | MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l); |
3994 | SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l); |
3995 | } |
3996 | return rv; |
3997 | } |
3998 | #endif |
3999 | if (ss->ssl3.hs.hashType == handshake_hash_single) { |
4000 | rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); |
4001 | if (rv != SECSuccess) { |
4002 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
4003 | return rv; |
4004 | } |
4005 | if (ss->ssl3.hs.backupHashmd5) { |
4006 | rv = PK11_DigestOp(ss->ssl3.hs.backupHashmd5, b, l); |
4007 | if (rv != SECSuccess) { |
4008 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4009 | return rv; |
4010 | } |
4011 | } |
4012 | } else { |
4013 | rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); |
4014 | if (rv != SECSuccess) { |
4015 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
4016 | return rv; |
4017 | } |
4018 | rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); |
4019 | if (rv != SECSuccess) { |
4020 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4021 | return rv; |
4022 | } |
4023 | } |
4024 | return rv; |
4025 | } |
4026 | |
4027 | /************************************************************************** |
4028 | * Append Handshake functions. |
4029 | * All these functions set appropriate error codes. |
4030 | * Most rely on ssl3_AppendHandshake to set the error code. |
4031 | **************************************************************************/ |
4032 | SECStatus |
4033 | ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes) |
4034 | { |
4035 | unsigned char * src = (unsigned char *)void_src; |
4036 | int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; |
4037 | SECStatus rv; |
4038 | |
4039 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",4039)); /* protects sendBuf. */ |
4040 | |
4041 | if (!bytes) |
4042 | return SECSuccess; |
4043 | if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH32000 && room < bytes) { |
4044 | rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,((4000)>(((32000)<(ss->sec.ci.sendBuf.len + bytes)?( 32000):(ss->sec.ci.sendBuf.len + bytes)))?(4000):(((32000) <(ss->sec.ci.sendBuf.len + bytes)?(32000):(ss->sec.ci .sendBuf.len + bytes)))) |
4045 | PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes))((4000)>(((32000)<(ss->sec.ci.sendBuf.len + bytes)?( 32000):(ss->sec.ci.sendBuf.len + bytes)))?(4000):(((32000) <(ss->sec.ci.sendBuf.len + bytes)?(32000):(ss->sec.ci .sendBuf.len + bytes))))); |
4046 | if (rv != SECSuccess) |
4047 | return rv; /* sslBuffer_Grow has set a memory error code. */ |
4048 | room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; |
4049 | } |
4050 | |
4051 | PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char*)void_src, bytes))if (ssl_trace >= (60)) ssl_PrintBuf (ss, "Append to Handshake" , (unsigned char*)void_src, bytes); |
4052 | rv = ssl3_UpdateHandshakeHashes(ss, src, bytes); |
4053 | if (rv != SECSuccess) |
4054 | return rv; /* error code set by ssl3_UpdateHandshakeHashes */ |
4055 | |
4056 | while (bytes > room) { |
4057 | if (room > 0) |
4058 | PORT_Memcpymemcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, |
4059 | room); |
4060 | ss->sec.ci.sendBuf.len += room; |
4061 | rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000); |
4062 | if (rv != SECSuccess) { |
4063 | return rv; /* error code set by ssl3_FlushHandshake */ |
4064 | } |
4065 | bytes -= room; |
4066 | src += room; |
4067 | room = ss->sec.ci.sendBuf.space; |
4068 | PORT_Assert(ss->sec.ci.sendBuf.len == 0)((ss->sec.ci.sendBuf.len == 0)?((void)0):PR_Assert("ss->sec.ci.sendBuf.len == 0" ,"ssl3con.c",4068)); |
4069 | } |
4070 | PORT_Memcpymemcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes); |
4071 | ss->sec.ci.sendBuf.len += bytes; |
4072 | return SECSuccess; |
4073 | } |
4074 | |
4075 | SECStatus |
4076 | ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize) |
4077 | { |
4078 | SECStatus rv; |
4079 | PRUint8 b[4]; |
4080 | PRUint8 * p = b; |
4081 | |
4082 | switch (lenSize) { |
4083 | case 4: |
4084 | *p++ = (num >> 24) & 0xff; |
4085 | case 3: |
4086 | *p++ = (num >> 16) & 0xff; |
4087 | case 2: |
4088 | *p++ = (num >> 8) & 0xff; |
4089 | case 1: |
4090 | *p = num & 0xff; |
4091 | } |
4092 | SSL_TRC(60, ("%d: number:", SSL_GETPID()))if (ssl_trace >= (60)) ssl_Trace ("%d: number:", getpid()); |
4093 | rv = ssl3_AppendHandshake(ss, &b[0], lenSize); |
4094 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4095 | } |
4096 | |
4097 | SECStatus |
4098 | ssl3_AppendHandshakeVariable( |
4099 | sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize) |
4100 | { |
4101 | SECStatus rv; |
4102 | |
4103 | PORT_Assert((bytes < (1<<8) && lenSize == 1) ||(((bytes < (1<<8) && lenSize == 1) || (bytes < (1L<<16) && lenSize == 2) || (bytes < ( 1L<<24) && lenSize == 3))?((void)0):PR_Assert("(bytes < (1<<8) && lenSize == 1) || (bytes < (1L<<16) && lenSize == 2) || (bytes < (1L<<24) && lenSize == 3)" ,"ssl3con.c",4105)) |
4104 | (bytes < (1L<<16) && lenSize == 2) ||(((bytes < (1<<8) && lenSize == 1) || (bytes < (1L<<16) && lenSize == 2) || (bytes < ( 1L<<24) && lenSize == 3))?((void)0):PR_Assert("(bytes < (1<<8) && lenSize == 1) || (bytes < (1L<<16) && lenSize == 2) || (bytes < (1L<<24) && lenSize == 3)" ,"ssl3con.c",4105)) |
4105 | (bytes < (1L<<24) && lenSize == 3))(((bytes < (1<<8) && lenSize == 1) || (bytes < (1L<<16) && lenSize == 2) || (bytes < ( 1L<<24) && lenSize == 3))?((void)0):PR_Assert("(bytes < (1<<8) && lenSize == 1) || (bytes < (1L<<16) && lenSize == 2) || (bytes < (1L<<24) && lenSize == 3)" ,"ssl3con.c",4105)); |
4106 | |
4107 | SSL_TRC(60,("%d: append variable:", SSL_GETPID()))if (ssl_trace >= (60)) ssl_Trace ("%d: append variable:", getpid ()); |
4108 | rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize); |
4109 | if (rv != SECSuccess) { |
4110 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4111 | } |
4112 | SSL_TRC(60, ("data:"))if (ssl_trace >= (60)) ssl_Trace ("data:"); |
4113 | rv = ssl3_AppendHandshake(ss, src, bytes); |
4114 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4115 | } |
4116 | |
4117 | SECStatus |
4118 | ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length) |
4119 | { |
4120 | SECStatus rv; |
4121 | |
4122 | /* If we already have a message in place, we need to enqueue it. |
4123 | * This empties the buffer. This is a convenient place to call |
4124 | * dtls_StageHandshakeMessage to mark the message boundary. |
4125 | */ |
4126 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
4127 | rv = dtls_StageHandshakeMessage(ss); |
4128 | if (rv != SECSuccess) { |
4129 | return rv; |
4130 | } |
4131 | } |
4132 | |
4133 | SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: append handshake header: type %s" , getpid(), ss->fd, ssl3_DecodeHandshakeType(t)) |
4134 | SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)))if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: append handshake header: type %s" , getpid(), ss->fd, ssl3_DecodeHandshakeType(t)); |
4135 | |
4136 | rv = ssl3_AppendHandshakeNumber(ss, t, 1); |
4137 | if (rv != SECSuccess) { |
4138 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4139 | } |
4140 | rv = ssl3_AppendHandshakeNumber(ss, length, 3); |
4141 | if (rv != SECSuccess) { |
4142 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4143 | } |
4144 | |
4145 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
4146 | /* Note that we make an unfragmented message here. We fragment in the |
4147 | * transmission code, if necessary */ |
4148 | rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.sendMessageSeq, 2); |
4149 | if (rv != SECSuccess) { |
4150 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4151 | } |
4152 | ss->ssl3.hs.sendMessageSeq++; |
4153 | |
4154 | /* 0 is the fragment offset, because it's not fragmented yet */ |
4155 | rv = ssl3_AppendHandshakeNumber(ss, 0, 3); |
4156 | if (rv != SECSuccess) { |
4157 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4158 | } |
4159 | |
4160 | /* Fragment length -- set to the packet length because not fragmented */ |
4161 | rv = ssl3_AppendHandshakeNumber(ss, length, 3); |
4162 | if (rv != SECSuccess) { |
4163 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4164 | } |
4165 | } |
4166 | |
4167 | return rv; /* error code set by AppendHandshake, if applicable. */ |
4168 | } |
4169 | |
4170 | /* ssl3_AppendSignatureAndHashAlgorithm appends the serialisation of |
4171 | * |sigAndHash| to the current handshake message. */ |
4172 | SECStatus |
4173 | ssl3_AppendSignatureAndHashAlgorithm( |
4174 | sslSocket *ss, const SSL3SignatureAndHashAlgorithm* sigAndHash) |
4175 | { |
4176 | unsigned char serialized[2]; |
4177 | |
4178 | serialized[0] = ssl3_OIDToTLSHashAlgorithm(sigAndHash->hashAlg); |
4179 | if (serialized[0] == 0) { |
4180 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
4181 | return SECFailure; |
4182 | } |
4183 | |
4184 | serialized[1] = sigAndHash->sigAlg; |
4185 | |
4186 | return ssl3_AppendHandshake(ss, serialized, sizeof(serialized)); |
4187 | } |
4188 | |
4189 | /************************************************************************** |
4190 | * Consume Handshake functions. |
4191 | * |
4192 | * All data used in these functions is protected by two locks, |
4193 | * the RecvBufLock and the SSL3HandshakeLock |
4194 | **************************************************************************/ |
4195 | |
4196 | /* Read up the next "bytes" number of bytes from the (decrypted) input |
4197 | * stream "b" (which is *length bytes long). Copy them into buffer "v". |
4198 | * Reduces *length by bytes. Advances *b by bytes. |
4199 | * |
4200 | * If this function returns SECFailure, it has already sent an alert, |
4201 | * and has set a generic error code. The caller should probably |
4202 | * override the generic error code by setting another. |
4203 | */ |
4204 | SECStatus |
4205 | ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, |
4206 | PRUint32 *length) |
4207 | { |
4208 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",4208)); |
4209 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",4209)); |
4210 | |
4211 | if ((PRUint32)bytes > *length) { |
4212 | return ssl3_DecodeError(ss); |
4213 | } |
4214 | PORT_Memcpymemcpy(v, *b, bytes); |
4215 | PRINT_BUF(60, (ss, "consume bytes:", *b, bytes))if (ssl_trace >= (60)) ssl_PrintBuf (ss, "consume bytes:", *b, bytes); |
4216 | *b += bytes; |
4217 | *length -= bytes; |
4218 | return SECSuccess; |
4219 | } |
4220 | |
4221 | /* Read up the next "bytes" number of bytes from the (decrypted) input |
4222 | * stream "b" (which is *length bytes long), and interpret them as an |
4223 | * integer in network byte order. Returns the received value. |
4224 | * Reduces *length by bytes. Advances *b by bytes. |
4225 | * |
4226 | * Returns SECFailure (-1) on failure. |
4227 | * This value is indistinguishable from the equivalent received value. |
4228 | * Only positive numbers are to be received this way. |
4229 | * Thus, the largest value that may be sent this way is 0x7fffffff. |
4230 | * On error, an alert has been sent, and a generic error code has been set. |
4231 | */ |
4232 | PRInt32 |
4233 | ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b, |
4234 | PRUint32 *length) |
4235 | { |
4236 | PRUint8 *buf = *b; |
4237 | int i; |
4238 | PRInt32 num = 0; |
4239 | |
4240 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",4240)); |
4241 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",4241)); |
4242 | PORT_Assert( bytes <= sizeof num)((bytes <= sizeof num)?((void)0):PR_Assert("bytes <= sizeof num" ,"ssl3con.c",4242)); |
4243 | |
4244 | if ((PRUint32)bytes > *length) { |
4245 | return ssl3_DecodeError(ss); |
4246 | } |
4247 | PRINT_BUF(60, (ss, "consume bytes:", *b, bytes))if (ssl_trace >= (60)) ssl_PrintBuf (ss, "consume bytes:", *b, bytes); |
4248 | |
4249 | for (i = 0; i < bytes; i++) |
4250 | num = (num << 8) + buf[i]; |
4251 | *b += bytes; |
4252 | *length -= bytes; |
4253 | return num; |
4254 | } |
4255 | |
4256 | /* Read in two values from the incoming decrypted byte stream "b", which is |
4257 | * *length bytes long. The first value is a number whose size is "bytes" |
4258 | * bytes long. The second value is a byte-string whose size is the value |
4259 | * of the first number received. The latter byte-string, and its length, |
4260 | * is returned in the SECItem i. |
4261 | * |
4262 | * Returns SECFailure (-1) on failure. |
4263 | * On error, an alert has been sent, and a generic error code has been set. |
4264 | * |
4265 | * RADICAL CHANGE for NSS 3.11. All callers of this function make copies |
4266 | * of the data returned in the SECItem *i, so making a copy of it here |
4267 | * is simply wasteful. So, This function now just sets SECItem *i to |
4268 | * point to the values in the buffer **b. |
4269 | */ |
4270 | SECStatus |
4271 | ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes, |
4272 | SSL3Opaque **b, PRUint32 *length) |
4273 | { |
4274 | PRInt32 count; |
4275 | |
4276 | PORT_Assert(bytes <= 3)((bytes <= 3)?((void)0):PR_Assert("bytes <= 3","ssl3con.c" ,4276)); |
4277 | i->len = 0; |
4278 | i->data = NULL((void*)0); |
4279 | count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length); |
4280 | if (count < 0) { /* Can't test for SECSuccess here. */ |
4281 | return SECFailure; |
4282 | } |
4283 | if (count > 0) { |
4284 | if ((PRUint32)count > *length) { |
4285 | return ssl3_DecodeError(ss); |
4286 | } |
4287 | i->data = *b; |
4288 | i->len = count; |
4289 | *b += count; |
4290 | *length -= count; |
4291 | } |
4292 | return SECSuccess; |
4293 | } |
4294 | |
4295 | /* tlsHashOIDMap contains the mapping between TLS hash identifiers and the |
4296 | * SECOidTag used internally by NSS. */ |
4297 | static const struct { |
4298 | int tlsHash; |
4299 | SECOidTag oid; |
4300 | } tlsHashOIDMap[] = { |
4301 | { tls_hash_md5, SEC_OID_MD5 }, |
4302 | { tls_hash_sha1, SEC_OID_SHA1 }, |
4303 | { tls_hash_sha224, SEC_OID_SHA224 }, |
4304 | { tls_hash_sha256, SEC_OID_SHA256 }, |
4305 | { tls_hash_sha384, SEC_OID_SHA384 }, |
4306 | { tls_hash_sha512, SEC_OID_SHA512 } |
4307 | }; |
4308 | |
4309 | /* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value. |
4310 | * If the hash is not recognised, SEC_OID_UNKNOWN is returned. |
4311 | * |
4312 | * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
4313 | SECOidTag |
4314 | ssl3_TLSHashAlgorithmToOID(int hashFunc) |
4315 | { |
4316 | unsigned int i; |
4317 | |
4318 | for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap)(sizeof(tlsHashOIDMap)/sizeof((tlsHashOIDMap)[0])); i++) { |
4319 | if (hashFunc == tlsHashOIDMap[i].tlsHash) { |
4320 | return tlsHashOIDMap[i].oid; |
4321 | } |
4322 | } |
4323 | return SEC_OID_UNKNOWN; |
4324 | } |
4325 | |
4326 | /* ssl3_OIDToTLSHashAlgorithm converts an OID to a TLS hash algorithm |
4327 | * identifier. If the hash is not recognised, zero is returned. |
4328 | * |
4329 | * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
4330 | static int |
4331 | ssl3_OIDToTLSHashAlgorithm(SECOidTag oid) |
4332 | { |
4333 | unsigned int i; |
4334 | |
4335 | for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap)(sizeof(tlsHashOIDMap)/sizeof((tlsHashOIDMap)[0])); i++) { |
4336 | if (oid == tlsHashOIDMap[i].oid) { |
4337 | return tlsHashOIDMap[i].tlsHash; |
4338 | } |
4339 | } |
4340 | return 0; |
4341 | } |
4342 | |
4343 | /* ssl3_TLSSignatureAlgorithmForKeyType returns the TLS 1.2 signature algorithm |
4344 | * identifier for a given KeyType. */ |
4345 | static SECStatus |
4346 | ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType, |
4347 | TLSSignatureAlgorithm *out) |
4348 | { |
4349 | switch (keyType) { |
4350 | case rsaKey: |
4351 | *out = tls_sig_rsa; |
4352 | return SECSuccess; |
4353 | case dsaKey: |
4354 | *out = tls_sig_dsa; |
4355 | return SECSuccess; |
4356 | case ecKey: |
4357 | *out = tls_sig_ecdsa; |
4358 | return SECSuccess; |
4359 | default: |
4360 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); |
4361 | return SECFailure; |
4362 | } |
4363 | } |
4364 | |
4365 | /* ssl3_TLSSignatureAlgorithmForCertificate returns the TLS 1.2 signature |
4366 | * algorithm identifier for the given certificate. */ |
4367 | static SECStatus |
4368 | ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert, |
4369 | TLSSignatureAlgorithm *out) |
4370 | { |
4371 | SECKEYPublicKey *key; |
4372 | KeyType keyType; |
4373 | |
4374 | key = CERT_ExtractPublicKey(cert); |
4375 | if (key == NULL((void*)0)) { |
4376 | ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
4377 | return SECFailure; |
4378 | } |
4379 | |
4380 | keyType = key->keyType; |
4381 | SECKEY_DestroyPublicKey(key); |
4382 | return ssl3_TLSSignatureAlgorithmForKeyType(keyType, out); |
4383 | } |
4384 | |
4385 | /* ssl3_CheckSignatureAndHashAlgorithmConsistency checks that the signature |
4386 | * algorithm identifier in |sigAndHash| is consistent with the public key in |
4387 | * |cert|. If so, SECSuccess is returned. Otherwise, PORT_SetError is called |
4388 | * and SECFailure is returned. */ |
4389 | SECStatus |
4390 | ssl3_CheckSignatureAndHashAlgorithmConsistency( |
4391 | const SSL3SignatureAndHashAlgorithm *sigAndHash, CERTCertificate* cert) |
4392 | { |
4393 | SECStatus rv; |
4394 | TLSSignatureAlgorithm sigAlg; |
4395 | |
4396 | rv = ssl3_TLSSignatureAlgorithmForCertificate(cert, &sigAlg); |
4397 | if (rv != SECSuccess) { |
4398 | return rv; |
4399 | } |
4400 | if (sigAlg != sigAndHash->sigAlg) { |
4401 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); |
4402 | return SECFailure; |
4403 | } |
4404 | return SECSuccess; |
4405 | } |
4406 | |
4407 | /* ssl3_ConsumeSignatureAndHashAlgorithm reads a SignatureAndHashAlgorithm |
4408 | * structure from |b| and puts the resulting value into |out|. |b| and |length| |
4409 | * are updated accordingly. |
4410 | * |
4411 | * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
4412 | SECStatus |
4413 | ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss, |
4414 | SSL3Opaque **b, |
4415 | PRUint32 *length, |
4416 | SSL3SignatureAndHashAlgorithm *out) |
4417 | { |
4418 | unsigned char bytes[2]; |
4419 | SECStatus rv; |
4420 | |
4421 | rv = ssl3_ConsumeHandshake(ss, bytes, sizeof(bytes), b, length); |
4422 | if (rv != SECSuccess) { |
4423 | return rv; |
4424 | } |
4425 | |
4426 | out->hashAlg = ssl3_TLSHashAlgorithmToOID(bytes[0]); |
4427 | if (out->hashAlg == SEC_OID_UNKNOWN) { |
4428 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
4429 | return SECFailure; |
4430 | } |
4431 | |
4432 | out->sigAlg = bytes[1]; |
4433 | return SECSuccess; |
4434 | } |
4435 | |
4436 | /************************************************************************** |
4437 | * end of Consume Handshake functions. |
4438 | **************************************************************************/ |
4439 | |
4440 | /* Extract the hashes of handshake messages to this point. |
4441 | * Called from ssl3_SendCertificateVerify |
4442 | * ssl3_SendFinished |
4443 | * ssl3_HandleHandshakeMessage |
4444 | * |
4445 | * Caller must hold the SSL3HandshakeLock. |
4446 | * Caller must hold a read or write lock on the Spec R/W lock. |
4447 | * (There is presently no way to assert on a Read lock.) |
4448 | */ |
4449 | static SECStatus |
4450 | ssl3_ComputeHandshakeHashes(sslSocket * ss, |
4451 | ssl3CipherSpec *spec, /* uses ->master_secret */ |
4452 | SSL3Hashes * hashes, /* output goes here. */ |
4453 | PRUint32 sender) |
4454 | { |
4455 | SECStatus rv = SECSuccess; |
4456 | PRBool isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_00x0300); |
4457 | unsigned int outLength; |
4458 | SSL3Opaque md5_inner[MAX_MAC_LENGTH64]; |
4459 | SSL3Opaque sha_inner[MAX_MAC_LENGTH64]; |
4460 | |
4461 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",4461)); |
4462 | hashes->hashAlg = SEC_OID_UNKNOWN; |
4463 | |
4464 | #ifndef NO_PKCS11_BYPASS1 |
4465 | if (ss->opt.bypassPKCS11 && |
4466 | ss->ssl3.hs.hashType == handshake_hash_single) { |
4467 | /* compute them without PKCS11 */ |
4468 | PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS(400 / 8)]; |
4469 | |
4470 | if (!spec->msItem.data) { |
4471 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); |
4472 | return SECFailure; |
4473 | } |
4474 | |
4475 | ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx); |
4476 | ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len, |
4477 | sizeof(hashes->u.raw)); |
4478 | |
4479 | PRINT_BUF(60, (NULL, "SHA-256: result", hashes->u.raw, hashes->len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "SHA-256: result" , hashes->u.raw, hashes->len); |
4480 | |
4481 | /* If we ever support ciphersuites where the PRF hash isn't SHA-256 |
4482 | * then this will need to be updated. */ |
4483 | hashes->hashAlg = SEC_OID_SHA256; |
4484 | rv = SECSuccess; |
4485 | } else if (ss->opt.bypassPKCS11) { |
4486 | /* compute them without PKCS11 */ |
4487 | PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS(400 / 8)]; |
4488 | PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS(400 / 8)]; |
4489 | |
4490 | #define md5cx ((MD5Context *)md5_cx) |
4491 | #define shacx ((SHA1Context *)sha_cx) |
4492 | |
4493 | if (!spec->msItem.data) { |
4494 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); |
4495 | return SECFailure; |
4496 | } |
4497 | |
4498 | MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx); |
4499 | SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx); |
4500 | |
4501 | if (!isTLS) { |
4502 | /* compute hashes for SSL3. */ |
4503 | unsigned char s[4]; |
4504 | |
4505 | s[0] = (unsigned char)(sender >> 24); |
4506 | s[1] = (unsigned char)(sender >> 16); |
4507 | s[2] = (unsigned char)(sender >> 8); |
4508 | s[3] = (unsigned char)sender; |
4509 | |
4510 | if (sender != 0) { |
4511 | MD5_Update(md5cx, s, 4); |
4512 | PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: sender" , s, 4); |
4513 | } |
4514 | |
4515 | PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_md5].pad_size) |
4516 | mac_defs[mac_md5].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_md5].pad_size); |
4517 | |
4518 | MD5_Update(md5cx, spec->msItem.data, spec->msItem.len); |
4519 | MD5_Update(md5cx, mac_pad_1, mac_defs[mac_md5ssl_mac_md5].pad_size); |
4520 | MD5_End(md5cx, md5_inner, &outLength, MD5_LENGTH16); |
4521 | |
4522 | PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: result" , md5_inner, outLength); |
4523 | |
4524 | if (sender != 0) { |
4525 | SHA1_Update(shacx, s, 4); |
4526 | PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: sender" , s, 4); |
4527 | } |
4528 | |
4529 | PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_sha].pad_size) |
4530 | mac_defs[mac_sha].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_sha].pad_size); |
4531 | |
4532 | SHA1_Update(shacx, spec->msItem.data, spec->msItem.len); |
4533 | SHA1_Update(shacx, mac_pad_1, mac_defs[mac_shassl_mac_sha].pad_size); |
4534 | SHA1_End(shacx, sha_inner, &outLength, SHA1_LENGTH20); |
4535 | |
4536 | PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: result" , sha_inner, outLength); |
4537 | PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_md5].pad_size) |
4538 | mac_defs[mac_md5].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_md5].pad_size); |
4539 | PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 outer: MD5 inner" , md5_inner, 16); |
4540 | |
4541 | MD5_Begin(md5cx); |
4542 | MD5_Update(md5cx, spec->msItem.data, spec->msItem.len); |
4543 | MD5_Update(md5cx, mac_pad_2, mac_defs[mac_md5ssl_mac_md5].pad_size); |
4544 | MD5_Update(md5cx, md5_inner, MD5_LENGTH16); |
4545 | } |
4546 | MD5_End(md5cx, hashes->u.s.md5, &outLength, MD5_LENGTH16); |
4547 | |
4548 | PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "MD5 outer: result" , hashes->u.s.md5, 16); |
4549 | |
4550 | if (!isTLS) { |
4551 | PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_sha].pad_size) |
4552 | mac_defs[mac_sha].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_sha].pad_size); |
4553 | PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA outer: SHA inner" , sha_inner, 20); |
4554 | |
4555 | SHA1_Begin(shacx); |
4556 | SHA1_Update(shacx, spec->msItem.data, spec->msItem.len); |
4557 | SHA1_Update(shacx, mac_pad_2, mac_defs[mac_shassl_mac_sha].pad_size); |
4558 | SHA1_Update(shacx, sha_inner, SHA1_LENGTH20); |
4559 | } |
4560 | SHA1_End(shacx, hashes->u.s.sha, &outLength, SHA1_LENGTH20); |
4561 | |
4562 | PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "SHA outer: result" , hashes->u.s.sha, 20); |
4563 | |
4564 | hashes->len = MD5_LENGTH16 + SHA1_LENGTH20; |
4565 | rv = SECSuccess; |
4566 | #undef md5cx |
4567 | #undef shacx |
4568 | } else |
4569 | #endif |
4570 | if (ss->ssl3.hs.hashType == handshake_hash_single) { |
4571 | /* compute hashes with PKCS11 */ |
4572 | PK11Context *h; |
4573 | unsigned int stateLen; |
4574 | unsigned char stackBuf[1024]; |
4575 | unsigned char *stateBuf = NULL((void*)0); |
4576 | |
4577 | if (!spec->master_secret) { |
4578 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); |
4579 | return SECFailure; |
4580 | } |
4581 | |
4582 | h = ss->ssl3.hs.sha; |
4583 | stateBuf = PK11_SaveContextAlloc(h, stackBuf, |
4584 | sizeof(stackBuf), &stateLen); |
4585 | if (stateBuf == NULL((void*)0)) { |
4586 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
4587 | goto tls12_loser; |
4588 | } |
4589 | rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len, |
4590 | sizeof(hashes->u.raw)); |
4591 | if (rv != SECSuccess) { |
4592 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
4593 | rv = SECFailure; |
4594 | goto tls12_loser; |
4595 | } |
4596 | /* If we ever support ciphersuites where the PRF hash isn't SHA-256 |
4597 | * then this will need to be updated. */ |
4598 | hashes->hashAlg = SEC_OID_SHA256; |
4599 | rv = SECSuccess; |
4600 | |
4601 | tls12_loser: |
4602 | if (stateBuf) { |
4603 | if (PK11_RestoreContext(h, stateBuf, stateLen) != SECSuccess) { |
4604 | ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); |
4605 | rv = SECFailure; |
4606 | } |
4607 | if (stateBuf != stackBuf) { |
4608 | PORT_ZFreePORT_ZFree_Util(stateBuf, stateLen); |
4609 | } |
4610 | } |
4611 | } else { |
4612 | /* compute hashes with PKCS11 */ |
4613 | PK11Context * md5; |
4614 | PK11Context * sha = NULL((void*)0); |
4615 | unsigned char *md5StateBuf = NULL((void*)0); |
4616 | unsigned char *shaStateBuf = NULL((void*)0); |
4617 | unsigned int md5StateLen, shaStateLen; |
4618 | unsigned char md5StackBuf[256]; |
4619 | unsigned char shaStackBuf[512]; |
4620 | |
4621 | if (!spec->master_secret) { |
4622 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); |
4623 | return SECFailure; |
4624 | } |
4625 | |
4626 | md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf, |
4627 | sizeof md5StackBuf, &md5StateLen); |
4628 | if (md5StateBuf == NULL((void*)0)) { |
4629 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
4630 | goto loser; |
4631 | } |
4632 | md5 = ss->ssl3.hs.md5; |
4633 | |
4634 | shaStateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.sha, shaStackBuf, |
4635 | sizeof shaStackBuf, &shaStateLen); |
4636 | if (shaStateBuf == NULL((void*)0)) { |
4637 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4638 | goto loser; |
4639 | } |
4640 | sha = ss->ssl3.hs.sha; |
4641 | |
4642 | if (!isTLS) { |
4643 | /* compute hashes for SSL3. */ |
4644 | unsigned char s[4]; |
4645 | |
4646 | s[0] = (unsigned char)(sender >> 24); |
4647 | s[1] = (unsigned char)(sender >> 16); |
4648 | s[2] = (unsigned char)(sender >> 8); |
4649 | s[3] = (unsigned char)sender; |
4650 | |
4651 | if (sender != 0) { |
4652 | rv |= PK11_DigestOp(md5, s, 4); |
4653 | PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: sender" , s, 4); |
4654 | } |
4655 | |
4656 | PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_md5].pad_size) |
4657 | mac_defs[mac_md5].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_md5].pad_size); |
4658 | |
4659 | rv |= PK11_DigestKey(md5,spec->master_secret); |
4660 | rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5ssl_mac_md5].pad_size); |
4661 | rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH16); |
4662 | PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH)((rv != SECSuccess || outLength == 16)?((void)0):PR_Assert("rv != SECSuccess || outLength == MD5_LENGTH" ,"ssl3con.c",4662)); |
4663 | if (rv != SECSuccess) { |
4664 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
4665 | rv = SECFailure; |
4666 | goto loser; |
4667 | } |
4668 | |
4669 | PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 inner: result" , md5_inner, outLength); |
4670 | |
4671 | if (sender != 0) { |
4672 | rv |= PK11_DigestOp(sha, s, 4); |
4673 | PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: sender" , s, 4); |
4674 | } |
4675 | |
4676 | PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_sha].pad_size) |
4677 | mac_defs[mac_sha].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: MAC Pad 1" , mac_pad_1, mac_defs[ssl_mac_sha].pad_size); |
4678 | |
4679 | rv |= PK11_DigestKey(sha, spec->master_secret); |
4680 | rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_shassl_mac_sha].pad_size); |
4681 | rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH20); |
4682 | PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH)((rv != SECSuccess || outLength == 20)?((void)0):PR_Assert("rv != SECSuccess || outLength == SHA1_LENGTH" ,"ssl3con.c",4682)); |
4683 | if (rv != SECSuccess) { |
4684 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4685 | rv = SECFailure; |
4686 | goto loser; |
4687 | } |
4688 | |
4689 | PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA inner: result" , sha_inner, outLength); |
4690 | |
4691 | PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_md5].pad_size) |
4692 | mac_defs[mac_md5].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_md5].pad_size); |
4693 | PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "MD5 outer: MD5 inner" , md5_inner, 16); |
4694 | |
4695 | rv |= PK11_DigestBegin(md5); |
4696 | rv |= PK11_DigestKey(md5, spec->master_secret); |
4697 | rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5ssl_mac_md5].pad_size); |
4698 | rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH16); |
4699 | } |
4700 | rv |= PK11_DigestFinal(md5, hashes->u.s.md5, &outLength, MD5_LENGTH16); |
4701 | PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH)((rv != SECSuccess || outLength == 16)?((void)0):PR_Assert("rv != SECSuccess || outLength == MD5_LENGTH" ,"ssl3con.c",4701)); |
4702 | if (rv != SECSuccess) { |
4703 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
4704 | rv = SECFailure; |
4705 | goto loser; |
4706 | } |
4707 | |
4708 | PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_LENGTH))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "MD5 outer: result" , hashes->u.s.md5, 16); |
4709 | |
4710 | if (!isTLS) { |
4711 | PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2,if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_sha].pad_size) |
4712 | mac_defs[mac_sha].pad_size))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA outer: MAC Pad 2" , mac_pad_2, mac_defs[ssl_mac_sha].pad_size); |
4713 | PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH))if (ssl_trace >= (95)) ssl_PrintBuf (((void*)0), "SHA outer: SHA inner" , sha_inner, 20); |
4714 | |
4715 | rv |= PK11_DigestBegin(sha); |
4716 | rv |= PK11_DigestKey(sha,spec->master_secret); |
4717 | rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_shassl_mac_sha].pad_size); |
4718 | rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH20); |
4719 | } |
4720 | rv |= PK11_DigestFinal(sha, hashes->u.s.sha, &outLength, SHA1_LENGTH20); |
4721 | PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH)((rv != SECSuccess || outLength == 20)?((void)0):PR_Assert("rv != SECSuccess || outLength == SHA1_LENGTH" ,"ssl3con.c",4721)); |
4722 | if (rv != SECSuccess) { |
4723 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4724 | rv = SECFailure; |
4725 | goto loser; |
4726 | } |
4727 | |
4728 | PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "SHA outer: result" , hashes->u.s.sha, 20); |
4729 | |
4730 | hashes->len = MD5_LENGTH16 + SHA1_LENGTH20; |
4731 | rv = SECSuccess; |
4732 | |
4733 | loser: |
4734 | if (md5StateBuf) { |
4735 | if (PK11_RestoreContext(ss->ssl3.hs.md5, md5StateBuf, md5StateLen) |
4736 | != SECSuccess) |
4737 | { |
4738 | ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
4739 | rv = SECFailure; |
4740 | } |
4741 | if (md5StateBuf != md5StackBuf) { |
4742 | PORT_ZFreePORT_ZFree_Util(md5StateBuf, md5StateLen); |
4743 | } |
4744 | } |
4745 | if (shaStateBuf) { |
4746 | if (PK11_RestoreContext(ss->ssl3.hs.sha, shaStateBuf, shaStateLen) |
4747 | != SECSuccess) |
4748 | { |
4749 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4750 | rv = SECFailure; |
4751 | } |
4752 | if (shaStateBuf != shaStackBuf) { |
4753 | PORT_ZFreePORT_ZFree_Util(shaStateBuf, shaStateLen); |
4754 | } |
4755 | } |
4756 | } |
4757 | return rv; |
4758 | } |
4759 | |
4760 | static SECStatus |
4761 | ssl3_ComputeBackupHandshakeHashes(sslSocket * ss, |
4762 | SSL3Hashes * hashes) /* output goes here. */ |
4763 | { |
4764 | SECStatus rv = SECSuccess; |
4765 | |
4766 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",4766)); |
4767 | PORT_Assert( !ss->sec.isServer )((!ss->sec.isServer)?((void)0):PR_Assert("!ss->sec.isServer" ,"ssl3con.c",4767)); |
4768 | PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single )((ss->ssl3.hs.hashType == handshake_hash_single)?((void)0) :PR_Assert("ss->ssl3.hs.hashType == handshake_hash_single" ,"ssl3con.c",4768)); |
4769 | |
4770 | rv = PK11_DigestFinal(ss->ssl3.hs.backupHashmd5, hashes->u.raw, &hashes->len, |
4771 | sizeof(hashes->u.raw)); |
4772 | if (rv != SECSuccess) { |
4773 | ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); |
4774 | rv = SECFailure; |
4775 | goto loser; |
4776 | } |
4777 | hashes->hashAlg = SEC_OID_SHA1; |
4778 | |
4779 | loser: |
4780 | PK11_DestroyContext(ss->ssl3.hs.backupHashmd5, PR_TRUE1); |
4781 | ss->ssl3.hs.backupHashmd5 = NULL((void*)0); |
4782 | return rv; |
4783 | } |
4784 | |
4785 | /* |
4786 | * SSL 2 based implementations pass in the initial outbound buffer |
4787 | * so that the handshake hash can contain the included information. |
4788 | * |
4789 | * Called from ssl2_BeginClientHandshake() in sslcon.c |
4790 | */ |
4791 | SECStatus |
4792 | ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length) |
4793 | { |
4794 | SECStatus rv; |
4795 | |
4796 | ssl_GetSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",4796)); PR_EnterMonitor(((ss)->ssl3HandshakeLock )); } }; /**************************************/ |
4797 | |
4798 | rv = ssl3_InitState(ss); |
4799 | if (rv != SECSuccess) { |
4800 | goto done; /* ssl3_InitState has set the error code. */ |
4801 | } |
4802 | rv = ssl3_RestartHandshakeHashes(ss); |
4803 | if (rv != SECSuccess) { |
4804 | goto done; |
4805 | } |
4806 | |
4807 | PORT_Memsetmemset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH32); |
4808 | PORT_Memcpymemcpy( |
4809 | &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH32 - SSL_CHALLENGE_BYTES16], |
4810 | &ss->sec.ci.clientChallenge, |
4811 | SSL_CHALLENGE_BYTES16); |
4812 | |
4813 | rv = ssl3_UpdateHandshakeHashes(ss, buf, length); |
4814 | /* if it failed, ssl3_UpdateHandshakeHashes has set the error code. */ |
4815 | |
4816 | done: |
4817 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; /**************************************/ |
4818 | return rv; |
4819 | } |
4820 | |
4821 | /************************************************************************** |
4822 | * end of Handshake Hash functions. |
4823 | * Begin Send and Handle functions for handshakes. |
4824 | **************************************************************************/ |
4825 | |
4826 | /* Called from ssl3_HandleHelloRequest(), |
4827 | * ssl3_RedoHandshake() |
4828 | * ssl2_BeginClientHandshake (when resuming ssl3 session) |
4829 | * dtls_HandleHelloVerifyRequest(with resending=PR_TRUE) |
4830 | */ |
4831 | SECStatus |
4832 | ssl3_SendClientHello(sslSocket *ss, PRBool resending) |
4833 | { |
4834 | sslSessionID * sid; |
4835 | ssl3CipherSpec * cwSpec; |
4836 | SECStatus rv; |
4837 | int i; |
4838 | int length; |
4839 | int num_suites; |
4840 | int actual_count = 0; |
4841 | PRBool isTLS = PR_FALSE0; |
4842 | PRInt32 total_exten_len = 0; |
4843 | unsigned paddingExtensionLen; |
4844 | unsigned numCompressionMethods; |
4845 | PRInt32 flags; |
4846 | |
4847 | SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send client_hello handshake" , getpid(), ss->fd) |
4848 | ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send client_hello handshake" , getpid(), ss->fd); |
4849 | |
4850 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",4850)); |
4851 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",4851)); |
4852 | |
4853 | rv = ssl3_InitState(ss); |
4854 | if (rv != SECSuccess) { |
4855 | return rv; /* ssl3_InitState has set the error code. */ |
4856 | } |
4857 | ss->ssl3.hs.sendingSCSV = PR_FALSE0; /* Must be reset every handshake */ |
4858 | PORT_Assert(IS_DTLS(ss) || !resending)(((ss->protocolVariant == ssl_variant_datagram) || !resending )?((void)0):PR_Assert("IS_DTLS(ss) || !resending","ssl3con.c" ,4858)); |
4859 | |
4860 | SECITEM_FreeItemSECITEM_FreeItem_Util(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE0); |
4861 | ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE0; |
4862 | |
4863 | /* We might be starting a session renegotiation in which case we should |
4864 | * clear previous state. |
4865 | */ |
4866 | PORT_Memsetmemset(&ss->xtnData, 0, sizeof(TLSExtensionData)); |
4867 | |
4868 | rv = ssl3_RestartHandshakeHashes(ss); |
4869 | if (rv != SECSuccess) { |
4870 | return rv; |
4871 | } |
4872 | |
4873 | /* |
4874 | * During a renegotiation, ss->clientHelloVersion will be used again to |
4875 | * work around a Windows SChannel bug. Ensure that it is still enabled. |
4876 | */ |
4877 | if (ss->firstHsDone) { |
4878 | if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)((&ss->vrange)->min == 0)) { |
4879 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SSL_DISABLED); |
4880 | return SECFailure; |
4881 | } |
4882 | |
4883 | if (ss->clientHelloVersion < ss->vrange.min || |
4884 | ss->clientHelloVersion > ss->vrange.max) { |
4885 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_CYPHER_OVERLAP); |
4886 | return SECFailure; |
4887 | } |
4888 | } |
4889 | |
4890 | /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup |
4891 | * handles expired entries and other details. |
4892 | * XXX If we've been called from ssl2_BeginClientHandshake, then |
4893 | * this lookup is duplicative and wasteful. |
4894 | */ |
4895 | sid = (ss->opt.noCache) ? NULL((void*)0) |
4896 | : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); |
4897 | |
4898 | /* We can't resume based on a different token. If the sid exists, |
4899 | * make sure the token that holds the master secret still exists ... |
4900 | * If we previously did client-auth, make sure that the token that holds |
4901 | * the private key still exists, is logged in, hasn't been removed, etc. |
4902 | */ |
4903 | if (sid) { |
4904 | PRBool sidOK = PR_TRUE1; |
4905 | if (sid->u.ssl3.keys.msIsWrapped) { |
4906 | /* Session key was wrapped, which means it was using PKCS11, */ |
4907 | PK11SlotInfo *slot = NULL((void*)0); |
4908 | if (sid->u.ssl3.masterValid && !ss->opt.bypassPKCS11) { |
4909 | slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID, |
4910 | sid->u.ssl3.masterSlotID); |
4911 | } |
4912 | if (slot == NULL((void*)0)) { |
4913 | sidOK = PR_FALSE0; |
4914 | } else { |
4915 | PK11SymKey *wrapKey = NULL((void*)0); |
4916 | if (!PK11_IsPresent(slot) || |
4917 | ((wrapKey = PK11_GetWrapKey(slot, |
4918 | sid->u.ssl3.masterWrapIndex, |
4919 | sid->u.ssl3.masterWrapMech, |
4920 | sid->u.ssl3.masterWrapSeries, |
4921 | ss->pkcs11PinArg)) == NULL((void*)0)) ) { |
4922 | sidOK = PR_FALSE0; |
4923 | } |
4924 | if (wrapKey) PK11_FreeSymKey(wrapKey); |
4925 | PK11_FreeSlot(slot); |
4926 | slot = NULL((void*)0); |
4927 | } |
4928 | } |
4929 | /* If we previously did client-auth, make sure that the token that |
4930 | ** holds the private key still exists, is logged in, hasn't been |
4931 | ** removed, etc. |
4932 | */ |
4933 | if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) { |
4934 | sidOK = PR_FALSE0; |
4935 | } |
4936 | |
4937 | /* TLS 1.0 (RFC 2246) Appendix E says: |
4938 | * Whenever a client already knows the highest protocol known to |
4939 | * a server (for example, when resuming a session), it should |
4940 | * initiate the connection in that native protocol. |
4941 | * So we pass sid->version to ssl3_NegotiateVersion() here, except |
4942 | * when renegotiating. |
4943 | * |
4944 | * Windows SChannel compares the client_version inside the RSA |
4945 | * EncryptedPreMasterSecret of a renegotiation with the |
4946 | * client_version of the initial ClientHello rather than the |
4947 | * ClientHello in the renegotiation. To work around this bug, we |
4948 | * continue to use the client_version used in the initial |
4949 | * ClientHello when renegotiating. |
4950 | */ |
4951 | if (sidOK) { |
4952 | if (ss->firstHsDone) { |
4953 | /* |
4954 | * The client_version of the initial ClientHello is still |
4955 | * available in ss->clientHelloVersion. Ensure that |
4956 | * sid->version is bounded within |
4957 | * [ss->vrange.min, ss->clientHelloVersion], otherwise we |
4958 | * can't use sid. |
4959 | */ |
4960 | if (sid->version >= ss->vrange.min && |
4961 | sid->version <= ss->clientHelloVersion) { |
4962 | ss->version = ss->clientHelloVersion; |
4963 | } else { |
4964 | sidOK = PR_FALSE0; |
4965 | } |
4966 | } else { |
4967 | if (ssl3_NegotiateVersion(ss, sid->version, |
4968 | PR_FALSE0) != SECSuccess) { |
4969 | sidOK = PR_FALSE0; |
4970 | } |
4971 | } |
4972 | } |
4973 | |
4974 | if (!sidOK) { |
4975 | SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok ); |
4976 | if (ss->sec.uncache) |
4977 | (*ss->sec.uncache)(sid); |
4978 | ssl_FreeSID(sid); |
4979 | sid = NULL((void*)0); |
4980 | } |
4981 | } |
4982 | |
4983 | if (sid) { |
4984 | SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); |
4985 | |
4986 | PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,if (ssl_trace >= (4)) ssl_PrintBuf (ss, "client, found session-id:" , sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength) |
4987 | sid->u.ssl3.sessionIDLength))if (ssl_trace >= (4)) ssl_PrintBuf (ss, "client, found session-id:" , sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength); |
4988 | |
4989 | ss->ssl3.policy = sid->u.ssl3.policy; |
4990 | } else { |
4991 | SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); |
4992 | |
4993 | /* |
4994 | * Windows SChannel compares the client_version inside the RSA |
4995 | * EncryptedPreMasterSecret of a renegotiation with the |
4996 | * client_version of the initial ClientHello rather than the |
4997 | * ClientHello in the renegotiation. To work around this bug, we |
4998 | * continue to use the client_version used in the initial |
4999 | * ClientHello when renegotiating. |
5000 | */ |
5001 | if (ss->firstHsDone) { |
5002 | ss->version = ss->clientHelloVersion; |
5003 | } else { |
5004 | rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED0x0303, |
5005 | PR_TRUE1); |
5006 | if (rv != SECSuccess) |
5007 | return rv; /* error code was set */ |
5008 | } |
5009 | |
5010 | sid = ssl3_NewSessionID(ss, PR_FALSE0); |
5011 | if (!sid) { |
5012 | return SECFailure; /* memory error is set */ |
5013 | } |
5014 | } |
5015 | |
5016 | isTLS = (ss->version > SSL_LIBRARY_VERSION_3_00x0300); |
5017 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; |
5018 | cwSpec = ss->ssl3.cwSpec; |
5019 | if (cwSpec->mac_def->mac == mac_nullssl_mac_null) { |
5020 | /* SSL records are not being MACed. */ |
5021 | cwSpec->version = ss->version; |
5022 | } |
5023 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
5024 | |
5025 | if (ss->sec.ci.sid != NULL((void*)0)) { |
5026 | ssl_FreeSID(ss->sec.ci.sid); /* decrement ref count, free if zero */ |
5027 | } |
5028 | ss->sec.ci.sid = sid; |
5029 | |
5030 | ss->sec.send = ssl3_SendApplicationData; |
5031 | |
5032 | /* shouldn't get here if SSL3 is disabled, but ... */ |
5033 | if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)((&ss->vrange)->min == 0)) { |
5034 | PR_NOT_REACHED("No versions of SSL 3.0 or later are enabled")PR_Assert("No versions of SSL 3.0 or later are enabled","ssl3con.c" ,5034); |
5035 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SSL_DISABLED); |
5036 | return SECFailure; |
5037 | } |
5038 | |
5039 | /* how many suites does our PKCS11 support (regardless of policy)? */ |
5040 | num_suites = ssl3_config_match_init(ss); |
5041 | if (!num_suites) |
5042 | return SECFailure; /* ssl3_config_match_init has set error code. */ |
5043 | |
5044 | /* HACK for SCSV in SSL 3.0. On initial handshake, prepend SCSV, |
5045 | * only if TLS is disabled. |
5046 | */ |
5047 | if (!ss->firstHsDone && !isTLS) { |
5048 | /* Must set this before calling Hello Extension Senders, |
5049 | * to suppress sending of empty RI extension. |
5050 | */ |
5051 | ss->ssl3.hs.sendingSCSV = PR_TRUE1; |
5052 | } |
5053 | |
5054 | /* When we attempt session resumption (only), we must lock the sid to |
5055 | * prevent races with other resumption connections that receive a |
5056 | * NewSessionTicket that will cause the ticket in the sid to be replaced. |
5057 | * Once we've copied the session ticket into our ClientHello message, it |
5058 | * is OK for the ticket to change, so we just need to make sure we hold |
5059 | * the lock across the calls to ssl3_CallHelloExtensionSenders. |
5060 | */ |
5061 | if (sid->u.ssl3.lock) { |
5062 | PR_RWLock_Rlock(sid->u.ssl3.lock); |
5063 | } |
5064 | |
5065 | if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) { |
5066 | PRUint32 maxBytes = 65535; /* 2^16 - 1 */ |
5067 | PRInt32 extLen; |
5068 | |
5069 | extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE0, maxBytes, NULL((void*)0)); |
5070 | if (extLen < 0) { |
5071 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5072 | return SECFailure; |
5073 | } |
5074 | maxBytes -= extLen; |
5075 | total_exten_len += extLen; |
5076 | |
5077 | if (total_exten_len > 0) |
5078 | total_exten_len += 2; |
5079 | } |
5080 | |
5081 | #if defined(NSS_ENABLE_ECC1) |
5082 | if (!total_exten_len || !isTLS) { |
5083 | /* not sending the elliptic_curves and ec_point_formats extensions */ |
5084 | ssl3_DisableECCSuites(ss, NULL((void*)0)); /* disable all ECC suites */ |
5085 | } |
5086 | #endif |
5087 | |
5088 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
5089 | ssl3_DisableNonDTLSSuites(ss); |
5090 | } |
5091 | |
5092 | /* how many suites are permitted by policy and user preference? */ |
5093 | num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE1); |
5094 | if (!num_suites) { |
5095 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5096 | return SECFailure; /* count_cipher_suites has set error code. */ |
5097 | } |
5098 | if (ss->ssl3.hs.sendingSCSV) { |
5099 | ++num_suites; /* make room for SCSV */ |
5100 | } |
5101 | |
5102 | /* count compression methods */ |
5103 | numCompressionMethods = 0; |
5104 | for (i = 0; i < compressionMethodsCount; i++) { |
5105 | if (compressionEnabled(ss, compressions[i])) |
5106 | numCompressionMethods++; |
5107 | } |
5108 | |
5109 | length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH32 + |
5110 | 1 + ((sid == NULL((void*)0)) ? 0 : sid->u.ssl3.sessionIDLength) + |
5111 | 2 + num_suites*sizeof(ssl3CipherSuite) + |
5112 | 1 + numCompressionMethods + total_exten_len; |
5113 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
5114 | length += 1 + ss->ssl3.hs.cookieLen; |
5115 | } |
5116 | |
5117 | /* A padding extension may be included to ensure that the record containing |
5118 | * the ClientHello doesn't have a length between 256 and 511 bytes |
5119 | * (inclusive). Initial, ClientHello records with such lengths trigger bugs |
5120 | * in F5 devices. |
5121 | * |
5122 | * This is not done for DTLS nor for renegotiation. */ |
5123 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram) && isTLS && !ss->firstHsDone) { |
5124 | paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length); |
5125 | total_exten_len += paddingExtensionLen; |
5126 | length += paddingExtensionLen; |
5127 | } else { |
5128 | paddingExtensionLen = 0; |
5129 | } |
5130 | |
5131 | rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); |
5132 | if (rv != SECSuccess) { |
5133 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5134 | return rv; /* err set by ssl3_AppendHandshake* */ |
5135 | } |
5136 | |
5137 | if (ss->firstHsDone) { |
5138 | /* The client hello version must stay unchanged to work around |
5139 | * the Windows SChannel bug described above. */ |
5140 | PORT_Assert(ss->version == ss->clientHelloVersion)((ss->version == ss->clientHelloVersion)?((void)0):PR_Assert ("ss->version == ss->clientHelloVersion","ssl3con.c",5140 )); |
5141 | } |
5142 | ss->clientHelloVersion = ss->version; |
5143 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
5144 | PRUint16 version; |
5145 | |
5146 | version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion); |
5147 | rv = ssl3_AppendHandshakeNumber(ss, version, 2); |
5148 | } else { |
5149 | rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); |
5150 | } |
5151 | if (rv != SECSuccess) { |
5152 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5153 | return rv; /* err set by ssl3_AppendHandshake* */ |
5154 | } |
5155 | |
5156 | if (!resending) { /* Don't re-generate if we are in DTLS re-sending mode */ |
5157 | rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random); |
5158 | if (rv != SECSuccess) { |
5159 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5160 | return rv; /* err set by GetNewRandom. */ |
5161 | } |
5162 | } |
5163 | rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random, |
5164 | SSL3_RANDOM_LENGTH32); |
5165 | if (rv != SECSuccess) { |
5166 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5167 | return rv; /* err set by ssl3_AppendHandshake* */ |
5168 | } |
5169 | |
5170 | if (sid) |
5171 | rv = ssl3_AppendHandshakeVariable( |
5172 | ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1); |
5173 | else |
5174 | rv = ssl3_AppendHandshakeVariable(ss, NULL((void*)0), 0, 1); |
5175 | if (rv != SECSuccess) { |
5176 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5177 | return rv; /* err set by ssl3_AppendHandshake* */ |
5178 | } |
5179 | |
5180 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
5181 | rv = ssl3_AppendHandshakeVariable( |
5182 | ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1); |
5183 | if (rv != SECSuccess) { |
5184 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5185 | return rv; /* err set by ssl3_AppendHandshake* */ |
5186 | } |
5187 | } |
5188 | |
5189 | rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2); |
5190 | if (rv != SECSuccess) { |
5191 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5192 | return rv; /* err set by ssl3_AppendHandshake* */ |
5193 | } |
5194 | |
5195 | if (ss->ssl3.hs.sendingSCSV) { |
5196 | /* Add the actual SCSV */ |
5197 | rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV0x00FF, |
5198 | sizeof(ssl3CipherSuite)); |
5199 | if (rv != SECSuccess) { |
5200 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5201 | return rv; /* err set by ssl3_AppendHandshake* */ |
5202 | } |
5203 | actual_count++; |
5204 | } |
5205 | for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED61; i++) { |
5206 | ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; |
5207 | if (config_match(suite, ss->ssl3.policy, PR_TRUE1, &ss->vrange)) { |
5208 | actual_count++; |
5209 | if (actual_count > num_suites) { |
5210 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5211 | /* set error card removal/insertion error */ |
5212 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
5213 | return SECFailure; |
5214 | } |
5215 | rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite, |
5216 | sizeof(ssl3CipherSuite)); |
5217 | if (rv != SECSuccess) { |
5218 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5219 | return rv; /* err set by ssl3_AppendHandshake* */ |
5220 | } |
5221 | } |
5222 | } |
5223 | |
5224 | /* if cards were removed or inserted between count_cipher_suites and |
5225 | * generating our list, detect the error here rather than send it off to |
5226 | * the server.. */ |
5227 | if (actual_count != num_suites) { |
5228 | /* Card removal/insertion error */ |
5229 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5230 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
5231 | return SECFailure; |
5232 | } |
5233 | |
5234 | rv = ssl3_AppendHandshakeNumber(ss, numCompressionMethods, 1); |
5235 | if (rv != SECSuccess) { |
5236 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5237 | return rv; /* err set by ssl3_AppendHandshake* */ |
5238 | } |
5239 | for (i = 0; i < compressionMethodsCount; i++) { |
5240 | if (!compressionEnabled(ss, compressions[i])) |
5241 | continue; |
5242 | rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1); |
5243 | if (rv != SECSuccess) { |
5244 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5245 | return rv; /* err set by ssl3_AppendHandshake* */ |
5246 | } |
5247 | } |
5248 | |
5249 | if (total_exten_len) { |
5250 | PRUint32 maxBytes = total_exten_len - 2; |
5251 | PRInt32 extLen; |
5252 | |
5253 | rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2); |
5254 | if (rv != SECSuccess) { |
5255 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5256 | return rv; /* err set by AppendHandshake. */ |
5257 | } |
5258 | |
5259 | extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE1, maxBytes, NULL((void*)0)); |
5260 | if (extLen < 0) { |
5261 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5262 | return SECFailure; |
5263 | } |
5264 | maxBytes -= extLen; |
5265 | |
5266 | extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes); |
5267 | if (extLen < 0) { |
5268 | if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } |
5269 | return SECFailure; |
5270 | } |
5271 | maxBytes -= extLen; |
5272 | |
5273 | PORT_Assert(!maxBytes)((!maxBytes)?((void)0):PR_Assert("!maxBytes","ssl3con.c",5273 )); |
5274 | } |
5275 | |
5276 | if (sid->u.ssl3.lock) { |
5277 | PR_RWLock_Unlock(sid->u.ssl3.lock); |
5278 | } |
5279 | |
5280 | if (ss->xtnData.sentSessionTicketInClientHello) { |
5281 | SSL_AtomicIncrementLong(&ssl3stats.sch_sid_stateless_resumes); |
5282 | } |
5283 | |
5284 | if (ss->ssl3.hs.sendingSCSV) { |
5285 | /* Since we sent the SCSV, pretend we sent empty RI extension. */ |
5286 | TLSExtensionData *xtnData = &ss->xtnData; |
5287 | xtnData->advertised[xtnData->numAdvertised++] = |
5288 | ssl_renegotiation_info_xtn; |
5289 | } |
5290 | |
5291 | flags = 0; |
5292 | if (!ss->firstHsDone && !IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
5293 | flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION0x04000000; |
5294 | } |
5295 | rv = ssl3_FlushHandshake(ss, flags); |
5296 | if (rv != SECSuccess) { |
5297 | return rv; /* error code set by ssl3_FlushHandshake */ |
5298 | } |
5299 | |
5300 | ss->ssl3.hs.ws = wait_server_hello; |
5301 | return rv; |
5302 | } |
5303 | |
5304 | |
5305 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
5306 | * ssl3 Hello Request. |
5307 | * Caller must hold Handshake and RecvBuf locks. |
5308 | */ |
5309 | static SECStatus |
5310 | ssl3_HandleHelloRequest(sslSocket *ss) |
5311 | { |
5312 | sslSessionID *sid = ss->sec.ci.sid; |
5313 | SECStatus rv; |
5314 | |
5315 | SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle hello_request handshake" , getpid(), ss->fd) |
5316 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle hello_request handshake" , getpid(), ss->fd); |
5317 | |
5318 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",5318)); |
5319 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",5319)); |
5320 | |
5321 | if (ss->ssl3.hs.ws == wait_server_hello) |
5322 | return SECSuccess; |
5323 | if (ss->ssl3.hs.ws != idle_handshake || ss->sec.isServer) { |
5324 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
5325 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST); |
5326 | return SECFailure; |
5327 | } |
5328 | if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER((PRBool)0)) { |
5329 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
5330 | rv = SSL3_SendAlert(ss, alert_warning, no_renegotiation); |
5331 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
5332 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); |
5333 | return SECFailure; |
5334 | } |
5335 | |
5336 | if (sid) { |
5337 | if (ss->sec.uncache) |
5338 | ss->sec.uncache(sid); |
5339 | ssl_FreeSID(sid); |
5340 | ss->sec.ci.sid = NULL((void*)0); |
5341 | } |
5342 | |
5343 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
5344 | dtls_RehandshakeCleanup(ss); |
5345 | } |
5346 | |
5347 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
5348 | rv = ssl3_SendClientHello(ss, PR_FALSE0); |
5349 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
5350 | |
5351 | return rv; |
5352 | } |
5353 | |
5354 | #define UNKNOWN_WRAP_MECHANISM0x7fffffff 0x7fffffff |
5355 | |
5356 | static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS16] = { |
5357 | CKM_DES3_ECB0x00000132, |
5358 | CKM_CAST5_ECB0x00000321, |
5359 | CKM_DES_ECB0x00000121, |
5360 | CKM_KEY_WRAP_LYNKS0x00000400, |
5361 | CKM_IDEA_ECB0x00000341, |
5362 | CKM_CAST3_ECB0x00000311, |
5363 | CKM_CAST_ECB0x00000301, |
5364 | CKM_RC5_ECB0x00000331, |
5365 | CKM_RC2_ECB0x00000101, |
5366 | CKM_CDMF_ECB0x00000141, |
5367 | CKM_SKIPJACK_WRAP0x00001008, |
5368 | CKM_SKIPJACK_CBC640x00001002, |
5369 | CKM_AES_ECB0x00001081, |
5370 | CKM_CAMELLIA_ECB0x00000551, |
5371 | CKM_SEED_ECB0x00000651, |
5372 | UNKNOWN_WRAP_MECHANISM0x7fffffff |
5373 | }; |
5374 | |
5375 | static int |
5376 | ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech) |
5377 | { |
5378 | const CK_MECHANISM_TYPE *pMech = wrapMechanismList; |
5379 | |
5380 | while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM0x7fffffff) { |
5381 | ++pMech; |
5382 | } |
5383 | return (*pMech == UNKNOWN_WRAP_MECHANISM0x7fffffff) ? -1 |
5384 | : (pMech - wrapMechanismList); |
5385 | } |
5386 | |
5387 | static PK11SymKey * |
5388 | ssl_UnwrapSymWrappingKey( |
5389 | SSLWrappedSymWrappingKey *pWswk, |
5390 | SECKEYPrivateKey * svrPrivKey, |
5391 | SSL3KEAType exchKeyType, |
5392 | CK_MECHANISM_TYPE masterWrapMech, |
5393 | void * pwArg) |
5394 | { |
5395 | PK11SymKey * unwrappedWrappingKey = NULL((void*)0); |
5396 | SECItem wrappedKey; |
5397 | #ifdef NSS_ENABLE_ECC1 |
5398 | PK11SymKey * Ks; |
5399 | SECKEYPublicKey pubWrapKey; |
5400 | ECCWrappedKeyInfo *ecWrapped; |
5401 | #endif /* NSS_ENABLE_ECC */ |
5402 | |
5403 | /* found the wrapping key on disk. */ |
5404 | PORT_Assert(pWswk->symWrapMechanism == masterWrapMech)((pWswk->symWrapMechanism == masterWrapMech)?((void)0):PR_Assert ("pWswk->symWrapMechanism == masterWrapMech","ssl3con.c",5404 )); |
5405 | PORT_Assert(pWswk->exchKeyType == exchKeyType)((pWswk->exchKeyType == exchKeyType)?((void)0):PR_Assert("pWswk->exchKeyType == exchKeyType" ,"ssl3con.c",5405)); |
5406 | if (pWswk->symWrapMechanism != masterWrapMech || |
5407 | pWswk->exchKeyType != exchKeyType) { |
5408 | goto loser; |
5409 | } |
5410 | wrappedKey.type = siBuffer; |
5411 | wrappedKey.data = pWswk->wrappedSymmetricWrappingkey; |
5412 | wrappedKey.len = pWswk->wrappedSymKeyLen; |
5413 | PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey)((wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey )?((void)0):PR_Assert("wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey" ,"ssl3con.c",5413)); |
5414 | |
5415 | switch (exchKeyType) { |
5416 | |
5417 | case kt_rsassl_kea_rsa: |
5418 | unwrappedWrappingKey = |
5419 | PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, |
5420 | masterWrapMech, CKA_UNWRAP0x00000107, 0); |
5421 | break; |
5422 | |
5423 | #ifdef NSS_ENABLE_ECC1 |
5424 | case kt_ecdhssl_kea_ecdh: |
5425 | /* |
5426 | * For kt_ecdh, we first create an EC public key based on |
5427 | * data stored with the wrappedSymmetricWrappingkey. Next, |
5428 | * we do an ECDH computation involving this public key and |
5429 | * the SSL server's (long-term) EC private key. The resulting |
5430 | * shared secret is treated the same way as Fortezza's Ks, i.e., |
5431 | * it is used to recover the symmetric wrapping key. |
5432 | * |
5433 | * The data in wrappedSymmetricWrappingkey is laid out as defined |
5434 | * in the ECCWrappedKeyInfo structure. |
5435 | */ |
5436 | ecWrapped = (ECCWrappedKeyInfo *) pWswk->wrappedSymmetricWrappingkey; |
5437 | |
5438 | PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen +((ecWrapped->encodedParamLen + ecWrapped->pubValueLen + ecWrapped->wrappedKeyLen <= 504)?((void)0):PR_Assert("ecWrapped->encodedParamLen + ecWrapped->pubValueLen + ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN" ,"ssl3con.c",5439)) |
5439 | ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN)((ecWrapped->encodedParamLen + ecWrapped->pubValueLen + ecWrapped->wrappedKeyLen <= 504)?((void)0):PR_Assert("ecWrapped->encodedParamLen + ecWrapped->pubValueLen + ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN" ,"ssl3con.c",5439)); |
5440 | |
5441 | if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen + |
5442 | ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN504) { |
5443 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
5444 | goto loser; |
5445 | } |
5446 | |
5447 | pubWrapKey.keyType = ecKey; |
5448 | pubWrapKey.u.ec.size = ecWrapped->size; |
5449 | pubWrapKey.u.ec.DEREncodedParams.len = ecWrapped->encodedParamLen; |
5450 | pubWrapKey.u.ec.DEREncodedParams.data = ecWrapped->var; |
5451 | pubWrapKey.u.ec.publicValue.len = ecWrapped->pubValueLen; |
5452 | pubWrapKey.u.ec.publicValue.data = ecWrapped->var + |
5453 | ecWrapped->encodedParamLen; |
5454 | |
5455 | wrappedKey.len = ecWrapped->wrappedKeyLen; |
5456 | wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + |
5457 | ecWrapped->pubValueLen; |
5458 | |
5459 | /* Derive Ks using ECDH */ |
5460 | Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE0, NULL((void*)0), |
5461 | NULL((void*)0), CKM_ECDH1_DERIVE0x00001050, masterWrapMech, |
5462 | CKA_DERIVE0x0000010C, 0, CKD_NULL0x00000001, NULL((void*)0), NULL((void*)0)); |
5463 | if (Ks == NULL((void*)0)) { |
5464 | goto loser; |
5465 | } |
5466 | |
5467 | /* Use Ks to unwrap the wrapping key */ |
5468 | unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL((void*)0), |
5469 | &wrappedKey, masterWrapMech, |
5470 | CKA_UNWRAP0x00000107, 0); |
5471 | PK11_FreeSymKey(Ks); |
5472 | |
5473 | break; |
5474 | #endif |
5475 | |
5476 | default: |
5477 | /* Assert? */ |
5478 | SET_ERROR_CODE |
5479 | goto loser; |
5480 | } |
5481 | loser: |
5482 | return unwrappedWrappingKey; |
5483 | } |
5484 | |
5485 | /* Each process sharing the server session ID cache has its own array of |
5486 | * SymKey pointers for the symmetric wrapping keys that are used to wrap |
5487 | * the master secrets. There is one key for each KEA type. These Symkeys |
5488 | * correspond to the wrapped SymKeys kept in the server session cache. |
5489 | */ |
5490 | |
5491 | typedef struct { |
5492 | PK11SymKey * symWrapKey[kt_kea_sizessl_kea_size]; |
5493 | } ssl3SymWrapKey; |
5494 | |
5495 | static PZLockPRLock * symWrapKeysLock = NULL((void*)0); |
5496 | static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS16]; |
5497 | |
5498 | SECStatus ssl_FreeSymWrapKeysLock(void) |
5499 | { |
5500 | if (symWrapKeysLock) { |
5501 | PZ_DestroyLock(symWrapKeysLock)PR_DestroyLock((symWrapKeysLock)); |
5502 | symWrapKeysLock = NULL((void*)0); |
5503 | return SECSuccess; |
5504 | } |
5505 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NOT_INITIALIZED); |
5506 | return SECFailure; |
5507 | } |
5508 | |
5509 | SECStatus |
5510 | SSL3_ShutdownServerCache(void) |
5511 | { |
5512 | int i, j; |
5513 | |
5514 | if (!symWrapKeysLock) |
5515 | return SECSuccess; /* lock was never initialized */ |
5516 | PZ_Lock(symWrapKeysLock)PR_Lock((symWrapKeysLock)); |
5517 | /* get rid of all symWrapKeys */ |
5518 | for (i = 0; i < SSL_NUM_WRAP_MECHS16; ++i) { |
5519 | for (j = 0; j < kt_kea_sizessl_kea_size; ++j) { |
5520 | PK11SymKey ** pSymWrapKey; |
5521 | pSymWrapKey = &symWrapKeys[i].symWrapKey[j]; |
5522 | if (*pSymWrapKey) { |
5523 | PK11_FreeSymKey(*pSymWrapKey); |
5524 | *pSymWrapKey = NULL((void*)0); |
5525 | } |
5526 | } |
5527 | } |
5528 | |
5529 | PZ_Unlock(symWrapKeysLock)PR_Unlock((symWrapKeysLock)); |
5530 | ssl_FreeSessionCacheLocks(); |
5531 | return SECSuccess; |
5532 | } |
5533 | |
5534 | SECStatus ssl_InitSymWrapKeysLock(void) |
5535 | { |
5536 | symWrapKeysLock = PZ_NewLock(nssILockOther)PR_NewLock(); |
5537 | return symWrapKeysLock ? SECSuccess : SECFailure; |
5538 | } |
5539 | |
5540 | /* Try to get wrapping key for mechanism from in-memory array. |
5541 | * If that fails, look for one on disk. |
5542 | * If that fails, generate a new one, put the new one on disk, |
5543 | * Put the new key in the in-memory array. |
5544 | */ |
5545 | static PK11SymKey * |
5546 | getWrappingKey( sslSocket * ss, |
5547 | PK11SlotInfo * masterSecretSlot, |
5548 | SSL3KEAType exchKeyType, |
5549 | CK_MECHANISM_TYPE masterWrapMech, |
5550 | void * pwArg) |
5551 | { |
5552 | SECKEYPrivateKey * svrPrivKey; |
5553 | SECKEYPublicKey * svrPubKey = NULL((void*)0); |
5554 | PK11SymKey * unwrappedWrappingKey = NULL((void*)0); |
5555 | PK11SymKey ** pSymWrapKey; |
5556 | CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM0xffffffffUL; |
5557 | int length; |
5558 | int symWrapMechIndex; |
5559 | SECStatus rv; |
5560 | SECItem wrappedKey; |
5561 | SSLWrappedSymWrappingKey wswk; |
5562 | #ifdef NSS_ENABLE_ECC1 |
5563 | PK11SymKey * Ks = NULL((void*)0); |
5564 | SECKEYPublicKey *pubWrapKey = NULL((void*)0); |
5565 | SECKEYPrivateKey *privWrapKey = NULL((void*)0); |
5566 | ECCWrappedKeyInfo *ecWrapped; |
5567 | #endif /* NSS_ENABLE_ECC */ |
5568 | |
5569 | svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEYserverKeyPair->privKey; |
5570 | PORT_Assert(svrPrivKey != NULL)((svrPrivKey != ((void*)0))?((void)0):PR_Assert("svrPrivKey != NULL" ,"ssl3con.c",5570)); |
5571 | if (!svrPrivKey) { |
5572 | return NULL((void*)0); /* why are we here?!? */ |
5573 | } |
5574 | |
5575 | symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech); |
5576 | PORT_Assert(symWrapMechIndex >= 0)((symWrapMechIndex >= 0)?((void)0):PR_Assert("symWrapMechIndex >= 0" ,"ssl3con.c",5576)); |
5577 | if (symWrapMechIndex < 0) |
5578 | return NULL((void*)0); /* invalid masterWrapMech. */ |
5579 | |
5580 | pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType]; |
5581 | |
5582 | ssl_InitSessionCacheLocks(PR_TRUE1); |
5583 | |
5584 | PZ_Lock(symWrapKeysLock)PR_Lock((symWrapKeysLock)); |
5585 | |
5586 | unwrappedWrappingKey = *pSymWrapKey; |
5587 | if (unwrappedWrappingKey != NULL((void*)0)) { |
5588 | if (PK11_VerifyKeyOK(unwrappedWrappingKey)) { |
5589 | unwrappedWrappingKey = PK11_ReferenceSymKey(unwrappedWrappingKey); |
5590 | goto done; |
5591 | } |
5592 | /* slot series has changed, so this key is no good any more. */ |
5593 | PK11_FreeSymKey(unwrappedWrappingKey); |
5594 | *pSymWrapKey = unwrappedWrappingKey = NULL((void*)0); |
5595 | } |
5596 | |
5597 | /* Try to get wrapped SymWrapping key out of the (disk) cache. */ |
5598 | /* Following call fills in wswk on success. */ |
5599 | if (ssl_GetWrappingKey(symWrapMechIndex, exchKeyType, &wswk)) { |
5600 | /* found the wrapped sym wrapping key on disk. */ |
5601 | unwrappedWrappingKey = |
5602 | ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType, |
5603 | masterWrapMech, pwArg); |
5604 | if (unwrappedWrappingKey) { |
5605 | goto install; |
5606 | } |
5607 | } |
5608 | |
5609 | if (!masterSecretSlot) /* caller doesn't want to create a new one. */ |
5610 | goto loser; |
5611 | |
5612 | length = PK11_GetBestKeyLength(masterSecretSlot, masterWrapMech); |
5613 | /* Zero length means fixed key length algorithm, or error. |
5614 | * It's ambiguous. |
5615 | */ |
5616 | unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL((void*)0), |
5617 | length, pwArg); |
5618 | if (!unwrappedWrappingKey) { |
5619 | goto loser; |
5620 | } |
5621 | |
5622 | /* Prepare the buffer to receive the wrappedWrappingKey, |
5623 | * the symmetric wrapping key wrapped using the server's pub key. |
5624 | */ |
5625 | PORT_Memsetmemset(&wswk, 0, sizeof wswk); /* eliminate UMRs. */ |
5626 | |
5627 | if (ss->serverCerts[exchKeyType].serverKeyPair) { |
5628 | svrPubKey = ss->serverCerts[exchKeyType].serverKeyPair->pubKey; |
5629 | } |
5630 | if (svrPubKey == NULL((void*)0)) { |
5631 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
5632 | goto loser; |
5633 | } |
5634 | wrappedKey.type = siBuffer; |
5635 | wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); |
5636 | wrappedKey.data = wswk.wrappedSymmetricWrappingkey; |
5637 | |
5638 | PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey)((wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey )?((void)0):PR_Assert("wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey" ,"ssl3con.c",5638)); |
5639 | if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey) |
5640 | goto loser; |
5641 | |
5642 | /* wrap symmetric wrapping key in server's public key. */ |
5643 | switch (exchKeyType) { |
5644 | case kt_rsassl_kea_rsa: |
5645 | asymWrapMechanism = CKM_RSA_PKCS0x00000001; |
5646 | rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey, |
5647 | unwrappedWrappingKey, &wrappedKey); |
5648 | break; |
5649 | |
5650 | #ifdef NSS_ENABLE_ECC1 |
5651 | case kt_ecdhssl_kea_ecdh: |
5652 | /* |
5653 | * We generate an ephemeral EC key pair. Perform an ECDH |
5654 | * computation involving this ephemeral EC public key and |
5655 | * the SSL server's (long-term) EC private key. The resulting |
5656 | * shared secret is treated in the same way as Fortezza's Ks, |
5657 | * i.e., it is used to wrap the wrapping key. To facilitate |
5658 | * unwrapping in ssl_UnwrapWrappingKey, we also store all |
5659 | * relevant info about the ephemeral EC public key in |
5660 | * wswk.wrappedSymmetricWrappingkey and lay it out as |
5661 | * described in the ECCWrappedKeyInfo structure. |
5662 | */ |
5663 | PORT_Assert(svrPubKey->keyType == ecKey)((svrPubKey->keyType == ecKey)?((void)0):PR_Assert("svrPubKey->keyType == ecKey" ,"ssl3con.c",5663)); |
5664 | if (svrPubKey->keyType != ecKey) { |
5665 | /* something is wrong in sslsecur.c if this isn't an ecKey */ |
5666 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
5667 | rv = SECFailure; |
5668 | goto ec_cleanup; |
5669 | } |
5670 | |
5671 | privWrapKey = SECKEY_CreateECPrivateKey( |
5672 | &svrPubKey->u.ec.DEREncodedParams, &pubWrapKey, NULL((void*)0)); |
5673 | if ((privWrapKey == NULL((void*)0)) || (pubWrapKey == NULL((void*)0))) { |
5674 | rv = SECFailure; |
5675 | goto ec_cleanup; |
5676 | } |
5677 | |
5678 | /* Set the key size in bits */ |
5679 | if (pubWrapKey->u.ec.size == 0) { |
5680 | pubWrapKey->u.ec.size = SECKEY_PublicKeyStrengthInBits(svrPubKey); |
5681 | } |
5682 | |
5683 | PORT_Assert(pubWrapKey->u.ec.DEREncodedParams.len +((pubWrapKey->u.ec.DEREncodedParams.len + pubWrapKey->u .ec.publicValue.len < 504)?((void)0):PR_Assert("pubWrapKey->u.ec.DEREncodedParams.len + pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN" ,"ssl3con.c",5684)) |
5684 | pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN)((pubWrapKey->u.ec.DEREncodedParams.len + pubWrapKey->u .ec.publicValue.len < 504)?((void)0):PR_Assert("pubWrapKey->u.ec.DEREncodedParams.len + pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN" ,"ssl3con.c",5684)); |
5685 | if (pubWrapKey->u.ec.DEREncodedParams.len + |
5686 | pubWrapKey->u.ec.publicValue.len >= MAX_EC_WRAPPED_KEY_BUFLEN504) { |
5687 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); |
5688 | rv = SECFailure; |
5689 | goto ec_cleanup; |
5690 | } |
5691 | |
5692 | /* Derive Ks using ECDH */ |
5693 | Ks = PK11_PubDeriveWithKDF(svrPrivKey, pubWrapKey, PR_FALSE0, NULL((void*)0), |
5694 | NULL((void*)0), CKM_ECDH1_DERIVE0x00001050, masterWrapMech, |
5695 | CKA_DERIVE0x0000010C, 0, CKD_NULL0x00000001, NULL((void*)0), NULL((void*)0)); |
5696 | if (Ks == NULL((void*)0)) { |
5697 | rv = SECFailure; |
5698 | goto ec_cleanup; |
5699 | } |
5700 | |
5701 | ecWrapped = (ECCWrappedKeyInfo *) (wswk.wrappedSymmetricWrappingkey); |
5702 | ecWrapped->size = pubWrapKey->u.ec.size; |
5703 | ecWrapped->encodedParamLen = pubWrapKey->u.ec.DEREncodedParams.len; |
5704 | PORT_Memcpymemcpy(ecWrapped->var, pubWrapKey->u.ec.DEREncodedParams.data, |
5705 | pubWrapKey->u.ec.DEREncodedParams.len); |
5706 | |
5707 | ecWrapped->pubValueLen = pubWrapKey->u.ec.publicValue.len; |
5708 | PORT_Memcpymemcpy(ecWrapped->var + ecWrapped->encodedParamLen, |
5709 | pubWrapKey->u.ec.publicValue.data, |
5710 | pubWrapKey->u.ec.publicValue.len); |
5711 | |
5712 | wrappedKey.len = MAX_EC_WRAPPED_KEY_BUFLEN504 - |
5713 | (ecWrapped->encodedParamLen + ecWrapped->pubValueLen); |
5714 | wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + |
5715 | ecWrapped->pubValueLen; |
5716 | |
5717 | /* wrap symmetricWrapping key with the local Ks */ |
5718 | rv = PK11_WrapSymKey(masterWrapMech, NULL((void*)0), Ks, |
5719 | unwrappedWrappingKey, &wrappedKey); |
5720 | |
5721 | if (rv != SECSuccess) { |
5722 | goto ec_cleanup; |
5723 | } |
5724 | |
5725 | /* Write down the length of wrapped key in the buffer |
5726 | * wswk.wrappedSymmetricWrappingkey at the appropriate offset |
5727 | */ |
5728 | ecWrapped->wrappedKeyLen = wrappedKey.len; |
5729 | |
5730 | ec_cleanup: |
5731 | if (privWrapKey) SECKEY_DestroyPrivateKey(privWrapKey); |
5732 | if (pubWrapKey) SECKEY_DestroyPublicKey(pubWrapKey); |
5733 | if (Ks) PK11_FreeSymKey(Ks); |
5734 | asymWrapMechanism = masterWrapMech; |
5735 | break; |
5736 | #endif /* NSS_ENABLE_ECC */ |
5737 | |
5738 | default: |
5739 | rv = SECFailure; |
5740 | break; |
5741 | } |
5742 | |
5743 | if (rv != SECSuccess) { |
5744 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
5745 | goto loser; |
5746 | } |
5747 | |
5748 | PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM)((asymWrapMechanism != 0xffffffffUL)?((void)0):PR_Assert("asymWrapMechanism != CKM_INVALID_MECHANISM" ,"ssl3con.c",5748)); |
5749 | |
5750 | wswk.symWrapMechanism = masterWrapMech; |
5751 | wswk.symWrapMechIndex = symWrapMechIndex; |
5752 | wswk.asymWrapMechanism = asymWrapMechanism; |
5753 | wswk.exchKeyType = exchKeyType; |
5754 | wswk.wrappedSymKeyLen = wrappedKey.len; |
5755 | |
5756 | /* put it on disk. */ |
5757 | /* If the wrapping key for this KEA type has already been set, |
5758 | * then abandon the value we just computed and |
5759 | * use the one we got from the disk. |
5760 | */ |
5761 | if (ssl_SetWrappingKey(&wswk)) { |
5762 | /* somebody beat us to it. The original contents of our wswk |
5763 | * has been replaced with the content on disk. Now, discard |
5764 | * the key we just created and unwrap this new one. |
5765 | */ |
5766 | PK11_FreeSymKey(unwrappedWrappingKey); |
5767 | |
5768 | unwrappedWrappingKey = |
5769 | ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType, |
5770 | masterWrapMech, pwArg); |
5771 | } |
5772 | |
5773 | install: |
5774 | if (unwrappedWrappingKey) { |
5775 | *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey); |
5776 | } |
5777 | |
5778 | loser: |
5779 | done: |
5780 | PZ_Unlock(symWrapKeysLock)PR_Unlock((symWrapKeysLock)); |
5781 | return unwrappedWrappingKey; |
5782 | } |
5783 | |
5784 | /* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2| |
5785 | * bytes to |out|. */ |
5786 | static void |
5787 | hexEncode(char *out, const unsigned char *in, unsigned int length) |
5788 | { |
5789 | static const char hextable[] = "0123456789abcdef"; |
5790 | unsigned int i; |
5791 | |
5792 | for (i = 0; i < length; i++) { |
5793 | *(out++) = hextable[in[i] >> 4]; |
5794 | *(out++) = hextable[in[i] & 15]; |
5795 | } |
5796 | } |
5797 | |
5798 | /* Called from ssl3_SendClientKeyExchange(). */ |
5799 | /* Presently, this always uses PKCS11. There is no bypass for this. */ |
5800 | static SECStatus |
5801 | sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
5802 | { |
5803 | PK11SymKey * pms = NULL((void*)0); |
5804 | SECStatus rv = SECFailure; |
5805 | SECItem enc_pms = {siBuffer, NULL((void*)0), 0}; |
5806 | PRBool isTLS; |
5807 | |
5808 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",5808)); |
5809 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",5809)); |
5810 | |
5811 | /* Generate the pre-master secret ... */ |
5812 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; |
5813 | isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
5814 | |
5815 | pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL((void*)0)); |
5816 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
5817 | if (pms == NULL((void*)0)) { |
5818 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
5819 | goto loser; |
5820 | } |
5821 | |
5822 | /* Get the wrapped (encrypted) pre-master secret, enc_pms */ |
5823 | enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey); |
5824 | enc_pms.data = (unsigned char*)PORT_AllocPORT_Alloc_Util(enc_pms.len); |
5825 | if (enc_pms.data == NULL((void*)0)) { |
5826 | goto loser; /* err set by PORT_Alloc */ |
5827 | } |
5828 | |
5829 | /* wrap pre-master secret in server's public key. */ |
5830 | rv = PK11_PubWrapSymKey(CKM_RSA_PKCS0x00000001, svrPubKey, pms, &enc_pms); |
5831 | if (rv != SECSuccess) { |
5832 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
5833 | goto loser; |
5834 | } |
5835 | |
5836 | if (ssl_keylog_iob) { |
5837 | SECStatus extractRV = PK11_ExtractKeyValue(pms); |
5838 | if (extractRV == SECSuccess) { |
5839 | SECItem * keyData = PK11_GetKeyData(pms); |
5840 | if (keyData && keyData->data && keyData->len) { |
5841 | #ifdef TRACE |
5842 | if (ssl_trace >= 100) { |
5843 | ssl_PrintBuf(ss, "Pre-Master Secret", |
5844 | keyData->data, keyData->len); |
5845 | } |
5846 | #endif |
5847 | if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) { |
5848 | /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ |
5849 | |
5850 | /* There could be multiple, concurrent writers to the |
5851 | * keylog, so we have to do everything in a single call to |
5852 | * fwrite. */ |
5853 | char buf[4 + 8*2 + 1 + 48*2 + 1]; |
5854 | |
5855 | strcpy(buf, "RSA "); |
5856 | hexEncode(buf + 4, enc_pms.data, 8); |
5857 | buf[20] = ' '; |
5858 | hexEncode(buf + 21, keyData->data, 48); |
5859 | buf[sizeof(buf) - 1] = '\n'; |
5860 | |
5861 | fwrite(buf, sizeof(buf), 1, ssl_keylog_iob); |
5862 | fflush(ssl_keylog_iob); |
5863 | } |
5864 | } |
5865 | } |
5866 | } |
5867 | |
5868 | rv = ssl3_InitPendingCipherSpec(ss, pms); |
5869 | PK11_FreeSymKey(pms); pms = NULL((void*)0); |
5870 | |
5871 | if (rv != SECSuccess) { |
5872 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
5873 | goto loser; |
5874 | } |
5875 | |
5876 | rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, |
5877 | isTLS ? enc_pms.len + 2 : enc_pms.len); |
5878 | if (rv != SECSuccess) { |
5879 | goto loser; /* err set by ssl3_AppendHandshake* */ |
5880 | } |
5881 | if (isTLS) { |
5882 | rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2); |
5883 | } else { |
5884 | rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len); |
5885 | } |
5886 | if (rv != SECSuccess) { |
5887 | goto loser; /* err set by ssl3_AppendHandshake* */ |
5888 | } |
5889 | |
5890 | rv = SECSuccess; |
5891 | |
5892 | loser: |
5893 | if (enc_pms.data != NULL((void*)0)) { |
5894 | PORT_FreePORT_Free_Util(enc_pms.data); |
5895 | } |
5896 | if (pms != NULL((void*)0)) { |
5897 | PK11_FreeSymKey(pms); |
5898 | } |
5899 | return rv; |
5900 | } |
5901 | |
5902 | /* Called from ssl3_SendClientKeyExchange(). */ |
5903 | /* Presently, this always uses PKCS11. There is no bypass for this. */ |
5904 | static SECStatus |
5905 | sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
5906 | { |
5907 | PK11SymKey * pms = NULL((void*)0); |
5908 | SECStatus rv = SECFailure; |
5909 | PRBool isTLS; |
5910 | CK_MECHANISM_TYPE target; |
5911 | |
5912 | SECKEYDHParams dhParam; /* DH parameters */ |
5913 | SECKEYPublicKey *pubKey = NULL((void*)0); /* Ephemeral DH key */ |
5914 | SECKEYPrivateKey *privKey = NULL((void*)0); /* Ephemeral DH key */ |
5915 | |
5916 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",5916)); |
5917 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",5917)); |
5918 | |
5919 | isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
5920 | |
5921 | /* Copy DH parameters from server key */ |
5922 | |
5923 | if (svrPubKey->keyType != dhKey) { |
5924 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY); |
5925 | goto loser; |
5926 | } |
5927 | dhParam.prime.data = svrPubKey->u.dh.prime.data; |
5928 | dhParam.prime.len = svrPubKey->u.dh.prime.len; |
5929 | dhParam.base.data = svrPubKey->u.dh.base.data; |
5930 | dhParam.base.len = svrPubKey->u.dh.base.len; |
5931 | |
5932 | /* Generate ephemeral DH keypair */ |
5933 | privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL((void*)0)); |
5934 | if (!privKey || !pubKey) { |
5935 | ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
5936 | rv = SECFailure; |
5937 | goto loser; |
5938 | } |
5939 | PRINT_BUF(50, (ss, "DH public value:",if (ssl_trace >= (50)) ssl_PrintBuf (ss, "DH public value:" , pubKey->u.dh.publicValue.data, pubKey->u.dh.publicValue .len) |
5940 | pubKey->u.dh.publicValue.data,if (ssl_trace >= (50)) ssl_PrintBuf (ss, "DH public value:" , pubKey->u.dh.publicValue.data, pubKey->u.dh.publicValue .len) |
5941 | pubKey->u.dh.publicValue.len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "DH public value:" , pubKey->u.dh.publicValue.data, pubKey->u.dh.publicValue .len); |
5942 | |
5943 | if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377; |
5944 | else target = CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373; |
5945 | |
5946 | /* Determine the PMS */ |
5947 | |
5948 | pms = PK11_PubDerive(privKey, svrPubKey, PR_FALSE0, NULL((void*)0), NULL((void*)0), |
5949 | CKM_DH_PKCS_DERIVE0x00000021, target, CKA_DERIVE0x0000010C, 0, NULL((void*)0)); |
5950 | |
5951 | if (pms == NULL((void*)0)) { |
5952 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
5953 | goto loser; |
5954 | } |
5955 | |
5956 | SECKEY_DestroyPrivateKey(privKey); |
5957 | privKey = NULL((void*)0); |
5958 | |
5959 | rv = ssl3_InitPendingCipherSpec(ss, pms); |
5960 | PK11_FreeSymKey(pms); pms = NULL((void*)0); |
5961 | |
5962 | if (rv != SECSuccess) { |
5963 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
5964 | goto loser; |
5965 | } |
5966 | |
5967 | rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, |
5968 | pubKey->u.dh.publicValue.len + 2); |
5969 | if (rv != SECSuccess) { |
5970 | goto loser; /* err set by ssl3_AppendHandshake* */ |
5971 | } |
5972 | rv = ssl3_AppendHandshakeVariable(ss, |
5973 | pubKey->u.dh.publicValue.data, |
5974 | pubKey->u.dh.publicValue.len, 2); |
5975 | SECKEY_DestroyPublicKey(pubKey); |
5976 | pubKey = NULL((void*)0); |
5977 | |
5978 | if (rv != SECSuccess) { |
5979 | goto loser; /* err set by ssl3_AppendHandshake* */ |
5980 | } |
5981 | |
5982 | rv = SECSuccess; |
5983 | |
5984 | |
5985 | loser: |
5986 | |
5987 | if(pms) PK11_FreeSymKey(pms); |
5988 | if(privKey) SECKEY_DestroyPrivateKey(privKey); |
5989 | if(pubKey) SECKEY_DestroyPublicKey(pubKey); |
5990 | return rv; |
5991 | } |
5992 | |
5993 | |
5994 | |
5995 | |
5996 | |
5997 | /* Called from ssl3_HandleServerHelloDone(). */ |
5998 | static SECStatus |
5999 | ssl3_SendClientKeyExchange(sslSocket *ss) |
6000 | { |
6001 | SECKEYPublicKey * serverKey = NULL((void*)0); |
6002 | SECStatus rv = SECFailure; |
6003 | PRBool isTLS; |
6004 | |
6005 | SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send client_key_exchange handshake" , getpid(), ss->fd) |
6006 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send client_key_exchange handshake" , getpid(), ss->fd); |
6007 | |
6008 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",6008)); |
6009 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",6009)); |
6010 | |
6011 | if (ss->sec.peerKey == NULL((void*)0)) { |
6012 | serverKey = CERT_ExtractPublicKey(ss->sec.peerCert); |
6013 | if (serverKey == NULL((void*)0)) { |
6014 | ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
6015 | return SECFailure; |
6016 | } |
6017 | } else { |
6018 | serverKey = ss->sec.peerKey; |
6019 | ss->sec.peerKey = NULL((void*)0); /* we're done with it now */ |
6020 | } |
6021 | |
6022 | isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
6023 | /* enforce limits on kea key sizes. */ |
6024 | if (ss->ssl3.hs.kea_def->is_limited) { |
6025 | int keyLen = SECKEY_PublicKeyStrength(serverKey); /* bytes */ |
6026 | |
6027 | if (keyLen * BPB8 > ss->ssl3.hs.kea_def->key_size_limit) { |
6028 | if (isTLS) |
6029 | (void)SSL3_SendAlert(ss, alert_fatal, export_restriction); |
6030 | else |
6031 | (void)ssl3_HandshakeFailure(ss); |
6032 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED); |
6033 | goto loser; |
6034 | } |
6035 | } |
6036 | |
6037 | ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType; |
6038 | ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey); |
6039 | |
6040 | switch (ss->ssl3.hs.kea_def->exchKeyType) { |
6041 | case kt_rsassl_kea_rsa: |
6042 | rv = sendRSAClientKeyExchange(ss, serverKey); |
6043 | break; |
6044 | |
6045 | case kt_dhssl_kea_dh: |
6046 | rv = sendDHClientKeyExchange(ss, serverKey); |
6047 | break; |
6048 | |
6049 | #ifdef NSS_ENABLE_ECC1 |
6050 | case kt_ecdhssl_kea_ecdh: |
6051 | rv = ssl3_SendECDHClientKeyExchange(ss, serverKey); |
6052 | break; |
6053 | #endif /* NSS_ENABLE_ECC */ |
6054 | |
6055 | default: |
6056 | /* got an unknown or unsupported Key Exchange Algorithm. */ |
6057 | SEND_ALERT |
6058 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_UNSUPPORTED_KEYALG); |
6059 | break; |
6060 | } |
6061 | |
6062 | SSL_TRC(3, ("%d: SSL3[%d]: DONE sending client_key_exchange",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: DONE sending client_key_exchange" , getpid(), ss->fd) |
6063 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: DONE sending client_key_exchange" , getpid(), ss->fd); |
6064 | |
6065 | loser: |
6066 | if (serverKey) |
6067 | SECKEY_DestroyPublicKey(serverKey); |
6068 | return rv; /* err code already set. */ |
6069 | } |
6070 | |
6071 | /* Called from ssl3_HandleServerHelloDone(). */ |
6072 | static SECStatus |
6073 | ssl3_SendCertificateVerify(sslSocket *ss) |
6074 | { |
6075 | SECStatus rv = SECFailure; |
6076 | PRBool isTLS; |
6077 | PRBool isTLS12; |
6078 | SECItem buf = {siBuffer, NULL((void*)0), 0}; |
6079 | SSL3Hashes hashes; |
6080 | KeyType keyType; |
6081 | unsigned int len; |
6082 | SSL3SignatureAndHashAlgorithm sigAndHash; |
6083 | |
6084 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",6084)); |
6085 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",6085)); |
6086 | |
6087 | SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate_verify handshake" , getpid(), ss->fd) |
6088 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate_verify handshake" , getpid(), ss->fd); |
6089 | |
6090 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; |
6091 | if (ss->ssl3.hs.hashType == handshake_hash_single && |
6092 | ss->ssl3.hs.backupHashmd5) { |
6093 | rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes); |
6094 | PORT_Assert(!ss->ssl3.hs.backupHash)((!ss->ssl3.hs.md5)?((void)0):PR_Assert("!ss->ssl3.hs.backupHash" ,"ssl3con.c",6094)); |
6095 | } else { |
6096 | rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); |
6097 | } |
6098 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
6099 | if (rv != SECSuccess) { |
6100 | goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ |
6101 | } |
6102 | |
6103 | isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
6104 | isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
6105 | keyType = ss->ssl3.clientPrivateKey->keyType; |
6106 | rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS); |
6107 | if (rv == SECSuccess) { |
6108 | PK11SlotInfo * slot; |
6109 | sslSessionID * sid = ss->sec.ci.sid; |
6110 | |
6111 | /* Remember the info about the slot that did the signing. |
6112 | ** Later, when doing an SSL restart handshake, verify this. |
6113 | ** These calls are mere accessors, and can't fail. |
6114 | */ |
6115 | slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey); |
6116 | sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot); |
6117 | sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot); |
6118 | sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot); |
6119 | sid->u.ssl3.clAuthValid = PR_TRUE1; |
6120 | PK11_FreeSlot(slot); |
6121 | } |
6122 | SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
6123 | ss->ssl3.clientPrivateKey = NULL((void*)0); |
6124 | if (rv != SECSuccess) { |
6125 | goto done; /* err code was set by ssl3_SignHashes */ |
6126 | } |
6127 | |
6128 | len = buf.len + 2 + (isTLS12 ? 2 : 0); |
6129 | |
6130 | rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); |
6131 | if (rv != SECSuccess) { |
6132 | goto done; /* error code set by AppendHandshake */ |
6133 | } |
6134 | if (isTLS12) { |
6135 | rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, |
6136 | &sigAndHash.sigAlg); |
6137 | if (rv != SECSuccess) { |
6138 | goto done; |
6139 | } |
6140 | sigAndHash.hashAlg = hashes.hashAlg; |
6141 | |
6142 | rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
6143 | if (rv != SECSuccess) { |
6144 | goto done; /* err set by AppendHandshake. */ |
6145 | } |
6146 | } |
6147 | rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2); |
6148 | if (rv != SECSuccess) { |
6149 | goto done; /* error code set by AppendHandshake */ |
6150 | } |
6151 | |
6152 | done: |
6153 | if (buf.data) |
6154 | PORT_FreePORT_Free_Util(buf.data); |
6155 | return rv; |
6156 | } |
6157 | |
6158 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
6159 | * ssl3 ServerHello message. |
6160 | * Caller must hold Handshake and RecvBuf locks. |
6161 | */ |
6162 | static SECStatus |
6163 | ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
6164 | { |
6165 | sslSessionID *sid = ss->sec.ci.sid; |
6166 | PRInt32 temp; /* allow for consume number failure */ |
6167 | PRBool suite_found = PR_FALSE0; |
6168 | int i; |
6169 | int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; |
6170 | SECStatus rv; |
6171 | SECItem sidBytes = {siBuffer, NULL((void*)0), 0}; |
6172 | PRBool sid_match; |
6173 | PRBool isTLS = PR_FALSE0; |
6174 | SSL3AlertDescription desc = illegal_parameter; |
6175 | SSL3ProtocolVersion version; |
6176 | |
6177 | SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle server_hello handshake" , getpid(), ss->fd) |
6178 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle server_hello handshake" , getpid(), ss->fd); |
6179 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",6179)); |
6180 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",6180)); |
6181 | PORT_Assert( ss->ssl3.initialized )((ss->ssl3.initialized)?((void)0):PR_Assert("ss->ssl3.initialized" ,"ssl3con.c",6181)); |
6182 | |
6183 | if (ss->ssl3.hs.ws != wait_server_hello) { |
6184 | errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO; |
6185 | desc = unexpected_message; |
6186 | goto alert_loser; |
6187 | } |
6188 | |
6189 | /* clean up anything left from previous handshake. */ |
6190 | if (ss->ssl3.clientCertChain != NULL((void*)0)) { |
6191 | CERT_DestroyCertificateList(ss->ssl3.clientCertChain); |
6192 | ss->ssl3.clientCertChain = NULL((void*)0); |
6193 | } |
6194 | if (ss->ssl3.clientCertificate != NULL((void*)0)) { |
6195 | CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
6196 | ss->ssl3.clientCertificate = NULL((void*)0); |
6197 | } |
6198 | if (ss->ssl3.clientPrivateKey != NULL((void*)0)) { |
6199 | SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
6200 | ss->ssl3.clientPrivateKey = NULL((void*)0); |
6201 | } |
6202 | |
6203 | temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
6204 | if (temp < 0) { |
6205 | goto loser; /* alert has been sent */ |
6206 | } |
6207 | version = (SSL3ProtocolVersion)temp; |
6208 | |
6209 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
6210 | /* RFC 4347 required that you verify that the server versions |
6211 | * match (Section 4.2.1) in the HelloVerifyRequest and the |
6212 | * ServerHello. |
6213 | * |
6214 | * RFC 6347 suggests (SHOULD) that servers always use 1.0 |
6215 | * in HelloVerifyRequest and allows the versions not to match, |
6216 | * especially when 1.2 is being negotiated. |
6217 | * |
6218 | * Therefore we do not check for matching here. |
6219 | */ |
6220 | version = dtls_DTLSVersionToTLSVersion(version); |
6221 | if (version == 0) { /* Insane version number */ |
6222 | goto alert_loser; |
6223 | } |
6224 | } |
6225 | |
6226 | rv = ssl3_NegotiateVersion(ss, version, PR_FALSE0); |
6227 | if (rv != SECSuccess) { |
6228 | desc = (version > SSL_LIBRARY_VERSION_3_00x0300) ? protocol_version |
6229 | : handshake_failure; |
6230 | errCode = SSL_ERROR_NO_CYPHER_OVERLAP; |
6231 | goto alert_loser; |
6232 | } |
6233 | isTLS = (ss->version > SSL_LIBRARY_VERSION_3_00x0300); |
6234 | |
6235 | rv = ssl3_InitHandshakeHashes(ss); |
6236 | if (rv != SECSuccess) { |
6237 | desc = internal_error; |
6238 | errCode = PORT_GetErrorPORT_GetError_Util(); |
6239 | goto alert_loser; |
6240 | } |
6241 | |
6242 | rv = ssl3_ConsumeHandshake( |
6243 | ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH32, &b, &length); |
6244 | if (rv != SECSuccess) { |
6245 | goto loser; /* alert has been sent */ |
6246 | } |
6247 | |
6248 | rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length); |
6249 | if (rv != SECSuccess) { |
6250 | goto loser; /* alert has been sent */ |
6251 | } |
6252 | if (sidBytes.len > SSL3_SESSIONID_BYTES32) { |
6253 | if (isTLS) |
6254 | desc = decode_error; |
6255 | goto alert_loser; /* malformed. */ |
6256 | } |
6257 | |
6258 | /* find selected cipher suite in our list. */ |
6259 | temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
6260 | if (temp < 0) { |
6261 | goto loser; /* alert has been sent */ |
6262 | } |
6263 | ssl3_config_match_init(ss); |
6264 | for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED61; i++) { |
6265 | ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; |
6266 | if (temp == suite->cipher_suite) { |
6267 | SSLVersionRange vrange = {ss->version, ss->version}; |
6268 | if (!config_match(suite, ss->ssl3.policy, PR_TRUE1, &vrange)) { |
6269 | /* config_match already checks whether the cipher suite is |
6270 | * acceptable for the version, but the check is repeated here |
6271 | * in order to give a more precise error code. */ |
6272 | if (!ssl3_CipherSuiteAllowedForVersionRange(temp, &vrange)) { |
6273 | desc = handshake_failure; |
6274 | errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION; |
6275 | goto alert_loser; |
6276 | } |
6277 | |
6278 | break; /* failure */ |
6279 | } |
6280 | |
6281 | suite_found = PR_TRUE1; |
6282 | break; /* success */ |
6283 | } |
6284 | } |
6285 | if (!suite_found) { |
6286 | desc = handshake_failure; |
6287 | errCode = SSL_ERROR_NO_CYPHER_OVERLAP; |
6288 | goto alert_loser; |
6289 | } |
6290 | ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp; |
6291 | ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp); |
6292 | PORT_Assert(ss->ssl3.hs.suite_def)((ss->ssl3.hs.suite_def)?((void)0):PR_Assert("ss->ssl3.hs.suite_def" ,"ssl3con.c",6292)); |
6293 | if (!ss->ssl3.hs.suite_def) { |
6294 | PORT_SetErrorPORT_SetError_Util(errCode = SEC_ERROR_LIBRARY_FAILURE); |
6295 | goto loser; /* we don't send alerts for our screw-ups. */ |
6296 | } |
6297 | |
6298 | /* find selected compression method in our list. */ |
6299 | temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length); |
6300 | if (temp < 0) { |
6301 | goto loser; /* alert has been sent */ |
6302 | } |
6303 | suite_found = PR_FALSE0; |
6304 | for (i = 0; i < compressionMethodsCount; i++) { |
6305 | if (temp == compressions[i]) { |
6306 | if (!compressionEnabled(ss, compressions[i])) { |
6307 | break; /* failure */ |
6308 | } |
6309 | suite_found = PR_TRUE1; |
6310 | break; /* success */ |
6311 | } |
6312 | } |
6313 | if (!suite_found) { |
6314 | desc = handshake_failure; |
6315 | errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP; |
6316 | goto alert_loser; |
6317 | } |
6318 | ss->ssl3.hs.compression = (SSLCompressionMethod)temp; |
6319 | |
6320 | /* Note that if !isTLS and the extra stuff is not extensions, we |
6321 | * do NOT goto alert_loser. |
6322 | * There are some old SSL 3.0 implementations that do send stuff |
6323 | * after the end of the server hello, and we deliberately ignore |
6324 | * such stuff in the interest of maximal interoperability (being |
6325 | * "generous in what you accept"). |
6326 | * Update: Starting in NSS 3.12.6, we handle the renegotiation_info |
6327 | * extension in SSL 3.0. |
6328 | */ |
6329 | if (length != 0) { |
6330 | SECItem extensions; |
6331 | rv = ssl3_ConsumeHandshakeVariable(ss, &extensions, 2, &b, &length); |
6332 | if (rv != SECSuccess || length != 0) { |
6333 | if (isTLS) |
6334 | goto alert_loser; |
6335 | } else { |
6336 | rv = ssl3_HandleHelloExtensions(ss, &extensions.data, |
6337 | &extensions.len); |
6338 | if (rv != SECSuccess) |
6339 | goto alert_loser; |
6340 | } |
6341 | } |
6342 | if ((ss->opt.requireSafeNegotiation || |
6343 | (ss->firstHsDone && (ss->peerRequestedProtection || |
6344 | ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN((PRBool)2)))) && |
6345 | !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { |
6346 | desc = handshake_failure; |
6347 | errCode = ss->firstHsDone ? SSL_ERROR_RENEGOTIATION_NOT_ALLOWED |
6348 | : SSL_ERROR_UNSAFE_NEGOTIATION; |
6349 | goto alert_loser; |
6350 | } |
6351 | |
6352 | /* Any errors after this point are not "malformed" errors. */ |
6353 | desc = handshake_failure; |
6354 | |
6355 | /* we need to call ssl3_SetupPendingCipherSpec here so we can check the |
6356 | * key exchange algorithm. */ |
6357 | rv = ssl3_SetupPendingCipherSpec(ss); |
6358 | if (rv != SECSuccess) { |
6359 | goto alert_loser; /* error code is set. */ |
6360 | } |
6361 | |
6362 | /* We may or may not have sent a session id, we may get one back or |
6363 | * not and if so it may match the one we sent. |
6364 | * Attempt to restore the master secret to see if this is so... |
6365 | * Don't consider failure to find a matching SID an error. |
6366 | */ |
6367 | sid_match = (PRBool)(sidBytes.len > 0 && |
6368 | sidBytes.len == sid->u.ssl3.sessionIDLength && |
6369 | !PORT_Memcmpmemcmp(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len)); |
6370 | |
6371 | if (sid_match && |
6372 | sid->version == ss->version && |
6373 | sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do { |
6374 | ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec; |
6375 | |
6376 | SECItem wrappedMS; /* wrapped master secret. */ |
6377 | |
6378 | ss->sec.authAlgorithm = sid->authAlgorithm; |
6379 | ss->sec.authKeyBits = sid->authKeyBits; |
6380 | ss->sec.keaType = sid->keaType; |
6381 | ss->sec.keaKeyBits = sid->keaKeyBits; |
6382 | |
6383 | /* 3 cases here: |
6384 | * a) key is wrapped (implies using PKCS11) |
6385 | * b) key is unwrapped, but we're still using PKCS11 |
6386 | * c) key is unwrapped, and we're bypassing PKCS11. |
6387 | */ |
6388 | if (sid->u.ssl3.keys.msIsWrapped) { |
6389 | PK11SlotInfo *slot; |
6390 | PK11SymKey * wrapKey; /* wrapping key */ |
6391 | CK_FLAGS keyFlags = 0; |
6392 | |
6393 | #ifndef NO_PKCS11_BYPASS1 |
6394 | if (ss->opt.bypassPKCS11) { |
6395 | /* we cannot restart a non-bypass session in a |
6396 | ** bypass socket. |
6397 | */ |
6398 | break; |
6399 | } |
6400 | #endif |
6401 | /* unwrap master secret with PKCS11 */ |
6402 | slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID, |
6403 | sid->u.ssl3.masterSlotID); |
6404 | if (slot == NULL((void*)0)) { |
6405 | break; /* not considered an error. */ |
6406 | } |
6407 | if (!PK11_IsPresent(slot)) { |
6408 | PK11_FreeSlot(slot); |
6409 | break; /* not considered an error. */ |
6410 | } |
6411 | wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex, |
6412 | sid->u.ssl3.masterWrapMech, |
6413 | sid->u.ssl3.masterWrapSeries, |
6414 | ss->pkcs11PinArg); |
6415 | PK11_FreeSlot(slot); |
6416 | if (wrapKey == NULL((void*)0)) { |
6417 | break; /* not considered an error. */ |
6418 | } |
6419 | |
6420 | if (ss->version > SSL_LIBRARY_VERSION_3_00x0300) { /* isTLS */ |
6421 | keyFlags = CKF_SIGN0x00000800 | CKF_VERIFY0x00002000; |
6422 | } |
6423 | |
6424 | wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; |
6425 | wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; |
6426 | pwSpec->master_secret = |
6427 | PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, |
6428 | NULL((void*)0), &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE0x00000371, |
6429 | CKA_DERIVE0x0000010C, sizeof(SSL3MasterSecret), keyFlags); |
6430 | errCode = PORT_GetErrorPORT_GetError_Util(); |
6431 | PK11_FreeSymKey(wrapKey); |
6432 | if (pwSpec->master_secret == NULL((void*)0)) { |
6433 | break; /* errorCode set just after call to UnwrapSymKey. */ |
6434 | } |
6435 | #ifndef NO_PKCS11_BYPASS1 |
6436 | } else if (ss->opt.bypassPKCS11) { |
6437 | /* MS is not wrapped */ |
6438 | wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; |
6439 | wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; |
6440 | memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len); |
6441 | pwSpec->msItem.data = pwSpec->raw_master_secret; |
6442 | pwSpec->msItem.len = wrappedMS.len; |
6443 | #endif |
6444 | } else { |
6445 | /* We CAN restart a bypass session in a non-bypass socket. */ |
6446 | /* need to import the raw master secret to session object */ |
6447 | PK11SlotInfo *slot = PK11_GetInternalSlot(); |
6448 | wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; |
6449 | wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; |
6450 | pwSpec->master_secret = |
6451 | PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE0x00000371, |
6452 | PK11_OriginUnwrap, CKA_ENCRYPT0x00000104, |
6453 | &wrappedMS, NULL((void*)0)); |
6454 | PK11_FreeSlot(slot); |
6455 | if (pwSpec->master_secret == NULL((void*)0)) { |
6456 | break; |
6457 | } |
6458 | } |
6459 | |
6460 | /* Got a Match */ |
6461 | SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits ); |
6462 | |
6463 | /* If we sent a session ticket, then this is a stateless resume. */ |
6464 | if (ss->xtnData.sentSessionTicketInClientHello) |
6465 | SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes ); |
6466 | |
6467 | if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) |
6468 | ss->ssl3.hs.ws = wait_new_session_ticket; |
6469 | else |
6470 | ss->ssl3.hs.ws = wait_change_cipher; |
6471 | |
6472 | ss->ssl3.hs.isResuming = PR_TRUE1; |
6473 | |
6474 | /* copy the peer cert from the SID */ |
6475 | if (sid->peerCert != NULL((void*)0)) { |
6476 | ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
6477 | } |
6478 | |
6479 | /* NULL value for PMS signifies re-use of the old MS */ |
6480 | rv = ssl3_InitPendingCipherSpec(ss, NULL((void*)0)); |
6481 | if (rv != SECSuccess) { |
6482 | goto alert_loser; /* err code was set */ |
6483 | } |
6484 | return SECSuccess; |
6485 | } while (0); |
6486 | |
6487 | if (sid_match) |
6488 | SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok ); |
6489 | else |
6490 | SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses ); |
6491 | |
6492 | /* throw the old one away */ |
6493 | sid->u.ssl3.keys.resumable = PR_FALSE0; |
6494 | if (ss->sec.uncache) |
6495 | (*ss->sec.uncache)(sid); |
6496 | ssl_FreeSID(sid); |
6497 | |
6498 | /* get a new sid */ |
6499 | ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE0); |
6500 | if (sid == NULL((void*)0)) { |
6501 | goto alert_loser; /* memory error is set. */ |
6502 | } |
6503 | |
6504 | sid->version = ss->version; |
6505 | sid->u.ssl3.sessionIDLength = sidBytes.len; |
6506 | PORT_Memcpymemcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len); |
6507 | |
6508 | ss->ssl3.hs.isResuming = PR_FALSE0; |
6509 | ss->ssl3.hs.ws = wait_server_cert; |
6510 | return SECSuccess; |
6511 | |
6512 | alert_loser: |
6513 | (void)SSL3_SendAlert(ss, alert_fatal, desc); |
6514 | |
6515 | loser: |
6516 | errCode = ssl_MapLowLevelError(errCode); |
6517 | return SECFailure; |
6518 | } |
6519 | |
6520 | /* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned, |
6521 | * big-endian integer is > 1 */ |
6522 | static PRBool |
6523 | ssl3_BigIntGreaterThanOne(const SECItem* mpint) { |
6524 | unsigned char firstNonZeroByte = 0; |
6525 | unsigned int i; |
6526 | |
6527 | for (i = 0; i < mpint->len; i++) { |
6528 | if (mpint->data[i]) { |
6529 | firstNonZeroByte = mpint->data[i]; |
6530 | break; |
6531 | } |
6532 | } |
6533 | |
6534 | if (firstNonZeroByte == 0) |
6535 | return PR_FALSE0; |
6536 | if (firstNonZeroByte > 1) |
6537 | return PR_TRUE1; |
6538 | |
6539 | /* firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte |
6540 | * is followed by another byte. */ |
6541 | return (i < mpint->len - 1); |
6542 | } |
6543 | |
6544 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
6545 | * ssl3 ServerKeyExchange message. |
6546 | * Caller must hold Handshake and RecvBuf locks. |
6547 | */ |
6548 | static SECStatus |
6549 | ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
6550 | { |
6551 | PLArenaPool * arena = NULL((void*)0); |
6552 | SECKEYPublicKey *peerKey = NULL((void*)0); |
6553 | PRBool isTLS, isTLS12; |
6554 | SECStatus rv; |
6555 | int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH; |
6556 | SSL3AlertDescription desc = illegal_parameter; |
6557 | SSL3Hashes hashes; |
6558 | SECItem signature = {siBuffer, NULL((void*)0), 0}; |
6559 | SSL3SignatureAndHashAlgorithm sigAndHash; |
6560 | |
6561 | sigAndHash.hashAlg = SEC_OID_UNKNOWN; |
6562 | |
6563 | SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle server_key_exchange handshake" , getpid(), ss->fd) |
6564 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle server_key_exchange handshake" , getpid(), ss->fd); |
6565 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",6565)); |
6566 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",6566)); |
6567 | |
6568 | if (ss->ssl3.hs.ws != wait_server_key && |
6569 | ss->ssl3.hs.ws != wait_server_cert) { |
6570 | errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; |
6571 | desc = unexpected_message; |
6572 | goto alert_loser; |
6573 | } |
6574 | if (ss->sec.peerCert == NULL((void*)0)) { |
6575 | errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; |
6576 | desc = unexpected_message; |
6577 | goto alert_loser; |
6578 | } |
6579 | |
6580 | isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
6581 | isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
6582 | |
6583 | switch (ss->ssl3.hs.kea_def->exchKeyType) { |
6584 | |
6585 | case kt_rsassl_kea_rsa: { |
6586 | SECItem modulus = {siBuffer, NULL((void*)0), 0}; |
6587 | SECItem exponent = {siBuffer, NULL((void*)0), 0}; |
6588 | |
6589 | rv = ssl3_ConsumeHandshakeVariable(ss, &modulus, 2, &b, &length); |
6590 | if (rv != SECSuccess) { |
6591 | goto loser; /* malformed. */ |
6592 | } |
6593 | rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length); |
6594 | if (rv != SECSuccess) { |
6595 | goto loser; /* malformed. */ |
6596 | } |
6597 | if (isTLS12) { |
6598 | rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
6599 | &sigAndHash); |
6600 | if (rv != SECSuccess) { |
6601 | goto loser; /* malformed or unsupported. */ |
6602 | } |
6603 | rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
6604 | &sigAndHash, ss->sec.peerCert); |
6605 | if (rv != SECSuccess) { |
6606 | goto loser; |
6607 | } |
6608 | } |
6609 | rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
6610 | if (rv != SECSuccess) { |
6611 | goto loser; /* malformed. */ |
6612 | } |
6613 | if (length != 0) { |
6614 | if (isTLS) |
6615 | desc = decode_error; |
6616 | goto alert_loser; /* malformed. */ |
6617 | } |
6618 | |
6619 | /* failures after this point are not malformed handshakes. */ |
6620 | /* TLS: send decrypt_error if signature failed. */ |
6621 | desc = isTLS ? decrypt_error : handshake_failure; |
6622 | |
6623 | /* |
6624 | * check to make sure the hash is signed by right guy |
6625 | */ |
6626 | rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent, |
6627 | &ss->ssl3.hs.client_random, |
6628 | &ss->ssl3.hs.server_random, |
6629 | &hashes, ss->opt.bypassPKCS11); |
6630 | if (rv != SECSuccess) { |
6631 | errCode = |
6632 | ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
6633 | goto alert_loser; |
6634 | } |
6635 | rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, |
6636 | isTLS, ss->pkcs11PinArg); |
6637 | if (rv != SECSuccess) { |
6638 | errCode = |
6639 | ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
6640 | goto alert_loser; |
6641 | } |
6642 | |
6643 | /* |
6644 | * we really need to build a new key here because we can no longer |
6645 | * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate |
6646 | * pkcs11 slots and ID's. |
6647 | */ |
6648 | arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); |
6649 | if (arena == NULL((void*)0)) { |
6650 | goto no_memory; |
6651 | } |
6652 | |
6653 | peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey)(SECKEYPublicKey*) PORT_ArenaZAlloc_Util(arena, sizeof(SECKEYPublicKey )); |
6654 | if (peerKey == NULL((void*)0)) { |
6655 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
6656 | goto no_memory; |
6657 | } |
6658 | |
6659 | peerKey->arena = arena; |
6660 | peerKey->keyType = rsaKey; |
6661 | peerKey->pkcs11Slot = NULL((void*)0); |
6662 | peerKey->pkcs11ID = CK_INVALID_HANDLE0; |
6663 | if (SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &peerKey->u.rsa.modulus, &modulus) || |
6664 | SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &peerKey->u.rsa.publicExponent, &exponent)) |
6665 | { |
6666 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
6667 | goto no_memory; |
6668 | } |
6669 | ss->sec.peerKey = peerKey; |
6670 | ss->ssl3.hs.ws = wait_cert_request; |
6671 | return SECSuccess; |
6672 | } |
6673 | |
6674 | case kt_dhssl_kea_dh: { |
6675 | SECItem dh_p = {siBuffer, NULL((void*)0), 0}; |
6676 | SECItem dh_g = {siBuffer, NULL((void*)0), 0}; |
6677 | SECItem dh_Ys = {siBuffer, NULL((void*)0), 0}; |
6678 | |
6679 | rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length); |
6680 | if (rv != SECSuccess) { |
6681 | goto loser; /* malformed. */ |
6682 | } |
6683 | if (dh_p.len < 512/8) { |
6684 | errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY; |
6685 | goto alert_loser; |
6686 | } |
6687 | rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length); |
6688 | if (rv != SECSuccess) { |
6689 | goto loser; /* malformed. */ |
6690 | } |
6691 | if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g)) |
6692 | goto alert_loser; |
6693 | rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length); |
6694 | if (rv != SECSuccess) { |
6695 | goto loser; /* malformed. */ |
6696 | } |
6697 | if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys)) |
6698 | goto alert_loser; |
6699 | if (isTLS12) { |
6700 | rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
6701 | &sigAndHash); |
6702 | if (rv != SECSuccess) { |
6703 | goto loser; /* malformed or unsupported. */ |
6704 | } |
6705 | rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
6706 | &sigAndHash, ss->sec.peerCert); |
6707 | if (rv != SECSuccess) { |
6708 | goto loser; |
6709 | } |
6710 | } |
6711 | rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
6712 | if (rv != SECSuccess) { |
6713 | goto loser; /* malformed. */ |
6714 | } |
6715 | if (length != 0) { |
6716 | if (isTLS) |
6717 | desc = decode_error; |
6718 | goto alert_loser; /* malformed. */ |
6719 | } |
6720 | |
6721 | PRINT_BUF(60, (NULL, "Server DH p", dh_p.data, dh_p.len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "Server DH p" , dh_p.data, dh_p.len); |
6722 | PRINT_BUF(60, (NULL, "Server DH g", dh_g.data, dh_g.len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "Server DH g" , dh_g.data, dh_g.len); |
6723 | PRINT_BUF(60, (NULL, "Server DH Ys", dh_Ys.data, dh_Ys.len))if (ssl_trace >= (60)) ssl_PrintBuf (((void*)0), "Server DH Ys" , dh_Ys.data, dh_Ys.len); |
6724 | |
6725 | /* failures after this point are not malformed handshakes. */ |
6726 | /* TLS: send decrypt_error if signature failed. */ |
6727 | desc = isTLS ? decrypt_error : handshake_failure; |
6728 | |
6729 | /* |
6730 | * check to make sure the hash is signed by right guy |
6731 | */ |
6732 | rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys, |
6733 | &ss->ssl3.hs.client_random, |
6734 | &ss->ssl3.hs.server_random, |
6735 | &hashes, ss->opt.bypassPKCS11); |
6736 | if (rv != SECSuccess) { |
6737 | errCode = |
6738 | ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
6739 | goto alert_loser; |
6740 | } |
6741 | rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, |
6742 | isTLS, ss->pkcs11PinArg); |
6743 | if (rv != SECSuccess) { |
6744 | errCode = |
6745 | ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
6746 | goto alert_loser; |
6747 | } |
6748 | |
6749 | /* |
6750 | * we really need to build a new key here because we can no longer |
6751 | * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate |
6752 | * pkcs11 slots and ID's. |
6753 | */ |
6754 | arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); |
6755 | if (arena == NULL((void*)0)) { |
6756 | goto no_memory; |
6757 | } |
6758 | |
6759 | ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey)(SECKEYPublicKey*) PORT_ArenaZAlloc_Util(arena, sizeof(SECKEYPublicKey )); |
6760 | if (peerKey == NULL((void*)0)) { |
6761 | goto no_memory; |
6762 | } |
6763 | |
6764 | peerKey->arena = arena; |
6765 | peerKey->keyType = dhKey; |
6766 | peerKey->pkcs11Slot = NULL((void*)0); |
6767 | peerKey->pkcs11ID = CK_INVALID_HANDLE0; |
6768 | |
6769 | if (SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &peerKey->u.dh.prime, &dh_p) || |
6770 | SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &peerKey->u.dh.base, &dh_g) || |
6771 | SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &peerKey->u.dh.publicValue, &dh_Ys)) |
6772 | { |
6773 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
6774 | goto no_memory; |
6775 | } |
6776 | ss->sec.peerKey = peerKey; |
6777 | ss->ssl3.hs.ws = wait_cert_request; |
6778 | return SECSuccess; |
6779 | } |
6780 | |
6781 | #ifdef NSS_ENABLE_ECC1 |
6782 | case kt_ecdhssl_kea_ecdh: |
6783 | rv = ssl3_HandleECDHServerKeyExchange(ss, b, length); |
6784 | return rv; |
6785 | #endif /* NSS_ENABLE_ECC */ |
6786 | |
6787 | default: |
6788 | desc = handshake_failure; |
6789 | errCode = SEC_ERROR_UNSUPPORTED_KEYALG; |
6790 | break; /* goto alert_loser; */ |
6791 | } |
6792 | |
6793 | alert_loser: |
6794 | (void)SSL3_SendAlert(ss, alert_fatal, desc); |
6795 | loser: |
6796 | PORT_SetErrorPORT_SetError_Util( errCode ); |
6797 | return SECFailure; |
6798 | |
6799 | no_memory: /* no-memory error has already been set. */ |
6800 | ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
6801 | return SECFailure; |
6802 | } |
6803 | |
6804 | |
6805 | /* |
6806 | * Returns the TLS signature algorithm for the client authentication key and |
6807 | * whether it is an RSA or DSA key that may be able to sign only SHA-1 hashes. |
6808 | */ |
6809 | static SECStatus |
6810 | ssl3_ExtractClientKeyInfo(sslSocket *ss, |
6811 | TLSSignatureAlgorithm *sigAlg, |
6812 | PRBool *preferSha1) |
6813 | { |
6814 | SECStatus rv = SECSuccess; |
6815 | SECKEYPublicKey *pubk; |
6816 | |
6817 | pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); |
6818 | if (pubk == NULL((void*)0)) { |
6819 | rv = SECFailure; |
6820 | goto done; |
6821 | } |
6822 | |
6823 | rv = ssl3_TLSSignatureAlgorithmForKeyType(pubk->keyType, sigAlg); |
6824 | if (rv != SECSuccess) { |
6825 | goto done; |
6826 | } |
6827 | |
6828 | /* If the key is a 1024-bit RSA or DSA key, assume conservatively that |
6829 | * it may be unable to sign SHA-256 hashes. This is the case for older |
6830 | * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and |
6831 | * older, DSA key size is at most 1024 bits and the hash function must |
6832 | * be SHA-1. |
6833 | */ |
6834 | if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) { |
6835 | *preferSha1 = SECKEY_PublicKeyStrength(pubk) <= 128; |
6836 | } else { |
6837 | *preferSha1 = PR_FALSE0; |
6838 | } |
6839 | |
6840 | done: |
6841 | if (pubk) |
6842 | SECKEY_DestroyPublicKey(pubk); |
6843 | return rv; |
6844 | } |
6845 | |
6846 | /* Destroys the backup handshake hash context if we don't need it. Note that |
6847 | * this function selects the hash algorithm for client authentication |
6848 | * signatures; ssl3_SendCertificateVerify uses the presence of the backup hash |
6849 | * to determine whether to use SHA-1 or SHA-256. */ |
6850 | static void |
6851 | ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss, |
6852 | const SECItem *algorithms) |
6853 | { |
6854 | SECStatus rv; |
6855 | TLSSignatureAlgorithm sigAlg; |
6856 | PRBool preferSha1; |
6857 | PRBool supportsSha1 = PR_FALSE0; |
6858 | PRBool supportsSha256 = PR_FALSE0; |
6859 | PRBool needBackupHash = PR_FALSE0; |
6860 | unsigned int i; |
6861 | |
6862 | #ifndef NO_PKCS11_BYPASS1 |
6863 | /* Backup handshake hash is not supported in PKCS #11 bypass mode. */ |
6864 | if (ss->opt.bypassPKCS11) { |
6865 | PORT_Assert(!ss->ssl3.hs.backupHash)((!ss->ssl3.hs.md5)?((void)0):PR_Assert("!ss->ssl3.hs.backupHash" ,"ssl3con.c",6865)); |
6866 | return; |
6867 | } |
6868 | #endif |
6869 | PORT_Assert(ss->ssl3.hs.backupHash)((ss->ssl3.hs.md5)?((void)0):PR_Assert("ss->ssl3.hs.backupHash" ,"ssl3con.c",6869)); |
6870 | |
6871 | /* Determine the key's signature algorithm and whether it prefers SHA-1. */ |
6872 | rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1); |
6873 | if (rv != SECSuccess) { |
6874 | goto done; |
6875 | } |
6876 | |
6877 | /* Determine the server's hash support for that signature algorithm. */ |
6878 | for (i = 0; i < algorithms->len; i += 2) { |
6879 | if (algorithms->data[i+1] == sigAlg) { |
6880 | if (algorithms->data[i] == tls_hash_sha1) { |
6881 | supportsSha1 = PR_TRUE1; |
6882 | } else if (algorithms->data[i] == tls_hash_sha256) { |
6883 | supportsSha256 = PR_TRUE1; |
6884 | } |
6885 | } |
6886 | } |
6887 | |
6888 | /* If either the server does not support SHA-256 or the client key prefers |
6889 | * SHA-1, leave the backup hash. */ |
6890 | if (supportsSha1 && (preferSha1 || !supportsSha256)) { |
6891 | needBackupHash = PR_TRUE1; |
6892 | } |
6893 | |
6894 | done: |
6895 | if (!needBackupHash) { |
6896 | PK11_DestroyContext(ss->ssl3.hs.backupHashmd5, PR_TRUE1); |
6897 | ss->ssl3.hs.backupHashmd5 = NULL((void*)0); |
6898 | } |
6899 | } |
6900 | |
6901 | typedef struct dnameNode { |
6902 | struct dnameNode *next; |
6903 | SECItem name; |
6904 | } dnameNode; |
6905 | |
6906 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
6907 | * ssl3 Certificate Request message. |
6908 | * Caller must hold Handshake and RecvBuf locks. |
6909 | */ |
6910 | static SECStatus |
6911 | ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
6912 | { |
6913 | PLArenaPool * arena = NULL((void*)0); |
6914 | dnameNode * node; |
6915 | PRInt32 remaining; |
6916 | PRBool isTLS = PR_FALSE0; |
6917 | PRBool isTLS12 = PR_FALSE0; |
6918 | int i; |
6919 | int errCode = SSL_ERROR_RX_MALFORMED_CERT_REQUEST; |
6920 | int nnames = 0; |
6921 | SECStatus rv; |
6922 | SSL3AlertDescription desc = illegal_parameter; |
6923 | SECItem cert_types = {siBuffer, NULL((void*)0), 0}; |
6924 | SECItem algorithms = {siBuffer, NULL((void*)0), 0}; |
6925 | CERTDistNames ca_list; |
6926 | |
6927 | SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle certificate_request handshake" , getpid(), ss->fd) |
6928 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle certificate_request handshake" , getpid(), ss->fd); |
6929 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",6929)); |
6930 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",6930)); |
6931 | |
6932 | if (ss->ssl3.hs.ws != wait_cert_request && |
6933 | ss->ssl3.hs.ws != wait_server_key) { |
6934 | desc = unexpected_message; |
6935 | errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST; |
6936 | goto alert_loser; |
6937 | } |
6938 | |
6939 | PORT_Assert(ss->ssl3.clientCertChain == NULL)((ss->ssl3.clientCertChain == ((void*)0))?((void)0):PR_Assert ("ss->ssl3.clientCertChain == NULL","ssl3con.c",6939)); |
6940 | PORT_Assert(ss->ssl3.clientCertificate == NULL)((ss->ssl3.clientCertificate == ((void*)0))?((void)0):PR_Assert ("ss->ssl3.clientCertificate == NULL","ssl3con.c",6940)); |
6941 | PORT_Assert(ss->ssl3.clientPrivateKey == NULL)((ss->ssl3.clientPrivateKey == ((void*)0))?((void)0):PR_Assert ("ss->ssl3.clientPrivateKey == NULL","ssl3con.c",6941)); |
6942 | |
6943 | isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
6944 | isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
6945 | rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length); |
6946 | if (rv != SECSuccess) |
6947 | goto loser; /* malformed, alert has been sent */ |
6948 | |
6949 | if (isTLS12) { |
6950 | rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &b, &length); |
6951 | if (rv != SECSuccess) |
6952 | goto loser; /* malformed, alert has been sent */ |
6953 | /* An empty or odd-length value is invalid. |
6954 | * SignatureAndHashAlgorithm |
6955 | * supported_signature_algorithms<2..2^16-2>; |
6956 | */ |
6957 | if (algorithms.len == 0 || (algorithms.len & 1) != 0) |
6958 | goto alert_loser; |
6959 | } |
6960 | |
6961 | arena = ca_list.arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); |
6962 | if (arena == NULL((void*)0)) |
6963 | goto no_mem; |
6964 | |
6965 | remaining = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
6966 | if (remaining < 0) |
6967 | goto loser; /* malformed, alert has been sent */ |
6968 | |
6969 | if ((PRUint32)remaining > length) |
6970 | goto alert_loser; |
6971 | |
6972 | ca_list.head = node = PORT_ArenaZNew(arena, dnameNode)(dnameNode*) PORT_ArenaZAlloc_Util(arena, sizeof(dnameNode)); |
6973 | if (node == NULL((void*)0)) |
6974 | goto no_mem; |
6975 | |
6976 | while (remaining > 0) { |
6977 | PRInt32 len; |
6978 | |
6979 | if (remaining < 2) |
6980 | goto alert_loser; /* malformed */ |
6981 | |
6982 | node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
6983 | if (len <= 0) |
6984 | goto loser; /* malformed, alert has been sent */ |
6985 | |
6986 | remaining -= 2; |
6987 | if (remaining < len) |
6988 | goto alert_loser; /* malformed */ |
6989 | |
6990 | node->name.data = b; |
6991 | b += len; |
6992 | length -= len; |
6993 | remaining -= len; |
6994 | nnames++; |
6995 | if (remaining <= 0) |
6996 | break; /* success */ |
6997 | |
6998 | node->next = PORT_ArenaZNew(arena, dnameNode)(dnameNode*) PORT_ArenaZAlloc_Util(arena, sizeof(dnameNode)); |
6999 | node = node->next; |
7000 | if (node == NULL((void*)0)) |
7001 | goto no_mem; |
7002 | } |
7003 | |
7004 | ca_list.nnames = nnames; |
7005 | ca_list.names = PORT_ArenaNewArray(arena, SECItem, nnames)(SECItem*) PORT_ArenaAlloc_Util (arena, sizeof(SECItem)*(nnames )); |
7006 | if (nnames > 0 && ca_list.names == NULL((void*)0)) |
7007 | goto no_mem; |
7008 | |
7009 | for(i = 0, node = (dnameNode*)ca_list.head; |
7010 | i < nnames; |
7011 | i++, node = node->next) { |
7012 | ca_list.names[i] = node->name; |
7013 | } |
7014 | |
7015 | if (length != 0) |
7016 | goto alert_loser; /* malformed */ |
7017 | |
7018 | desc = no_certificate; |
7019 | ss->ssl3.hs.ws = wait_hello_done; |
7020 | |
7021 | if (ss->getClientAuthData != NULL((void*)0)) { |
7022 | /* XXX Should pass cert_types and algorithms in this call!! */ |
7023 | rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg, |
7024 | ss->fd, &ca_list, |
7025 | &ss->ssl3.clientCertificate, |
7026 | &ss->ssl3.clientPrivateKey); |
7027 | } else { |
7028 | rv = SECFailure; /* force it to send a no_certificate alert */ |
7029 | } |
7030 | switch (rv) { |
7031 | case SECWouldBlock: /* getClientAuthData has put up a dialog box. */ |
7032 | ssl3_SetAlwaysBlock(ss); |
7033 | break; /* not an error */ |
7034 | |
7035 | case SECSuccess: |
7036 | /* check what the callback function returned */ |
7037 | if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { |
7038 | /* we are missing either the key or cert */ |
7039 | if (ss->ssl3.clientCertificate) { |
7040 | /* got a cert, but no key - free it */ |
7041 | CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
7042 | ss->ssl3.clientCertificate = NULL((void*)0); |
7043 | } |
7044 | if (ss->ssl3.clientPrivateKey) { |
7045 | /* got a key, but no cert - free it */ |
7046 | SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
7047 | ss->ssl3.clientPrivateKey = NULL((void*)0); |
7048 | } |
7049 | goto send_no_certificate; |
7050 | } |
7051 | /* Setting ssl3.clientCertChain non-NULL will cause |
7052 | * ssl3_HandleServerHelloDone to call SendCertificate. |
7053 | */ |
7054 | ss->ssl3.clientCertChain = CERT_CertChainFromCert( |
7055 | ss->ssl3.clientCertificate, |
7056 | certUsageSSLClient, PR_FALSE0); |
7057 | if (ss->ssl3.clientCertChain == NULL((void*)0)) { |
7058 | CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
7059 | ss->ssl3.clientCertificate = NULL((void*)0); |
7060 | SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
7061 | ss->ssl3.clientPrivateKey = NULL((void*)0); |
7062 | goto send_no_certificate; |
7063 | } |
7064 | if (ss->ssl3.hs.hashType == handshake_hash_single) { |
7065 | ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms); |
7066 | } |
7067 | break; /* not an error */ |
7068 | |
7069 | case SECFailure: |
7070 | default: |
7071 | send_no_certificate: |
7072 | if (isTLS) { |
7073 | ss->ssl3.sendEmptyCert = PR_TRUE1; |
7074 | } else { |
7075 | (void)SSL3_SendAlert(ss, alert_warning, no_certificate); |
7076 | } |
7077 | rv = SECSuccess; |
7078 | break; |
7079 | } |
7080 | goto done; |
7081 | |
7082 | no_mem: |
7083 | rv = SECFailure; |
7084 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MEMORY); |
7085 | goto done; |
7086 | |
7087 | alert_loser: |
7088 | if (isTLS && desc == illegal_parameter) |
7089 | desc = decode_error; |
7090 | (void)SSL3_SendAlert(ss, alert_fatal, desc); |
7091 | loser: |
7092 | PORT_SetErrorPORT_SetError_Util(errCode); |
7093 | rv = SECFailure; |
7094 | done: |
7095 | if (arena != NULL((void*)0)) |
7096 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
7097 | return rv; |
7098 | } |
7099 | |
7100 | static SECStatus |
7101 | ssl3_CheckFalseStart(sslSocket *ss) |
7102 | { |
7103 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7103)); |
7104 | PORT_Assert( !ss->ssl3.hs.authCertificatePending )((!ss->ssl3.hs.authCertificatePending)?((void)0):PR_Assert ("!ss->ssl3.hs.authCertificatePending","ssl3con.c",7104)); |
7105 | PORT_Assert( !ss->ssl3.hs.canFalseStart )((!ss->ssl3.hs.canFalseStart)?((void)0):PR_Assert("!ss->ssl3.hs.canFalseStart" ,"ssl3con.c",7105)); |
7106 | |
7107 | if (!ss->canFalseStartCallback) { |
7108 | SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: no false start callback so no false start" , getpid(), ss->fd) |
7109 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: no false start callback so no false start" , getpid(), ss->fd); |
7110 | } else { |
7111 | PRBool maybeFalseStart; |
7112 | SECStatus rv; |
7113 | |
7114 | /* An attacker can control the selected ciphersuite so we only wish to |
7115 | * do False Start in the case that the selected ciphersuite is |
7116 | * sufficiently strong that the attack can gain no advantage. |
7117 | * Therefore we always require an 80-bit cipher. */ |
7118 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; |
7119 | maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10; |
7120 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
7121 | |
7122 | if (!maybeFalseStart) { |
7123 | SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: no false start due to weak cipher" , getpid(), ss->fd) |
7124 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: no false start due to weak cipher" , getpid(), ss->fd); |
7125 | } else { |
7126 | rv = (ss->canFalseStartCallback)(ss->fd, |
7127 | ss->canFalseStartCallbackData, |
7128 | &ss->ssl3.hs.canFalseStart); |
7129 | if (rv == SECSuccess) { |
7130 | SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: false start callback returned %s" , getpid(), ss->fd, ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE") |
7131 | SSL_GETPID(), ss->fd,if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: false start callback returned %s" , getpid(), ss->fd, ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE") |
7132 | ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: false start callback returned %s" , getpid(), ss->fd, ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"); |
7133 | } else { |
7134 | SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: false start callback failed (%s)" , getpid(), ss->fd, PR_ErrorToName(PR_GetError())) |
7135 | SSL_GETPID(), ss->fd,if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: false start callback failed (%s)" , getpid(), ss->fd, PR_ErrorToName(PR_GetError())) |
7136 | PR_ErrorToName(PR_GetError())))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL[%d]: false start callback failed (%s)" , getpid(), ss->fd, PR_ErrorToName(PR_GetError())); |
7137 | } |
7138 | return rv; |
7139 | } |
7140 | } |
7141 | |
7142 | ss->ssl3.hs.canFalseStart = PR_FALSE0; |
7143 | return SECSuccess; |
7144 | } |
7145 | |
7146 | PRBool |
7147 | ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss) |
7148 | { |
7149 | PRBool result; |
7150 | |
7151 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7151)); |
7152 | |
7153 | switch (ss->ssl3.hs.ws) { |
7154 | case wait_new_session_ticket: |
7155 | result = PR_TRUE1; |
7156 | break; |
7157 | case wait_change_cipher: |
7158 | result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn); |
7159 | break; |
7160 | default: |
7161 | result = PR_FALSE0; |
7162 | break; |
7163 | } |
7164 | |
7165 | return result; |
7166 | } |
7167 | |
7168 | static SECStatus ssl3_SendClientSecondRound(sslSocket *ss); |
7169 | |
7170 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
7171 | * ssl3 Server Hello Done message. |
7172 | * Caller must hold Handshake and RecvBuf locks. |
7173 | */ |
7174 | static SECStatus |
7175 | ssl3_HandleServerHelloDone(sslSocket *ss) |
7176 | { |
7177 | SECStatus rv; |
7178 | SSL3WaitState ws = ss->ssl3.hs.ws; |
7179 | |
7180 | SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle server_hello_done handshake" , getpid(), ss->fd) |
7181 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle server_hello_done handshake" , getpid(), ss->fd); |
7182 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",7182)); |
7183 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7183)); |
7184 | |
7185 | if (ws != wait_hello_done && |
7186 | ws != wait_server_cert && |
7187 | ws != wait_server_key && |
7188 | ws != wait_cert_request) { |
7189 | SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
7190 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); |
7191 | return SECFailure; |
7192 | } |
7193 | |
7194 | rv = ssl3_SendClientSecondRound(ss); |
7195 | |
7196 | return rv; |
7197 | } |
7198 | |
7199 | /* Called from ssl3_HandleServerHelloDone and ssl3_AuthCertificateComplete. |
7200 | * |
7201 | * Caller must hold Handshake and RecvBuf locks. |
7202 | */ |
7203 | static SECStatus |
7204 | ssl3_SendClientSecondRound(sslSocket *ss) |
7205 | { |
7206 | SECStatus rv; |
7207 | PRBool sendClientCert; |
7208 | |
7209 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",7209)); |
7210 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7210)); |
7211 | |
7212 | sendClientCert = !ss->ssl3.sendEmptyCert && |
7213 | ss->ssl3.clientCertChain != NULL((void*)0) && |
7214 | ss->ssl3.clientPrivateKey != NULL((void*)0); |
7215 | |
7216 | if (!sendClientCert && |
7217 | ss->ssl3.hs.hashType == handshake_hash_single && |
7218 | ss->ssl3.hs.backupHashmd5) { |
7219 | /* Don't need the backup handshake hash. */ |
7220 | PK11_DestroyContext(ss->ssl3.hs.backupHashmd5, PR_TRUE1); |
7221 | ss->ssl3.hs.backupHashmd5 = NULL((void*)0); |
7222 | } |
7223 | |
7224 | /* We must wait for the server's certificate to be authenticated before |
7225 | * sending the client certificate in order to disclosing the client |
7226 | * certificate to an attacker that does not have a valid cert for the |
7227 | * domain we are connecting to. |
7228 | * |
7229 | * XXX: We should do the same for the NPN extension, but for that we |
7230 | * need an option to give the application the ability to leak the NPN |
7231 | * information to get better performance. |
7232 | * |
7233 | * During the initial handshake on a connection, we never send/receive |
7234 | * application data until we have authenticated the server's certificate; |
7235 | * i.e. we have fully authenticated the handshake before using the cipher |
7236 | * specs agreed upon for that handshake. During a renegotiation, we may |
7237 | * continue sending and receiving application data during the handshake |
7238 | * interleaved with the handshake records. If we were to send the client's |
7239 | * second round for a renegotiation before the server's certificate was |
7240 | * authenticated, then the application data sent/received after this point |
7241 | * would be using cipher spec that hadn't been authenticated. By waiting |
7242 | * until the server's certificate has been authenticated during |
7243 | * renegotiations, we ensure that renegotiations have the same property |
7244 | * as initial handshakes; i.e. we have fully authenticated the handshake |
7245 | * before using the cipher specs agreed upon for that handshake for |
7246 | * application data. |
7247 | */ |
7248 | if (ss->ssl3.hs.restartTarget) { |
7249 | PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget")PR_Assert("unexpected ss->ssl3.hs.restartTarget","ssl3con.c" ,7249); |
7250 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
7251 | return SECFailure; |
7252 | } |
7253 | if (ss->ssl3.hs.authCertificatePending && |
7254 | (sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) { |
7255 | SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because" " certificate authentication is still pending.", getpid(), ss ->fd) |
7256 | " certificate authentication is still pending.",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because" " certificate authentication is still pending.", getpid(), ss ->fd) |
7257 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because" " certificate authentication is still pending.", getpid(), ss ->fd); |
7258 | ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound; |
7259 | return SECWouldBlock; |
7260 | } |
7261 | |
7262 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; /*******************************/ |
7263 | |
7264 | if (ss->ssl3.sendEmptyCert) { |
7265 | ss->ssl3.sendEmptyCert = PR_FALSE0; |
7266 | rv = ssl3_SendEmptyCertificate(ss); |
7267 | /* Don't send verify */ |
7268 | if (rv != SECSuccess) { |
7269 | goto loser; /* error code is set. */ |
7270 | } |
7271 | } else if (sendClientCert) { |
7272 | rv = ssl3_SendCertificate(ss); |
7273 | if (rv != SECSuccess) { |
7274 | goto loser; /* error code is set. */ |
7275 | } |
7276 | } |
7277 | |
7278 | rv = ssl3_SendClientKeyExchange(ss); |
7279 | if (rv != SECSuccess) { |
7280 | goto loser; /* err is set. */ |
7281 | } |
7282 | |
7283 | if (sendClientCert) { |
7284 | rv = ssl3_SendCertificateVerify(ss); |
7285 | if (rv != SECSuccess) { |
7286 | goto loser; /* err is set. */ |
7287 | } |
7288 | } |
7289 | |
7290 | rv = ssl3_SendChangeCipherSpecs(ss); |
7291 | if (rv != SECSuccess) { |
7292 | goto loser; /* err code was set. */ |
7293 | } |
7294 | |
7295 | /* This must be done after we've set ss->ssl3.cwSpec in |
7296 | * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information |
7297 | * from cwSpec. This must be done before we call ssl3_CheckFalseStart |
7298 | * because the false start callback (if any) may need the information from |
7299 | * the functions that depend on this being set. |
7300 | */ |
7301 | ss->enoughFirstHsDone = PR_TRUE1; |
7302 | |
7303 | if (!ss->firstHsDone) { |
7304 | /* XXX: If the server's certificate hasn't been authenticated by this |
7305 | * point, then we may be leaking this NPN message to an attacker. |
7306 | */ |
7307 | rv = ssl3_SendNextProto(ss); |
7308 | if (rv != SECSuccess) { |
7309 | goto loser; /* err code was set. */ |
7310 | } |
7311 | |
7312 | if (ss->opt.enableFalseStart) { |
7313 | if (!ss->ssl3.hs.authCertificatePending) { |
7314 | /* When we fix bug 589047, we will need to know whether we are |
7315 | * false starting before we try to flush the client second |
7316 | * round to the network. With that in mind, we purposefully |
7317 | * call ssl3_CheckFalseStart before calling ssl3_SendFinished, |
7318 | * which includes a call to ssl3_FlushHandshake, so that |
7319 | * no application develops a reliance on such flushing being |
7320 | * done before its false start callback is called. |
7321 | */ |
7322 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
7323 | rv = ssl3_CheckFalseStart(ss); |
7324 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
7325 | if (rv != SECSuccess) { |
7326 | goto loser; |
7327 | } |
7328 | } else { |
7329 | /* The certificate authentication and the server's Finished |
7330 | * message are racing each other. If the certificate |
7331 | * authentication wins, then we will try to false start in |
7332 | * ssl3_AuthCertificateComplete. |
7333 | */ |
7334 | SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: deferring false start check because" " certificate authentication is still pending.", getpid(), ss ->fd) |
7335 | " certificate authentication is still pending.",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: deferring false start check because" " certificate authentication is still pending.", getpid(), ss ->fd) |
7336 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: deferring false start check because" " certificate authentication is still pending.", getpid(), ss ->fd); |
7337 | } |
7338 | } |
7339 | } |
7340 | |
7341 | rv = ssl3_SendFinished(ss, 0); |
7342 | if (rv != SECSuccess) { |
7343 | goto loser; /* err code was set. */ |
7344 | } |
7345 | |
7346 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; /*******************************/ |
7347 | |
7348 | if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) |
7349 | ss->ssl3.hs.ws = wait_new_session_ticket; |
7350 | else |
7351 | ss->ssl3.hs.ws = wait_change_cipher; |
7352 | |
7353 | PORT_Assert(ssl3_WaitingForStartOfServerSecondRound(ss))((ssl3_WaitingForStartOfServerSecondRound(ss))?((void)0):PR_Assert ("ssl3_WaitingForStartOfServerSecondRound(ss)","ssl3con.c",7353 )); |
7354 | |
7355 | return SECSuccess; |
7356 | |
7357 | loser: |
7358 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
7359 | return rv; |
7360 | } |
7361 | |
7362 | /* |
7363 | * Routines used by servers |
7364 | */ |
7365 | static SECStatus |
7366 | ssl3_SendHelloRequest(sslSocket *ss) |
7367 | { |
7368 | SECStatus rv; |
7369 | |
7370 | SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send hello_request handshake" , getpid(), ss->fd) |
7371 | ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send hello_request handshake" , getpid(), ss->fd); |
7372 | |
7373 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7373)); |
7374 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",7374)); |
7375 | |
7376 | rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0); |
7377 | if (rv != SECSuccess) { |
7378 | return rv; /* err set by AppendHandshake */ |
7379 | } |
7380 | rv = ssl3_FlushHandshake(ss, 0); |
7381 | if (rv != SECSuccess) { |
7382 | return rv; /* error code set by ssl3_FlushHandshake */ |
7383 | } |
7384 | ss->ssl3.hs.ws = wait_client_hello; |
7385 | return SECSuccess; |
7386 | } |
7387 | |
7388 | /* |
7389 | * Called from: |
7390 | * ssl3_HandleClientHello() |
7391 | */ |
7392 | static SECComparison |
7393 | ssl3_ServerNameCompare(const SECItem *name1, const SECItem *name2) |
7394 | { |
7395 | if (!name1 != !name2) { |
7396 | return SECLessThan; |
7397 | } |
7398 | if (!name1) { |
7399 | return SECEqual; |
7400 | } |
7401 | if (name1->type != name2->type) { |
7402 | return SECLessThan; |
7403 | } |
7404 | return SECITEM_CompareItemSECITEM_CompareItem_Util(name1, name2); |
7405 | } |
7406 | |
7407 | /* Sets memory error when returning NULL. |
7408 | * Called from: |
7409 | * ssl3_SendClientHello() |
7410 | * ssl3_HandleServerHello() |
7411 | * ssl3_HandleClientHello() |
7412 | * ssl3_HandleV2ClientHello() |
7413 | */ |
7414 | sslSessionID * |
7415 | ssl3_NewSessionID(sslSocket *ss, PRBool is_server) |
7416 | { |
7417 | sslSessionID *sid; |
7418 | |
7419 | sid = PORT_ZNew(sslSessionID)(sslSessionID*)PORT_ZAlloc_Util(sizeof(sslSessionID)); |
7420 | if (sid == NULL((void*)0)) |
7421 | return sid; |
7422 | |
7423 | if (is_server) { |
7424 | const SECItem * srvName; |
7425 | SECStatus rv = SECSuccess; |
7426 | |
7427 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; /********************************/ |
7428 | srvName = &ss->ssl3.prSpec->srvVirtName; |
7429 | if (srvName->len && srvName->data) { |
7430 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &sid->u.ssl3.srvName, srvName); |
7431 | } |
7432 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; /************************************/ |
7433 | if (rv != SECSuccess) { |
7434 | PORT_FreePORT_Free_Util(sid); |
7435 | return NULL((void*)0); |
7436 | } |
7437 | } |
7438 | sid->peerID = (ss->peerID == NULL((void*)0)) ? NULL((void*)0) : PORT_StrdupPORT_Strdup_Util(ss->peerID); |
7439 | sid->urlSvrName = (ss->url == NULL((void*)0)) ? NULL((void*)0) : PORT_StrdupPORT_Strdup_Util(ss->url); |
7440 | sid->addr = ss->sec.ci.peer; |
7441 | sid->port = ss->sec.ci.port; |
7442 | sid->references = 1; |
7443 | sid->cached = never_cached; |
7444 | sid->version = ss->version; |
7445 | |
7446 | sid->u.ssl3.keys.resumable = PR_TRUE1; |
7447 | sid->u.ssl3.policy = SSL_ALLOWED1; |
7448 | sid->u.ssl3.clientWriteKey = NULL((void*)0); |
7449 | sid->u.ssl3.serverWriteKey = NULL((void*)0); |
7450 | |
7451 | if (is_server) { |
7452 | SECStatus rv; |
7453 | int pid = SSL_GETPIDgetpid(); |
7454 | |
7455 | sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES32; |
7456 | sid->u.ssl3.sessionID[0] = (pid >> 8) & 0xff; |
7457 | sid->u.ssl3.sessionID[1] = pid & 0xff; |
7458 | rv = PK11_GenerateRandom(sid->u.ssl3.sessionID + 2, |
7459 | SSL3_SESSIONID_BYTES32 -2); |
7460 | if (rv != SECSuccess) { |
7461 | ssl_FreeSID(sid); |
7462 | ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); |
7463 | return NULL((void*)0); |
7464 | } |
7465 | } |
7466 | return sid; |
7467 | } |
7468 | |
7469 | /* Called from: ssl3_HandleClientHello, ssl3_HandleV2ClientHello */ |
7470 | static SECStatus |
7471 | ssl3_SendServerHelloSequence(sslSocket *ss) |
7472 | { |
7473 | const ssl3KEADef *kea_def; |
7474 | SECStatus rv; |
7475 | |
7476 | SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: begin send server_hello sequence" , getpid(), ss->fd) |
7477 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: begin send server_hello sequence" , getpid(), ss->fd); |
7478 | |
7479 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7479)); |
7480 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",7480)); |
7481 | |
7482 | rv = ssl3_SendServerHello(ss); |
7483 | if (rv != SECSuccess) { |
7484 | return rv; /* err code is set. */ |
7485 | } |
7486 | rv = ssl3_SendCertificate(ss); |
7487 | if (rv != SECSuccess) { |
7488 | return rv; /* error code is set. */ |
7489 | } |
7490 | rv = ssl3_SendCertificateStatus(ss); |
7491 | if (rv != SECSuccess) { |
7492 | return rv; /* error code is set. */ |
7493 | } |
7494 | /* We have to do this after the call to ssl3_SendServerHello, |
7495 | * because kea_def is set up by ssl3_SendServerHello(). |
7496 | */ |
7497 | kea_def = ss->ssl3.hs.kea_def; |
7498 | ss->ssl3.hs.usedStepDownKey = PR_FALSE0; |
7499 | |
7500 | if (kea_def->is_limited && kea_def->exchKeyType == kt_rsassl_kea_rsa) { |
7501 | /* see if we can legally use the key in the cert. */ |
7502 | int keyLen; /* bytes */ |
7503 | |
7504 | keyLen = PK11_GetPrivateModulusLen( |
7505 | ss->serverCerts[kea_def->exchKeyType].SERVERKEYserverKeyPair->privKey); |
7506 | |
7507 | if (keyLen > 0 && |
7508 | keyLen * BPB8 <= kea_def->key_size_limit ) { |
7509 | /* XXX AND cert is not signing only!! */ |
7510 | /* just fall through and use it. */ |
7511 | } else if (ss->stepDownKeyPair != NULL((void*)0)) { |
7512 | ss->ssl3.hs.usedStepDownKey = PR_TRUE1; |
7513 | rv = ssl3_SendServerKeyExchange(ss); |
7514 | if (rv != SECSuccess) { |
7515 | return rv; /* err code was set. */ |
7516 | } |
7517 | } else { |
7518 | #ifndef HACKED_EXPORT_SERVER |
7519 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED); |
7520 | return rv; |
7521 | #endif |
7522 | } |
7523 | #ifdef NSS_ENABLE_ECC1 |
7524 | } else if ((kea_def->kea == kea_ecdhe_rsa) || |
7525 | (kea_def->kea == kea_ecdhe_ecdsa)) { |
7526 | rv = ssl3_SendServerKeyExchange(ss); |
7527 | if (rv != SECSuccess) { |
7528 | return rv; /* err code was set. */ |
7529 | } |
7530 | #endif /* NSS_ENABLE_ECC */ |
7531 | } |
7532 | |
7533 | if (ss->opt.requestCertificate) { |
7534 | rv = ssl3_SendCertificateRequest(ss); |
7535 | if (rv != SECSuccess) { |
7536 | return rv; /* err code is set. */ |
7537 | } |
7538 | } |
7539 | rv = ssl3_SendServerHelloDone(ss); |
7540 | if (rv != SECSuccess) { |
7541 | return rv; /* err code is set. */ |
7542 | } |
7543 | |
7544 | ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert |
7545 | : wait_client_key; |
7546 | return SECSuccess; |
7547 | } |
7548 | |
7549 | /* An empty TLS Renegotiation Info (RI) extension */ |
7550 | static const PRUint8 emptyRIext[5] = {0xff, 0x01, 0x00, 0x01, 0x00}; |
7551 | |
7552 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
7553 | * ssl3 Client Hello message. |
7554 | * Caller must hold Handshake and RecvBuf locks. |
7555 | */ |
7556 | static SECStatus |
7557 | ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
7558 | { |
7559 | sslSessionID * sid = NULL((void*)0); |
7560 | PRInt32 tmp; |
7561 | unsigned int i; |
7562 | int j; |
7563 | SECStatus rv; |
7564 | int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO; |
7565 | SSL3AlertDescription desc = illegal_parameter; |
7566 | SSL3AlertLevel level = alert_fatal; |
7567 | SSL3ProtocolVersion version; |
7568 | SECItem sidBytes = {siBuffer, NULL((void*)0), 0}; |
7569 | SECItem cookieBytes = {siBuffer, NULL((void*)0), 0}; |
7570 | SECItem suites = {siBuffer, NULL((void*)0), 0}; |
7571 | SECItem comps = {siBuffer, NULL((void*)0), 0}; |
7572 | PRBool haveSpecWriteLock = PR_FALSE0; |
7573 | PRBool haveXmitBufLock = PR_FALSE0; |
7574 | |
7575 | SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle client_hello handshake" , getpid(), ss->fd) |
7576 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle client_hello handshake" , getpid(), ss->fd); |
7577 | |
7578 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",7578)); |
7579 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",7579)); |
7580 | PORT_Assert( ss->ssl3.initialized )((ss->ssl3.initialized)?((void)0):PR_Assert("ss->ssl3.initialized" ,"ssl3con.c",7580)); |
7581 | |
7582 | /* Get peer name of client */ |
7583 | rv = ssl_GetPeerInfo(ss); |
7584 | if (rv != SECSuccess) { |
7585 | return rv; /* error code is set. */ |
7586 | } |
7587 | |
7588 | /* Clearing the handshake pointers so that ssl_Do1stHandshake won't |
7589 | * call ssl2_HandleMessage. |
7590 | * |
7591 | * The issue here is that TLS ordinarily starts out in |
7592 | * ssl2_HandleV3HandshakeRecord() because of the backward-compatibility |
7593 | * code paths. That function zeroes these next pointers. But with DTLS, |
7594 | * we don't even try to do the v2 ClientHello so we skip that function |
7595 | * and need to reset these values here. |
7596 | */ |
7597 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
7598 | ss->nextHandshake = 0; |
7599 | ss->securityHandshake = 0; |
7600 | } |
7601 | |
7602 | /* We might be starting session renegotiation in which case we should |
7603 | * clear previous state. |
7604 | */ |
7605 | PORT_Memsetmemset(&ss->xtnData, 0, sizeof(TLSExtensionData)); |
7606 | ss->statelessResume = PR_FALSE0; |
7607 | |
7608 | if ((ss->ssl3.hs.ws != wait_client_hello) && |
7609 | (ss->ssl3.hs.ws != idle_handshake)) { |
7610 | desc = unexpected_message; |
7611 | errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO; |
7612 | goto alert_loser; |
7613 | } |
7614 | if (ss->ssl3.hs.ws == idle_handshake && |
7615 | ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER((PRBool)0)) { |
7616 | desc = no_renegotiation; |
7617 | level = alert_warning; |
7618 | errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; |
7619 | goto alert_loser; |
7620 | } |
7621 | |
7622 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
7623 | dtls_RehandshakeCleanup(ss); |
7624 | } |
7625 | |
7626 | tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
7627 | if (tmp < 0) |
7628 | goto loser; /* malformed, alert already sent */ |
7629 | |
7630 | /* Translate the version */ |
7631 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
7632 | ss->clientHelloVersion = version = |
7633 | dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp); |
7634 | } else { |
7635 | ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp; |
7636 | } |
7637 | |
7638 | rv = ssl3_NegotiateVersion(ss, version, PR_TRUE1); |
7639 | if (rv != SECSuccess) { |
7640 | desc = (version > SSL_LIBRARY_VERSION_3_00x0300) ? protocol_version |
7641 | : handshake_failure; |
7642 | errCode = SSL_ERROR_NO_CYPHER_OVERLAP; |
7643 | goto alert_loser; |
7644 | } |
7645 | |
7646 | rv = ssl3_InitHandshakeHashes(ss); |
7647 | if (rv != SECSuccess) { |
7648 | desc = internal_error; |
7649 | errCode = PORT_GetErrorPORT_GetError_Util(); |
7650 | goto alert_loser; |
7651 | } |
7652 | |
7653 | /* grab the client random data. */ |
7654 | rv = ssl3_ConsumeHandshake( |
7655 | ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH32, &b, &length); |
7656 | if (rv != SECSuccess) { |
7657 | goto loser; /* malformed */ |
7658 | } |
7659 | |
7660 | /* grab the client's SID, if present. */ |
7661 | rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length); |
7662 | if (rv != SECSuccess) { |
7663 | goto loser; /* malformed */ |
7664 | } |
7665 | |
7666 | /* grab the client's cookie, if present. */ |
7667 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
7668 | rv = ssl3_ConsumeHandshakeVariable(ss, &cookieBytes, 1, &b, &length); |
7669 | if (rv != SECSuccess) { |
7670 | goto loser; /* malformed */ |
7671 | } |
7672 | } |
7673 | |
7674 | /* grab the list of cipher suites. */ |
7675 | rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length); |
7676 | if (rv != SECSuccess) { |
7677 | goto loser; /* malformed */ |
7678 | } |
7679 | |
7680 | /* grab the list of compression methods. */ |
7681 | rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length); |
7682 | if (rv != SECSuccess) { |
7683 | goto loser; /* malformed */ |
7684 | } |
7685 | |
7686 | desc = handshake_failure; |
7687 | |
7688 | /* Handle TLS hello extensions for SSL3 & TLS. We do not know if |
7689 | * we are restarting a previous session until extensions have been |
7690 | * parsed, since we might have received a SessionTicket extension. |
7691 | * Note: we allow extensions even when negotiating SSL3 for the sake |
7692 | * of interoperability (and backwards compatibility). |
7693 | */ |
7694 | |
7695 | if (length) { |
7696 | /* Get length of hello extensions */ |
7697 | PRInt32 extension_length; |
7698 | extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); |
7699 | if (extension_length < 0) { |
7700 | goto loser; /* alert already sent */ |
7701 | } |
7702 | if (extension_length != length) { |
7703 | ssl3_DecodeError(ss); /* send alert */ |
7704 | goto loser; |
7705 | } |
7706 | rv = ssl3_HandleHelloExtensions(ss, &b, &length); |
7707 | if (rv != SECSuccess) { |
7708 | goto loser; /* malformed */ |
7709 | } |
7710 | } |
7711 | if (!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { |
7712 | /* If we didn't receive an RI extension, look for the SCSV, |
7713 | * and if found, treat it just like an empty RI extension |
7714 | * by processing a local copy of an empty RI extension. |
7715 | */ |
7716 | for (i = 0; i + 1 < suites.len; i += 2) { |
7717 | PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; |
7718 | if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV0x00FF) { |
7719 | SSL3Opaque * b2 = (SSL3Opaque *)emptyRIext; |
7720 | PRUint32 L2 = sizeof emptyRIext; |
7721 | (void)ssl3_HandleHelloExtensions(ss, &b2, &L2); |
7722 | break; |
7723 | } |
7724 | } |
7725 | } |
7726 | if (ss->firstHsDone && |
7727 | (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN((PRBool)2) || |
7728 | ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL((PRBool)3)) && |
7729 | !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { |
7730 | desc = no_renegotiation; |
7731 | level = alert_warning; |
7732 | errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; |
7733 | goto alert_loser; |
7734 | } |
7735 | if ((ss->opt.requireSafeNegotiation || |
7736 | (ss->firstHsDone && ss->peerRequestedProtection)) && |
7737 | !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { |
7738 | desc = handshake_failure; |
7739 | errCode = SSL_ERROR_UNSAFE_NEGOTIATION; |
7740 | goto alert_loser; |
7741 | } |
7742 | |
7743 | /* We do stateful resumes only if either of the following |
7744 | * conditions are satisfied: (1) the client does not support the |
7745 | * session ticket extension, or (2) the client support the session |
7746 | * ticket extension, but sent an empty ticket. |
7747 | */ |
7748 | if (!ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) || |
7749 | ss->xtnData.emptySessionTicket) { |
7750 | if (sidBytes.len > 0 && !ss->opt.noCache) { |
7751 | SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",if (ssl_trace >= (7)) ssl_Trace ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x" , getpid(), ss->fd, ss->sec.ci.peer._S6_un._S6_u32[0], ss ->sec.ci.peer._S6_un._S6_u32[1], ss->sec.ci.peer._S6_un ._S6_u32[2], ss->sec.ci.peer._S6_un._S6_u32[3]) |
7752 | SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],if (ssl_trace >= (7)) ssl_Trace ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x" , getpid(), ss->fd, ss->sec.ci.peer._S6_un._S6_u32[0], ss ->sec.ci.peer._S6_un._S6_u32[1], ss->sec.ci.peer._S6_un ._S6_u32[2], ss->sec.ci.peer._S6_un._S6_u32[3]) |
7753 | ss->sec.ci.peer.pr_s6_addr32[1],if (ssl_trace >= (7)) ssl_Trace ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x" , getpid(), ss->fd, ss->sec.ci.peer._S6_un._S6_u32[0], ss ->sec.ci.peer._S6_un._S6_u32[1], ss->sec.ci.peer._S6_un ._S6_u32[2], ss->sec.ci.peer._S6_un._S6_u32[3]) |
7754 | ss->sec.ci.peer.pr_s6_addr32[2],if (ssl_trace >= (7)) ssl_Trace ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x" , getpid(), ss->fd, ss->sec.ci.peer._S6_un._S6_u32[0], ss ->sec.ci.peer._S6_un._S6_u32[1], ss->sec.ci.peer._S6_un ._S6_u32[2], ss->sec.ci.peer._S6_un._S6_u32[3]) |
7755 | ss->sec.ci.peer.pr_s6_addr32[3]))if (ssl_trace >= (7)) ssl_Trace ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x" , getpid(), ss->fd, ss->sec.ci.peer._S6_un._S6_u32[0], ss ->sec.ci.peer._S6_un._S6_u32[1], ss->sec.ci.peer._S6_un ._S6_u32[2], ss->sec.ci.peer._S6_un._S6_u32[3]); |
7756 | if (ssl_sid_lookup) { |
7757 | sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sidBytes.data, |
7758 | sidBytes.len, ss->dbHandle); |
7759 | } else { |
7760 | errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED; |
7761 | goto loser; |
7762 | } |
7763 | } |
7764 | } else if (ss->statelessResume) { |
7765 | /* Fill in the client's session ID if doing a stateless resume. |
7766 | * (When doing stateless resumes, server echos client's SessionID.) |
7767 | */ |
7768 | sid = ss->sec.ci.sid; |
7769 | PORT_Assert(sid != NULL)((sid != ((void*)0))?((void)0):PR_Assert("sid != NULL","ssl3con.c" ,7769)); /* Should have already been filled in.*/ |
7770 | |
7771 | if (sidBytes.len > 0 && sidBytes.len <= SSL3_SESSIONID_BYTES32) { |
7772 | sid->u.ssl3.sessionIDLength = sidBytes.len; |
7773 | PORT_Memcpymemcpy(sid->u.ssl3.sessionID, sidBytes.data, |
7774 | sidBytes.len); |
7775 | sid->u.ssl3.sessionIDLength = sidBytes.len; |
7776 | } else { |
7777 | sid->u.ssl3.sessionIDLength = 0; |
7778 | } |
7779 | ss->sec.ci.sid = NULL((void*)0); |
7780 | } |
7781 | |
7782 | /* We only send a session ticket extension if the client supports |
7783 | * the extension and we are unable to do either a stateful or |
7784 | * stateless resume. |
7785 | * |
7786 | * TODO: send a session ticket if performing a stateful |
7787 | * resumption. (As per RFC4507, a server may issue a session |
7788 | * ticket while doing a (stateless or stateful) session resume, |
7789 | * but OpenSSL-0.9.8g does not accept session tickets while |
7790 | * resuming.) |
7791 | */ |
7792 | if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && sid == NULL((void*)0)) { |
7793 | ssl3_RegisterServerHelloExtensionSender(ss, |
7794 | ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn); |
7795 | } |
7796 | |
7797 | if (sid != NULL((void*)0)) { |
7798 | /* We've found a session cache entry for this client. |
7799 | * Now, if we're going to require a client-auth cert, |
7800 | * and we don't already have this client's cert in the session cache, |
7801 | * and this is the first handshake on this connection (not a redo), |
7802 | * then drop this old cache entry and start a new session. |
7803 | */ |
7804 | if ((sid->peerCert == NULL((void*)0)) && ss->opt.requestCertificate && |
7805 | ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS((PRBool)1)) || |
7806 | (ss->opt.requireCertificate == SSL_REQUIRE_NO_ERROR((PRBool)3)) || |
7807 | ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE((PRBool)2)) |
7808 | && !ss->firstHsDone))) { |
7809 | |
7810 | SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok ); |
7811 | if (ss->sec.uncache) |
7812 | ss->sec.uncache(sid); |
7813 | ssl_FreeSID(sid); |
7814 | sid = NULL((void*)0); |
7815 | } |
7816 | } |
7817 | |
7818 | #ifdef NSS_ENABLE_ECC1 |
7819 | /* Disable any ECC cipher suites for which we have no cert. */ |
7820 | ssl3_FilterECCipherSuitesByServerCerts(ss); |
7821 | #endif |
7822 | |
7823 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
7824 | ssl3_DisableNonDTLSSuites(ss); |
7825 | } |
7826 | |
7827 | #ifdef PARANOID |
7828 | /* Look for a matching cipher suite. */ |
7829 | j = ssl3_config_match_init(ss); |
7830 | if (j <= 0) { /* no ciphers are working/supported by PK11 */ |
7831 | errCode = PORT_GetErrorPORT_GetError_Util(); /* error code is already set. */ |
7832 | goto alert_loser; |
7833 | } |
7834 | #endif |
7835 | |
7836 | /* If we already have a session for this client, be sure to pick the |
7837 | ** same cipher suite and compression method we picked before. |
7838 | ** This is not a loop, despite appearances. |
7839 | */ |
7840 | if (sid) do { |
7841 | ssl3CipherSuiteCfg *suite; |
7842 | #ifdef PARANOID |
7843 | SSLVersionRange vrange = {ss->version, ss->version}; |
7844 | #endif |
7845 | |
7846 | /* Check that the cached compression method is still enabled. */ |
7847 | if (!compressionEnabled(ss, sid->u.ssl3.compression)) |
7848 | break; |
7849 | |
7850 | /* Check that the cached compression method is in the client's list */ |
7851 | for (i = 0; i < comps.len; i++) { |
7852 | if (comps.data[i] == sid->u.ssl3.compression) |
7853 | break; |
7854 | } |
7855 | if (i == comps.len) |
7856 | break; |
7857 | |
7858 | suite = ss->cipherSuites; |
7859 | /* Find the entry for the cipher suite used in the cached session. */ |
7860 | for (j = ssl_V3_SUITES_IMPLEMENTED61; j > 0; --j, ++suite) { |
7861 | if (suite->cipher_suite == sid->u.ssl3.cipherSuite) |
7862 | break; |
7863 | } |
7864 | PORT_Assert(j > 0)((j > 0)?((void)0):PR_Assert("j > 0","ssl3con.c",7864)); |
7865 | if (j <= 0) |
7866 | break; |
7867 | #ifdef PARANOID |
7868 | /* Double check that the cached cipher suite is still enabled, |
7869 | * implemented, and allowed by policy. Might have been disabled. |
7870 | * The product policy won't change during the process lifetime. |
7871 | * Implemented ("isPresent") shouldn't change for servers. |
7872 | */ |
7873 | if (!config_match(suite, ss->ssl3.policy, PR_TRUE1, &vrange)) |
7874 | break; |
7875 | #else |
7876 | if (!suite->enabled) |
7877 | break; |
7878 | #endif |
7879 | /* Double check that the cached cipher suite is in the client's list */ |
7880 | for (i = 0; i + 1 < suites.len; i += 2) { |
7881 | PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; |
7882 | if (suite_i == suite->cipher_suite) { |
7883 | ss->ssl3.hs.cipher_suite = suite->cipher_suite; |
7884 | ss->ssl3.hs.suite_def = |
7885 | ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); |
7886 | |
7887 | /* Use the cached compression method. */ |
7888 | ss->ssl3.hs.compression = sid->u.ssl3.compression; |
7889 | goto compression_found; |
7890 | } |
7891 | } |
7892 | } while (0); |
7893 | |
7894 | /* START A NEW SESSION */ |
7895 | |
7896 | #ifndef PARANOID |
7897 | /* Look for a matching cipher suite. */ |
7898 | j = ssl3_config_match_init(ss); |
7899 | if (j <= 0) { /* no ciphers are working/supported by PK11 */ |
7900 | errCode = PORT_GetErrorPORT_GetError_Util(); /* error code is already set. */ |
7901 | goto alert_loser; |
7902 | } |
7903 | #endif |
7904 | |
7905 | /* Select a cipher suite. |
7906 | ** |
7907 | ** NOTE: This suite selection algorithm should be the same as the one in |
7908 | ** ssl3_HandleV2ClientHello(). |
7909 | ** |
7910 | ** If TLS 1.0 is enabled, we could handle the case where the client |
7911 | ** offered TLS 1.1 but offered only export cipher suites by choosing TLS |
7912 | ** 1.0 and selecting one of those export cipher suites. However, a secure |
7913 | ** TLS 1.1 client should not have export cipher suites enabled at all, |
7914 | ** and a TLS 1.1 client should definitely not be offering *only* export |
7915 | ** cipher suites. Therefore, we refuse to negotiate export cipher suites |
7916 | ** with any client that indicates support for TLS 1.1 or higher when we |
7917 | ** (the server) have TLS 1.1 support enabled. |
7918 | */ |
7919 | for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED61; j++) { |
7920 | ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j]; |
7921 | SSLVersionRange vrange = {ss->version, ss->version}; |
7922 | if (!config_match(suite, ss->ssl3.policy, PR_TRUE1, &vrange)) { |
7923 | continue; |
7924 | } |
7925 | for (i = 0; i + 1 < suites.len; i += 2) { |
7926 | PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; |
7927 | if (suite_i == suite->cipher_suite) { |
7928 | ss->ssl3.hs.cipher_suite = suite->cipher_suite; |
7929 | ss->ssl3.hs.suite_def = |
7930 | ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); |
7931 | goto suite_found; |
7932 | } |
7933 | } |
7934 | } |
7935 | errCode = SSL_ERROR_NO_CYPHER_OVERLAP; |
7936 | goto alert_loser; |
7937 | |
7938 | suite_found: |
7939 | /* Select a compression algorithm. */ |
7940 | for (i = 0; i < comps.len; i++) { |
7941 | if (!compressionEnabled(ss, comps.data[i])) |
7942 | continue; |
7943 | for (j = 0; j < compressionMethodsCount; j++) { |
7944 | if (comps.data[i] == compressions[j]) { |
7945 | ss->ssl3.hs.compression = |
7946 | (SSLCompressionMethod)compressions[j]; |
7947 | goto compression_found; |
7948 | } |
7949 | } |
7950 | } |
7951 | errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP; |
7952 | /* null compression must be supported */ |
7953 | goto alert_loser; |
7954 | |
7955 | compression_found: |
7956 | suites.data = NULL((void*)0); |
7957 | comps.data = NULL((void*)0); |
7958 | |
7959 | ss->sec.send = ssl3_SendApplicationData; |
7960 | |
7961 | /* If there are any failures while processing the old sid, |
7962 | * we don't consider them to be errors. Instead, We just behave |
7963 | * as if the client had sent us no sid to begin with, and make a new one. |
7964 | */ |
7965 | if (sid != NULL((void*)0)) do { |
7966 | ssl3CipherSpec *pwSpec; |
7967 | SECItem wrappedMS; /* wrapped key */ |
7968 | |
7969 | if (sid->version != ss->version || |
7970 | sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite || |
7971 | sid->u.ssl3.compression != ss->ssl3.hs.compression) { |
7972 | break; /* not an error */ |
7973 | } |
7974 | |
7975 | if (ss->sec.ci.sid) { |
7976 | if (ss->sec.uncache) |
7977 | ss->sec.uncache(ss->sec.ci.sid); |
7978 | PORT_Assert(ss->sec.ci.sid != sid)((ss->sec.ci.sid != sid)?((void)0):PR_Assert("ss->sec.ci.sid != sid" ,"ssl3con.c",7978)); /* should be impossible, but ... */ |
7979 | if (ss->sec.ci.sid != sid) { |
7980 | ssl_FreeSID(ss->sec.ci.sid); |
7981 | } |
7982 | ss->sec.ci.sid = NULL((void*)0); |
7983 | } |
7984 | /* we need to resurrect the master secret.... */ |
7985 | |
7986 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; haveSpecWriteLock = PR_TRUE1; |
7987 | pwSpec = ss->ssl3.pwSpec; |
7988 | if (sid->u.ssl3.keys.msIsWrapped) { |
7989 | PK11SymKey * wrapKey; /* wrapping key */ |
7990 | CK_FLAGS keyFlags = 0; |
7991 | #ifndef NO_PKCS11_BYPASS1 |
7992 | if (ss->opt.bypassPKCS11) { |
7993 | /* we cannot restart a non-bypass session in a |
7994 | ** bypass socket. |
7995 | */ |
7996 | break; |
7997 | } |
7998 | #endif |
7999 | |
8000 | wrapKey = getWrappingKey(ss, NULL((void*)0), sid->u.ssl3.exchKeyType, |
8001 | sid->u.ssl3.masterWrapMech, |
8002 | ss->pkcs11PinArg); |
8003 | if (!wrapKey) { |
8004 | /* we have a SID cache entry, but no wrapping key for it??? */ |
8005 | break; |
8006 | } |
8007 | |
8008 | if (ss->version > SSL_LIBRARY_VERSION_3_00x0300) { /* isTLS */ |
8009 | keyFlags = CKF_SIGN0x00000800 | CKF_VERIFY0x00002000; |
8010 | } |
8011 | |
8012 | wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; |
8013 | wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; |
8014 | |
8015 | /* unwrap the master secret. */ |
8016 | pwSpec->master_secret = |
8017 | PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, |
8018 | NULL((void*)0), &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE0x00000371, |
8019 | CKA_DERIVE0x0000010C, sizeof(SSL3MasterSecret), keyFlags); |
8020 | PK11_FreeSymKey(wrapKey); |
8021 | if (pwSpec->master_secret == NULL((void*)0)) { |
8022 | break; /* not an error */ |
8023 | } |
8024 | #ifndef NO_PKCS11_BYPASS1 |
8025 | } else if (ss->opt.bypassPKCS11) { |
8026 | wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; |
8027 | wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; |
8028 | memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len); |
8029 | pwSpec->msItem.data = pwSpec->raw_master_secret; |
8030 | pwSpec->msItem.len = wrappedMS.len; |
8031 | #endif |
8032 | } else { |
8033 | /* We CAN restart a bypass session in a non-bypass socket. */ |
8034 | /* need to import the raw master secret to session object */ |
8035 | PK11SlotInfo * slot; |
8036 | wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret; |
8037 | wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len; |
8038 | slot = PK11_GetInternalSlot(); |
8039 | pwSpec->master_secret = |
8040 | PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE0x00000371, |
8041 | PK11_OriginUnwrap, CKA_ENCRYPT0x00000104, &wrappedMS, |
8042 | NULL((void*)0)); |
8043 | PK11_FreeSlot(slot); |
8044 | if (pwSpec->master_secret == NULL((void*)0)) { |
8045 | break; /* not an error */ |
8046 | } |
8047 | } |
8048 | ss->sec.ci.sid = sid; |
8049 | if (sid->peerCert != NULL((void*)0)) { |
8050 | ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
8051 | } |
8052 | |
8053 | /* |
8054 | * Old SID passed all tests, so resume this old session. |
8055 | * |
8056 | * XXX make sure compression still matches |
8057 | */ |
8058 | SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_hits ); |
8059 | if (ss->statelessResume) |
8060 | SSL_AtomicIncrementLong(& ssl3stats.hch_sid_stateless_resumes ); |
8061 | ss->ssl3.hs.isResuming = PR_TRUE1; |
8062 | |
8063 | ss->sec.authAlgorithm = sid->authAlgorithm; |
8064 | ss->sec.authKeyBits = sid->authKeyBits; |
8065 | ss->sec.keaType = sid->keaType; |
8066 | ss->sec.keaKeyBits = sid->keaKeyBits; |
8067 | |
8068 | /* server sids don't remember the server cert we previously sent, |
8069 | ** but they do remember the kea type we originally used, so we |
8070 | ** can locate it again, provided that the current ssl socket |
8071 | ** has had its server certs configured the same as the previous one. |
8072 | */ |
8073 | ss->sec.localCert = |
8074 | CERT_DupCertificate(ss->serverCerts[sid->keaType].serverCert); |
8075 | |
8076 | /* Copy cached name in to pending spec */ |
8077 | if (sid != NULL((void*)0) && |
8078 | sid->version > SSL_LIBRARY_VERSION_3_00x0300 && |
8079 | sid->u.ssl3.srvName.len && sid->u.ssl3.srvName.data) { |
8080 | /* Set server name from sid */ |
8081 | SECItem *sidName = &sid->u.ssl3.srvName; |
8082 | SECItem *pwsName = &ss->ssl3.pwSpec->srvVirtName; |
8083 | if (pwsName->data) { |
8084 | SECITEM_FreeItemSECITEM_FreeItem_Util(pwsName, PR_FALSE0); |
8085 | } |
8086 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), pwsName, sidName); |
8087 | if (rv != SECSuccess) { |
8088 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8089 | desc = internal_error; |
8090 | goto alert_loser; |
8091 | } |
8092 | } |
8093 | |
8094 | /* Clean up sni name array */ |
8095 | if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn) && |
8096 | ss->xtnData.sniNameArr) { |
8097 | PORT_FreePORT_Free_Util(ss->xtnData.sniNameArr); |
8098 | ss->xtnData.sniNameArr = NULL((void*)0); |
8099 | ss->xtnData.sniNameArrSize = 0; |
8100 | } |
8101 | |
8102 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; haveXmitBufLock = PR_TRUE1; |
8103 | |
8104 | rv = ssl3_SendServerHello(ss); |
8105 | if (rv != SECSuccess) { |
8106 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8107 | goto loser; |
8108 | } |
8109 | |
8110 | if (haveSpecWriteLock) { |
8111 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
8112 | haveSpecWriteLock = PR_FALSE0; |
8113 | } |
8114 | |
8115 | /* NULL value for PMS signifies re-use of the old MS */ |
8116 | rv = ssl3_InitPendingCipherSpec(ss, NULL((void*)0)); |
8117 | if (rv != SECSuccess) { |
8118 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8119 | goto loser; |
8120 | } |
8121 | |
8122 | rv = ssl3_SendChangeCipherSpecs(ss); |
8123 | if (rv != SECSuccess) { |
8124 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8125 | goto loser; |
8126 | } |
8127 | rv = ssl3_SendFinished(ss, 0); |
8128 | ss->ssl3.hs.ws = wait_change_cipher; |
8129 | if (rv != SECSuccess) { |
8130 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8131 | goto loser; |
8132 | } |
8133 | |
8134 | if (haveXmitBufLock) { |
8135 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
8136 | haveXmitBufLock = PR_FALSE0; |
8137 | } |
8138 | |
8139 | return SECSuccess; |
8140 | } while (0); |
8141 | |
8142 | if (haveSpecWriteLock) { |
8143 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
8144 | haveSpecWriteLock = PR_FALSE0; |
8145 | } |
8146 | |
8147 | if (sid) { /* we had a sid, but it's no longer valid, free it */ |
8148 | SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok ); |
8149 | if (ss->sec.uncache) |
8150 | ss->sec.uncache(sid); |
8151 | ssl_FreeSID(sid); |
8152 | sid = NULL((void*)0); |
8153 | } |
8154 | SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses ); |
8155 | |
8156 | if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) { |
8157 | int ret = 0; |
8158 | if (ss->sniSocketConfig) do { /* not a loop */ |
8159 | ret = SSL_SNI_SEND_ALERT-2; |
8160 | /* If extension is negotiated, the len of names should > 0. */ |
8161 | if (ss->xtnData.sniNameArrSize) { |
8162 | /* Calling client callback to reconfigure the socket. */ |
8163 | ret = (SECStatus)(*ss->sniSocketConfig)(ss->fd, |
8164 | ss->xtnData.sniNameArr, |
8165 | ss->xtnData.sniNameArrSize, |
8166 | ss->sniSocketConfigArg); |
8167 | } |
8168 | if (ret <= SSL_SNI_SEND_ALERT-2) { |
8169 | /* Application does not know the name or was not able to |
8170 | * properly reconfigure the socket. */ |
8171 | errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; |
8172 | desc = unrecognized_name; |
8173 | break; |
8174 | } else if (ret == SSL_SNI_CURRENT_CONFIG_IS_USED-1) { |
8175 | SECStatus rv = SECSuccess; |
8176 | SECItem * cwsName, *pwsName; |
8177 | |
8178 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; /*******************************/ |
8179 | pwsName = &ss->ssl3.pwSpec->srvVirtName; |
8180 | cwsName = &ss->ssl3.cwSpec->srvVirtName; |
8181 | #ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS |
8182 | /* not allow name change on the 2d HS */ |
8183 | if (ss->firstHsDone) { |
8184 | if (ssl3_ServerNameCompare(pwsName, cwsName)) { |
8185 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /******************/ |
8186 | errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; |
8187 | desc = handshake_failure; |
8188 | ret = SSL_SNI_SEND_ALERT-2; |
8189 | break; |
8190 | } |
8191 | } |
8192 | #endif |
8193 | if (pwsName->data) { |
8194 | SECITEM_FreeItemSECITEM_FreeItem_Util(pwsName, PR_FALSE0); |
8195 | } |
8196 | if (cwsName->data) { |
8197 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), pwsName, cwsName); |
8198 | } |
8199 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /**************************/ |
8200 | if (rv != SECSuccess) { |
8201 | errCode = SSL_ERROR_INTERNAL_ERROR_ALERT; |
8202 | desc = internal_error; |
8203 | ret = SSL_SNI_SEND_ALERT-2; |
8204 | break; |
8205 | } |
8206 | } else if (ret < ss->xtnData.sniNameArrSize) { |
8207 | /* Application has configured new socket info. Lets check it |
8208 | * and save the name. */ |
8209 | SECStatus rv; |
8210 | SECItem * name = &ss->xtnData.sniNameArr[ret]; |
8211 | int configedCiphers; |
8212 | SECItem * pwsName; |
8213 | |
8214 | /* get rid of the old name and save the newly picked. */ |
8215 | /* This code is protected by ssl3HandshakeLock. */ |
8216 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; /*******************************/ |
8217 | #ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS |
8218 | /* not allow name change on the 2d HS */ |
8219 | if (ss->firstHsDone) { |
8220 | SECItem *cwsName = &ss->ssl3.cwSpec->srvVirtName; |
8221 | if (ssl3_ServerNameCompare(name, cwsName)) { |
8222 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /******************/ |
8223 | errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; |
8224 | desc = handshake_failure; |
8225 | ret = SSL_SNI_SEND_ALERT-2; |
8226 | break; |
8227 | } |
8228 | } |
8229 | #endif |
8230 | pwsName = &ss->ssl3.pwSpec->srvVirtName; |
8231 | if (pwsName->data) { |
8232 | SECITEM_FreeItemSECITEM_FreeItem_Util(pwsName, PR_FALSE0); |
8233 | } |
8234 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), pwsName, name); |
8235 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; /***************************/ |
8236 | if (rv != SECSuccess) { |
8237 | errCode = SSL_ERROR_INTERNAL_ERROR_ALERT; |
8238 | desc = internal_error; |
8239 | ret = SSL_SNI_SEND_ALERT-2; |
8240 | break; |
8241 | } |
8242 | configedCiphers = ssl3_config_match_init(ss); |
8243 | if (configedCiphers <= 0) { |
8244 | /* no ciphers are working/supported */ |
8245 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8246 | desc = handshake_failure; |
8247 | ret = SSL_SNI_SEND_ALERT-2; |
8248 | break; |
8249 | } |
8250 | /* Need to tell the client that application has picked |
8251 | * the name from the offered list and reconfigured the socket. |
8252 | */ |
8253 | ssl3_RegisterServerHelloExtensionSender(ss, ssl_server_name_xtn, |
8254 | ssl3_SendServerNameXtn); |
8255 | } else { |
8256 | /* Callback returned index outside of the boundary. */ |
8257 | PORT_Assert(ret < ss->xtnData.sniNameArrSize)((ret < ss->xtnData.sniNameArrSize)?((void)0):PR_Assert ("ret < ss->xtnData.sniNameArrSize","ssl3con.c",8257)); |
8258 | errCode = SSL_ERROR_INTERNAL_ERROR_ALERT; |
8259 | desc = internal_error; |
8260 | ret = SSL_SNI_SEND_ALERT-2; |
8261 | break; |
8262 | } |
8263 | } while (0); |
8264 | /* Free sniNameArr. The data that each SECItem in the array |
8265 | * points into is the data from the input buffer "b". It will |
8266 | * not be available outside the scope of this or it's child |
8267 | * functions.*/ |
8268 | if (ss->xtnData.sniNameArr) { |
8269 | PORT_FreePORT_Free_Util(ss->xtnData.sniNameArr); |
8270 | ss->xtnData.sniNameArr = NULL((void*)0); |
8271 | ss->xtnData.sniNameArrSize = 0; |
8272 | } |
8273 | if (ret <= SSL_SNI_SEND_ALERT-2) { |
8274 | /* desc and errCode should be set. */ |
8275 | goto alert_loser; |
8276 | } |
8277 | } |
8278 | #ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS |
8279 | else if (ss->firstHsDone) { |
8280 | /* Check that we don't have the name is current spec |
8281 | * if this extension was not negotiated on the 2d hs. */ |
8282 | PRBool passed = PR_TRUE1; |
8283 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; /*******************************/ |
8284 | if (ss->ssl3.cwSpec->srvVirtName.data) { |
8285 | passed = PR_FALSE0; |
8286 | } |
8287 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; /***************************/ |
8288 | if (!passed) { |
8289 | errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; |
8290 | desc = handshake_failure; |
8291 | goto alert_loser; |
8292 | } |
8293 | } |
8294 | #endif |
8295 | |
8296 | sid = ssl3_NewSessionID(ss, PR_TRUE1); |
8297 | if (sid == NULL((void*)0)) { |
8298 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8299 | goto loser; /* memory error is set. */ |
8300 | } |
8301 | ss->sec.ci.sid = sid; |
8302 | |
8303 | ss->ssl3.hs.isResuming = PR_FALSE0; |
8304 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
8305 | rv = ssl3_SendServerHelloSequence(ss); |
8306 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
8307 | if (rv != SECSuccess) { |
8308 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8309 | goto loser; |
8310 | } |
8311 | |
8312 | if (haveXmitBufLock) { |
8313 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
8314 | haveXmitBufLock = PR_FALSE0; |
8315 | } |
8316 | |
8317 | return SECSuccess; |
8318 | |
8319 | alert_loser: |
8320 | if (haveSpecWriteLock) { |
8321 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
8322 | haveSpecWriteLock = PR_FALSE0; |
8323 | } |
8324 | (void)SSL3_SendAlert(ss, level, desc); |
8325 | /* FALLTHRU */ |
8326 | loser: |
8327 | if (haveSpecWriteLock) { |
8328 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
8329 | haveSpecWriteLock = PR_FALSE0; |
Value stored to 'haveSpecWriteLock' is never read | |
8330 | } |
8331 | |
8332 | if (haveXmitBufLock) { |
8333 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
8334 | haveXmitBufLock = PR_FALSE0; |
8335 | } |
8336 | |
8337 | PORT_SetErrorPORT_SetError_Util(errCode); |
8338 | return SECFailure; |
8339 | } |
8340 | |
8341 | /* |
8342 | * ssl3_HandleV2ClientHello is used when a V2 formatted hello comes |
8343 | * in asking to use the V3 handshake. |
8344 | * Called from ssl2_HandleClientHelloMessage() in sslcon.c |
8345 | */ |
8346 | SECStatus |
8347 | ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length) |
8348 | { |
8349 | sslSessionID * sid = NULL((void*)0); |
8350 | unsigned char * suites; |
8351 | unsigned char * random; |
8352 | SSL3ProtocolVersion version; |
8353 | SECStatus rv; |
8354 | int i; |
8355 | int j; |
8356 | int sid_length; |
8357 | int suite_length; |
8358 | int rand_length; |
8359 | int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO; |
8360 | SSL3AlertDescription desc = handshake_failure; |
8361 | |
8362 | SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle v2 client_hello" , getpid(), ss->fd); |
8363 | |
8364 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",8364)); |
8365 | |
8366 | ssl_GetSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",8366)); PR_EnterMonitor(((ss)->ssl3HandshakeLock )); } }; |
8367 | |
8368 | PORT_Memsetmemset(&ss->xtnData, 0, sizeof(TLSExtensionData)); |
8369 | |
8370 | rv = ssl3_InitState(ss); |
8371 | if (rv != SECSuccess) { |
8372 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
8373 | return rv; /* ssl3_InitState has set the error code. */ |
8374 | } |
8375 | rv = ssl3_RestartHandshakeHashes(ss); |
8376 | if (rv != SECSuccess) { |
8377 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
8378 | return rv; |
8379 | } |
8380 | |
8381 | if (ss->ssl3.hs.ws != wait_client_hello) { |
8382 | desc = unexpected_message; |
8383 | errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO; |
8384 | goto loser; /* alert_loser */ |
8385 | } |
8386 | |
8387 | version = (buffer[1] << 8) | buffer[2]; |
8388 | suite_length = (buffer[3] << 8) | buffer[4]; |
8389 | sid_length = (buffer[5] << 8) | buffer[6]; |
8390 | rand_length = (buffer[7] << 8) | buffer[8]; |
8391 | ss->clientHelloVersion = version; |
8392 | |
8393 | rv = ssl3_NegotiateVersion(ss, version, PR_TRUE1); |
8394 | if (rv != SECSuccess) { |
8395 | /* send back which ever alert client will understand. */ |
8396 | desc = (version > SSL_LIBRARY_VERSION_3_00x0300) ? protocol_version : handshake_failure; |
8397 | errCode = SSL_ERROR_NO_CYPHER_OVERLAP; |
8398 | goto alert_loser; |
8399 | } |
8400 | |
8401 | rv = ssl3_InitHandshakeHashes(ss); |
8402 | if (rv != SECSuccess) { |
8403 | desc = internal_error; |
8404 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8405 | goto alert_loser; |
8406 | } |
8407 | |
8408 | /* if we get a non-zero SID, just ignore it. */ |
8409 | if (length != |
8410 | SSL_HL_CLIENT_HELLO_HBYTES9 + suite_length + sid_length + rand_length) { |
8411 | SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d" , getpid(), ss->fd, length, 9 + suite_length + sid_length + rand_length) |
8412 | SSL_GETPID(), ss->fd, length,if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d" , getpid(), ss->fd, length, 9 + suite_length + sid_length + rand_length) |
8413 | SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length +if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d" , getpid(), ss->fd, length, 9 + suite_length + sid_length + rand_length) |
8414 | rand_length))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d" , getpid(), ss->fd, length, 9 + suite_length + sid_length + rand_length); |
8415 | goto loser; /* malformed */ /* alert_loser */ |
8416 | } |
8417 | |
8418 | suites = buffer + SSL_HL_CLIENT_HELLO_HBYTES9; |
8419 | random = suites + suite_length + sid_length; |
8420 | |
8421 | if (rand_length < SSL_MIN_CHALLENGE_BYTES16 || |
8422 | rand_length > SSL_MAX_CHALLENGE_BYTES32) { |
8423 | goto loser; /* malformed */ /* alert_loser */ |
8424 | } |
8425 | |
8426 | PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH)((32 == 32)?((void)0):PR_Assert("SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH" ,"ssl3con.c",8426)); |
8427 | |
8428 | PORT_Memsetmemset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH32); |
8429 | PORT_Memcpymemcpy( |
8430 | &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH32 - rand_length], |
8431 | random, rand_length); |
8432 | |
8433 | PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0],if (ssl_trace >= (60)) ssl_PrintBuf (ss, "client random:", &ss->ssl3.hs.client_random.rand[0], 32) |
8434 | SSL3_RANDOM_LENGTH))if (ssl_trace >= (60)) ssl_PrintBuf (ss, "client random:", &ss->ssl3.hs.client_random.rand[0], 32); |
8435 | #ifdef NSS_ENABLE_ECC1 |
8436 | /* Disable any ECC cipher suites for which we have no cert. */ |
8437 | ssl3_FilterECCipherSuitesByServerCerts(ss); |
8438 | #endif |
8439 | i = ssl3_config_match_init(ss); |
8440 | if (i <= 0) { |
8441 | errCode = PORT_GetErrorPORT_GetError_Util(); /* error code is already set. */ |
8442 | goto alert_loser; |
8443 | } |
8444 | |
8445 | /* Select a cipher suite. |
8446 | ** |
8447 | ** NOTE: This suite selection algorithm should be the same as the one in |
8448 | ** ssl3_HandleClientHello(). |
8449 | ** |
8450 | ** See the comments about export cipher suites in ssl3_HandleClientHello(). |
8451 | */ |
8452 | for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED61; j++) { |
8453 | ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j]; |
8454 | SSLVersionRange vrange = {ss->version, ss->version}; |
8455 | if (!config_match(suite, ss->ssl3.policy, PR_TRUE1, &vrange)) { |
8456 | continue; |
8457 | } |
8458 | for (i = 0; i+2 < suite_length; i += 3) { |
8459 | PRUint32 suite_i = (suites[i] << 16)|(suites[i+1] << 8)|suites[i+2]; |
8460 | if (suite_i == suite->cipher_suite) { |
8461 | ss->ssl3.hs.cipher_suite = suite->cipher_suite; |
8462 | ss->ssl3.hs.suite_def = |
8463 | ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite); |
8464 | goto suite_found; |
8465 | } |
8466 | } |
8467 | } |
8468 | errCode = SSL_ERROR_NO_CYPHER_OVERLAP; |
8469 | goto alert_loser; |
8470 | |
8471 | suite_found: |
8472 | |
8473 | /* Look for the SCSV, and if found, treat it just like an empty RI |
8474 | * extension by processing a local copy of an empty RI extension. |
8475 | */ |
8476 | for (i = 0; i+2 < suite_length; i += 3) { |
8477 | PRUint32 suite_i = (suites[i] << 16) | (suites[i+1] << 8) | suites[i+2]; |
8478 | if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV0x00FF) { |
8479 | SSL3Opaque * b2 = (SSL3Opaque *)emptyRIext; |
8480 | PRUint32 L2 = sizeof emptyRIext; |
8481 | (void)ssl3_HandleHelloExtensions(ss, &b2, &L2); |
8482 | break; |
8483 | } |
8484 | } |
8485 | |
8486 | if (ss->opt.requireSafeNegotiation && |
8487 | !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { |
8488 | desc = handshake_failure; |
8489 | errCode = SSL_ERROR_UNSAFE_NEGOTIATION; |
8490 | goto alert_loser; |
8491 | } |
8492 | |
8493 | ss->ssl3.hs.compression = ssl_compression_null; |
8494 | ss->sec.send = ssl3_SendApplicationData; |
8495 | |
8496 | /* we don't even search for a cache hit here. It's just a miss. */ |
8497 | SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses ); |
8498 | sid = ssl3_NewSessionID(ss, PR_TRUE1); |
8499 | if (sid == NULL((void*)0)) { |
8500 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8501 | goto loser; /* memory error is set. */ |
8502 | } |
8503 | ss->sec.ci.sid = sid; |
8504 | /* do not worry about memory leak of sid since it now belongs to ci */ |
8505 | |
8506 | /* We have to update the handshake hashes before we can send stuff */ |
8507 | rv = ssl3_UpdateHandshakeHashes(ss, buffer, length); |
8508 | if (rv != SECSuccess) { |
8509 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8510 | goto loser; |
8511 | } |
8512 | |
8513 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; |
8514 | rv = ssl3_SendServerHelloSequence(ss); |
8515 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; |
8516 | if (rv != SECSuccess) { |
8517 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8518 | goto loser; |
8519 | } |
8520 | |
8521 | /* XXX_1 The call stack to here is: |
8522 | * ssl_Do1stHandshake -> ssl2_HandleClientHelloMessage -> here. |
8523 | * ssl2_HandleClientHelloMessage returns whatever we return here. |
8524 | * ssl_Do1stHandshake will continue looping if it gets back either |
8525 | * SECSuccess or SECWouldBlock. |
8526 | * SECSuccess is preferable here. See XXX_1 in sslgathr.c. |
8527 | */ |
8528 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
8529 | return SECSuccess; |
8530 | |
8531 | alert_loser: |
8532 | SSL3_SendAlert(ss, alert_fatal, desc); |
8533 | loser: |
8534 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
8535 | PORT_SetErrorPORT_SetError_Util(errCode); |
8536 | return SECFailure; |
8537 | } |
8538 | |
8539 | /* The negotiated version number has been already placed in ss->version. |
8540 | ** |
8541 | ** Called from: ssl3_HandleClientHello (resuming session), |
8542 | ** ssl3_SendServerHelloSequence <- ssl3_HandleClientHello (new session), |
8543 | ** ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session) |
8544 | */ |
8545 | static SECStatus |
8546 | ssl3_SendServerHello(sslSocket *ss) |
8547 | { |
8548 | sslSessionID *sid; |
8549 | SECStatus rv; |
8550 | PRUint32 maxBytes = 65535; |
8551 | PRUint32 length; |
8552 | PRInt32 extensions_len = 0; |
8553 | SSL3ProtocolVersion version; |
8554 | |
8555 | SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send server_hello handshake" , getpid(), ss->fd) |
8556 | ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send server_hello handshake" , getpid(), ss->fd); |
8557 | |
8558 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",8558)); |
8559 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",8559)); |
8560 | |
8561 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
8562 | PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0))((((unsigned char) (((unsigned)(ss->version)) >> 8)) == ((unsigned char) (((unsigned)(0x0300)) >> 8)))?((void )0):PR_Assert("MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0)" ,"ssl3con.c",8562)); |
8563 | |
8564 | if (MSB(ss->version)((unsigned char) (((unsigned)(ss->version)) >> 8)) != MSB(SSL_LIBRARY_VERSION_3_0)((unsigned char) (((unsigned)(0x0300)) >> 8))) { |
8565 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_CYPHER_OVERLAP); |
8566 | return SECFailure; |
8567 | } |
8568 | } else { |
8569 | PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_DTLS_1_0))((((unsigned char) (((unsigned)(ss->version)) >> 8)) == ((unsigned char) (((unsigned)(0x0302)) >> 8)))?((void )0):PR_Assert("MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_DTLS_1_0)" ,"ssl3con.c",8569)); |
8570 | |
8571 | if (MSB(ss->version)((unsigned char) (((unsigned)(ss->version)) >> 8)) != MSB(SSL_LIBRARY_VERSION_DTLS_1_0)((unsigned char) (((unsigned)(0x0302)) >> 8))) { |
8572 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_CYPHER_OVERLAP); |
8573 | return SECFailure; |
8574 | } |
8575 | } |
8576 | |
8577 | sid = ss->sec.ci.sid; |
8578 | |
8579 | extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE0, maxBytes, |
8580 | &ss->xtnData.serverSenders[0]); |
8581 | if (extensions_len > 0) |
8582 | extensions_len += 2; /* Add sizeof total extension length */ |
8583 | |
8584 | length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH32 + 1 + |
8585 | ((sid == NULL((void*)0)) ? 0: sid->u.ssl3.sessionIDLength) + |
8586 | sizeof(ssl3CipherSuite) + 1 + extensions_len; |
8587 | rv = ssl3_AppendHandshakeHeader(ss, server_hello, length); |
8588 | if (rv != SECSuccess) { |
8589 | return rv; /* err set by AppendHandshake. */ |
8590 | } |
8591 | |
8592 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
8593 | version = dtls_TLSVersionToDTLSVersion(ss->version); |
8594 | } else { |
8595 | version = ss->version; |
8596 | } |
8597 | |
8598 | rv = ssl3_AppendHandshakeNumber(ss, version, 2); |
8599 | if (rv != SECSuccess) { |
8600 | return rv; /* err set by AppendHandshake. */ |
8601 | } |
8602 | rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random); |
8603 | if (rv != SECSuccess) { |
8604 | ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); |
8605 | return rv; |
8606 | } |
8607 | rv = ssl3_AppendHandshake( |
8608 | ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH32); |
8609 | if (rv != SECSuccess) { |
8610 | return rv; /* err set by AppendHandshake. */ |
8611 | } |
8612 | |
8613 | if (sid) |
8614 | rv = ssl3_AppendHandshakeVariable( |
8615 | ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1); |
8616 | else |
8617 | rv = ssl3_AppendHandshakeVariable(ss, NULL((void*)0), 0, 1); |
8618 | if (rv != SECSuccess) { |
8619 | return rv; /* err set by AppendHandshake. */ |
8620 | } |
8621 | |
8622 | rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2); |
8623 | if (rv != SECSuccess) { |
8624 | return rv; /* err set by AppendHandshake. */ |
8625 | } |
8626 | rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1); |
8627 | if (rv != SECSuccess) { |
8628 | return rv; /* err set by AppendHandshake. */ |
8629 | } |
8630 | if (extensions_len) { |
8631 | PRInt32 sent_len; |
8632 | |
8633 | extensions_len -= 2; |
8634 | rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2); |
8635 | if (rv != SECSuccess) |
8636 | return rv; /* err set by ssl3_SetupPendingCipherSpec */ |
8637 | sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE1, extensions_len, |
8638 | &ss->xtnData.serverSenders[0]); |
8639 | PORT_Assert(sent_len == extensions_len)((sent_len == extensions_len)?((void)0):PR_Assert("sent_len == extensions_len" ,"ssl3con.c",8639)); |
8640 | if (sent_len != extensions_len) { |
8641 | if (sent_len >= 0) |
8642 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
8643 | return SECFailure; |
8644 | } |
8645 | } |
8646 | rv = ssl3_SetupPendingCipherSpec(ss); |
8647 | if (rv != SECSuccess) { |
8648 | return rv; /* err set by ssl3_SetupPendingCipherSpec */ |
8649 | } |
8650 | |
8651 | return SECSuccess; |
8652 | } |
8653 | |
8654 | /* ssl3_PickSignatureHashAlgorithm selects a hash algorithm to use when signing |
8655 | * elements of the handshake. (The negotiated cipher suite determines the |
8656 | * signature algorithm.) Prior to TLS 1.2, the MD5/SHA1 combination is always |
8657 | * used. With TLS 1.2, a client may advertise its support for signature and |
8658 | * hash combinations. */ |
8659 | static SECStatus |
8660 | ssl3_PickSignatureHashAlgorithm(sslSocket *ss, |
8661 | SSL3SignatureAndHashAlgorithm* out) |
8662 | { |
8663 | TLSSignatureAlgorithm sigAlg; |
8664 | unsigned int i, j; |
8665 | /* hashPreference expresses our preferences for hash algorithms, most |
8666 | * preferable first. */ |
8667 | static const PRUint8 hashPreference[] = { |
8668 | tls_hash_sha256, |
8669 | tls_hash_sha384, |
8670 | tls_hash_sha512, |
8671 | tls_hash_sha1, |
8672 | }; |
8673 | |
8674 | switch (ss->ssl3.hs.kea_def->kea) { |
8675 | case kea_rsa: |
8676 | case kea_rsa_export: |
8677 | case kea_rsa_export_1024: |
8678 | case kea_dh_rsa: |
8679 | case kea_dh_rsa_export: |
8680 | case kea_dhe_rsa: |
8681 | case kea_dhe_rsa_export: |
8682 | case kea_rsa_fips: |
8683 | case kea_ecdh_rsa: |
8684 | case kea_ecdhe_rsa: |
8685 | sigAlg = tls_sig_rsa; |
8686 | break; |
8687 | case kea_dh_dss: |
8688 | case kea_dh_dss_export: |
8689 | case kea_dhe_dss: |
8690 | case kea_dhe_dss_export: |
8691 | sigAlg = tls_sig_dsa; |
8692 | break; |
8693 | case kea_ecdh_ecdsa: |
8694 | case kea_ecdhe_ecdsa: |
8695 | sigAlg = tls_sig_ecdsa; |
8696 | break; |
8697 | default: |
8698 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_UNSUPPORTED_KEYALG); |
8699 | return SECFailure; |
8700 | } |
8701 | out->sigAlg = sigAlg; |
8702 | |
8703 | if (ss->version <= SSL_LIBRARY_VERSION_TLS_1_10x0302) { |
8704 | /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and |
8705 | * prior. */ |
8706 | out->hashAlg = SEC_OID_UNKNOWN; |
8707 | return SECSuccess; |
8708 | } |
8709 | |
8710 | if (ss->ssl3.hs.numClientSigAndHash == 0) { |
8711 | /* If the client didn't provide any signature_algorithms extension then |
8712 | * we can assume that they support SHA-1: |
8713 | * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
8714 | out->hashAlg = SEC_OID_SHA1; |
8715 | return SECSuccess; |
8716 | } |
8717 | |
8718 | for (i = 0; i < PR_ARRAY_SIZE(hashPreference)(sizeof(hashPreference)/sizeof((hashPreference)[0])); i++) { |
8719 | for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) { |
8720 | const SSL3SignatureAndHashAlgorithm* sh = |
8721 | &ss->ssl3.hs.clientSigAndHash[j]; |
8722 | if (sh->sigAlg == sigAlg && sh->hashAlg == hashPreference[i]) { |
8723 | out->hashAlg = sh->hashAlg; |
8724 | return SECSuccess; |
8725 | } |
8726 | } |
8727 | } |
8728 | |
8729 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
8730 | return SECFailure; |
8731 | } |
8732 | |
8733 | |
8734 | static SECStatus |
8735 | ssl3_SendServerKeyExchange(sslSocket *ss) |
8736 | { |
8737 | const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
8738 | SECStatus rv = SECFailure; |
8739 | int length; |
8740 | PRBool isTLS; |
8741 | SECItem signed_hash = {siBuffer, NULL((void*)0), 0}; |
8742 | SSL3Hashes hashes; |
8743 | SECKEYPublicKey * sdPub; /* public key for step-down */ |
8744 | SSL3SignatureAndHashAlgorithm sigAndHash; |
8745 | |
8746 | SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send server_key_exchange handshake" , getpid(), ss->fd) |
8747 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send server_key_exchange handshake" , getpid(), ss->fd); |
8748 | |
8749 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",8749)); |
8750 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",8750)); |
8751 | |
8752 | if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) { |
8753 | return SECFailure; |
8754 | } |
8755 | |
8756 | switch (kea_def->exchKeyType) { |
8757 | case kt_rsassl_kea_rsa: |
8758 | /* Perform SSL Step-Down here. */ |
8759 | sdPub = ss->stepDownKeyPair->pubKey; |
8760 | PORT_Assert(sdPub != NULL)((sdPub != ((void*)0))?((void)0):PR_Assert("sdPub != NULL","ssl3con.c" ,8760)); |
8761 | if (!sdPub) { |
8762 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
8763 | return SECFailure; |
8764 | } |
8765 | rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, |
8766 | sdPub->u.rsa.modulus, |
8767 | sdPub->u.rsa.publicExponent, |
8768 | &ss->ssl3.hs.client_random, |
8769 | &ss->ssl3.hs.server_random, |
8770 | &hashes, ss->opt.bypassPKCS11); |
8771 | if (rv != SECSuccess) { |
8772 | ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
8773 | return rv; |
8774 | } |
8775 | |
8776 | isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
8777 | rv = ssl3_SignHashes(&hashes, ss->serverCerts[kt_rsassl_kea_rsa].SERVERKEYserverKeyPair->privKey, |
8778 | &signed_hash, isTLS); |
8779 | if (rv != SECSuccess) { |
8780 | goto loser; /* ssl3_SignHashes has set err. */ |
8781 | } |
8782 | if (signed_hash.data == NULL((void*)0)) { |
8783 | /* how can this happen and rv == SECSuccess ?? */ |
8784 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
8785 | goto loser; |
8786 | } |
8787 | length = 2 + sdPub->u.rsa.modulus.len + |
8788 | 2 + sdPub->u.rsa.publicExponent.len + |
8789 | 2 + signed_hash.len; |
8790 | |
8791 | rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); |
8792 | if (rv != SECSuccess) { |
8793 | goto loser; /* err set by AppendHandshake. */ |
8794 | } |
8795 | |
8796 | rv = ssl3_AppendHandshakeVariable(ss, sdPub->u.rsa.modulus.data, |
8797 | sdPub->u.rsa.modulus.len, 2); |
8798 | if (rv != SECSuccess) { |
8799 | goto loser; /* err set by AppendHandshake. */ |
8800 | } |
8801 | |
8802 | rv = ssl3_AppendHandshakeVariable( |
8803 | ss, sdPub->u.rsa.publicExponent.data, |
8804 | sdPub->u.rsa.publicExponent.len, 2); |
8805 | if (rv != SECSuccess) { |
8806 | goto loser; /* err set by AppendHandshake. */ |
8807 | } |
8808 | |
8809 | if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303) { |
8810 | rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); |
8811 | if (rv != SECSuccess) { |
8812 | goto loser; /* err set by AppendHandshake. */ |
8813 | } |
8814 | } |
8815 | |
8816 | rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, |
8817 | signed_hash.len, 2); |
8818 | if (rv != SECSuccess) { |
8819 | goto loser; /* err set by AppendHandshake. */ |
8820 | } |
8821 | PORT_FreePORT_Free_Util(signed_hash.data); |
8822 | return SECSuccess; |
8823 | |
8824 | #ifdef NSS_ENABLE_ECC1 |
8825 | case kt_ecdhssl_kea_ecdh: { |
8826 | rv = ssl3_SendECDHServerKeyExchange(ss, &sigAndHash); |
8827 | return rv; |
8828 | } |
8829 | #endif /* NSS_ENABLE_ECC */ |
8830 | |
8831 | case kt_dhssl_kea_dh: |
8832 | case kt_nullssl_kea_null: |
8833 | default: |
8834 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_UNSUPPORTED_KEYALG); |
8835 | break; |
8836 | } |
8837 | loser: |
8838 | if (signed_hash.data != NULL((void*)0)) |
8839 | PORT_FreePORT_Free_Util(signed_hash.data); |
8840 | return SECFailure; |
8841 | } |
8842 | |
8843 | |
8844 | static SECStatus |
8845 | ssl3_SendCertificateRequest(sslSocket *ss) |
8846 | { |
8847 | PRBool isTLS12; |
8848 | SECItem * name; |
8849 | CERTDistNames *ca_list; |
8850 | const PRUint8 *certTypes; |
8851 | const PRUint8 *sigAlgs; |
8852 | SECItem * names = NULL((void*)0); |
8853 | SECStatus rv; |
8854 | int length; |
8855 | int i; |
8856 | int calen = 0; |
8857 | int nnames = 0; |
8858 | int certTypesLength; |
8859 | int sigAlgsLength; |
8860 | |
8861 | SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate_request handshake" , getpid(), ss->fd) |
8862 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate_request handshake" , getpid(), ss->fd); |
8863 | |
8864 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",8864)); |
8865 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",8865)); |
8866 | |
8867 | isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
8868 | |
8869 | /* ssl3.ca_list is initialized to NULL, and never changed. */ |
8870 | ca_list = ss->ssl3.ca_list; |
8871 | if (!ca_list) { |
8872 | ca_list = ssl3_server_ca_list; |
8873 | } |
8874 | |
8875 | if (ca_list != NULL((void*)0)) { |
8876 | names = ca_list->names; |
8877 | nnames = ca_list->nnames; |
8878 | } |
8879 | |
8880 | for (i = 0, name = names; i < nnames; i++, name++) { |
8881 | calen += 2 + name->len; |
8882 | } |
8883 | |
8884 | certTypes = certificate_types; |
8885 | certTypesLength = sizeof certificate_types; |
8886 | sigAlgs = supported_signature_algorithms; |
8887 | sigAlgsLength = sizeof supported_signature_algorithms; |
8888 | |
8889 | length = 1 + certTypesLength + 2 + calen; |
8890 | if (isTLS12) { |
8891 | length += 2 + sigAlgsLength; |
8892 | } |
8893 | |
8894 | rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length); |
8895 | if (rv != SECSuccess) { |
8896 | return rv; /* err set by AppendHandshake. */ |
8897 | } |
8898 | rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1); |
8899 | if (rv != SECSuccess) { |
8900 | return rv; /* err set by AppendHandshake. */ |
8901 | } |
8902 | if (isTLS12) { |
8903 | rv = ssl3_AppendHandshakeVariable(ss, sigAlgs, sigAlgsLength, 2); |
8904 | if (rv != SECSuccess) { |
8905 | return rv; /* err set by AppendHandshake. */ |
8906 | } |
8907 | } |
8908 | rv = ssl3_AppendHandshakeNumber(ss, calen, 2); |
8909 | if (rv != SECSuccess) { |
8910 | return rv; /* err set by AppendHandshake. */ |
8911 | } |
8912 | for (i = 0, name = names; i < nnames; i++, name++) { |
8913 | rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2); |
8914 | if (rv != SECSuccess) { |
8915 | return rv; /* err set by AppendHandshake. */ |
8916 | } |
8917 | } |
8918 | |
8919 | return SECSuccess; |
8920 | } |
8921 | |
8922 | static SECStatus |
8923 | ssl3_SendServerHelloDone(sslSocket *ss) |
8924 | { |
8925 | SECStatus rv; |
8926 | |
8927 | SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send server_hello_done handshake" , getpid(), ss->fd) |
8928 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send server_hello_done handshake" , getpid(), ss->fd); |
8929 | |
8930 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",8930)); |
8931 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",8931)); |
8932 | |
8933 | rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0); |
8934 | if (rv != SECSuccess) { |
8935 | return rv; /* err set by AppendHandshake. */ |
8936 | } |
8937 | rv = ssl3_FlushHandshake(ss, 0); |
8938 | if (rv != SECSuccess) { |
8939 | return rv; /* error code set by ssl3_FlushHandshake */ |
8940 | } |
8941 | return SECSuccess; |
8942 | } |
8943 | |
8944 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
8945 | * ssl3 Certificate Verify message |
8946 | * Caller must hold Handshake and RecvBuf locks. |
8947 | */ |
8948 | static SECStatus |
8949 | ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, |
8950 | SSL3Hashes *hashes) |
8951 | { |
8952 | SECItem signed_hash = {siBuffer, NULL((void*)0), 0}; |
8953 | SECStatus rv; |
8954 | int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY; |
8955 | SSL3AlertDescription desc = handshake_failure; |
8956 | PRBool isTLS, isTLS12; |
8957 | SSL3SignatureAndHashAlgorithm sigAndHash; |
8958 | |
8959 | SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle certificate_verify handshake" , getpid(), ss->fd) |
8960 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle certificate_verify handshake" , getpid(), ss->fd); |
8961 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",8961)); |
8962 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",8962)); |
8963 | |
8964 | isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
8965 | isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303); |
8966 | |
8967 | if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL((void*)0)) { |
8968 | desc = unexpected_message; |
8969 | errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY; |
8970 | goto alert_loser; |
8971 | } |
8972 | |
8973 | if (isTLS12) { |
8974 | rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
8975 | &sigAndHash); |
8976 | if (rv != SECSuccess) { |
8977 | goto loser; /* malformed or unsupported. */ |
8978 | } |
8979 | rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
8980 | &sigAndHash, ss->sec.peerCert); |
8981 | if (rv != SECSuccess) { |
8982 | errCode = PORT_GetErrorPORT_GetError_Util(); |
8983 | desc = decrypt_error; |
8984 | goto alert_loser; |
8985 | } |
8986 | |
8987 | /* We only support CertificateVerify messages that use the handshake |
8988 | * hash. */ |
8989 | if (sigAndHash.hashAlg != hashes->hashAlg) { |
8990 | errCode = SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM; |
8991 | desc = decrypt_error; |
8992 | goto alert_loser; |
8993 | } |
8994 | } |
8995 | |
8996 | rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length); |
8997 | if (rv != SECSuccess) { |
8998 | goto loser; /* malformed. */ |
8999 | } |
9000 | |
9001 | /* XXX verify that the key & kea match */ |
9002 | rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash, |
9003 | isTLS, ss->pkcs11PinArg); |
9004 | if (rv != SECSuccess) { |
9005 | errCode = PORT_GetErrorPORT_GetError_Util(); |
9006 | desc = isTLS ? decrypt_error : handshake_failure; |
9007 | goto alert_loser; |
9008 | } |
9009 | |
9010 | signed_hash.data = NULL((void*)0); |
9011 | |
9012 | if (length != 0) { |
9013 | desc = isTLS ? decode_error : illegal_parameter; |
9014 | goto alert_loser; /* malformed */ |
9015 | } |
9016 | ss->ssl3.hs.ws = wait_change_cipher; |
9017 | return SECSuccess; |
9018 | |
9019 | alert_loser: |
9020 | SSL3_SendAlert(ss, alert_fatal, desc); |
9021 | loser: |
9022 | PORT_SetErrorPORT_SetError_Util(errCode); |
9023 | return SECFailure; |
9024 | } |
9025 | |
9026 | |
9027 | /* find a slot that is able to generate a PMS and wrap it with RSA. |
9028 | * Then generate and return the PMS. |
9029 | * If the serverKeySlot parameter is non-null, this function will use |
9030 | * that slot to do the job, otherwise it will find a slot. |
9031 | * |
9032 | * Called from ssl3_DeriveConnectionKeysPKCS11() (above) |
9033 | * sendRSAClientKeyExchange() (above) |
9034 | * ssl3_HandleRSAClientKeyExchange() (below) |
9035 | * Caller must hold the SpecWriteLock, the SSL3HandshakeLock |
9036 | */ |
9037 | static PK11SymKey * |
9038 | ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, |
9039 | PK11SlotInfo * serverKeySlot) |
9040 | { |
9041 | PK11SymKey * pms = NULL((void*)0); |
9042 | PK11SlotInfo * slot = serverKeySlot; |
9043 | void * pwArg = ss->pkcs11PinArg; |
9044 | SECItem param; |
9045 | CK_VERSION version; |
9046 | CK_MECHANISM_TYPE mechanism_array[3]; |
9047 | |
9048 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9048)); |
9049 | |
9050 | if (slot == NULL((void*)0)) { |
9051 | SSLCipherAlgorithm calg; |
9052 | /* The specReadLock would suffice here, but we cannot assert on |
9053 | ** read locks. Also, all the callers who call with a non-null |
9054 | ** slot already hold the SpecWriteLock. |
9055 | */ |
9056 | PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss))((ss->opt.noLocks || (NSSRWLock_HaveWriteLock_Util((ss)-> specLock)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)" ,"ssl3con.c",9056)); |
9057 | PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec)((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",9057) ); |
9058 | |
9059 | calg = spec->cipher_def->calg; |
9060 | PORT_Assert(alg2Mech[calg].calg == calg)((alg2Mech[calg].calg == calg)?((void)0):PR_Assert("alg2Mech[calg].calg == calg" ,"ssl3con.c",9060)); |
9061 | |
9062 | /* First get an appropriate slot. */ |
9063 | mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN0x00000370; |
9064 | mechanism_array[1] = CKM_RSA_PKCS0x00000001; |
9065 | mechanism_array[2] = alg2Mech[calg].cmech; |
9066 | |
9067 | slot = PK11_GetBestSlotMultiple(mechanism_array, 3, pwArg); |
9068 | if (slot == NULL((void*)0)) { |
9069 | /* can't find a slot with all three, find a slot with the minimum */ |
9070 | slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); |
9071 | if (slot == NULL((void*)0)) { |
9072 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); |
9073 | return pms; /* which is NULL */ |
9074 | } |
9075 | } |
9076 | } |
9077 | |
9078 | /* Generate the pre-master secret ... */ |
9079 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
9080 | SSL3ProtocolVersion temp; |
9081 | |
9082 | temp = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion); |
9083 | version.major = MSB(temp)((unsigned char) (((unsigned)(temp)) >> 8)); |
9084 | version.minor = LSB(temp)((unsigned char) ((temp) & 0xff)); |
9085 | } else { |
9086 | version.major = MSB(ss->clientHelloVersion)((unsigned char) (((unsigned)(ss->clientHelloVersion)) >> 8)); |
9087 | version.minor = LSB(ss->clientHelloVersion)((unsigned char) ((ss->clientHelloVersion) & 0xff)); |
9088 | } |
9089 | |
9090 | param.data = (unsigned char *)&version; |
9091 | param.len = sizeof version; |
9092 | |
9093 | pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN0x00000370, ¶m, 0, pwArg); |
9094 | if (!serverKeySlot) |
9095 | PK11_FreeSlot(slot); |
9096 | if (pms == NULL((void*)0)) { |
9097 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
9098 | } |
9099 | return pms; |
9100 | } |
9101 | |
9102 | /* Note: The Bleichenbacher attack on PKCS#1 necessitates that we NEVER |
9103 | * return any indication of failure of the Client Key Exchange message, |
9104 | * where that failure is caused by the content of the client's message. |
9105 | * This function must not return SECFailure for any reason that is directly |
9106 | * or indirectly caused by the content of the client's encrypted PMS. |
9107 | * We must not send an alert and also not drop the connection. |
9108 | * Instead, we generate a random PMS. This will cause a failure |
9109 | * in the processing the finished message, which is exactly where |
9110 | * the failure must occur. |
9111 | * |
9112 | * Called from ssl3_HandleClientKeyExchange |
9113 | */ |
9114 | static SECStatus |
9115 | ssl3_HandleRSAClientKeyExchange(sslSocket *ss, |
9116 | SSL3Opaque *b, |
9117 | PRUint32 length, |
9118 | SECKEYPrivateKey *serverKey) |
9119 | { |
9120 | PK11SymKey * pms; |
9121 | #ifndef NO_PKCS11_BYPASS1 |
9122 | unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random; |
9123 | unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random; |
9124 | ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; |
9125 | unsigned int outLen = 0; |
9126 | #endif |
9127 | PRBool isTLS = PR_FALSE0; |
9128 | SECStatus rv; |
9129 | SECItem enc_pms; |
9130 | unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH48]; |
9131 | SECItem pmsItem = {siBuffer, NULL((void*)0), 0}; |
9132 | |
9133 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",9133)); |
9134 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9134)); |
9135 | PORT_Assert( ss->ssl3.prSpec == ss->ssl3.pwSpec )((ss->ssl3.prSpec == ss->ssl3.pwSpec)?((void)0):PR_Assert ("ss->ssl3.prSpec == ss->ssl3.pwSpec","ssl3con.c",9135) ); |
9136 | |
9137 | enc_pms.data = b; |
9138 | enc_pms.len = length; |
9139 | pmsItem.data = rsaPmsBuf; |
9140 | pmsItem.len = sizeof rsaPmsBuf; |
9141 | |
9142 | if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_00x0300) { /* isTLS */ |
9143 | PRInt32 kLen; |
9144 | kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len); |
9145 | if (kLen < 0) { |
9146 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
9147 | return SECFailure; |
9148 | } |
9149 | if ((unsigned)kLen < enc_pms.len) { |
9150 | enc_pms.len = kLen; |
9151 | } |
9152 | isTLS = PR_TRUE1; |
9153 | } else { |
9154 | isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0); |
9155 | } |
9156 | |
9157 | #ifndef NO_PKCS11_BYPASS1 |
9158 | if (ss->opt.bypassPKCS11) { |
9159 | /* TRIPLE BYPASS, get PMS directly from RSA decryption. |
9160 | * Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer, |
9161 | * then, check for version rollback attack, then |
9162 | * do the equivalent of ssl3_DeriveMasterSecret, placing the MS in |
9163 | * pwSpec->msItem. Finally call ssl3_InitPendingCipherSpec with |
9164 | * ss and NULL, so that it will use the MS we've already derived here. |
9165 | */ |
9166 | |
9167 | rv = PK11_PrivDecryptPKCS1(serverKey, rsaPmsBuf, &outLen, |
9168 | sizeof rsaPmsBuf, enc_pms.data, enc_pms.len); |
9169 | if (rv != SECSuccess) { |
9170 | /* triple bypass failed. Let's try for a double bypass. */ |
9171 | goto double_bypass; |
9172 | } else if (ss->opt.detectRollBack) { |
9173 | SSL3ProtocolVersion client_version = |
9174 | (rsaPmsBuf[0] << 8) | rsaPmsBuf[1]; |
9175 | |
9176 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
9177 | client_version = dtls_DTLSVersionToTLSVersion(client_version); |
9178 | } |
9179 | |
9180 | if (client_version != ss->clientHelloVersion) { |
9181 | /* Version roll-back detected. ensure failure. */ |
9182 | rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf); |
9183 | } |
9184 | } |
9185 | /* have PMS, build MS without PKCS11 */ |
9186 | rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS, |
9187 | PR_TRUE1); |
9188 | if (rv != SECSuccess) { |
9189 | pwSpec->msItem.data = pwSpec->raw_master_secret; |
9190 | pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH48; |
9191 | PK11_GenerateRandom(pwSpec->msItem.data, pwSpec->msItem.len); |
9192 | } |
9193 | rv = ssl3_InitPendingCipherSpec(ss, NULL((void*)0)); |
9194 | } else |
9195 | #endif |
9196 | { |
9197 | #ifndef NO_PKCS11_BYPASS1 |
9198 | double_bypass: |
9199 | #endif |
9200 | /* |
9201 | * unwrap pms out of the incoming buffer |
9202 | * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do |
9203 | * the unwrap. Rather, it is the mechanism with which the |
9204 | * unwrapped pms will be used. |
9205 | */ |
9206 | pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms, |
9207 | CKM_SSL3_MASTER_KEY_DERIVE0x00000371, CKA_DERIVE0x0000010C, 0); |
9208 | if (pms != NULL((void*)0)) { |
9209 | PRINT_BUF(60, (ss, "decrypted premaster secret:",if (ssl_trace >= (60)) ssl_PrintBuf (ss, "decrypted premaster secret:" , PK11_GetKeyData(pms)->data, PK11_GetKeyData(pms)->len ) |
9210 | PK11_GetKeyData(pms)->data,if (ssl_trace >= (60)) ssl_PrintBuf (ss, "decrypted premaster secret:" , PK11_GetKeyData(pms)->data, PK11_GetKeyData(pms)->len ) |
9211 | PK11_GetKeyData(pms)->len))if (ssl_trace >= (60)) ssl_PrintBuf (ss, "decrypted premaster secret:" , PK11_GetKeyData(pms)->data, PK11_GetKeyData(pms)->len ); |
9212 | } else { |
9213 | /* unwrap failed. Generate a bogus PMS and carry on. */ |
9214 | PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey); |
9215 | |
9216 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; |
9217 | pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot); |
9218 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
9219 | PK11_FreeSlot(slot); |
9220 | } |
9221 | |
9222 | if (pms == NULL((void*)0)) { |
9223 | /* last gasp. */ |
9224 | ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
9225 | return SECFailure; |
9226 | } |
9227 | |
9228 | /* This step will derive the MS from the PMS, among other things. */ |
9229 | rv = ssl3_InitPendingCipherSpec(ss, pms); |
9230 | PK11_FreeSymKey(pms); |
9231 | } |
9232 | |
9233 | if (rv != SECSuccess) { |
9234 | SEND_ALERT |
9235 | return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */ |
9236 | } |
9237 | return SECSuccess; |
9238 | } |
9239 | |
9240 | |
9241 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
9242 | * ssl3 ClientKeyExchange message from the remote client |
9243 | * Caller must hold Handshake and RecvBuf locks. |
9244 | */ |
9245 | static SECStatus |
9246 | ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
9247 | { |
9248 | SECKEYPrivateKey *serverKey = NULL((void*)0); |
9249 | SECStatus rv; |
9250 | const ssl3KEADef *kea_def; |
9251 | ssl3KeyPair *serverKeyPair = NULL((void*)0); |
9252 | #ifdef NSS_ENABLE_ECC1 |
9253 | SECKEYPublicKey *serverPubKey = NULL((void*)0); |
9254 | #endif /* NSS_ENABLE_ECC */ |
9255 | |
9256 | SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle client_key_exchange handshake" , getpid(), ss->fd) |
9257 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle client_key_exchange handshake" , getpid(), ss->fd); |
9258 | |
9259 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",9259)); |
9260 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9260)); |
9261 | |
9262 | if (ss->ssl3.hs.ws != wait_client_key) { |
9263 | SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
9264 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH); |
9265 | return SECFailure; |
9266 | } |
9267 | |
9268 | kea_def = ss->ssl3.hs.kea_def; |
9269 | |
9270 | if (ss->ssl3.hs.usedStepDownKey) { |
9271 | PORT_Assert(kea_def->is_limited /* XXX OR cert is signing only */((kea_def->is_limited && kea_def->exchKeyType == ssl_kea_rsa && ss->stepDownKeyPair != ((void*)0)) ?((void)0):PR_Assert("kea_def->is_limited && kea_def->exchKeyType == kt_rsa && ss->stepDownKeyPair != NULL" ,"ssl3con.c",9273)) |
9272 | && kea_def->exchKeyType == kt_rsa((kea_def->is_limited && kea_def->exchKeyType == ssl_kea_rsa && ss->stepDownKeyPair != ((void*)0)) ?((void)0):PR_Assert("kea_def->is_limited && kea_def->exchKeyType == kt_rsa && ss->stepDownKeyPair != NULL" ,"ssl3con.c",9273)) |
9273 | && ss->stepDownKeyPair != NULL)((kea_def->is_limited && kea_def->exchKeyType == ssl_kea_rsa && ss->stepDownKeyPair != ((void*)0)) ?((void)0):PR_Assert("kea_def->is_limited && kea_def->exchKeyType == kt_rsa && ss->stepDownKeyPair != NULL" ,"ssl3con.c",9273)); |
9274 | if (!kea_def->is_limited || |
9275 | kea_def->exchKeyType != kt_rsassl_kea_rsa || |
9276 | ss->stepDownKeyPair == NULL((void*)0)) { |
9277 | /* shouldn't happen, don't use step down if it does */ |
9278 | goto skip; |
9279 | } |
9280 | serverKeyPair = ss->stepDownKeyPair; |
9281 | ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH64 * BPB8; |
9282 | } else |
9283 | skip: |
9284 | #ifdef NSS_ENABLE_ECC1 |
9285 | /* XXX Using SSLKEAType to index server certifiates |
9286 | * does not work for (EC)DHE ciphers. Until we have |
9287 | * an indexing mechanism general enough for all key |
9288 | * exchange algorithms, we'll need to deal with each |
9289 | * one seprately. |
9290 | */ |
9291 | if ((kea_def->kea == kea_ecdhe_rsa) || |
9292 | (kea_def->kea == kea_ecdhe_ecdsa)) { |
9293 | if (ss->ephemeralECDHKeyPair != NULL((void*)0)) { |
9294 | serverKeyPair = ss->ephemeralECDHKeyPair; |
9295 | if (serverKeyPair->pubKey) { |
9296 | ss->sec.keaKeyBits = |
9297 | SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey); |
9298 | } |
9299 | } |
9300 | } else |
9301 | #endif |
9302 | { |
9303 | sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType; |
9304 | serverKeyPair = sc->serverKeyPair; |
9305 | ss->sec.keaKeyBits = sc->serverKeyBits; |
9306 | } |
9307 | |
9308 | if (serverKeyPair) { |
9309 | serverKey = serverKeyPair->privKey; |
9310 | } |
9311 | |
9312 | if (serverKey == NULL((void*)0)) { |
9313 | SEND_ALERT |
9314 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_NO_SERVER_KEY_FOR_ALG); |
9315 | return SECFailure; |
9316 | } |
9317 | |
9318 | ss->sec.keaType = kea_def->exchKeyType; |
9319 | |
9320 | switch (kea_def->exchKeyType) { |
9321 | case kt_rsassl_kea_rsa: |
9322 | rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKey); |
9323 | if (rv != SECSuccess) { |
9324 | SEND_ALERT |
9325 | return SECFailure; /* error code set */ |
9326 | } |
9327 | break; |
9328 | |
9329 | |
9330 | #ifdef NSS_ENABLE_ECC1 |
9331 | case kt_ecdhssl_kea_ecdh: |
9332 | /* XXX We really ought to be able to store multiple |
9333 | * EC certs (a requirement if we wish to support both |
9334 | * ECDH-RSA and ECDH-ECDSA key exchanges concurrently). |
9335 | * When we make that change, we'll need an index other |
9336 | * than kt_ecdh to pick the right EC certificate. |
9337 | */ |
9338 | if (serverKeyPair) { |
9339 | serverPubKey = serverKeyPair->pubKey; |
9340 | } |
9341 | if (serverPubKey == NULL((void*)0)) { |
9342 | /* XXX Is this the right error code? */ |
9343 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
9344 | return SECFailure; |
9345 | } |
9346 | rv = ssl3_HandleECDHClientKeyExchange(ss, b, length, |
9347 | serverPubKey, serverKey); |
9348 | if (rv != SECSuccess) { |
9349 | return SECFailure; /* error code set */ |
9350 | } |
9351 | break; |
9352 | #endif /* NSS_ENABLE_ECC */ |
9353 | |
9354 | default: |
9355 | (void) ssl3_HandshakeFailure(ss); |
9356 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_UNSUPPORTED_KEYALG); |
9357 | return SECFailure; |
9358 | } |
9359 | ss->ssl3.hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher; |
9360 | return SECSuccess; |
9361 | |
9362 | } |
9363 | |
9364 | /* This is TLS's equivalent of sending a no_certificate alert. */ |
9365 | static SECStatus |
9366 | ssl3_SendEmptyCertificate(sslSocket *ss) |
9367 | { |
9368 | SECStatus rv; |
9369 | |
9370 | rv = ssl3_AppendHandshakeHeader(ss, certificate, 3); |
9371 | if (rv == SECSuccess) { |
9372 | rv = ssl3_AppendHandshakeNumber(ss, 0, 3); |
9373 | } |
9374 | return rv; /* error, if any, set by functions called above. */ |
9375 | } |
9376 | |
9377 | SECStatus |
9378 | ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
9379 | { |
9380 | SECStatus rv; |
9381 | SECItem ticketData; |
9382 | |
9383 | SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle session_ticket handshake" , getpid(), ss->fd) |
9384 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle session_ticket handshake" , getpid(), ss->fd); |
9385 | |
9386 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",9386)); |
9387 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9387)); |
9388 | |
9389 | PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data)((!ss->ssl3.hs.newSessionTicket.ticket.data)?((void)0):PR_Assert ("!ss->ssl3.hs.newSessionTicket.ticket.data","ssl3con.c",9389 )); |
9390 | PORT_Assert(!ss->ssl3.hs.receivedNewSessionTicket)((!ss->ssl3.hs.receivedNewSessionTicket)?((void)0):PR_Assert ("!ss->ssl3.hs.receivedNewSessionTicket","ssl3con.c",9390) ); |
9391 | |
9392 | if (ss->ssl3.hs.ws != wait_new_session_ticket) { |
9393 | SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
9394 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET); |
9395 | return SECFailure; |
9396 | } |
9397 | |
9398 | /* RFC5077 Section 3.3: "The client MUST NOT treat the ticket as valid |
9399 | * until it has verified the server's Finished message." See the comment in |
9400 | * ssl3_FinishHandshake for more details. |
9401 | */ |
9402 | ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_Time(); |
9403 | if (length < 4) { |
9404 | (void)SSL3_SendAlert(ss, alert_fatal, decode_error); |
9405 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); |
9406 | return SECFailure; |
9407 | } |
9408 | ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint = |
9409 | (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length); |
9410 | |
9411 | rv = ssl3_ConsumeHandshakeVariable(ss, &ticketData, 2, &b, &length); |
9412 | if (length != 0 || rv != SECSuccess) { |
9413 | (void)SSL3_SendAlert(ss, alert_fatal, decode_error); |
9414 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); |
9415 | return SECFailure; /* malformed */ |
9416 | } |
9417 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &ss->ssl3.hs.newSessionTicket.ticket, |
9418 | &ticketData); |
9419 | if (rv != SECSuccess) { |
9420 | return rv; |
9421 | } |
9422 | ss->ssl3.hs.receivedNewSessionTicket = PR_TRUE1; |
9423 | |
9424 | ss->ssl3.hs.ws = wait_change_cipher; |
9425 | return SECSuccess; |
9426 | } |
9427 | |
9428 | #ifdef NISCC_TEST |
9429 | static PRInt32 connNum = 0; |
9430 | |
9431 | static SECStatus |
9432 | get_fake_cert(SECItem *pCertItem, int *pIndex) |
9433 | { |
9434 | PRFileDesc *cf; |
9435 | char * testdir; |
9436 | char * startat; |
9437 | char * stopat; |
9438 | const char *extension; |
9439 | int fileNum; |
9440 | PRInt32 numBytes = 0; |
9441 | PRStatus prStatus; |
9442 | PRFileInfo info; |
9443 | char cfn[100]; |
9444 | |
9445 | pCertItem->data = 0; |
9446 | if ((testdir = PR_GetEnv("NISCC_TEST")) == NULL((void*)0)) { |
9447 | return SECSuccess; |
9448 | } |
9449 | *pIndex = (NULL((void*)0) != strstr(testdir, "root")); |
9450 | extension = (strstr(testdir, "simple") ? "" : ".der"); |
9451 | fileNum = PR_ATOMIC_INCREMENT(&connNum)__sync_add_and_fetch(&connNum, 1) - 1; |
9452 | if ((startat = PR_GetEnv("START_AT")) != NULL((void*)0)) { |
9453 | fileNum += atoi(startat); |
9454 | } |
9455 | if ((stopat = PR_GetEnv("STOP_AT")) != NULL((void*)0) && |
9456 | fileNum >= atoi(stopat)) { |
9457 | *pIndex = -1; |
9458 | return SECSuccess; |
9459 | } |
9460 | sprintf(cfn, "%s/%08d%s", testdir, fileNum, extension); |
9461 | cf = PR_Open(cfn, PR_RDONLY0x01, 0); |
9462 | if (!cf) { |
9463 | goto loser; |
9464 | } |
9465 | prStatus = PR_GetOpenFileInfo(cf, &info); |
9466 | if (prStatus != PR_SUCCESS) { |
9467 | PR_Close(cf); |
9468 | goto loser; |
9469 | } |
9470 | pCertItem = SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), pCertItem, info.size); |
9471 | if (pCertItem) { |
9472 | numBytes = PR_Read(cf, pCertItem->data, info.size); |
9473 | } |
9474 | PR_Close(cf); |
9475 | if (numBytes != info.size) { |
9476 | SECITEM_FreeItemSECITEM_FreeItem_Util(pCertItem, PR_FALSE0); |
9477 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_IO); |
9478 | goto loser; |
9479 | } |
9480 | fprintf(stderrstderr, "using %s\n", cfn); |
9481 | return SECSuccess; |
9482 | |
9483 | loser: |
9484 | fprintf(stderrstderr, "failed to use %s\n", cfn); |
9485 | *pIndex = -1; |
9486 | return SECFailure; |
9487 | } |
9488 | #endif |
9489 | |
9490 | /* |
9491 | * Used by both client and server. |
9492 | * Called from HandleServerHelloDone and from SendServerHelloSequence. |
9493 | */ |
9494 | static SECStatus |
9495 | ssl3_SendCertificate(sslSocket *ss) |
9496 | { |
9497 | SECStatus rv; |
9498 | CERTCertificateList *certChain; |
9499 | int len = 0; |
9500 | int i; |
9501 | SSL3KEAType certIndex; |
9502 | #ifdef NISCC_TEST |
9503 | SECItem fakeCert; |
9504 | int ndex = -1; |
9505 | #endif |
9506 | |
9507 | SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate handshake" , getpid(), ss->fd) |
9508 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate handshake" , getpid(), ss->fd); |
9509 | |
9510 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",9510)); |
9511 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9511)); |
9512 | |
9513 | if (ss->sec.localCert) |
9514 | CERT_DestroyCertificate(ss->sec.localCert); |
9515 | if (ss->sec.isServer) { |
9516 | sslServerCerts * sc = NULL((void*)0); |
9517 | |
9518 | /* XXX SSLKEAType isn't really a good choice for |
9519 | * indexing certificates (it breaks when we deal |
9520 | * with (EC)DHE-* cipher suites. This hack ensures |
9521 | * the RSA cert is picked for (EC)DHE-RSA. |
9522 | * Revisit this when we add server side support |
9523 | * for ECDHE-ECDSA or client-side authentication |
9524 | * using EC certificates. |
9525 | */ |
9526 | if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) || |
9527 | (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) { |
9528 | certIndex = kt_rsassl_kea_rsa; |
9529 | } else { |
9530 | certIndex = ss->ssl3.hs.kea_def->exchKeyType; |
9531 | } |
9532 | sc = ss->serverCerts + certIndex; |
9533 | certChain = sc->serverCertChain; |
9534 | ss->sec.authKeyBits = sc->serverKeyBits; |
9535 | ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType; |
9536 | ss->sec.localCert = CERT_DupCertificate(sc->serverCert); |
9537 | } else { |
9538 | certChain = ss->ssl3.clientCertChain; |
9539 | ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate); |
9540 | } |
9541 | |
9542 | #ifdef NISCC_TEST |
9543 | rv = get_fake_cert(&fakeCert, &ndex); |
9544 | #endif |
9545 | |
9546 | if (certChain) { |
9547 | for (i = 0; i < certChain->len; i++) { |
9548 | #ifdef NISCC_TEST |
9549 | if (fakeCert.len > 0 && i == ndex) { |
9550 | len += fakeCert.len + 3; |
9551 | } else { |
9552 | len += certChain->certs[i].len + 3; |
9553 | } |
9554 | #else |
9555 | len += certChain->certs[i].len + 3; |
9556 | #endif |
9557 | } |
9558 | } |
9559 | |
9560 | rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3); |
9561 | if (rv != SECSuccess) { |
9562 | return rv; /* err set by AppendHandshake. */ |
9563 | } |
9564 | rv = ssl3_AppendHandshakeNumber(ss, len, 3); |
9565 | if (rv != SECSuccess) { |
9566 | return rv; /* err set by AppendHandshake. */ |
9567 | } |
9568 | if (certChain) { |
9569 | for (i = 0; i < certChain->len; i++) { |
9570 | #ifdef NISCC_TEST |
9571 | if (fakeCert.len > 0 && i == ndex) { |
9572 | rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data, |
9573 | fakeCert.len, 3); |
9574 | SECITEM_FreeItemSECITEM_FreeItem_Util(&fakeCert, PR_FALSE0); |
9575 | } else { |
9576 | rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, |
9577 | certChain->certs[i].len, 3); |
9578 | } |
9579 | #else |
9580 | rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, |
9581 | certChain->certs[i].len, 3); |
9582 | #endif |
9583 | if (rv != SECSuccess) { |
9584 | return rv; /* err set by AppendHandshake. */ |
9585 | } |
9586 | } |
9587 | } |
9588 | |
9589 | return SECSuccess; |
9590 | } |
9591 | |
9592 | /* |
9593 | * Used by server only. |
9594 | * single-stapling, send only a single cert status |
9595 | */ |
9596 | static SECStatus |
9597 | ssl3_SendCertificateStatus(sslSocket *ss) |
9598 | { |
9599 | SECStatus rv; |
9600 | int len = 0; |
9601 | SECItemArray *statusToSend = NULL((void*)0); |
9602 | SSL3KEAType certIndex; |
9603 | |
9604 | SSL_TRC(3, ("%d: SSL3[%d]: send certificate status handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate status handshake" , getpid(), ss->fd) |
9605 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send certificate status handshake" , getpid(), ss->fd); |
9606 | |
9607 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",9607)); |
9608 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9608)); |
9609 | PORT_Assert( ss->sec.isServer)((ss->sec.isServer)?((void)0):PR_Assert("ss->sec.isServer" ,"ssl3con.c",9609)); |
9610 | |
9611 | if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn)) |
9612 | return SECSuccess; |
9613 | |
9614 | /* Use certStatus based on the cert being used. */ |
9615 | if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) || |
9616 | (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) { |
9617 | certIndex = kt_rsassl_kea_rsa; |
9618 | } else { |
9619 | certIndex = ss->ssl3.hs.kea_def->exchKeyType; |
9620 | } |
9621 | if (ss->certStatusArray[certIndex] && ss->certStatusArray[certIndex]->len) { |
9622 | statusToSend = ss->certStatusArray[certIndex]; |
9623 | } |
9624 | if (!statusToSend) |
9625 | return SECSuccess; |
9626 | |
9627 | /* Use the array's first item only (single stapling) */ |
9628 | len = 1 + statusToSend->items[0].len + 3; |
9629 | |
9630 | rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len); |
9631 | if (rv != SECSuccess) { |
9632 | return rv; /* err set by AppendHandshake. */ |
9633 | } |
9634 | rv = ssl3_AppendHandshakeNumber(ss, 1 /*ocsp*/, 1); |
9635 | if (rv != SECSuccess) |
9636 | return rv; /* err set by AppendHandshake. */ |
9637 | |
9638 | rv = ssl3_AppendHandshakeVariable(ss, |
9639 | statusToSend->items[0].data, |
9640 | statusToSend->items[0].len, |
9641 | 3); |
9642 | if (rv != SECSuccess) |
9643 | return rv; /* err set by AppendHandshake. */ |
9644 | |
9645 | return SECSuccess; |
9646 | } |
9647 | |
9648 | /* This is used to delete the CA certificates in the peer certificate chain |
9649 | * from the cert database after they've been validated. |
9650 | */ |
9651 | static void |
9652 | ssl3_CleanupPeerCerts(sslSocket *ss) |
9653 | { |
9654 | PLArenaPool * arena = ss->ssl3.peerCertArena; |
9655 | ssl3CertNode *certs = (ssl3CertNode *)ss->ssl3.peerCertChain; |
9656 | |
9657 | for (; certs; certs = certs->next) { |
9658 | CERT_DestroyCertificate(certs->cert); |
9659 | } |
9660 | if (arena) PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
9661 | ss->ssl3.peerCertArena = NULL((void*)0); |
9662 | ss->ssl3.peerCertChain = NULL((void*)0); |
9663 | } |
9664 | |
9665 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
9666 | * ssl3 CertificateStatus message. |
9667 | * Caller must hold Handshake and RecvBuf locks. |
9668 | * This is always called before ssl3_HandleCertificate, even if the Certificate |
9669 | * message is sent first. |
9670 | */ |
9671 | static SECStatus |
9672 | ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
9673 | { |
9674 | PRInt32 status, len; |
9675 | |
9676 | if (ss->ssl3.hs.ws != wait_certificate_status) { |
9677 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
9678 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS); |
9679 | return SECFailure; |
9680 | } |
9681 | |
9682 | PORT_Assert(!ss->sec.isServer)((!ss->sec.isServer)?((void)0):PR_Assert("!ss->sec.isServer" ,"ssl3con.c",9682)); |
9683 | |
9684 | /* Consume the CertificateStatusType enum */ |
9685 | status = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length); |
9686 | if (status != 1 /* ocsp */) { |
9687 | goto format_loser; |
9688 | } |
9689 | |
9690 | len = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
9691 | if (len != length) { |
9692 | goto format_loser; |
9693 | } |
9694 | |
9695 | #define MAX_CERTSTATUS_LEN 0x1ffff /* 128k - 1 */ |
9696 | if (length > MAX_CERTSTATUS_LEN) |
9697 | goto format_loser; |
9698 | #undef MAX_CERTSTATUS_LEN |
9699 | |
9700 | /* Array size 1, because we currently implement single-stapling only */ |
9701 | SECITEM_AllocArray(NULL((void*)0), &ss->sec.ci.sid->peerCertStatus, 1); |
9702 | if (!ss->sec.ci.sid->peerCertStatus.items) |
9703 | return SECFailure; |
9704 | |
9705 | ss->sec.ci.sid->peerCertStatus.items[0].data = PORT_AllocPORT_Alloc_Util(length); |
9706 | |
9707 | if (!ss->sec.ci.sid->peerCertStatus.items[0].data) { |
9708 | SECITEM_FreeArray(&ss->sec.ci.sid->peerCertStatus, PR_FALSE0); |
9709 | return SECFailure; |
9710 | } |
9711 | |
9712 | PORT_Memcpymemcpy(ss->sec.ci.sid->peerCertStatus.items[0].data, b, length); |
9713 | ss->sec.ci.sid->peerCertStatus.items[0].len = length; |
9714 | ss->sec.ci.sid->peerCertStatus.items[0].type = siBuffer; |
9715 | |
9716 | return ssl3_AuthCertificate(ss); |
9717 | |
9718 | format_loser: |
9719 | return ssl3_DecodeError(ss); |
9720 | } |
9721 | |
9722 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
9723 | * ssl3 Certificate message. |
9724 | * Caller must hold Handshake and RecvBuf locks. |
9725 | */ |
9726 | static SECStatus |
9727 | ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
9728 | { |
9729 | ssl3CertNode * c; |
9730 | ssl3CertNode * lastCert = NULL((void*)0); |
9731 | PRInt32 remaining = 0; |
9732 | PRInt32 size; |
9733 | SECStatus rv; |
9734 | PRBool isServer = (PRBool)(!!ss->sec.isServer); |
9735 | PRBool isTLS; |
9736 | SSL3AlertDescription desc; |
9737 | int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; |
9738 | SECItem certItem; |
9739 | |
9740 | SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle certificate handshake" , getpid(), ss->fd) |
9741 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle certificate handshake" , getpid(), ss->fd); |
9742 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",9742)); |
9743 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",9743)); |
9744 | |
9745 | if ((ss->ssl3.hs.ws != wait_server_cert) && |
9746 | (ss->ssl3.hs.ws != wait_client_cert)) { |
9747 | desc = unexpected_message; |
9748 | errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE; |
9749 | goto alert_loser; |
9750 | } |
9751 | |
9752 | if (ss->sec.peerCert != NULL((void*)0)) { |
9753 | if (ss->sec.peerKey) { |
9754 | SECKEY_DestroyPublicKey(ss->sec.peerKey); |
9755 | ss->sec.peerKey = NULL((void*)0); |
9756 | } |
9757 | CERT_DestroyCertificate(ss->sec.peerCert); |
9758 | ss->sec.peerCert = NULL((void*)0); |
9759 | } |
9760 | |
9761 | ssl3_CleanupPeerCerts(ss); |
9762 | isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
9763 | |
9764 | /* It is reported that some TLS client sends a Certificate message |
9765 | ** with a zero-length message body. We'll treat that case like a |
9766 | ** normal no_certificates message to maximize interoperability. |
9767 | */ |
9768 | if (length) { |
9769 | remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
9770 | if (remaining < 0) |
9771 | goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
9772 | if ((PRUint32)remaining > length) |
9773 | goto decode_loser; |
9774 | } |
9775 | |
9776 | if (!remaining) { |
9777 | if (!(isTLS && isServer)) { |
9778 | desc = bad_certificate; |
9779 | goto alert_loser; |
9780 | } |
9781 | /* This is TLS's version of a no_certificate alert. */ |
9782 | /* I'm a server. I've requested a client cert. He hasn't got one. */ |
9783 | rv = ssl3_HandleNoCertificate(ss); |
9784 | if (rv != SECSuccess) { |
9785 | errCode = PORT_GetErrorPORT_GetError_Util(); |
9786 | goto loser; |
9787 | } |
9788 | ss->ssl3.hs.ws = wait_client_key; |
9789 | return SECSuccess; |
9790 | } |
9791 | |
9792 | ss->ssl3.peerCertArena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); |
9793 | if (ss->ssl3.peerCertArena == NULL((void*)0)) { |
9794 | goto loser; /* don't send alerts on memory errors */ |
9795 | } |
9796 | |
9797 | /* First get the peer cert. */ |
9798 | remaining -= 3; |
9799 | if (remaining < 0) |
9800 | goto decode_loser; |
9801 | |
9802 | size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
9803 | if (size <= 0) |
9804 | goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
9805 | |
9806 | if (remaining < size) |
9807 | goto decode_loser; |
9808 | |
9809 | certItem.data = b; |
9810 | certItem.len = size; |
9811 | b += size; |
9812 | length -= size; |
9813 | remaining -= size; |
9814 | |
9815 | ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL((void*)0), |
9816 | PR_FALSE0, PR_TRUE1); |
9817 | if (ss->sec.peerCert == NULL((void*)0)) { |
9818 | /* We should report an alert if the cert was bad, but not if the |
9819 | * problem was just some local problem, like memory error. |
9820 | */ |
9821 | goto ambiguous_err; |
9822 | } |
9823 | |
9824 | /* Now get all of the CA certs. */ |
9825 | while (remaining > 0) { |
9826 | remaining -= 3; |
9827 | if (remaining < 0) |
9828 | goto decode_loser; |
9829 | |
9830 | size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
9831 | if (size <= 0) |
9832 | goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
9833 | |
9834 | if (remaining < size) |
9835 | goto decode_loser; |
9836 | |
9837 | certItem.data = b; |
9838 | certItem.len = size; |
9839 | b += size; |
9840 | length -= size; |
9841 | remaining -= size; |
9842 | |
9843 | c = PORT_ArenaNew(ss->ssl3.peerCertArena, ssl3CertNode)(ssl3CertNode*) PORT_ArenaAlloc_Util(ss->ssl3.peerCertArena , sizeof(ssl3CertNode)); |
9844 | if (c == NULL((void*)0)) { |
9845 | goto loser; /* don't send alerts on memory errors */ |
9846 | } |
9847 | |
9848 | c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL((void*)0), |
9849 | PR_FALSE0, PR_TRUE1); |
9850 | if (c->cert == NULL((void*)0)) { |
9851 | goto ambiguous_err; |
9852 | } |
9853 | |
9854 | c->next = NULL((void*)0); |
9855 | if (lastCert) { |
9856 | lastCert->next = c; |
9857 | } else { |
9858 | ss->ssl3.peerCertChain = c; |
9859 | } |
9860 | lastCert = c; |
9861 | } |
9862 | |
9863 | if (remaining != 0) |
9864 | goto decode_loser; |
9865 | |
9866 | SECKEY_UpdateCertPQG(ss->sec.peerCert); |
9867 | |
9868 | if (!isServer && ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn)) { |
9869 | ss->ssl3.hs.ws = wait_certificate_status; |
9870 | rv = SECSuccess; |
9871 | } else { |
9872 | rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */ |
9873 | } |
9874 | |
9875 | return rv; |
9876 | |
9877 | ambiguous_err: |
9878 | errCode = PORT_GetErrorPORT_GetError_Util(); |
9879 | switch (errCode) { |
9880 | case PR_OUT_OF_MEMORY_ERROR(-6000L): |
9881 | case SEC_ERROR_BAD_DATABASE: |
9882 | case SEC_ERROR_NO_MEMORY: |
9883 | if (isTLS) { |
9884 | desc = internal_error; |
9885 | goto alert_loser; |
9886 | } |
9887 | goto loser; |
9888 | } |
9889 | ssl3_SendAlertForCertError(ss, errCode); |
9890 | goto loser; |
9891 | |
9892 | decode_loser: |
9893 | desc = isTLS ? decode_error : bad_certificate; |
9894 | |
9895 | alert_loser: |
9896 | (void)SSL3_SendAlert(ss, alert_fatal, desc); |
9897 | |
9898 | loser: |
9899 | (void)ssl_MapLowLevelError(errCode); |
9900 | return SECFailure; |
9901 | } |
9902 | |
9903 | static SECStatus |
9904 | ssl3_AuthCertificate(sslSocket *ss) |
9905 | { |
9906 | SECStatus rv; |
9907 | PRBool isServer = (PRBool)(!!ss->sec.isServer); |
9908 | int errCode; |
9909 | |
9910 | ss->ssl3.hs.authCertificatePending = PR_FALSE0; |
9911 | |
9912 | /* |
9913 | * Ask caller-supplied callback function to validate cert chain. |
9914 | */ |
9915 | rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, |
9916 | PR_TRUE1, isServer); |
9917 | if (rv) { |
9918 | errCode = PORT_GetErrorPORT_GetError_Util(); |
9919 | if (rv != SECWouldBlock) { |
9920 | if (ss->handleBadCert) { |
9921 | rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); |
9922 | } |
9923 | } |
9924 | |
9925 | if (rv == SECWouldBlock) { |
9926 | if (ss->sec.isServer) { |
9927 | errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS; |
9928 | rv = SECFailure; |
9929 | goto loser; |
9930 | } |
9931 | |
9932 | ss->ssl3.hs.authCertificatePending = PR_TRUE1; |
9933 | rv = SECSuccess; |
9934 | } |
9935 | |
9936 | if (rv != SECSuccess) { |
9937 | ssl3_SendAlertForCertError(ss, errCode); |
9938 | goto loser; |
9939 | } |
9940 | } |
9941 | |
9942 | ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); |
9943 | |
9944 | if (!ss->sec.isServer) { |
9945 | CERTCertificate *cert = ss->sec.peerCert; |
9946 | |
9947 | /* set the server authentication and key exchange types and sizes |
9948 | ** from the value in the cert. If the key exchange key is different, |
9949 | ** it will get fixed when we handle the server key exchange message. |
9950 | */ |
9951 | SECKEYPublicKey * pubKey = CERT_ExtractPublicKey(cert); |
9952 | ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType; |
9953 | ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType; |
9954 | if (pubKey) { |
9955 | ss->sec.keaKeyBits = ss->sec.authKeyBits = |
9956 | SECKEY_PublicKeyStrengthInBits(pubKey); |
9957 | #ifdef NSS_ENABLE_ECC1 |
9958 | if (ss->sec.keaType == kt_ecdhssl_kea_ecdh) { |
9959 | /* Get authKeyBits from signing key. |
9960 | * XXX The code below uses a quick approximation of |
9961 | * key size based on cert->signatureWrap.signature.data |
9962 | * (which contains the DER encoded signature). The field |
9963 | * cert->signatureWrap.signature.len contains the |
9964 | * length of the encoded signature in bits. |
9965 | */ |
9966 | if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) { |
9967 | ss->sec.authKeyBits = |
9968 | cert->signatureWrap.signature.data[3]*8; |
9969 | if (cert->signatureWrap.signature.data[4] == 0x00) |
9970 | ss->sec.authKeyBits -= 8; |
9971 | /* |
9972 | * XXX: if cert is not signed by ecdsa we should |
9973 | * destroy pubKey and goto bad_cert |
9974 | */ |
9975 | } else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) { |
9976 | ss->sec.authKeyBits = cert->signatureWrap.signature.len; |
9977 | /* |
9978 | * XXX: if cert is not signed by rsa we should |
9979 | * destroy pubKey and goto bad_cert |
9980 | */ |
9981 | } |
9982 | } |
9983 | #endif /* NSS_ENABLE_ECC */ |
9984 | SECKEY_DestroyPublicKey(pubKey); |
9985 | pubKey = NULL((void*)0); |
9986 | } |
9987 | |
9988 | ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ |
9989 | if (ss->ssl3.hs.kea_def->is_limited || |
9990 | /* XXX OR server cert is signing only. */ |
9991 | #ifdef NSS_ENABLE_ECC1 |
9992 | ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
9993 | ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || |
9994 | #endif /* NSS_ENABLE_ECC */ |
9995 | ss->ssl3.hs.kea_def->exchKeyType == kt_dhssl_kea_dh) { |
9996 | ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */ |
9997 | } |
9998 | } else { |
9999 | ss->ssl3.hs.ws = wait_client_key; |
10000 | } |
10001 | |
10002 | PORT_Assert(rv == SECSuccess)((rv == SECSuccess)?((void)0):PR_Assert("rv == SECSuccess","ssl3con.c" ,10002)); |
10003 | if (rv != SECSuccess) { |
10004 | errCode = SEC_ERROR_LIBRARY_FAILURE; |
10005 | rv = SECFailure; |
10006 | goto loser; |
10007 | } |
10008 | |
10009 | return rv; |
10010 | |
10011 | loser: |
10012 | (void)ssl_MapLowLevelError(errCode); |
10013 | return SECFailure; |
10014 | } |
10015 | |
10016 | static SECStatus ssl3_FinishHandshake(sslSocket *ss); |
10017 | |
10018 | static SECStatus |
10019 | ssl3_AlwaysFail(sslSocket * ss) |
10020 | { |
10021 | PORT_SetErrorPORT_SetError_Util(PR_INVALID_STATE_ERROR(-5931L)); |
10022 | return SECFailure; |
10023 | } |
10024 | |
10025 | /* Caller must hold 1stHandshakeLock. |
10026 | */ |
10027 | SECStatus |
10028 | ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error) |
10029 | { |
10030 | SECStatus rv; |
10031 | |
10032 | PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->firstHandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)" ,"ssl3con.c",10032)); |
10033 | |
10034 | if (ss->sec.isServer) { |
10035 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS); |
10036 | return SECFailure; |
10037 | } |
10038 | |
10039 | ssl_GetRecvBufLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->ssl3HandshakeLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10039)); ((!((PR_GetMonitorEntryCount(((ss)-> xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",10039)); PR_EnterMonitor(((ss)->recvBufLock)) ; } }; |
10040 | ssl_GetSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",10040)); PR_EnterMonitor(((ss)->ssl3HandshakeLock )); } }; |
10041 | |
10042 | if (!ss->ssl3.hs.authCertificatePending) { |
10043 | PORT_SetErrorPORT_SetError_Util(PR_INVALID_STATE_ERROR(-5931L)); |
10044 | rv = SECFailure; |
10045 | goto done; |
10046 | } |
10047 | |
10048 | ss->ssl3.hs.authCertificatePending = PR_FALSE0; |
10049 | |
10050 | if (error != 0) { |
10051 | ss->ssl3.hs.restartTarget = ssl3_AlwaysFail; |
10052 | ssl3_SendAlertForCertError(ss, error); |
10053 | rv = SECSuccess; |
10054 | } else if (ss->ssl3.hs.restartTarget != NULL((void*)0)) { |
10055 | sslRestartTarget target = ss->ssl3.hs.restartTarget; |
10056 | ss->ssl3.hs.restartTarget = NULL((void*)0); |
10057 | |
10058 | if (target == ssl3_FinishHandshake) { |
10059 | SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: certificate authentication lost the race" " with peer's finished message", getpid(), ss->fd) |
10060 | " with peer's finished message", SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: certificate authentication lost the race" " with peer's finished message", getpid(), ss->fd); |
10061 | } |
10062 | |
10063 | rv = target(ss); |
10064 | /* Even if we blocked here, we have accomplished enough to claim |
10065 | * success. Any remaining work will be taken care of by subsequent |
10066 | * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. |
10067 | */ |
10068 | if (rv == SECWouldBlock) { |
10069 | rv = SECSuccess; |
10070 | } |
10071 | } else { |
10072 | SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: certificate authentication won the race with" " peer's finished message", getpid(), ss->fd) |
10073 | " peer's finished message", SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%p]: certificate authentication won the race with" " peer's finished message", getpid(), ss->fd); |
10074 | |
10075 | PORT_Assert(!ss->ssl3.hs.isResuming)((!ss->ssl3.hs.isResuming)?((void)0):PR_Assert("!ss->ssl3.hs.isResuming" ,"ssl3con.c",10075)); |
10076 | PORT_Assert(ss->ssl3.hs.ws != idle_handshake)((ss->ssl3.hs.ws != idle_handshake)?((void)0):PR_Assert("ss->ssl3.hs.ws != idle_handshake" ,"ssl3con.c",10076)); |
10077 | |
10078 | if (ss->opt.enableFalseStart && |
10079 | !ss->firstHsDone && |
10080 | !ss->ssl3.hs.isResuming && |
10081 | ssl3_WaitingForStartOfServerSecondRound(ss)) { |
10082 | /* ssl3_SendClientSecondRound deferred the false start check because |
10083 | * certificate authentication was pending, so we do it now if we still |
10084 | * haven't received any of the server's second round yet. |
10085 | */ |
10086 | rv = ssl3_CheckFalseStart(ss); |
10087 | } else { |
10088 | rv = SECSuccess; |
10089 | } |
10090 | } |
10091 | |
10092 | done: |
10093 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
10094 | ssl_ReleaseRecvBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->recvBufLock )); }; |
10095 | |
10096 | return rv; |
10097 | } |
10098 | |
10099 | static SECStatus |
10100 | ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, |
10101 | PRBool isServer, |
10102 | const SSL3Hashes * hashes, |
10103 | TLSFinished * tlsFinished) |
10104 | { |
10105 | const char * label; |
10106 | unsigned int len; |
10107 | SECStatus rv; |
10108 | |
10109 | label = isServer ? "server finished" : "client finished"; |
10110 | len = 15; |
10111 | |
10112 | rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw, |
10113 | hashes->len, tlsFinished->verify_data, |
10114 | sizeof tlsFinished->verify_data); |
10115 | |
10116 | return rv; |
10117 | } |
10118 | |
10119 | /* The calling function must acquire and release the appropriate |
10120 | * lock (e.g., ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for |
10121 | * ss->ssl3.crSpec). |
10122 | */ |
10123 | SECStatus |
10124 | ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, |
10125 | unsigned int labelLen, const unsigned char *val, unsigned int valLen, |
10126 | unsigned char *out, unsigned int outLen) |
10127 | { |
10128 | SECStatus rv = SECSuccess; |
10129 | |
10130 | if (spec->master_secret && !spec->bypassCiphers) { |
10131 | SECItem param = {siBuffer, NULL((void*)0), 0}; |
10132 | CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL0x80000373UL; |
10133 | PK11Context *prf_context; |
10134 | unsigned int retLen; |
10135 | |
10136 | if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303) { |
10137 | mech = CKM_NSS_TLS_PRF_GENERAL_SHA256((0x80000000|0x4E534350) + 21); |
10138 | } |
10139 | prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN0x00000108, |
10140 | spec->master_secret, ¶m); |
10141 | if (!prf_context) |
10142 | return SECFailure; |
10143 | |
10144 | rv = PK11_DigestBegin(prf_context); |
10145 | rv |= PK11_DigestOp(prf_context, (unsigned char *) label, labelLen); |
10146 | rv |= PK11_DigestOp(prf_context, val, valLen); |
10147 | rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen); |
10148 | PORT_Assert(rv != SECSuccess || retLen == outLen)((rv != SECSuccess || retLen == outLen)?((void)0):PR_Assert("rv != SECSuccess || retLen == outLen" ,"ssl3con.c",10148)); |
10149 | |
10150 | PK11_DestroyContext(prf_context, PR_TRUE1); |
10151 | } else { |
10152 | /* bypass PKCS11 */ |
10153 | #ifdef NO_PKCS11_BYPASS1 |
10154 | PORT_Assert(spec->master_secret)((spec->master_secret)?((void)0):PR_Assert("spec->master_secret" ,"ssl3con.c",10154)); |
10155 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
10156 | rv = SECFailure; |
10157 | #else |
10158 | SECItem inData = { siBuffer, }; |
10159 | SECItem outData = { siBuffer, }; |
10160 | PRBool isFIPS = PR_FALSE0; |
10161 | |
10162 | inData.data = (unsigned char *) val; |
10163 | inData.len = valLen; |
10164 | outData.data = out; |
10165 | outData.len = outLen; |
10166 | if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_20x0303) { |
10167 | rv = TLS_P_hash(HASH_AlgSHA256, &spec->msItem, label, &inData, |
10168 | &outData, isFIPS); |
10169 | } else { |
10170 | rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS); |
10171 | } |
10172 | PORT_Assert(rv != SECSuccess || outData.len == outLen)((rv != SECSuccess || outData.len == outLen)?((void)0):PR_Assert ("rv != SECSuccess || outData.len == outLen","ssl3con.c",10172 )); |
10173 | #endif |
10174 | } |
10175 | return rv; |
10176 | } |
10177 | |
10178 | /* called from ssl3_SendClientSecondRound |
10179 | * ssl3_HandleFinished |
10180 | */ |
10181 | static SECStatus |
10182 | ssl3_SendNextProto(sslSocket *ss) |
10183 | { |
10184 | SECStatus rv; |
10185 | int padding_len; |
10186 | static const unsigned char padding[32] = {0}; |
10187 | |
10188 | if (ss->ssl3.nextProto.len == 0 || |
10189 | ss->ssl3.nextProtoState == SSL_NEXT_PROTO_SELECTED) { |
10190 | return SECSuccess; |
10191 | } |
10192 | |
10193 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",10193)); |
10194 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10194)); |
10195 | |
10196 | padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); |
10197 | |
10198 | rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + |
10199 | 2 + padding_len); |
10200 | if (rv != SECSuccess) { |
10201 | return rv; /* error code set by AppendHandshakeHeader */ |
10202 | } |
10203 | rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, |
10204 | ss->ssl3.nextProto.len, 1); |
10205 | if (rv != SECSuccess) { |
10206 | return rv; /* error code set by AppendHandshake */ |
10207 | } |
10208 | rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1); |
10209 | if (rv != SECSuccess) { |
10210 | return rv; /* error code set by AppendHandshake */ |
10211 | } |
10212 | return rv; |
10213 | } |
10214 | |
10215 | /* called from ssl3_SendFinished |
10216 | * |
10217 | * This function is simply a debugging aid and therefore does not return a |
10218 | * SECStatus. */ |
10219 | static void |
10220 | ssl3_RecordKeyLog(sslSocket *ss) |
10221 | { |
10222 | SECStatus rv; |
10223 | SECItem *keyData; |
10224 | char buf[14 /* "CLIENT_RANDOM " */ + |
10225 | SSL3_RANDOM_LENGTH32*2 /* client_random */ + |
10226 | 1 /* " " */ + |
10227 | 48*2 /* master secret */ + |
10228 | 1 /* new line */]; |
10229 | unsigned int j; |
10230 | |
10231 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10231)); |
10232 | |
10233 | if (!ssl_keylog_iob) |
10234 | return; |
10235 | |
10236 | rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret); |
10237 | if (rv != SECSuccess) |
10238 | return; |
10239 | |
10240 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; |
10241 | |
10242 | /* keyData does not need to be freed. */ |
10243 | keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret); |
10244 | if (!keyData || !keyData->data || keyData->len != 48) { |
10245 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
10246 | return; |
10247 | } |
10248 | |
10249 | /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ |
10250 | |
10251 | /* There could be multiple, concurrent writers to the |
10252 | * keylog, so we have to do everything in a single call to |
10253 | * fwrite. */ |
10254 | |
10255 | memcpy(buf, "CLIENT_RANDOM ", 14); |
10256 | j = 14; |
10257 | hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH32); |
10258 | j += SSL3_RANDOM_LENGTH32*2; |
10259 | buf[j++] = ' '; |
10260 | hexEncode(buf + j, keyData->data, 48); |
10261 | j += 48*2; |
10262 | buf[j++] = '\n'; |
10263 | |
10264 | PORT_Assert(j == sizeof(buf))((j == sizeof(buf))?((void)0):PR_Assert("j == sizeof(buf)","ssl3con.c" ,10264)); |
10265 | |
10266 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
10267 | |
10268 | if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1) |
10269 | return; |
10270 | fflush(ssl_keylog_iob); |
10271 | return; |
10272 | } |
10273 | |
10274 | /* called from ssl3_SendClientSecondRound |
10275 | * ssl3_HandleClientHello |
10276 | * ssl3_HandleFinished |
10277 | */ |
10278 | static SECStatus |
10279 | ssl3_SendFinished(sslSocket *ss, PRInt32 flags) |
10280 | { |
10281 | ssl3CipherSpec *cwSpec; |
10282 | PRBool isTLS; |
10283 | PRBool isServer = ss->sec.isServer; |
10284 | SECStatus rv; |
10285 | SSL3Sender sender = isServer ? sender_server : sender_client; |
10286 | SSL3Hashes hashes; |
10287 | TLSFinished tlsFinished; |
10288 | |
10289 | SSL_TRC(3, ("%d: SSL3[%d]: send finished handshake", SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: send finished handshake" , getpid(), ss->fd); |
10290 | |
10291 | PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->xmitBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",10291)); |
10292 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10292)); |
10293 | |
10294 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; |
10295 | cwSpec = ss->ssl3.cwSpec; |
10296 | isTLS = (PRBool)(cwSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
10297 | rv = ssl3_ComputeHandshakeHashes(ss, cwSpec, &hashes, sender); |
10298 | if (isTLS && rv == SECSuccess) { |
10299 | rv = ssl3_ComputeTLSFinished(cwSpec, isServer, &hashes, &tlsFinished); |
10300 | } |
10301 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
10302 | if (rv != SECSuccess) { |
10303 | goto fail; /* err code was set by ssl3_ComputeHandshakeHashes */ |
10304 | } |
10305 | |
10306 | if (isTLS) { |
10307 | if (isServer) |
10308 | ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished; |
10309 | else |
10310 | ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished; |
10311 | ss->ssl3.hs.finishedBytes = sizeof tlsFinished; |
10312 | rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof tlsFinished); |
10313 | if (rv != SECSuccess) |
10314 | goto fail; /* err set by AppendHandshake. */ |
10315 | rv = ssl3_AppendHandshake(ss, &tlsFinished, sizeof tlsFinished); |
10316 | if (rv != SECSuccess) |
10317 | goto fail; /* err set by AppendHandshake. */ |
10318 | } else { |
10319 | if (isServer) |
10320 | ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes.u.s; |
10321 | else |
10322 | ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s; |
10323 | PORT_Assert(hashes.len == sizeof hashes.u.s)((hashes.len == sizeof hashes.u.s)?((void)0):PR_Assert("hashes.len == sizeof hashes.u.s" ,"ssl3con.c",10323)); |
10324 | ss->ssl3.hs.finishedBytes = sizeof hashes.u.s; |
10325 | rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes.u.s); |
10326 | if (rv != SECSuccess) |
10327 | goto fail; /* err set by AppendHandshake. */ |
10328 | rv = ssl3_AppendHandshake(ss, &hashes.u.s, sizeof hashes.u.s); |
10329 | if (rv != SECSuccess) |
10330 | goto fail; /* err set by AppendHandshake. */ |
10331 | } |
10332 | rv = ssl3_FlushHandshake(ss, flags); |
10333 | if (rv != SECSuccess) { |
10334 | goto fail; /* error code set by ssl3_FlushHandshake */ |
10335 | } |
10336 | |
10337 | ssl3_RecordKeyLog(ss); |
10338 | |
10339 | return SECSuccess; |
10340 | |
10341 | fail: |
10342 | return rv; |
10343 | } |
10344 | |
10345 | /* wrap the master secret, and put it into the SID. |
10346 | * Caller holds the Spec read lock. |
10347 | */ |
10348 | SECStatus |
10349 | ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, |
10350 | ssl3CipherSpec *spec, SSL3KEAType effectiveExchKeyType) |
10351 | { |
10352 | PK11SymKey * wrappingKey = NULL((void*)0); |
10353 | PK11SlotInfo * symKeySlot; |
10354 | void * pwArg = ss->pkcs11PinArg; |
10355 | SECStatus rv = SECFailure; |
10356 | PRBool isServer = ss->sec.isServer; |
10357 | CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM0xffffffffUL; |
10358 | symKeySlot = PK11_GetSlotFromKey(spec->master_secret); |
10359 | if (!isServer) { |
10360 | int wrapKeyIndex; |
10361 | int incarnation; |
10362 | |
10363 | /* these next few functions are mere accessors and don't fail. */ |
10364 | sid->u.ssl3.masterWrapIndex = wrapKeyIndex = |
10365 | PK11_GetCurrentWrapIndex(symKeySlot); |
10366 | PORT_Assert(wrapKeyIndex == 0)((wrapKeyIndex == 0)?((void)0):PR_Assert("wrapKeyIndex == 0", "ssl3con.c",10366)); /* array has only one entry! */ |
10367 | |
10368 | sid->u.ssl3.masterWrapSeries = incarnation = |
10369 | PK11_GetSlotSeries(symKeySlot); |
10370 | sid->u.ssl3.masterSlotID = PK11_GetSlotID(symKeySlot); |
10371 | sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot); |
10372 | sid->u.ssl3.masterValid = PR_TRUE1; |
10373 | /* Get the default wrapping key, for wrapping the master secret before |
10374 | * placing it in the SID cache entry. */ |
10375 | wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex, |
10376 | CKM_INVALID_MECHANISM0xffffffffUL, incarnation, |
10377 | pwArg); |
10378 | if (wrappingKey) { |
10379 | mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */ |
10380 | } else { |
10381 | int keyLength; |
10382 | /* if the wrappingKey doesn't exist, attempt to create it. |
10383 | * Note: we intentionally ignore errors here. If we cannot |
10384 | * generate a wrapping key, it is not fatal to this SSL connection, |
10385 | * but we will not be able to restart this session. |
10386 | */ |
10387 | mechanism = PK11_GetBestWrapMechanism(symKeySlot); |
10388 | keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism); |
10389 | /* Zero length means fixed key length algorithm, or error. |
10390 | * It's ambiguous. |
10391 | */ |
10392 | wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL((void*)0), |
10393 | keyLength, pwArg); |
10394 | if (wrappingKey) { |
10395 | PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey); |
10396 | } |
10397 | } |
10398 | } else { |
10399 | /* server socket using session cache. */ |
10400 | mechanism = PK11_GetBestWrapMechanism(symKeySlot); |
10401 | if (mechanism != CKM_INVALID_MECHANISM0xffffffffUL) { |
10402 | wrappingKey = |
10403 | getWrappingKey(ss, symKeySlot, effectiveExchKeyType, |
10404 | mechanism, pwArg); |
10405 | if (wrappingKey) { |
10406 | mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */ |
10407 | } |
10408 | } |
10409 | } |
10410 | |
10411 | sid->u.ssl3.masterWrapMech = mechanism; |
10412 | PK11_FreeSlot(symKeySlot); |
10413 | |
10414 | if (wrappingKey) { |
10415 | SECItem wmsItem; |
10416 | |
10417 | wmsItem.data = sid->u.ssl3.keys.wrapped_master_secret; |
10418 | wmsItem.len = sizeof sid->u.ssl3.keys.wrapped_master_secret; |
10419 | rv = PK11_WrapSymKey(mechanism, NULL((void*)0), wrappingKey, |
10420 | spec->master_secret, &wmsItem); |
10421 | /* rv is examined below. */ |
10422 | sid->u.ssl3.keys.wrapped_master_secret_len = wmsItem.len; |
10423 | PK11_FreeSymKey(wrappingKey); |
10424 | } |
10425 | return rv; |
10426 | } |
10427 | |
10428 | /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
10429 | * ssl3 Finished message from the peer. |
10430 | * Caller must hold Handshake and RecvBuf locks. |
10431 | */ |
10432 | static SECStatus |
10433 | ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, |
10434 | const SSL3Hashes *hashes) |
10435 | { |
10436 | sslSessionID * sid = ss->sec.ci.sid; |
10437 | SECStatus rv = SECSuccess; |
10438 | PRBool isServer = ss->sec.isServer; |
10439 | PRBool isTLS; |
10440 | SSL3KEAType effectiveExchKeyType; |
10441 | |
10442 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",10442)); |
10443 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10443)); |
10444 | |
10445 | SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake",if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle finished handshake" , getpid(), ss->fd) |
10446 | SSL_GETPID(), ss->fd))if (ssl_trace >= (3)) ssl_Trace ("%d: SSL3[%d]: handle finished handshake" , getpid(), ss->fd); |
10447 | |
10448 | if (ss->ssl3.hs.ws != wait_finished) { |
10449 | SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10450 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_FINISHED); |
10451 | return SECFailure; |
10452 | } |
10453 | |
10454 | isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
10455 | if (isTLS) { |
10456 | TLSFinished tlsFinished; |
10457 | |
10458 | if (length != sizeof tlsFinished) { |
10459 | (void)SSL3_SendAlert(ss, alert_fatal, decode_error); |
10460 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_FINISHED); |
10461 | return SECFailure; |
10462 | } |
10463 | rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer, |
10464 | hashes, &tlsFinished); |
10465 | if (!isServer) |
10466 | ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished; |
10467 | else |
10468 | ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished; |
10469 | ss->ssl3.hs.finishedBytes = sizeof tlsFinished; |
10470 | if (rv != SECSuccess || |
10471 | 0 != NSS_SecureMemcmp(&tlsFinished, b, length)) { |
10472 | (void)SSL3_SendAlert(ss, alert_fatal, decrypt_error); |
10473 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
10474 | return SECFailure; |
10475 | } |
10476 | } else { |
10477 | if (length != sizeof(SSL3Finished)) { |
10478 | (void)ssl3_IllegalParameter(ss); |
10479 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_FINISHED); |
10480 | return SECFailure; |
10481 | } |
10482 | |
10483 | if (!isServer) |
10484 | ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes->u.s; |
10485 | else |
10486 | ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes->u.s; |
10487 | PORT_Assert(hashes->len == sizeof hashes->u.s)((hashes->len == sizeof hashes->u.s)?((void)0):PR_Assert ("hashes->len == sizeof hashes->u.s","ssl3con.c",10487) ); |
10488 | ss->ssl3.hs.finishedBytes = sizeof hashes->u.s; |
10489 | if (0 != NSS_SecureMemcmp(&hashes->u.s, b, length)) { |
10490 | (void)ssl3_HandshakeFailure(ss); |
10491 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
10492 | return SECFailure; |
10493 | } |
10494 | } |
10495 | |
10496 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; /*************************************/ |
10497 | |
10498 | if ((isServer && !ss->ssl3.hs.isResuming) || |
10499 | (!isServer && ss->ssl3.hs.isResuming)) { |
10500 | PRInt32 flags = 0; |
10501 | |
10502 | /* Send a NewSessionTicket message if the client sent us |
10503 | * either an empty session ticket, or one that did not verify. |
10504 | * (Note that if either of these conditions was met, then the |
10505 | * server has sent a SessionTicket extension in the |
10506 | * ServerHello message.) |
10507 | */ |
10508 | if (isServer && !ss->ssl3.hs.isResuming && |
10509 | ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) { |
10510 | /* RFC 5077 Section 3.3: "In the case of a full handshake, the |
10511 | * server MUST verify the client's Finished message before sending |
10512 | * the ticket." Presumably, this also means that the client's |
10513 | * certificate, if any, must be verified beforehand too. |
10514 | */ |
10515 | rv = ssl3_SendNewSessionTicket(ss); |
10516 | if (rv != SECSuccess) { |
10517 | goto xmit_loser; |
10518 | } |
10519 | } |
10520 | |
10521 | rv = ssl3_SendChangeCipherSpecs(ss); |
10522 | if (rv != SECSuccess) { |
10523 | goto xmit_loser; /* err is set. */ |
10524 | } |
10525 | /* If this thread is in SSL_SecureSend (trying to write some data) |
10526 | ** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the |
10527 | ** last two handshake messages (change cipher spec and finished) |
10528 | ** will be sent in the same send/write call as the application data. |
10529 | */ |
10530 | if (ss->writerThread == PR_GetCurrentThread()) { |
10531 | flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER0x40000000; |
10532 | } |
10533 | |
10534 | if (!isServer && !ss->firstHsDone) { |
10535 | rv = ssl3_SendNextProto(ss); |
10536 | if (rv != SECSuccess) { |
10537 | goto xmit_loser; /* err code was set. */ |
10538 | } |
10539 | } |
10540 | |
10541 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
10542 | flags |= ssl_SEND_FLAG_NO_RETRANSMIT0x08000000; |
10543 | } |
10544 | |
10545 | rv = ssl3_SendFinished(ss, flags); |
10546 | if (rv != SECSuccess) { |
10547 | goto xmit_loser; /* err is set. */ |
10548 | } |
10549 | } |
10550 | |
10551 | xmit_loser: |
10552 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; /*************************************/ |
10553 | if (rv != SECSuccess) { |
10554 | return rv; |
10555 | } |
10556 | |
10557 | if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { |
10558 | effectiveExchKeyType = kt_rsassl_kea_rsa; |
10559 | } else { |
10560 | effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; |
10561 | } |
10562 | |
10563 | if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) { |
10564 | /* fill in the sid */ |
10565 | sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite; |
10566 | sid->u.ssl3.compression = ss->ssl3.hs.compression; |
10567 | sid->u.ssl3.policy = ss->ssl3.policy; |
10568 | #ifdef NSS_ENABLE_ECC1 |
10569 | sid->u.ssl3.negotiatedECCurves = ss->ssl3.hs.negotiatedECCurves; |
10570 | #endif |
10571 | sid->u.ssl3.exchKeyType = effectiveExchKeyType; |
10572 | sid->version = ss->version; |
10573 | sid->authAlgorithm = ss->sec.authAlgorithm; |
10574 | sid->authKeyBits = ss->sec.authKeyBits; |
10575 | sid->keaType = ss->sec.keaType; |
10576 | sid->keaKeyBits = ss->sec.keaKeyBits; |
10577 | sid->lastAccessTime = sid->creationTime = ssl_Time(); |
10578 | sid->expirationTime = sid->creationTime + ssl3_sid_timeout; |
10579 | sid->localCert = CERT_DupCertificate(ss->sec.localCert); |
10580 | |
10581 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; /*************************************/ |
10582 | |
10583 | /* Copy the master secret (wrapped or unwrapped) into the sid */ |
10584 | if (ss->ssl3.crSpec->msItem.len && ss->ssl3.crSpec->msItem.data) { |
10585 | sid->u.ssl3.keys.wrapped_master_secret_len = |
10586 | ss->ssl3.crSpec->msItem.len; |
10587 | memcpy(sid->u.ssl3.keys.wrapped_master_secret, |
10588 | ss->ssl3.crSpec->msItem.data, ss->ssl3.crSpec->msItem.len); |
10589 | sid->u.ssl3.masterValid = PR_TRUE1; |
10590 | sid->u.ssl3.keys.msIsWrapped = PR_FALSE0; |
10591 | rv = SECSuccess; |
10592 | } else { |
10593 | rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid, |
10594 | ss->ssl3.crSpec, |
10595 | effectiveExchKeyType); |
10596 | sid->u.ssl3.keys.msIsWrapped = PR_TRUE1; |
10597 | } |
10598 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; /*************************************/ |
10599 | |
10600 | /* If the wrap failed, we don't cache the sid. |
10601 | * The connection continues normally however. |
10602 | */ |
10603 | ss->ssl3.hs.cacheSID = rv == SECSuccess; |
10604 | } |
10605 | |
10606 | if (ss->ssl3.hs.authCertificatePending) { |
10607 | if (ss->ssl3.hs.restartTarget) { |
10608 | PR_NOT_REACHED("ssl3_HandleFinished: unexpected restartTarget")PR_Assert("ssl3_HandleFinished: unexpected restartTarget","ssl3con.c" ,10608); |
10609 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
10610 | return SECFailure; |
10611 | } |
10612 | |
10613 | ss->ssl3.hs.restartTarget = ssl3_FinishHandshake; |
10614 | return SECWouldBlock; |
10615 | } |
10616 | |
10617 | rv = ssl3_FinishHandshake(ss); |
10618 | return rv; |
10619 | } |
10620 | |
10621 | /* The return type is SECStatus instead of void because this function needs |
10622 | * to have type sslRestartTarget. |
10623 | */ |
10624 | SECStatus |
10625 | ssl3_FinishHandshake(sslSocket * ss) |
10626 | { |
10627 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",10627)); |
10628 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10628)); |
10629 | PORT_Assert( ss->ssl3.hs.restartTarget == NULL )((ss->ssl3.hs.restartTarget == ((void*)0))?((void)0):PR_Assert ("ss->ssl3.hs.restartTarget == NULL","ssl3con.c",10629)); |
10630 | |
10631 | /* The first handshake is now completed. */ |
10632 | ss->handshake = NULL((void*)0); |
10633 | |
10634 | /* RFC 5077 Section 3.3: "The client MUST NOT treat the ticket as valid |
10635 | * until it has verified the server's Finished message." When the server |
10636 | * sends a NewSessionTicket in a resumption handshake, we must wait until |
10637 | * the handshake is finished (we have verified the server's Finished |
10638 | * AND the server's certificate) before we update the ticket in the sid. |
10639 | * |
10640 | * This must be done before we call (*ss->sec.cache)(ss->sec.ci.sid) |
10641 | * because CacheSID requires the session ticket to already be set, and also |
10642 | * because of the lazy lock creation scheme used by CacheSID and |
10643 | * ssl3_SetSIDSessionTicket. |
10644 | */ |
10645 | if (ss->ssl3.hs.receivedNewSessionTicket) { |
10646 | PORT_Assert(!ss->sec.isServer)((!ss->sec.isServer)?((void)0):PR_Assert("!ss->sec.isServer" ,"ssl3con.c",10646)); |
10647 | ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ss->ssl3.hs.newSessionTicket); |
10648 | /* The sid took over the ticket data */ |
10649 | PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data)((!ss->ssl3.hs.newSessionTicket.ticket.data)?((void)0):PR_Assert ("!ss->ssl3.hs.newSessionTicket.ticket.data","ssl3con.c",10649 )); |
10650 | ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE0; |
10651 | } |
10652 | |
10653 | if (ss->ssl3.hs.cacheSID) { |
10654 | PORT_Assert(ss->sec.ci.sid->cached == never_cached)((ss->sec.ci.sid->cached == never_cached)?((void)0):PR_Assert ("ss->sec.ci.sid->cached == never_cached","ssl3con.c",10654 )); |
10655 | (*ss->sec.cache)(ss->sec.ci.sid); |
10656 | ss->ssl3.hs.cacheSID = PR_FALSE0; |
10657 | } |
10658 | |
10659 | ss->ssl3.hs.canFalseStart = PR_FALSE0; /* False Start phase is complete */ |
10660 | ss->ssl3.hs.ws = idle_handshake; |
10661 | |
10662 | ssl_FinishHandshake(ss); |
10663 | |
10664 | return SECSuccess; |
10665 | } |
10666 | |
10667 | /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3 |
10668 | * hanshake message. |
10669 | * Caller must hold Handshake and RecvBuf locks. |
10670 | */ |
10671 | SECStatus |
10672 | ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
10673 | { |
10674 | SECStatus rv = SECSuccess; |
10675 | SSL3HandshakeType type = ss->ssl3.hs.msg_type; |
10676 | SSL3Hashes hashes; /* computed hashes are put here. */ |
10677 | PRUint8 hdr[4]; |
10678 | PRUint8 dtlsData[8]; |
10679 | |
10680 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",10680)); |
10681 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10681)); |
10682 | /* |
10683 | * We have to compute the hashes before we update them with the |
10684 | * current message. |
10685 | */ |
10686 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; /************************************/ |
10687 | if((type == finished) || (type == certificate_verify)) { |
10688 | SSL3Sender sender = (SSL3Sender)0; |
10689 | ssl3CipherSpec *rSpec = ss->ssl3.prSpec; |
10690 | |
10691 | if (type == finished) { |
10692 | sender = ss->sec.isServer ? sender_client : sender_server; |
10693 | rSpec = ss->ssl3.crSpec; |
10694 | } |
10695 | rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); |
10696 | } |
10697 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; /************************************/ |
10698 | if (rv != SECSuccess) { |
10699 | return rv; /* error code was set by ssl3_ComputeHandshakeHashes*/ |
10700 | } |
10701 | SSL_TRC(30,("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: handle handshake message: %s" , getpid(), ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs .msg_type)) |
10702 | ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type)))if (ssl_trace >= (30)) ssl_Trace ("%d: SSL3[%d]: handle handshake message: %s" , getpid(), ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs .msg_type)); |
10703 | |
10704 | hdr[0] = (PRUint8)ss->ssl3.hs.msg_type; |
10705 | hdr[1] = (PRUint8)(length >> 16); |
10706 | hdr[2] = (PRUint8)(length >> 8); |
10707 | hdr[3] = (PRUint8)(length ); |
10708 | |
10709 | /* Start new handshake hashes when we start a new handshake */ |
10710 | if (ss->ssl3.hs.msg_type == client_hello) { |
10711 | rv = ssl3_RestartHandshakeHashes(ss); |
10712 | if (rv != SECSuccess) { |
10713 | return rv; |
10714 | } |
10715 | } |
10716 | /* We should not include hello_request and hello_verify_request messages |
10717 | * in the handshake hashes */ |
10718 | if ((ss->ssl3.hs.msg_type != hello_request) && |
10719 | (ss->ssl3.hs.msg_type != hello_verify_request)) { |
10720 | rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4); |
10721 | if (rv != SECSuccess) return rv; /* err code already set. */ |
10722 | |
10723 | /* Extra data to simulate a complete DTLS handshake fragment */ |
10724 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
10725 | /* Sequence number */ |
10726 | dtlsData[0] = MSB(ss->ssl3.hs.recvMessageSeq)((unsigned char) (((unsigned)(ss->ssl3.hs.recvMessageSeq)) >> 8)); |
10727 | dtlsData[1] = LSB(ss->ssl3.hs.recvMessageSeq)((unsigned char) ((ss->ssl3.hs.recvMessageSeq) & 0xff) ); |
10728 | |
10729 | /* Fragment offset */ |
10730 | dtlsData[2] = 0; |
10731 | dtlsData[3] = 0; |
10732 | dtlsData[4] = 0; |
10733 | |
10734 | /* Fragment length */ |
10735 | dtlsData[5] = (PRUint8)(length >> 16); |
10736 | dtlsData[6] = (PRUint8)(length >> 8); |
10737 | dtlsData[7] = (PRUint8)(length ); |
10738 | |
10739 | rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) dtlsData, |
10740 | sizeof(dtlsData)); |
10741 | if (rv != SECSuccess) return rv; /* err code already set. */ |
10742 | } |
10743 | |
10744 | /* The message body */ |
10745 | rv = ssl3_UpdateHandshakeHashes(ss, b, length); |
10746 | if (rv != SECSuccess) return rv; /* err code already set. */ |
10747 | } |
10748 | |
10749 | PORT_SetErrorPORT_SetError_Util(0); /* each message starts with no error. */ |
10750 | |
10751 | if (ss->ssl3.hs.ws == wait_certificate_status && |
10752 | ss->ssl3.hs.msg_type != certificate_status) { |
10753 | /* If we negotiated the certificate_status extension then we deferred |
10754 | * certificate validation until we get the CertificateStatus messsage. |
10755 | * But the CertificateStatus message is optional. If the server did |
10756 | * not send it then we need to validate the certificate now. If the |
10757 | * server does send the CertificateStatus message then we will |
10758 | * authenticate the certificate in ssl3_HandleCertificateStatus. |
10759 | */ |
10760 | rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */ |
10761 | PORT_Assert(rv != SECWouldBlock)((rv != SECWouldBlock)?((void)0):PR_Assert("rv != SECWouldBlock" ,"ssl3con.c",10761)); |
10762 | if (rv != SECSuccess) { |
10763 | return rv; |
10764 | } |
10765 | } |
10766 | |
10767 | switch (ss->ssl3.hs.msg_type) { |
10768 | case hello_request: |
10769 | if (length != 0) { |
10770 | (void)ssl3_DecodeError(ss); |
10771 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST); |
10772 | return SECFailure; |
10773 | } |
10774 | if (ss->sec.isServer) { |
10775 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10776 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST); |
10777 | return SECFailure; |
10778 | } |
10779 | rv = ssl3_HandleHelloRequest(ss); |
10780 | break; |
10781 | case client_hello: |
10782 | if (!ss->sec.isServer) { |
10783 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10784 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO); |
10785 | return SECFailure; |
10786 | } |
10787 | rv = ssl3_HandleClientHello(ss, b, length); |
10788 | break; |
10789 | case server_hello: |
10790 | if (ss->sec.isServer) { |
10791 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10792 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO); |
10793 | return SECFailure; |
10794 | } |
10795 | rv = ssl3_HandleServerHello(ss, b, length); |
10796 | break; |
10797 | case hello_verify_request: |
10798 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram) || ss->sec.isServer) { |
10799 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10800 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST); |
10801 | return SECFailure; |
10802 | } |
10803 | rv = dtls_HandleHelloVerifyRequest(ss, b, length); |
10804 | break; |
10805 | case certificate: |
10806 | rv = ssl3_HandleCertificate(ss, b, length); |
10807 | break; |
10808 | case certificate_status: |
10809 | rv = ssl3_HandleCertificateStatus(ss, b, length); |
10810 | break; |
10811 | case server_key_exchange: |
10812 | if (ss->sec.isServer) { |
10813 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10814 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); |
10815 | return SECFailure; |
10816 | } |
10817 | rv = ssl3_HandleServerKeyExchange(ss, b, length); |
10818 | break; |
10819 | case certificate_request: |
10820 | if (ss->sec.isServer) { |
10821 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10822 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST); |
10823 | return SECFailure; |
10824 | } |
10825 | rv = ssl3_HandleCertificateRequest(ss, b, length); |
10826 | break; |
10827 | case server_hello_done: |
10828 | if (length != 0) { |
10829 | (void)ssl3_DecodeError(ss); |
10830 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_HELLO_DONE); |
10831 | return SECFailure; |
10832 | } |
10833 | if (ss->sec.isServer) { |
10834 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10835 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); |
10836 | return SECFailure; |
10837 | } |
10838 | rv = ssl3_HandleServerHelloDone(ss); |
10839 | break; |
10840 | case certificate_verify: |
10841 | if (!ss->sec.isServer) { |
10842 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10843 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); |
10844 | return SECFailure; |
10845 | } |
10846 | rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes); |
10847 | break; |
10848 | case client_key_exchange: |
10849 | if (!ss->sec.isServer) { |
10850 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10851 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH); |
10852 | return SECFailure; |
10853 | } |
10854 | rv = ssl3_HandleClientKeyExchange(ss, b, length); |
10855 | break; |
10856 | case new_session_ticket: |
10857 | if (ss->sec.isServer) { |
10858 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10859 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET); |
10860 | return SECFailure; |
10861 | } |
10862 | rv = ssl3_HandleNewSessionTicket(ss, b, length); |
10863 | break; |
10864 | case finished: |
10865 | rv = ssl3_HandleFinished(ss, b, length, &hashes); |
10866 | break; |
10867 | default: |
10868 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
10869 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNKNOWN_HANDSHAKE); |
10870 | rv = SECFailure; |
10871 | } |
10872 | |
10873 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram) && (rv != SECFailure)) { |
10874 | /* Increment the expected sequence number */ |
10875 | ss->ssl3.hs.recvMessageSeq++; |
10876 | } |
10877 | |
10878 | return rv; |
10879 | } |
10880 | |
10881 | /* Called only from ssl3_HandleRecord, for each (deciphered) ssl3 record. |
10882 | * origBuf is the decrypted ssl record content. |
10883 | * Caller must hold the handshake and RecvBuf locks. |
10884 | */ |
10885 | static SECStatus |
10886 | ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) |
10887 | { |
10888 | /* |
10889 | * There may be a partial handshake message already in the handshake |
10890 | * state. The incoming buffer may contain another portion, or a |
10891 | * complete message or several messages followed by another portion. |
10892 | * |
10893 | * Each message is made contiguous before being passed to the actual |
10894 | * message parser. |
10895 | */ |
10896 | sslBuffer *buf = &ss->ssl3.hs.msgState; /* do not lose the original buffer pointer */ |
10897 | SECStatus rv; |
10898 | |
10899 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",10899)); |
10900 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",10900)); |
10901 | |
10902 | if (buf->buf == NULL((void*)0)) { |
10903 | *buf = *origBuf; |
10904 | } |
10905 | while (buf->len > 0) { |
10906 | if (ss->ssl3.hs.header_bytes < 4) { |
10907 | PRUint8 t; |
10908 | t = *(buf->buf++); |
10909 | buf->len--; |
10910 | if (ss->ssl3.hs.header_bytes++ == 0) |
10911 | ss->ssl3.hs.msg_type = (SSL3HandshakeType)t; |
10912 | else |
10913 | ss->ssl3.hs.msg_len = (ss->ssl3.hs.msg_len << 8) + t; |
10914 | if (ss->ssl3.hs.header_bytes < 4) |
10915 | continue; |
10916 | |
10917 | #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ |
10918 | if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) { |
10919 | (void)ssl3_DecodeError(ss); |
10920 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_RECORD_TOO_LONG); |
10921 | return SECFailure; |
10922 | } |
10923 | #undef MAX_HANDSHAKE_MSG_LEN |
10924 | |
10925 | /* If msg_len is zero, be sure we fall through, |
10926 | ** even if buf->len is zero. |
10927 | */ |
10928 | if (ss->ssl3.hs.msg_len > 0) |
10929 | continue; |
10930 | } |
10931 | |
10932 | /* |
10933 | * Header has been gathered and there is at least one byte of new |
10934 | * data available for this message. If it can be done right out |
10935 | * of the original buffer, then use it from there. |
10936 | */ |
10937 | if (ss->ssl3.hs.msg_body.len == 0 && buf->len >= ss->ssl3.hs.msg_len) { |
10938 | /* handle it from input buffer */ |
10939 | rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ss->ssl3.hs.msg_len); |
10940 | if (rv == SECFailure) { |
10941 | /* This test wants to fall through on either |
10942 | * SECSuccess or SECWouldBlock. |
10943 | * ssl3_HandleHandshakeMessage MUST set the error code. |
10944 | */ |
10945 | return rv; |
10946 | } |
10947 | buf->buf += ss->ssl3.hs.msg_len; |
10948 | buf->len -= ss->ssl3.hs.msg_len; |
10949 | ss->ssl3.hs.msg_len = 0; |
10950 | ss->ssl3.hs.header_bytes = 0; |
10951 | if (rv != SECSuccess) { /* return if SECWouldBlock. */ |
10952 | return rv; |
10953 | } |
10954 | } else { |
10955 | /* must be copied to msg_body and dealt with from there */ |
10956 | unsigned int bytes; |
10957 | |
10958 | PORT_Assert(ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len)((ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len)?(( void)0):PR_Assert("ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len" ,"ssl3con.c",10958)); |
10959 | bytes = PR_MIN(buf->len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len)((buf->len)<(ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body .len)?(buf->len):(ss->ssl3.hs.msg_len - ss->ssl3.hs. msg_body.len)); |
10960 | |
10961 | /* Grow the buffer if needed */ |
10962 | rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, ss->ssl3.hs.msg_len); |
10963 | if (rv != SECSuccess) { |
10964 | /* sslBuffer_Grow has set a memory error code. */ |
10965 | return SECFailure; |
10966 | } |
10967 | |
10968 | PORT_Memcpymemcpy(ss->ssl3.hs.msg_body.buf + ss->ssl3.hs.msg_body.len, |
10969 | buf->buf, bytes); |
10970 | ss->ssl3.hs.msg_body.len += bytes; |
10971 | buf->buf += bytes; |
10972 | buf->len -= bytes; |
10973 | |
10974 | PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len)((ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len)?( (void)0):PR_Assert("ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len" ,"ssl3con.c",10974)); |
10975 | |
10976 | /* if we have a whole message, do it */ |
10977 | if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) { |
10978 | rv = ssl3_HandleHandshakeMessage( |
10979 | ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len); |
10980 | if (rv == SECFailure) { |
10981 | /* This test wants to fall through on either |
10982 | * SECSuccess or SECWouldBlock. |
10983 | * ssl3_HandleHandshakeMessage MUST set error code. |
10984 | */ |
10985 | return rv; |
10986 | } |
10987 | ss->ssl3.hs.msg_body.len = 0; |
10988 | ss->ssl3.hs.msg_len = 0; |
10989 | ss->ssl3.hs.header_bytes = 0; |
10990 | if (rv != SECSuccess) { /* return if SECWouldBlock. */ |
10991 | return rv; |
10992 | } |
10993 | } else { |
10994 | PORT_Assert(buf->len == 0)((buf->len == 0)?((void)0):PR_Assert("buf->len == 0","ssl3con.c" ,10994)); |
10995 | break; |
10996 | } |
10997 | } |
10998 | } /* end loop */ |
10999 | |
11000 | origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ |
11001 | buf->buf = NULL((void*)0); /* not a leak. */ |
11002 | return SECSuccess; |
11003 | } |
11004 | |
11005 | /* These macros return the given value with the MSB copied to all the other |
11006 | * bits. They use the fact that arithmetic shift shifts-in the sign bit. |
11007 | * However, this is not ensured by the C standard so you may need to replace |
11008 | * them with something else for odd compilers. */ |
11009 | #define DUPLICATE_MSB_TO_ALL(x)( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ) |
11010 | #define DUPLICATE_MSB_TO_ALL_8(x)((unsigned char)(( (unsigned)( (int)(x) >> (sizeof(int) *8-1) ) ))) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ))) |
11011 | |
11012 | /* SECStatusToMask returns, in constant time, a mask value of all ones if |
11013 | * rv == SECSuccess. Otherwise it returns zero. */ |
11014 | static unsigned int |
11015 | SECStatusToMask(SECStatus rv) |
11016 | { |
11017 | unsigned int good; |
11018 | /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results |
11019 | * in the MSB being set to one iff it was zero before. */ |
11020 | good = rv ^ SECSuccess; |
11021 | good--; |
11022 | return DUPLICATE_MSB_TO_ALL(good)( (unsigned)( (int)(good) >> (sizeof(int)*8-1) ) ); |
11023 | } |
11024 | |
11025 | /* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */ |
11026 | static unsigned char |
11027 | ssl_ConstantTimeGE(unsigned int a, unsigned int b) |
11028 | { |
11029 | a -= b; |
11030 | return DUPLICATE_MSB_TO_ALL(~a)( (unsigned)( (int)(~a) >> (sizeof(int)*8-1) ) ); |
11031 | } |
11032 | |
11033 | /* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */ |
11034 | static unsigned char |
11035 | ssl_ConstantTimeEQ8(unsigned char a, unsigned char b) |
11036 | { |
11037 | unsigned int c = a ^ b; |
11038 | c--; |
11039 | return DUPLICATE_MSB_TO_ALL_8(c)((unsigned char)(( (unsigned)( (int)(c) >> (sizeof(int) *8-1) ) ))); |
11040 | } |
11041 | |
11042 | static SECStatus |
11043 | ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext, |
11044 | unsigned int blockSize, |
11045 | unsigned int macSize) |
11046 | { |
11047 | unsigned int paddingLength, good, t; |
11048 | const unsigned int overhead = 1 /* padding length byte */ + macSize; |
11049 | |
11050 | /* These lengths are all public so we can test them in non-constant |
11051 | * time. */ |
11052 | if (overhead > plaintext->len) { |
11053 | return SECFailure; |
11054 | } |
11055 | |
11056 | paddingLength = plaintext->buf[plaintext->len-1]; |
11057 | /* SSLv3 padding bytes are random and cannot be checked. */ |
11058 | t = plaintext->len; |
11059 | t -= paddingLength+overhead; |
11060 | /* If len >= paddingLength+overhead then the MSB of t is zero. */ |
11061 | good = DUPLICATE_MSB_TO_ALL(~t)( (unsigned)( (int)(~t) >> (sizeof(int)*8-1) ) ); |
11062 | /* SSLv3 requires that the padding is minimal. */ |
11063 | t = blockSize - (paddingLength+1); |
11064 | good &= DUPLICATE_MSB_TO_ALL(~t)( (unsigned)( (int)(~t) >> (sizeof(int)*8-1) ) ); |
11065 | plaintext->len -= good & (paddingLength+1); |
11066 | return (good & SECSuccess) | (~good & SECFailure); |
11067 | } |
11068 | |
11069 | static SECStatus |
11070 | ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize) |
11071 | { |
11072 | unsigned int paddingLength, good, t, toCheck, i; |
11073 | const unsigned int overhead = 1 /* padding length byte */ + macSize; |
11074 | |
11075 | /* These lengths are all public so we can test them in non-constant |
11076 | * time. */ |
11077 | if (overhead > plaintext->len) { |
11078 | return SECFailure; |
11079 | } |
11080 | |
11081 | paddingLength = plaintext->buf[plaintext->len-1]; |
11082 | t = plaintext->len; |
11083 | t -= paddingLength+overhead; |
11084 | /* If len >= paddingLength+overhead then the MSB of t is zero. */ |
11085 | good = DUPLICATE_MSB_TO_ALL(~t)( (unsigned)( (int)(~t) >> (sizeof(int)*8-1) ) ); |
11086 | |
11087 | /* The padding consists of a length byte at the end of the record and then |
11088 | * that many bytes of padding, all with the same value as the length byte. |
11089 | * Thus, with the length byte included, there are paddingLength+1 bytes of |
11090 | * padding. |
11091 | * |
11092 | * We can't check just |paddingLength+1| bytes because that leaks |
11093 | * decrypted information. Therefore we always have to check the maximum |
11094 | * amount of padding possible. (Again, the length of the record is |
11095 | * public information so we can use it.) */ |
11096 | toCheck = 255; /* maximum amount of padding. */ |
11097 | if (toCheck > plaintext->len-1) { |
11098 | toCheck = plaintext->len-1; |
11099 | } |
11100 | |
11101 | for (i = 0; i < toCheck; i++) { |
11102 | unsigned int t = paddingLength - i; |
11103 | /* If i <= paddingLength then the MSB of t is zero and mask is |
11104 | * 0xff. Otherwise, mask is 0. */ |
11105 | unsigned char mask = DUPLICATE_MSB_TO_ALL(~t)( (unsigned)( (int)(~t) >> (sizeof(int)*8-1) ) ); |
11106 | unsigned char b = plaintext->buf[plaintext->len-1-i]; |
11107 | /* The final |paddingLength+1| bytes should all have the value |
11108 | * |paddingLength|. Therefore the XOR should be zero. */ |
11109 | good &= ~(mask&(paddingLength ^ b)); |
11110 | } |
11111 | |
11112 | /* If any of the final |paddingLength+1| bytes had the wrong value, |
11113 | * one or more of the lower eight bits of |good| will be cleared. We |
11114 | * AND the bottom 8 bits together and duplicate the result to all the |
11115 | * bits. */ |
11116 | good &= good >> 4; |
11117 | good &= good >> 2; |
11118 | good &= good >> 1; |
11119 | good <<= sizeof(good)*8-1; |
11120 | good = DUPLICATE_MSB_TO_ALL(good)( (unsigned)( (int)(good) >> (sizeof(int)*8-1) ) ); |
11121 | |
11122 | plaintext->len -= good & (paddingLength+1); |
11123 | return (good & SECSuccess) | (~good & SECFailure); |
11124 | } |
11125 | |
11126 | /* On entry: |
11127 | * originalLength >= macSize |
11128 | * macSize <= MAX_MAC_LENGTH |
11129 | * plaintext->len >= macSize |
11130 | */ |
11131 | static void |
11132 | ssl_CBCExtractMAC(sslBuffer *plaintext, |
11133 | unsigned int originalLength, |
11134 | SSL3Opaque* out, |
11135 | unsigned int macSize) |
11136 | { |
11137 | unsigned char rotatedMac[MAX_MAC_LENGTH64]; |
11138 | /* macEnd is the index of |plaintext->buf| just after the end of the |
11139 | * MAC. */ |
11140 | unsigned macEnd = plaintext->len; |
11141 | unsigned macStart = macEnd - macSize; |
11142 | /* scanStart contains the number of bytes that we can ignore because |
11143 | * the MAC's position can only vary by 255 bytes. */ |
11144 | unsigned scanStart = 0; |
11145 | unsigned i, j, divSpoiler; |
11146 | unsigned char rotateOffset; |
11147 | |
11148 | if (originalLength > macSize + 255 + 1) |
11149 | scanStart = originalLength - (macSize + 255 + 1); |
11150 | |
11151 | /* divSpoiler contains a multiple of macSize that is used to cause the |
11152 | * modulo operation to be constant time. Without this, the time varies |
11153 | * based on the amount of padding when running on Intel chips at least. |
11154 | * |
11155 | * The aim of right-shifting macSize is so that the compiler doesn't |
11156 | * figure out that it can remove divSpoiler as that would require it |
11157 | * to prove that macSize is always even, which I hope is beyond it. */ |
11158 | divSpoiler = macSize >> 1; |
11159 | divSpoiler <<= (sizeof(divSpoiler)-1)*8; |
11160 | rotateOffset = (divSpoiler + macStart - scanStart) % macSize; |
11161 | |
11162 | memset(rotatedMac, 0, macSize); |
11163 | for (i = scanStart; i < originalLength;) { |
11164 | for (j = 0; j < macSize && i < originalLength; i++, j++) { |
11165 | unsigned char macStarted = ssl_ConstantTimeGE(i, macStart); |
11166 | unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd); |
11167 | unsigned char b = 0; |
11168 | b = plaintext->buf[i]; |
11169 | rotatedMac[j] |= b & macStarted & ~macEnded; |
11170 | } |
11171 | } |
11172 | |
11173 | /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line |
11174 | * we could line-align |rotatedMac| and rotate in place. */ |
11175 | memset(out, 0, macSize); |
11176 | for (i = 0; i < macSize; i++) { |
11177 | unsigned char offset = |
11178 | (divSpoiler + macSize - rotateOffset + i) % macSize; |
11179 | for (j = 0; j < macSize; j++) { |
11180 | out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset); |
11181 | } |
11182 | } |
11183 | } |
11184 | |
11185 | /* if cText is non-null, then decipher, check MAC, and decompress the |
11186 | * SSL record from cText->buf (typically gs->inbuf) |
11187 | * into databuf (typically gs->buf), and any previous contents of databuf |
11188 | * is lost. Then handle databuf according to its SSL record type, |
11189 | * unless it's an application record. |
11190 | * |
11191 | * If cText is NULL, then the ciphertext has previously been deciphered and |
11192 | * checked, and is already sitting in databuf. It is processed as an SSL |
11193 | * Handshake message. |
11194 | * |
11195 | * DOES NOT process the decrypted/decompressed application data. |
11196 | * On return, databuf contains the decrypted/decompressed record. |
11197 | * |
11198 | * Called from ssl3_GatherCompleteHandshake |
11199 | * ssl3_RestartHandshakeAfterCertReq |
11200 | * |
11201 | * Caller must hold the RecvBufLock. |
11202 | * |
11203 | * This function aquires and releases the SSL3Handshake Lock, holding the |
11204 | * lock around any calls to functions that handle records other than |
11205 | * Application Data records. |
11206 | */ |
11207 | SECStatus |
11208 | ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) |
11209 | { |
11210 | const ssl3BulkCipherDef *cipher_def; |
11211 | ssl3CipherSpec * crSpec; |
11212 | SECStatus rv; |
11213 | unsigned int hashBytes = MAX_MAC_LENGTH64 + 1; |
11214 | PRBool isTLS; |
11215 | SSL3ContentType rType; |
11216 | SSL3Opaque hash[MAX_MAC_LENGTH64]; |
11217 | SSL3Opaque givenHashBuf[MAX_MAC_LENGTH64]; |
11218 | SSL3Opaque *givenHash; |
11219 | sslBuffer *plaintext; |
11220 | sslBuffer temp_buf; |
11221 | PRUint64 dtls_seq_num; |
11222 | unsigned int ivLen = 0; |
11223 | unsigned int originalLen = 0; |
11224 | unsigned int good; |
11225 | unsigned int minLength; |
11226 | unsigned char header[13]; |
11227 | unsigned int headerLen; |
11228 | |
11229 | PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->recvBufLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveRecvBufLock(ss)" ,"ssl3con.c",11229)); |
11230 | |
11231 | if (!ss->ssl3.initialized) { |
11232 | ssl_GetSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",11232)); PR_EnterMonitor(((ss)->ssl3HandshakeLock )); } }; |
11233 | rv = ssl3_InitState(ss); |
11234 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
11235 | if (rv != SECSuccess) { |
11236 | return rv; /* ssl3_InitState has set the error code. */ |
11237 | } |
11238 | } |
11239 | |
11240 | /* check for Token Presence */ |
11241 | if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { |
11242 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
11243 | return SECFailure; |
11244 | } |
11245 | |
11246 | /* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX(). |
11247 | * This implies that databuf holds a previously deciphered SSL Handshake |
11248 | * message. |
11249 | */ |
11250 | if (cText == NULL((void*)0)) { |
11251 | SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, resuming handshake" , getpid(), ss->fd) |
11252 | SSL_GETPID(), ss->fd))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, resuming handshake" , getpid(), ss->fd); |
11253 | rType = content_handshake; |
11254 | goto process_it; |
11255 | } |
11256 | |
11257 | ssl_GetSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockRead_Util((ss)->specLock ); }; /******************************************/ |
11258 | |
11259 | crSpec = ss->ssl3.crSpec; |
11260 | cipher_def = crSpec->cipher_def; |
11261 | |
11262 | /* |
11263 | * DTLS relevance checks: |
11264 | * Note that this code currently ignores all out-of-epoch packets, |
11265 | * which means we lose some in the case of rehandshake + |
11266 | * loss/reordering. Since DTLS is explicitly unreliable, this |
11267 | * seems like a good tradeoff for implementation effort and is |
11268 | * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1 |
11269 | */ |
11270 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
11271 | DTLSEpoch epoch = (cText->seq_num.high >> 16) & 0xffff; |
11272 | |
11273 | if (crSpec->epoch != epoch) { |
11274 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
11275 | SSL_DBG(("%d: SSL3[%d]: HandleRecord, received packet "if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, received packet " "from irrelevant epoch %d", getpid(), ss->fd, epoch) |
11276 | "from irrelevant epoch %d", SSL_GETPID(), ss->fd, epoch))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, received packet " "from irrelevant epoch %d", getpid(), ss->fd, epoch); |
11277 | /* Silently drop the packet */ |
11278 | databuf->len = 0; /* Needed to ensure data not left around */ |
11279 | return SECSuccess; |
11280 | } |
11281 | |
11282 | dtls_seq_num = (((PRUint64)(cText->seq_num.high & 0xffff)) << 32) | |
11283 | ((PRUint64)cText->seq_num.low); |
11284 | |
11285 | if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) { |
11286 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
11287 | SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, rejecting " "potentially replayed packet", getpid(), ss->fd) |
11288 | "potentially replayed packet", SSL_GETPID(), ss->fd))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, rejecting " "potentially replayed packet", getpid(), ss->fd); |
11289 | /* Silently drop the packet */ |
11290 | databuf->len = 0; /* Needed to ensure data not left around */ |
11291 | return SECSuccess; |
11292 | } |
11293 | } |
11294 | |
11295 | good = ~0U; |
11296 | minLength = crSpec->mac_size; |
11297 | if (cipher_def->type == type_block) { |
11298 | /* CBC records have a padding length byte at the end. */ |
11299 | minLength++; |
11300 | if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_10x0302) { |
11301 | /* With >= TLS 1.1, CBC records have an explicit IV. */ |
11302 | minLength += cipher_def->iv_size; |
11303 | } |
11304 | } else if (cipher_def->type == type_aead) { |
11305 | minLength = cipher_def->explicit_nonce_size + cipher_def->tag_size; |
11306 | } |
11307 | |
11308 | /* We can perform this test in variable time because the record's total |
11309 | * length and the ciphersuite are both public knowledge. */ |
11310 | if (cText->buf->len < minLength) { |
11311 | goto decrypt_loser; |
11312 | } |
11313 | |
11314 | if (cipher_def->type == type_block && |
11315 | crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_10x0302) { |
11316 | /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states |
11317 | * "The receiver decrypts the entire GenericBlockCipher structure and |
11318 | * then discards the first cipher block corresponding to the IV |
11319 | * component." Instead, we decrypt the first cipher block and then |
11320 | * discard it before decrypting the rest. |
11321 | */ |
11322 | SSL3Opaque iv[MAX_IV_LENGTH24]; |
11323 | int decoded; |
11324 | |
11325 | ivLen = cipher_def->iv_size; |
11326 | if (ivLen < 8 || ivLen > sizeof(iv)) { |
11327 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
11328 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); |
11329 | return SECFailure; |
11330 | } |
11331 | |
11332 | PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen))if (ssl_trace >= (80)) ssl_PrintBuf (ss, "IV (ciphertext):" , cText->buf->buf, ivLen); |
11333 | |
11334 | /* The decryption result is garbage, but since we just throw away |
11335 | * the block it doesn't matter. The decryption of the next block |
11336 | * depends only on the ciphertext of the IV block. |
11337 | */ |
11338 | rv = crSpec->decode(crSpec->decodeContext, iv, &decoded, |
11339 | sizeof(iv), cText->buf->buf, ivLen); |
11340 | |
11341 | good &= SECStatusToMask(rv); |
11342 | } |
11343 | |
11344 | /* If we will be decompressing the buffer we need to decrypt somewhere |
11345 | * other than into databuf */ |
11346 | if (crSpec->decompressor) { |
11347 | temp_buf.buf = NULL((void*)0); |
11348 | temp_buf.space = 0; |
11349 | plaintext = &temp_buf; |
11350 | } else { |
11351 | plaintext = databuf; |
11352 | } |
11353 | |
11354 | plaintext->len = 0; /* filled in by decode call below. */ |
11355 | if (plaintext->space < MAX_FRAGMENT_LENGTH16384) { |
11356 | rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH16384 + 2048); |
11357 | if (rv != SECSuccess) { |
11358 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
11359 | SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, tried to get %d bytes" , getpid(), ss->fd, 16384 + 2048) |
11360 | SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, tried to get %d bytes" , getpid(), ss->fd, 16384 + 2048); |
11361 | /* sslBuffer_Grow has set a memory error code. */ |
11362 | /* Perhaps we should send an alert. (but we have no memory!) */ |
11363 | return SECFailure; |
11364 | } |
11365 | } |
11366 | |
11367 | PRINT_BUF(80, (ss, "ciphertext:", cText->buf->buf + ivLen,if (ssl_trace >= (80)) ssl_PrintBuf (ss, "ciphertext:", cText ->buf->buf + ivLen, cText->buf->len - ivLen) |
11368 | cText->buf->len - ivLen))if (ssl_trace >= (80)) ssl_PrintBuf (ss, "ciphertext:", cText ->buf->buf + ivLen, cText->buf->len - ivLen); |
11369 | |
11370 | isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_00x0300); |
11371 | |
11372 | if (isTLS && cText->buf->len - ivLen > (MAX_FRAGMENT_LENGTH16384 + 2048)) { |
11373 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
11374 | SSL3_SendAlert(ss, alert_fatal, record_overflow); |
11375 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_RECORD_TOO_LONG); |
11376 | return SECFailure; |
11377 | } |
11378 | |
11379 | rType = cText->type; |
11380 | if (cipher_def->type == type_aead) { |
11381 | /* XXX For many AEAD ciphers, the plaintext is shorter than the |
11382 | * ciphertext by a fixed byte count, but it is not true in general. |
11383 | * Each AEAD cipher should provide a function that returns the |
11384 | * plaintext length for a given ciphertext. */ |
11385 | unsigned int decryptedLen = |
11386 | cText->buf->len - cipher_def->explicit_nonce_size - |
11387 | cipher_def->tag_size; |
11388 | headerLen = ssl3_BuildRecordPseudoHeader( |
11389 | header, IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram) ? cText->seq_num : crSpec->read_seq_num, |
11390 | rType, isTLS, cText->version, IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram), decryptedLen); |
11391 | PORT_Assert(headerLen <= sizeof(header))((headerLen <= sizeof(header))?((void)0):PR_Assert("headerLen <= sizeof(header)" ,"ssl3con.c",11391)); |
11392 | rv = crSpec->aead( |
11393 | ss->sec.isServer ? &crSpec->client : &crSpec->server, |
11394 | PR_TRUE1, /* do decrypt */ |
11395 | plaintext->buf, /* out */ |
11396 | (int*) &plaintext->len, /* outlen */ |
11397 | plaintext->space, /* maxout */ |
11398 | cText->buf->buf, /* in */ |
11399 | cText->buf->len, /* inlen */ |
11400 | header, headerLen); |
11401 | if (rv != SECSuccess) { |
11402 | good = 0; |
11403 | } |
11404 | } else { |
11405 | if (cipher_def->type == type_block && |
11406 | ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) { |
11407 | goto decrypt_loser; |
11408 | } |
11409 | |
11410 | /* decrypt from cText buf to plaintext. */ |
11411 | rv = crSpec->decode( |
11412 | crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, |
11413 | plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); |
11414 | if (rv != SECSuccess) { |
11415 | goto decrypt_loser; |
11416 | } |
11417 | |
11418 | PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len))if (ssl_trace >= (80)) ssl_PrintBuf (ss, "cleartext:", plaintext ->buf, plaintext->len); |
11419 | |
11420 | originalLen = plaintext->len; |
11421 | |
11422 | /* If it's a block cipher, check and strip the padding. */ |
11423 | if (cipher_def->type == type_block) { |
11424 | const unsigned int blockSize = cipher_def->block_size; |
11425 | const unsigned int macSize = crSpec->mac_size; |
11426 | |
11427 | if (!isTLS) { |
11428 | good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding( |
11429 | plaintext, blockSize, macSize)); |
11430 | } else { |
11431 | good &= SECStatusToMask(ssl_RemoveTLSCBCPadding( |
11432 | plaintext, macSize)); |
11433 | } |
11434 | } |
11435 | |
11436 | /* compute the MAC */ |
11437 | headerLen = ssl3_BuildRecordPseudoHeader( |
11438 | header, IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram) ? cText->seq_num : crSpec->read_seq_num, |
11439 | rType, isTLS, cText->version, IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram), |
11440 | plaintext->len - crSpec->mac_size); |
11441 | PORT_Assert(headerLen <= sizeof(header))((headerLen <= sizeof(header))?((void)0):PR_Assert("headerLen <= sizeof(header)" ,"ssl3con.c",11441)); |
11442 | if (cipher_def->type == type_block) { |
11443 | rv = ssl3_ComputeRecordMACConstantTime( |
11444 | crSpec, (PRBool)(!ss->sec.isServer), header, headerLen, |
11445 | plaintext->buf, plaintext->len, originalLen, |
11446 | hash, &hashBytes); |
11447 | |
11448 | ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf, |
11449 | crSpec->mac_size); |
11450 | givenHash = givenHashBuf; |
11451 | |
11452 | /* plaintext->len will always have enough space to remove the MAC |
11453 | * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust |
11454 | * plaintext->len if the result has enough space for the MAC and we |
11455 | * tested the unadjusted size against minLength, above. */ |
11456 | plaintext->len -= crSpec->mac_size; |
11457 | } else { |
11458 | /* This is safe because we checked the minLength above. */ |
11459 | plaintext->len -= crSpec->mac_size; |
11460 | |
11461 | rv = ssl3_ComputeRecordMAC( |
11462 | crSpec, (PRBool)(!ss->sec.isServer), header, headerLen, |
11463 | plaintext->buf, plaintext->len, hash, &hashBytes); |
11464 | |
11465 | /* We can read the MAC directly from the record because its location |
11466 | * is public when a stream cipher is used. */ |
11467 | givenHash = plaintext->buf + plaintext->len; |
11468 | } |
11469 | |
11470 | good &= SECStatusToMask(rv); |
11471 | |
11472 | if (hashBytes != (unsigned)crSpec->mac_size || |
11473 | NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) { |
11474 | /* We're allowed to leak whether or not the MAC check was correct */ |
11475 | good = 0; |
11476 | } |
11477 | } |
11478 | |
11479 | if (good == 0) { |
11480 | decrypt_loser: |
11481 | /* must not hold spec lock when calling SSL3_SendAlert. */ |
11482 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; |
11483 | |
11484 | SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: decryption failed", getpid (), ss->fd); |
11485 | |
11486 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
11487 | SSL3_SendAlert(ss, alert_fatal, bad_record_mac); |
11488 | /* always log mac error, in case attacker can read server logs. */ |
11489 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_BAD_MAC_READ); |
11490 | return SECFailure; |
11491 | } else { |
11492 | /* Silently drop the packet */ |
11493 | databuf->len = 0; /* Needed to ensure data not left around */ |
11494 | return SECSuccess; |
11495 | } |
11496 | } |
11497 | |
11498 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
11499 | ssl3_BumpSequenceNumber(&crSpec->read_seq_num); |
11500 | } else { |
11501 | dtls_RecordSetRecvd(&crSpec->recvdRecords, dtls_seq_num); |
11502 | } |
11503 | |
11504 | ssl_ReleaseSpecReadLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockRead_Util((ss)-> specLock); }; /*****************************************/ |
11505 | |
11506 | /* |
11507 | * The decrypted data is now in plaintext. |
11508 | */ |
11509 | |
11510 | /* possibly decompress the record. If we aren't using compression then |
11511 | * plaintext == databuf and so the uncompressed data is already in |
11512 | * databuf. */ |
11513 | if (crSpec->decompressor) { |
11514 | if (databuf->space < plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION0) { |
11515 | rv = sslBuffer_Grow( |
11516 | databuf, plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION0); |
11517 | if (rv != SECSuccess) { |
11518 | SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, tried to get %d bytes" , getpid(), ss->fd, plaintext->len + 0) |
11519 | SSL_GETPID(), ss->fd,if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, tried to get %d bytes" , getpid(), ss->fd, plaintext->len + 0) |
11520 | plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: HandleRecord, tried to get %d bytes" , getpid(), ss->fd, plaintext->len + 0); |
11521 | /* sslBuffer_Grow has set a memory error code. */ |
11522 | /* Perhaps we should send an alert. (but we have no memory!) */ |
11523 | PORT_FreePORT_Free_Util(plaintext->buf); |
11524 | return SECFailure; |
11525 | } |
11526 | } |
11527 | |
11528 | rv = crSpec->decompressor(crSpec->decompressContext, |
11529 | databuf->buf, |
11530 | (int*) &databuf->len, |
11531 | databuf->space, |
11532 | plaintext->buf, |
11533 | plaintext->len); |
11534 | |
11535 | if (rv != SECSuccess) { |
11536 | int err = ssl_MapLowLevelError(SSL_ERROR_DECOMPRESSION_FAILURE); |
11537 | SSL3_SendAlert(ss, alert_fatal, |
11538 | isTLS ? decompression_failure : bad_record_mac); |
11539 | |
11540 | /* There appears to be a bug with (at least) Apache + OpenSSL where |
11541 | * resumed SSLv3 connections don't actually use compression. See |
11542 | * comments 93-95 of |
11543 | * https://bugzilla.mozilla.org/show_bug.cgi?id=275744 |
11544 | * |
11545 | * So, if we get a decompression error, and the record appears to |
11546 | * be already uncompressed, then we return a more specific error |
11547 | * code to hopefully save somebody some debugging time in the |
11548 | * future. |
11549 | */ |
11550 | if (plaintext->len >= 4) { |
11551 | unsigned int len = ((unsigned int) plaintext->buf[1] << 16) | |
11552 | ((unsigned int) plaintext->buf[2] << 8) | |
11553 | (unsigned int) plaintext->buf[3]; |
11554 | if (len == plaintext->len - 4) { |
11555 | /* This appears to be uncompressed already */ |
11556 | err = SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD; |
11557 | } |
11558 | } |
11559 | |
11560 | PORT_FreePORT_Free_Util(plaintext->buf); |
11561 | PORT_SetErrorPORT_SetError_Util(err); |
11562 | return SECFailure; |
11563 | } |
11564 | |
11565 | PORT_FreePORT_Free_Util(plaintext->buf); |
11566 | } |
11567 | |
11568 | /* |
11569 | ** Having completed the decompression, check the length again. |
11570 | */ |
11571 | if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH16384 + 1024)) { |
11572 | SSL3_SendAlert(ss, alert_fatal, record_overflow); |
11573 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_RECORD_TOO_LONG); |
11574 | return SECFailure; |
11575 | } |
11576 | |
11577 | /* Application data records are processed by the caller of this |
11578 | ** function, not by this function. |
11579 | */ |
11580 | if (rType == content_application_data) { |
11581 | if (ss->firstHsDone) |
11582 | return SECSuccess; |
11583 | (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
11584 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA); |
11585 | return SECFailure; |
11586 | } |
11587 | |
11588 | /* It's a record that must be handled by ssl itself, not the application. |
11589 | */ |
11590 | process_it: |
11591 | /* XXX Get the xmit lock here. Odds are very high that we'll be xmiting |
11592 | * data ang getting the xmit lock here prevents deadlocks. |
11593 | */ |
11594 | ssl_GetSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) { ((!((PR_GetMonitorEntryCount(((ss )->xmitBufLock)) > 0)))?((void)0):PR_Assert("!ssl_HaveXmitBufLock(ss)" ,"ssl3con.c",11594)); PR_EnterMonitor(((ss)->ssl3HandshakeLock )); } }; |
11595 | |
11596 | /* All the functions called in this switch MUST set error code if |
11597 | ** they return SECFailure or SECWouldBlock. |
11598 | */ |
11599 | switch (rType) { |
11600 | case content_change_cipher_spec: |
11601 | rv = ssl3_HandleChangeCipherSpecs(ss, databuf); |
11602 | break; |
11603 | case content_alert: |
11604 | rv = ssl3_HandleAlert(ss, databuf); |
11605 | break; |
11606 | case content_handshake: |
11607 | if (!IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
11608 | rv = ssl3_HandleHandshake(ss, databuf); |
11609 | } else { |
11610 | rv = dtls_HandleHandshake(ss, databuf); |
11611 | } |
11612 | break; |
11613 | /* |
11614 | case content_application_data is handled before this switch |
11615 | */ |
11616 | default: |
11617 | SSL_DBG(("%d: SSL3[%d]: bogus content type=%d",if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: bogus content type=%d" , getpid(), ss->fd, cText->type) |
11618 | SSL_GETPID(), ss->fd, cText->type))if (ssl_debug) ssl_Trace ("%d: SSL3[%d]: bogus content type=%d" , getpid(), ss->fd, cText->type); |
11619 | /* XXX Send an alert ??? */ |
11620 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE); |
11621 | rv = SECFailure; |
11622 | break; |
11623 | } |
11624 | |
11625 | ssl_ReleaseSSL3HandshakeLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->ssl3HandshakeLock )); }; |
11626 | return rv; |
11627 | } |
11628 | |
11629 | /* |
11630 | * Initialization functions |
11631 | */ |
11632 | |
11633 | /* Called from ssl3_InitState, immediately below. */ |
11634 | /* Caller must hold the SpecWriteLock. */ |
11635 | static void |
11636 | ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec) |
11637 | { |
11638 | spec->cipher_def = &bulk_cipher_defs[cipher_null]; |
11639 | PORT_Assert(spec->cipher_def->cipher == cipher_null)((spec->cipher_def->cipher == cipher_null)?((void)0):PR_Assert ("spec->cipher_def->cipher == cipher_null","ssl3con.c", 11639)); |
11640 | spec->mac_def = &mac_defs[mac_nullssl_mac_null]; |
11641 | PORT_Assert(spec->mac_def->mac == mac_null)((spec->mac_def->mac == ssl_mac_null)?((void)0):PR_Assert ("spec->mac_def->mac == mac_null","ssl3con.c",11641)); |
11642 | spec->encode = Null_Cipher; |
11643 | spec->decode = Null_Cipher; |
11644 | spec->destroy = NULL((void*)0); |
11645 | spec->compressor = NULL((void*)0); |
11646 | spec->decompressor = NULL((void*)0); |
11647 | spec->destroyCompressContext = NULL((void*)0); |
11648 | spec->destroyDecompressContext = NULL((void*)0); |
11649 | spec->mac_size = 0; |
11650 | spec->master_secret = NULL((void*)0); |
11651 | spec->bypassCiphers = PR_FALSE0; |
11652 | |
11653 | spec->msItem.data = NULL((void*)0); |
11654 | spec->msItem.len = 0; |
11655 | |
11656 | spec->client.write_key = NULL((void*)0); |
11657 | spec->client.write_mac_key = NULL((void*)0); |
11658 | spec->client.write_mac_context = NULL((void*)0); |
11659 | |
11660 | spec->server.write_key = NULL((void*)0); |
11661 | spec->server.write_mac_key = NULL((void*)0); |
11662 | spec->server.write_mac_context = NULL((void*)0); |
11663 | |
11664 | spec->write_seq_num.high = 0; |
11665 | spec->write_seq_num.low = 0; |
11666 | |
11667 | spec->read_seq_num.high = 0; |
11668 | spec->read_seq_num.low = 0; |
11669 | |
11670 | spec->epoch = 0; |
11671 | dtls_InitRecvdRecords(&spec->recvdRecords); |
11672 | |
11673 | spec->version = ss->vrange.max; |
11674 | } |
11675 | |
11676 | /* Called from: ssl3_SendRecord |
11677 | ** ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake() |
11678 | ** ssl3_SendClientHello() |
11679 | ** ssl3_HandleV2ClientHello() |
11680 | ** ssl3_HandleRecord() |
11681 | ** |
11682 | ** This function should perhaps acquire and release the SpecWriteLock. |
11683 | ** |
11684 | ** |
11685 | */ |
11686 | static SECStatus |
11687 | ssl3_InitState(sslSocket *ss) |
11688 | { |
11689 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss))((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",11689)); |
11690 | |
11691 | if (ss->ssl3.initialized) |
11692 | return SECSuccess; /* Function should be idempotent */ |
11693 | |
11694 | ss->ssl3.policy = SSL_ALLOWED1; |
11695 | |
11696 | ssl_GetSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_LockWrite_Util((ss)-> specLock); }; |
11697 | ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0]; |
11698 | ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1]; |
11699 | ss->ssl3.hs.sendingSCSV = PR_FALSE0; |
11700 | ssl3_InitCipherSpec(ss, ss->ssl3.crSpec); |
11701 | ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); |
11702 | |
11703 | ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; |
11704 | #ifdef NSS_ENABLE_ECC1 |
11705 | ss->ssl3.hs.negotiatedECCurves = ssl3_GetSupportedECCurveMask(ss); |
11706 | #endif |
11707 | ssl_ReleaseSpecWriteLock(ss){ if (!ss->opt.noLocks) NSSRWLock_UnlockWrite_Util((ss)-> specLock); }; |
11708 | |
11709 | PORT_Memsetmemset(&ss->xtnData, 0, sizeof(TLSExtensionData)); |
11710 | |
11711 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
11712 | ss->ssl3.hs.sendMessageSeq = 0; |
11713 | ss->ssl3.hs.recvMessageSeq = 0; |
11714 | ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS1000; |
11715 | ss->ssl3.hs.rtRetries = 0; |
11716 | ss->ssl3.hs.recvdHighWater = -1; |
11717 | PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight)do { (&ss->ssl3.hs.lastMessageFlight)->next = (& ss->ssl3.hs.lastMessageFlight); (&ss->ssl3.hs.lastMessageFlight )->prev = (&ss->ssl3.hs.lastMessageFlight); } while (0); |
11718 | dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */ |
11719 | } |
11720 | |
11721 | PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space)((!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages .space)?((void)0):PR_Assert("!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space" ,"ssl3con.c",11721)); |
11722 | ss->ssl3.hs.messages.buf = NULL((void*)0); |
11723 | ss->ssl3.hs.messages.space = 0; |
11724 | |
11725 | ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE0; |
11726 | PORT_Memsetmemset(&ss->ssl3.hs.newSessionTicket, 0, |
11727 | sizeof(ss->ssl3.hs.newSessionTicket)); |
11728 | |
11729 | ss->ssl3.initialized = PR_TRUE1; |
11730 | return SECSuccess; |
11731 | } |
11732 | |
11733 | /* Returns a reference counted object that contains a key pair. |
11734 | * Or NULL on failure. Initial ref count is 1. |
11735 | * Uses the keys in the pair as input. |
11736 | */ |
11737 | ssl3KeyPair * |
11738 | ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey) |
11739 | { |
11740 | ssl3KeyPair * pair; |
11741 | |
11742 | if (!privKey || !pubKey) { |
11743 | PORT_SetErrorPORT_SetError_Util(PR_INVALID_ARGUMENT_ERROR(-5987L)); |
11744 | return NULL((void*)0); |
11745 | } |
11746 | pair = PORT_ZNew(ssl3KeyPair)(ssl3KeyPair*)PORT_ZAlloc_Util(sizeof(ssl3KeyPair)); |
11747 | if (!pair) |
11748 | return NULL((void*)0); /* error code is set. */ |
11749 | pair->refCount = 1; |
11750 | pair->privKey = privKey; |
11751 | pair->pubKey = pubKey; |
11752 | return pair; /* success */ |
11753 | } |
11754 | |
11755 | ssl3KeyPair * |
11756 | ssl3_GetKeyPairRef(ssl3KeyPair * keyPair) |
11757 | { |
11758 | PR_ATOMIC_INCREMENT(&keyPair->refCount)__sync_add_and_fetch(&keyPair->refCount, 1); |
11759 | return keyPair; |
11760 | } |
11761 | |
11762 | void |
11763 | ssl3_FreeKeyPair(ssl3KeyPair * keyPair) |
11764 | { |
11765 | PRInt32 newCount = PR_ATOMIC_DECREMENT(&keyPair->refCount)__sync_sub_and_fetch(&keyPair->refCount, 1); |
11766 | if (!newCount) { |
11767 | if (keyPair->privKey) |
11768 | SECKEY_DestroyPrivateKey(keyPair->privKey); |
11769 | if (keyPair->pubKey) |
11770 | SECKEY_DestroyPublicKey( keyPair->pubKey); |
11771 | PORT_FreePORT_Free_Util(keyPair); |
11772 | } |
11773 | } |
11774 | |
11775 | |
11776 | |
11777 | /* |
11778 | * Creates the public and private RSA keys for SSL Step down. |
11779 | * Called from SSL_ConfigSecureServer in sslsecur.c |
11780 | */ |
11781 | SECStatus |
11782 | ssl3_CreateRSAStepDownKeys(sslSocket *ss) |
11783 | { |
11784 | SECStatus rv = SECSuccess; |
11785 | SECKEYPrivateKey * privKey; /* RSA step down key */ |
11786 | SECKEYPublicKey * pubKey; /* RSA step down key */ |
11787 | |
11788 | if (ss->stepDownKeyPair) |
11789 | ssl3_FreeKeyPair(ss->stepDownKeyPair); |
11790 | ss->stepDownKeyPair = NULL((void*)0); |
11791 | #ifndef HACKED_EXPORT_SERVER |
11792 | /* Sigh, should have a get key strength call for private keys */ |
11793 | if (PK11_GetPrivateModulusLen(ss->serverCerts[kt_rsassl_kea_rsa].SERVERKEYserverKeyPair->privKey) > |
11794 | EXPORT_RSA_KEY_LENGTH64) { |
11795 | /* need to ask for the key size in bits */ |
11796 | privKey = SECKEY_CreateRSAPrivateKey(EXPORT_RSA_KEY_LENGTH64 * BPB8, |
11797 | &pubKey, NULL((void*)0)); |
11798 | if (!privKey || !pubKey || |
11799 | !(ss->stepDownKeyPair = ssl3_NewKeyPair(privKey, pubKey))) { |
11800 | ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
11801 | rv = SECFailure; |
11802 | } |
11803 | } |
11804 | #endif |
11805 | return rv; |
11806 | } |
11807 | |
11808 | |
11809 | /* record the export policy for this cipher suite */ |
11810 | SECStatus |
11811 | ssl3_SetPolicy(ssl3CipherSuite which, int policy) |
11812 | { |
11813 | ssl3CipherSuiteCfg *suite; |
11814 | |
11815 | suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); |
11816 | if (suite == NULL((void*)0)) { |
11817 | return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ |
11818 | } |
11819 | suite->policy = policy; |
11820 | |
11821 | return SECSuccess; |
11822 | } |
11823 | |
11824 | SECStatus |
11825 | ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy) |
11826 | { |
11827 | ssl3CipherSuiteCfg *suite; |
11828 | PRInt32 policy; |
11829 | SECStatus rv; |
11830 | |
11831 | suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); |
11832 | if (suite) { |
11833 | policy = suite->policy; |
11834 | rv = SECSuccess; |
11835 | } else { |
11836 | policy = SSL_NOT_ALLOWED0; |
11837 | rv = SECFailure; /* err code was set by Lookup. */ |
11838 | } |
11839 | *oPolicy = policy; |
11840 | return rv; |
11841 | } |
11842 | |
11843 | /* record the user preference for this suite */ |
11844 | SECStatus |
11845 | ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled) |
11846 | { |
11847 | ssl3CipherSuiteCfg *suite; |
11848 | |
11849 | suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); |
11850 | if (suite == NULL((void*)0)) { |
11851 | return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ |
11852 | } |
11853 | suite->enabled = enabled; |
11854 | return SECSuccess; |
11855 | } |
11856 | |
11857 | /* return the user preference for this suite */ |
11858 | SECStatus |
11859 | ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled) |
11860 | { |
11861 | ssl3CipherSuiteCfg *suite; |
11862 | PRBool pref; |
11863 | SECStatus rv; |
11864 | |
11865 | suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); |
11866 | if (suite) { |
11867 | pref = suite->enabled; |
11868 | rv = SECSuccess; |
11869 | } else { |
11870 | pref = SSL_NOT_ALLOWED0; |
11871 | rv = SECFailure; /* err code was set by Lookup. */ |
11872 | } |
11873 | *enabled = pref; |
11874 | return rv; |
11875 | } |
11876 | |
11877 | SECStatus |
11878 | ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled) |
11879 | { |
11880 | ssl3CipherSuiteCfg *suite; |
11881 | |
11882 | suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites); |
11883 | if (suite == NULL((void*)0)) { |
11884 | return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ |
11885 | } |
11886 | suite->enabled = enabled; |
11887 | return SECSuccess; |
11888 | } |
11889 | |
11890 | SECStatus |
11891 | ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled) |
11892 | { |
11893 | ssl3CipherSuiteCfg *suite; |
11894 | PRBool pref; |
11895 | SECStatus rv; |
11896 | |
11897 | suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites); |
11898 | if (suite) { |
11899 | pref = suite->enabled; |
11900 | rv = SECSuccess; |
11901 | } else { |
11902 | pref = SSL_NOT_ALLOWED0; |
11903 | rv = SECFailure; /* err code was set by Lookup. */ |
11904 | } |
11905 | *enabled = pref; |
11906 | return rv; |
11907 | } |
11908 | |
11909 | /* copy global default policy into socket. */ |
11910 | void |
11911 | ssl3_InitSocketPolicy(sslSocket *ss) |
11912 | { |
11913 | PORT_Memcpymemcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites); |
11914 | } |
11915 | |
11916 | /* ssl3_config_match_init must have already been called by |
11917 | * the caller of this function. |
11918 | */ |
11919 | SECStatus |
11920 | ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size) |
11921 | { |
11922 | int i, count = 0; |
11923 | |
11924 | PORT_Assert(ss != 0)((ss != 0)?((void)0):PR_Assert("ss != 0","ssl3con.c",11924)); |
11925 | if (!ss) { |
11926 | PORT_SetErrorPORT_SetError_Util(PR_INVALID_ARGUMENT_ERROR(-5987L)); |
11927 | return SECFailure; |
11928 | } |
11929 | if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)((&ss->vrange)->min == 0)) { |
11930 | *size = 0; |
11931 | return SECSuccess; |
11932 | } |
11933 | if (cs == NULL((void*)0)) { |
11934 | *size = count_cipher_suites(ss, SSL_ALLOWED1, PR_TRUE1); |
11935 | return SECSuccess; |
11936 | } |
11937 | |
11938 | /* ssl3_config_match_init was called by the caller of this function. */ |
11939 | for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED61; i++) { |
11940 | ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; |
11941 | if (config_match(suite, SSL_ALLOWED1, PR_TRUE1, &ss->vrange)) { |
11942 | if (cs != NULL((void*)0)) { |
11943 | *cs++ = 0x00; |
11944 | *cs++ = (suite->cipher_suite >> 8) & 0xFF; |
11945 | *cs++ = suite->cipher_suite & 0xFF; |
11946 | } |
11947 | count++; |
11948 | } |
11949 | } |
11950 | *size = count; |
11951 | return SECSuccess; |
11952 | } |
11953 | |
11954 | /* |
11955 | ** If ssl3 socket has completed the first handshake, and is in idle state, |
11956 | ** then start a new handshake. |
11957 | ** If flushCache is true, the SID cache will be flushed first, forcing a |
11958 | ** "Full" handshake (not a session restart handshake), to be done. |
11959 | ** |
11960 | ** called from SSL_RedoHandshake(), which already holds the handshake locks. |
11961 | */ |
11962 | SECStatus |
11963 | ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) |
11964 | { |
11965 | sslSessionID * sid = ss->sec.ci.sid; |
11966 | SECStatus rv; |
11967 | |
11968 | PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) )((ss->opt.noLocks || ((PR_GetMonitorEntryCount(((ss)->ssl3HandshakeLock )) > 0)))?((void)0):PR_Assert("ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)" ,"ssl3con.c",11968)); |
11969 | |
11970 | if (!ss->firstHsDone || |
11971 | ((ss->version >= SSL_LIBRARY_VERSION_3_00x0300) && |
11972 | ss->ssl3.initialized && |
11973 | (ss->ssl3.hs.ws != idle_handshake))) { |
11974 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); |
11975 | return SECFailure; |
11976 | } |
11977 | |
11978 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
11979 | dtls_RehandshakeCleanup(ss); |
11980 | } |
11981 | |
11982 | if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER((PRBool)0)) { |
11983 | PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); |
11984 | return SECFailure; |
11985 | } |
11986 | if (sid && flushCache) { |
11987 | if (ss->sec.uncache) |
11988 | ss->sec.uncache(sid); /* remove it from whichever cache it's in. */ |
11989 | ssl_FreeSID(sid); /* dec ref count and free if zero. */ |
11990 | ss->sec.ci.sid = NULL((void*)0); |
11991 | } |
11992 | |
11993 | ssl_GetXmitBufLock(ss){ if (!ss->opt.noLocks) PR_EnterMonitor(((ss)->xmitBufLock )); }; /**************************************/ |
11994 | |
11995 | /* start off a new handshake. */ |
11996 | rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) |
11997 | : ssl3_SendClientHello(ss, PR_FALSE0); |
11998 | |
11999 | ssl_ReleaseXmitBufLock(ss){ if (!ss->opt.noLocks) PR_ExitMonitor(((ss)->xmitBufLock )); }; /**************************************/ |
12000 | return rv; |
12001 | } |
12002 | |
12003 | /* Called from ssl_DestroySocketContents() in sslsock.c */ |
12004 | void |
12005 | ssl3_DestroySSL3Info(sslSocket *ss) |
12006 | { |
12007 | |
12008 | if (ss->ssl3.clientCertificate != NULL((void*)0)) |
12009 | CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
12010 | |
12011 | if (ss->ssl3.clientPrivateKey != NULL((void*)0)) |
12012 | SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
12013 | |
12014 | if (ss->ssl3.peerCertArena != NULL((void*)0)) |
12015 | ssl3_CleanupPeerCerts(ss); |
12016 | |
12017 | if (ss->ssl3.clientCertChain != NULL((void*)0)) { |
12018 | CERT_DestroyCertificateList(ss->ssl3.clientCertChain); |
12019 | ss->ssl3.clientCertChain = NULL((void*)0); |
12020 | } |
12021 | |
12022 | /* clean up handshake */ |
12023 | #ifndef NO_PKCS11_BYPASS1 |
12024 | if (ss->opt.bypassPKCS11) { |
12025 | if (ss->ssl3.hs.hashType == handshake_hash_combo) { |
12026 | SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE0); |
12027 | MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE0); |
12028 | } else if (ss->ssl3.hs.hashType == handshake_hash_single) { |
12029 | ss->ssl3.hs.sha_obj->destroy(ss->ssl3.hs.sha_cx, PR_FALSE0); |
12030 | } |
12031 | } |
12032 | #endif |
12033 | if (ss->ssl3.hs.md5) { |
12034 | PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE1); |
12035 | } |
12036 | if (ss->ssl3.hs.sha) { |
12037 | PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE1); |
12038 | } |
12039 | if (ss->ssl3.hs.clientSigAndHash) { |
12040 | PORT_FreePORT_Free_Util(ss->ssl3.hs.clientSigAndHash); |
12041 | } |
12042 | if (ss->ssl3.hs.messages.buf) { |
12043 | PORT_FreePORT_Free_Util(ss->ssl3.hs.messages.buf); |
12044 | ss->ssl3.hs.messages.buf = NULL((void*)0); |
12045 | ss->ssl3.hs.messages.len = 0; |
12046 | ss->ssl3.hs.messages.space = 0; |
12047 | } |
12048 | |
12049 | /* free the SSL3Buffer (msg_body) */ |
12050 | PORT_FreePORT_Free_Util(ss->ssl3.hs.msg_body.buf); |
12051 | |
12052 | SECITEM_FreeItemSECITEM_FreeItem_Util(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE0); |
12053 | |
12054 | /* free up the CipherSpecs */ |
12055 | ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE1/*freeSrvName*/); |
12056 | ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE1/*freeSrvName*/); |
12057 | |
12058 | /* Destroy the DTLS data */ |
12059 | if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) { |
12060 | dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); |
12061 | if (ss->ssl3.hs.recvdFragments.buf) { |
12062 | PORT_FreePORT_Free_Util(ss->ssl3.hs.recvdFragments.buf); |
12063 | } |
12064 | } |
12065 | |
12066 | ss->ssl3.initialized = PR_FALSE0; |
12067 | |
12068 | SECITEM_FreeItemSECITEM_FreeItem_Util(&ss->ssl3.nextProto, PR_FALSE0); |
12069 | } |
12070 | |
12071 | /* End of ssl3con.c */ |