OLD | NEW |
1 /* | 1 /* |
2 * SSL v2 handshake functions, and functions common to SSL2 and SSL3. | 2 * SSL v2 handshake functions, and functions common to SSL2 and SSL3. |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | 7 |
8 #include "nssrenam.h" | 8 #include "nssrenam.h" |
9 #include "cert.h" | 9 #include "cert.h" |
10 #include "secitem.h" | 10 #include "secitem.h" |
11 #include "sechash.h" | 11 #include "sechash.h" |
12 #include "cryptohi.h"» » /* for SGN_ funcs */ | 12 #include "cryptohi.h" /* for SGN_ funcs */ |
13 #include "keyhi.h" » » /* for SECKEY_ high level functions. */ | 13 #include "keyhi.h" /* for SECKEY_ high level functions. */ |
14 #include "ssl.h" | 14 #include "ssl.h" |
15 #include "sslimpl.h" | 15 #include "sslimpl.h" |
16 #include "sslproto.h" | 16 #include "sslproto.h" |
17 #include "ssl3prot.h" | 17 #include "ssl3prot.h" |
18 #include "sslerr.h" | 18 #include "sslerr.h" |
19 #include "pk11func.h" | 19 #include "pk11func.h" |
20 #include "prinit.h" | 20 #include "prinit.h" |
21 #include "prtime.h" » /* for PR_Now() */ | 21 #include "prtime.h" /* for PR_Now() */ |
22 | 22 |
23 static PRBool policyWasSet; | 23 static PRBool policyWasSet; |
24 | 24 |
25 #define ssl2_NUM_SUITES_IMPLEMENTED 6 | 25 #define ssl2_NUM_SUITES_IMPLEMENTED 6 |
26 | 26 |
27 /* This list is sent back to the client when the client-hello message | 27 /* This list is sent back to the client when the client-hello message |
28 * contains no overlapping ciphers, so the client can report what ciphers | 28 * contains no overlapping ciphers, so the client can report what ciphers |
29 * are supported by the server. Unlike allCipherSuites (above), this list | 29 * are supported by the server. Unlike allCipherSuites (above), this list |
30 * is sorted by descending preference, not by cipherSuite number. | 30 * is sorted by descending preference, not by cipherSuite number. |
31 */ | 31 */ |
| 32 /* clang-format off */ |
32 static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] =
{ | 33 static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] =
{ |
33 SSL_CK_RC4_128_WITH_MD5,» » » 0x00, 0x80, | 34 SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80, |
34 SSL_CK_RC2_128_CBC_WITH_MD5,» » 0x00, 0x80, | 35 SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80, |
35 SSL_CK_DES_192_EDE3_CBC_WITH_MD5,» » 0x00, 0xC0, | 36 SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0, |
36 SSL_CK_DES_64_CBC_WITH_MD5,»» » 0x00, 0x40, | 37 SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40, |
37 SSL_CK_RC4_128_EXPORT40_WITH_MD5,» » 0x00, 0x80, | 38 SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80, |
38 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,» 0x00, 0x80 | 39 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80 |
39 }; | 40 }; |
40 | 41 |
| 42 |
41 typedef struct ssl2SpecsStr { | 43 typedef struct ssl2SpecsStr { |
42 PRUint8 nkm; /* do this many hashes to generate key material. */ | 44 PRUint8 nkm; /* do this many hashes to generate key material. */ |
43 PRUint8 nkd; /* size of readKey and writeKey in bytes. */ | 45 PRUint8 nkd; /* size of readKey and writeKey in bytes. */ |
44 PRUint8 blockSize; | 46 PRUint8 blockSize; |
45 PRUint8 blockShift; | 47 PRUint8 blockShift; |
46 CK_MECHANISM_TYPE mechanism; | 48 CK_MECHANISM_TYPE mechanism; |
47 PRUint8 keyLen;» /* cipher symkey size in bytes. */ | 49 PRUint8 keyLen; /* cipher symkey size in bytes. */ |
48 PRUint8 pubLen;» /* publicly reveal this many bytes of key. */ | 50 PRUint8 pubLen; /* publicly reveal this many bytes of key. */ |
49 PRUint8 ivLen;» /* length of IV data at *ca.» */ | 51 PRUint8 ivLen; /* length of IV data at *ca. */ |
50 } ssl2Specs; | 52 } ssl2Specs; |
51 | 53 |
52 static const ssl2Specs ssl_Specs[] = { | 54 static const ssl2Specs ssl_Specs[] = { |
53 /* NONE */ | 55 /* NONE */ |
54 » » » » { 0, 0, 0, 0, }, | 56 { 0, 0, 0, 0 }, |
55 /* SSL_CK_RC4_128_WITH_MD5» » */ | 57 /* SSL_CK_RC4_128_WITH_MD5 */ |
56 » » » » { 2, 16, 1, 0, CKM_RC4, 16, 0, 0, }, | 58 { 2, 16, 1, 0, CKM_RC4, 16, 0, 0 }, |
57 /* SSL_CK_RC4_128_EXPORT40_WITH_MD5» */ | 59 /* SSL_CK_RC4_128_EXPORT40_WITH_MD5 */ |
58 » » » » { 2, 16, 1, 0, CKM_RC4, 16, 11, 0, }, | 60 { 2, 16, 1, 0, CKM_RC4, 16, 11, 0 }, |
59 /* SSL_CK_RC2_128_CBC_WITH_MD5» » */ | 61 /* SSL_CK_RC2_128_CBC_WITH_MD5 */ |
60 » » » » { 2, 16, 8, 3, CKM_RC2_CBC, 16, 0, 8, }, | 62 { 2, 16, 8, 3, CKM_RC2_CBC, 16, 0, 8 }, |
61 /* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5»*/ | 63 /* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 */ |
62 » » » » { 2, 16, 8, 3, CKM_RC2_CBC, 16, 11, 8, }, | 64 { 2, 16, 8, 3, CKM_RC2_CBC, 16, 11, 8 }, |
63 /* SSL_CK_IDEA_128_CBC_WITH_MD5»» */ | 65 /* SSL_CK_IDEA_128_CBC_WITH_MD5 */ |
64 » » » » { 0, 0, 0, 0, }, | 66 { 0, 0, 0, 0 }, |
65 /* SSL_CK_DES_64_CBC_WITH_MD5» » */ | 67 /* SSL_CK_DES_64_CBC_WITH_MD5 */ |
66 » » » » { 1, 8, 8, 3, CKM_DES_CBC, 8, 0, 8, }, | 68 { 1, 8, 8, 3, CKM_DES_CBC, 8, 0, 8 }, |
67 /* SSL_CK_DES_192_EDE3_CBC_WITH_MD5» */ | 69 /* SSL_CK_DES_192_EDE3_CBC_WITH_MD5 */ |
68 » » » » { 3, 24, 8, 3, CKM_DES3_CBC, 24, 0, 8, }, | 70 { 3, 24, 8, 3, CKM_DES3_CBC, 24, 0, 8 }, |
69 }; | 71 }; |
| 72 /* clang-format on */ |
70 | 73 |
71 #define SET_ERROR_CODE» /* reminder */ | 74 #define SET_ERROR_CODE /* reminder */ |
72 #define TEST_FOR_FAILURE /* reminder */ | 75 #define TEST_FOR_FAILURE /* reminder */ |
73 | 76 |
74 /* | 77 /* |
75 ** Put a string tag in the library so that we can examine an executable | 78 ** Put a string tag in the library so that we can examine an executable |
76 ** and see what kind of security it supports. | 79 ** and see what kind of security it supports. |
77 */ | 80 */ |
78 const char *ssl_version = "SECURITY_VERSION:" | 81 const char *ssl_version = "SECURITY_VERSION:" |
79 » » » " +us" | 82 " +us" |
80 » » » " +export" | 83 " +export" |
81 #ifdef TRACE | 84 #ifdef TRACE |
82 » » » " +trace" | 85 " +trace" |
83 #endif | 86 #endif |
84 #ifdef DEBUG | 87 #ifdef DEBUG |
85 » » » " +debug" | 88 " +debug" |
86 #endif | 89 #endif |
87 » » » ; | 90 ; |
88 | 91 |
89 const char * const ssl_cipherName[] = { | 92 const char *const ssl_cipherName[] = { |
90 "unknown", | 93 "unknown", |
91 "RC4", | 94 "RC4", |
92 "RC4-Export", | 95 "RC4-Export", |
93 "RC2-CBC", | 96 "RC2-CBC", |
94 "RC2-CBC-Export", | 97 "RC2-CBC-Export", |
95 "IDEA-CBC", | 98 "IDEA-CBC", |
96 "DES-CBC", | 99 "DES-CBC", |
97 "DES-EDE3-CBC", | 100 "DES-EDE3-CBC", |
98 "unknown", | 101 "unknown", |
99 "unknown", /* was fortezza, NO LONGER USED */ | 102 "unknown", /* was fortezza, NO LONGER USED */ |
100 }; | 103 }; |
101 | 104 |
102 | |
103 /* bit-masks, showing which SSLv2 suites are allowed. | 105 /* bit-masks, showing which SSLv2 suites are allowed. |
104 * lsb corresponds to first cipher suite in allCipherSuites[]. | 106 * lsb corresponds to first cipher suite in allCipherSuites[]. |
105 */ | 107 */ |
106 static PRUint16»allowedByPolicy; /* all off by default */ | 108 static PRUint16 allowedByPolicy; /* all off by default */ |
107 static PRUint16»maybeAllowedByPolicy; /* all off by default */ | 109 static PRUint16 maybeAllowedByPolicy; /* all off by default */ |
108 static PRUint16»chosenPreference = 0xff; /* all on by default */ | 110 static PRUint16 chosenPreference = 0xff; /* all on by default */ |
109 | 111 |
110 /* bit values for the above two bit masks */ | 112 /* bit values for the above two bit masks */ |
111 #define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5) | 113 #define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5) |
112 #define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_
MD5) | 114 #define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5) |
113 #define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5) | 115 #define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5) |
114 #define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_W
ITH_MD5) | 116 #define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_W
ITH_MD5) |
115 #define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5) | 117 #define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5) |
116 #define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5) | 118 #define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5) |
117 #define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_
MD5) | 119 #define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5) |
118 #define SSL_CB_IMPLEMENTED \ | 120 #define SSL_CB_IMPLEMENTED \ |
119 (SSL_CB_RC4_128_WITH_MD5 | \ | 121 (SSL_CB_RC4_128_WITH_MD5 | \ |
120 SSL_CB_RC4_128_EXPORT40_WITH_MD5 | \ | 122 SSL_CB_RC4_128_EXPORT40_WITH_MD5 | \ |
121 SSL_CB_RC2_128_CBC_WITH_MD5 | \ | 123 SSL_CB_RC2_128_CBC_WITH_MD5 | \ |
122 SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \ | 124 SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \ |
123 SSL_CB_DES_64_CBC_WITH_MD5 | \ | 125 SSL_CB_DES_64_CBC_WITH_MD5 | \ |
124 SSL_CB_DES_192_EDE3_CBC_WITH_MD5) | 126 SSL_CB_DES_192_EDE3_CBC_WITH_MD5) |
125 | |
126 | 127 |
127 /* Construct a socket's list of cipher specs from the global default values. | 128 /* Construct a socket's list of cipher specs from the global default values. |
128 */ | 129 */ |
129 static SECStatus | 130 static SECStatus |
130 ssl2_ConstructCipherSpecs(sslSocket *ss) | 131 ssl2_ConstructCipherSpecs(sslSocket *ss) |
131 { | 132 { |
132 PRUint8 *» cs» » = NULL; | 133 PRUint8 *cs = NULL; |
133 unsigned int» allowed; | 134 unsigned int allowed; |
134 unsigned int» count; | 135 unsigned int count; |
135 int » » ssl3_count» = 0; | 136 int ssl3_count = 0; |
136 int » » final_count; | 137 int final_count; |
137 int » » i; | 138 int i; |
138 SECStatus » » rv; | 139 SECStatus rv; |
139 | 140 |
140 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 141 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
141 | 142 |
142 count = 0; | 143 count = 0; |
143 PORT_Assert(ss != 0); | 144 PORT_Assert(ss != 0); |
144 allowed = !ss->opt.enableSSL2 ? 0 : | 145 allowed = !ss->opt.enableSSL2 ? 0 : (ss->allowedByPolicy & |
145 » (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); | 146 ss->chosenPreference & SSL_CB_IMPLEMENT
ED); |
146 while (allowed) { | 147 while (allowed) { |
147 » if (allowed & 1) | 148 if (allowed & 1) |
148 » ++count; | 149 ++count; |
149 » allowed >>= 1; | 150 allowed >>= 1; |
150 } | 151 } |
151 | 152 |
152 /* Call ssl3_config_match_init() once here, | 153 /* Call ssl3_config_match_init() once here, |
153 * instead of inside ssl3_ConstructV2CipherSpecsHack(), | 154 * instead of inside ssl3_ConstructV2CipherSpecsHack(), |
154 * because the latter gets called twice below, | 155 * because the latter gets called twice below, |
155 * and then again in ssl2_BeginClientHandshake(). | 156 * and then again in ssl2_BeginClientHandshake(). |
156 */ | 157 */ |
157 ssl3_config_match_init(ss); | 158 ssl3_config_match_init(ss); |
158 | 159 |
159 /* ask SSL3 how many cipher suites it has. */ | 160 /* ask SSL3 how many cipher suites it has. */ |
160 rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count); | 161 rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count); |
161 if (rv < 0) | 162 if (rv < 0) |
162 » return rv; | 163 return rv; |
163 count += ssl3_count; | 164 count += ssl3_count; |
164 | 165 |
165 /* Allocate memory to hold cipher specs */ | 166 /* Allocate memory to hold cipher specs */ |
166 if (count > 0) | 167 if (count > 0) |
167 » cs = (PRUint8*) PORT_Alloc(count * 3); | 168 cs = (PRUint8 *)PORT_Alloc(count * 3); |
168 else | 169 else |
169 » PORT_SetError(SSL_ERROR_SSL_DISABLED); | 170 PORT_SetError(SSL_ERROR_SSL_DISABLED); |
170 if (cs == NULL) | 171 if (cs == NULL) |
171 » return SECFailure; | 172 return SECFailure; |
172 | 173 |
173 if (ss->cipherSpecs != NULL) { | 174 if (ss->cipherSpecs != NULL) { |
174 » PORT_Free(ss->cipherSpecs); | 175 PORT_Free(ss->cipherSpecs); |
175 } | 176 } |
176 ss->cipherSpecs = cs; | 177 ss->cipherSpecs = cs; |
177 ss->sizeCipherSpecs = count * 3; | 178 ss->sizeCipherSpecs = count * 3; |
178 | 179 |
179 /* fill in cipher specs for SSL2 cipher suites */ | 180 /* fill in cipher specs for SSL2 cipher suites */ |
180 allowed = !ss->opt.enableSSL2 ? 0 : | 181 allowed = !ss->opt.enableSSL2 ? 0 : (ss->allowedByPolicy & |
181 » (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); | 182 ss->chosenPreference & SSL_CB_IMPLEMENT
ED); |
182 for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) { | 183 for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) { |
183 » const PRUint8 * hs = implementedCipherSuites + i; | 184 const PRUint8 *hs = implementedCipherSuites + i; |
184 » int ok = allowed & (1U << hs[0]); | 185 int ok = allowed & (1U << hs[0]); |
185 » if (ok) { | 186 if (ok) { |
186 » cs[0] = hs[0]; | 187 cs[0] = hs[0]; |
187 » cs[1] = hs[1]; | 188 cs[1] = hs[1]; |
188 » cs[2] = hs[2]; | 189 cs[2] = hs[2]; |
189 » cs += 3; | 190 cs += 3; |
190 » } | 191 } |
191 } | 192 } |
192 | 193 |
193 /* now have SSL3 add its suites onto the end */ | 194 /* now have SSL3 add its suites onto the end */ |
194 rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count); | 195 rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count); |
195 | 196 |
196 /* adjust for any difference between first pass and second pass */ | 197 /* adjust for any difference between first pass and second pass */ |
197 ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3; | 198 ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3; |
198 | 199 |
199 return rv; | 200 return rv; |
200 } | 201 } |
201 | 202 |
202 /* This function is called immediately after ssl2_ConstructCipherSpecs() | 203 /* This function is called immediately after ssl2_ConstructCipherSpecs() |
203 ** at the beginning of a handshake. It detects cases where a protocol | 204 ** at the beginning of a handshake. It detects cases where a protocol |
204 ** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites | 205 ** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites |
205 ** for that protocol have been disabled. If such cases, it clears the | 206 ** for that protocol have been disabled. If such cases, it clears the |
206 ** enable bit for the protocol. If no protocols remain enabled, or | 207 ** enable bit for the protocol. If no protocols remain enabled, or |
207 ** if no cipher suites are found, it sets the error code and returns | 208 ** if no cipher suites are found, it sets the error code and returns |
208 ** SECFailure, otherwise it returns SECSuccess. | 209 ** SECFailure, otherwise it returns SECSuccess. |
209 */ | 210 */ |
210 static SECStatus | 211 static SECStatus |
211 ssl2_CheckConfigSanity(sslSocket *ss) | 212 ssl2_CheckConfigSanity(sslSocket *ss) |
212 { | 213 { |
213 unsigned int allowed; | 214 unsigned int allowed; |
214 int ssl3CipherCount = 0; | 215 int ssl3CipherCount = 0; |
215 SECStatus rv; | 216 SECStatus rv; |
216 | 217 |
217 /* count the SSL2 and SSL3 enabled ciphers. | 218 /* count the SSL2 and SSL3 enabled ciphers. |
218 * if either is zero, clear the socket's enable for that protocol. | 219 * if either is zero, clear the socket's enable for that protocol. |
219 */ | 220 */ |
220 if (!ss->cipherSpecs) | 221 if (!ss->cipherSpecs) |
221 » goto disabled; | 222 goto disabled; |
222 | 223 |
223 allowed = ss->allowedByPolicy & ss->chosenPreference; | 224 allowed = ss->allowedByPolicy & ss->chosenPreference; |
224 if (! allowed) | 225 if (!allowed) |
225 » ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */ | 226 ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */ |
226 | 227 |
227 /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */ | 228 /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */ |
228 /* Ask how many ssl3 CipherSuites were enabled. */ | 229 /* Ask how many ssl3 CipherSuites were enabled. */ |
229 rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount); | 230 rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount); |
230 if (rv != SECSuccess || ssl3CipherCount <= 0) { | 231 if (rv != SECSuccess || ssl3CipherCount <= 0) { |
231 » /* SSL3/TLS not really enabled if no ciphers */ | 232 /* SSL3/TLS not really enabled if no ciphers */ |
232 » ss->vrange.min = SSL_LIBRARY_VERSION_NONE; | 233 ss->vrange.min = SSL_LIBRARY_VERSION_NONE; |
233 » ss->vrange.max = SSL_LIBRARY_VERSION_NONE; | 234 ss->vrange.max = SSL_LIBRARY_VERSION_NONE; |
234 } | 235 } |
235 | 236 |
236 if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { | 237 if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
237 » SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.", | 238 SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.", |
238 » » SSL_GETPID(), ss->fd)); | 239 SSL_GETPID(), ss->fd)); |
239 disabled: | 240 disabled: |
240 » PORT_SetError(SSL_ERROR_SSL_DISABLED); | 241 PORT_SetError(SSL_ERROR_SSL_DISABLED); |
241 » return SECFailure; | 242 return SECFailure; |
242 } | 243 } |
243 return SECSuccess; | 244 return SECSuccess; |
244 } | 245 } |
245 | 246 |
246 /* | 247 /* |
247 * Since this is a global (not per-socket) setting, we cannot use the | 248 * Since this is a global (not per-socket) setting, we cannot use the |
248 * HandshakeLock to protect this. Probably want a global lock. | 249 * HandshakeLock to protect this. Probably want a global lock. |
249 */ | 250 */ |
250 SECStatus | 251 SECStatus |
251 ssl2_SetPolicy(PRInt32 which, PRInt32 policy) | 252 ssl2_SetPolicy(PRInt32 which, PRInt32 policy) |
252 { | 253 { |
253 PRUint32 bitMask; | 254 PRUint32 bitMask; |
254 SECStatus rv = SECSuccess; | 255 SECStatus rv = SECSuccess; |
255 | 256 |
256 which &= 0x000f; | 257 which &= 0x000f; |
257 bitMask = 1 << which; | 258 bitMask = 1 << which; |
258 | 259 |
259 if (!(bitMask & SSL_CB_IMPLEMENTED)) { | 260 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
260 » PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); | 261 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
261 » return SECFailure; | 262 return SECFailure; |
262 } | 263 } |
263 | 264 |
264 if (policy == SSL_ALLOWED) { | 265 if (policy == SSL_ALLOWED) { |
265 » allowedByPolicy » |= bitMask; | 266 allowedByPolicy |= bitMask; |
266 » maybeAllowedByPolicy » |= bitMask; | 267 maybeAllowedByPolicy |= bitMask; |
267 } else if (policy == SSL_RESTRICTED) { | 268 } else if (policy == SSL_RESTRICTED) { |
268 » allowedByPolicy » &= ~bitMask; | 269 allowedByPolicy &= ~bitMask; |
269 » maybeAllowedByPolicy » |= bitMask; | 270 maybeAllowedByPolicy |= bitMask; |
270 } else { | 271 } else { |
271 » allowedByPolicy » &= ~bitMask; | 272 allowedByPolicy &= ~bitMask; |
272 » maybeAllowedByPolicy » &= ~bitMask; | 273 maybeAllowedByPolicy &= ~bitMask; |
273 } | 274 } |
274 allowedByPolicy » » &= SSL_CB_IMPLEMENTED; | 275 allowedByPolicy &= SSL_CB_IMPLEMENTED; |
275 maybeAllowedByPolicy » &= SSL_CB_IMPLEMENTED; | 276 maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED; |
276 | 277 |
277 policyWasSet = PR_TRUE; | 278 policyWasSet = PR_TRUE; |
278 return rv; | 279 return rv; |
279 } | 280 } |
280 | 281 |
281 SECStatus | 282 SECStatus |
282 ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy) | 283 ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy) |
283 { | 284 { |
284 PRUint32 bitMask; | 285 PRUint32 bitMask; |
285 PRInt32 policy; | 286 PRInt32 policy; |
286 | 287 |
287 which &= 0x000f; | 288 which &= 0x000f; |
288 bitMask = 1 << which; | 289 bitMask = 1 << which; |
289 | 290 |
290 /* Caller assures oPolicy is not null. */ | 291 /* Caller assures oPolicy is not null. */ |
291 if (!(bitMask & SSL_CB_IMPLEMENTED)) { | 292 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
292 » PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); | 293 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
293 » *oPolicy = SSL_NOT_ALLOWED; | 294 *oPolicy = SSL_NOT_ALLOWED; |
294 » return SECFailure; | 295 return SECFailure; |
295 } | 296 } |
296 | 297 |
297 if (maybeAllowedByPolicy & bitMask) { | 298 if (maybeAllowedByPolicy & bitMask) { |
298 » policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED; | 299 policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED; |
299 } else { | 300 } else { |
300 » policy = SSL_NOT_ALLOWED; | 301 policy = SSL_NOT_ALLOWED; |
301 } | 302 } |
302 | 303 |
303 *oPolicy = policy; | 304 *oPolicy = policy; |
304 return SECSuccess; | 305 return SECSuccess; |
305 } | 306 } |
306 | 307 |
307 /* | 308 /* |
308 * Since this is a global (not per-socket) setting, we cannot use the | 309 * Since this is a global (not per-socket) setting, we cannot use the |
309 * HandshakeLock to protect this. Probably want a global lock. | 310 * HandshakeLock to protect this. Probably want a global lock. |
310 * Called from SSL_CipherPrefSetDefault in sslsock.c | 311 * Called from SSL_CipherPrefSetDefault in sslsock.c |
311 * These changes have no effect on any sslSockets already created. | 312 * These changes have no effect on any sslSockets already created. |
312 */ | 313 */ |
313 SECStatus | 314 SECStatus |
314 ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled) | 315 ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled) |
315 { | 316 { |
316 PRUint32 bitMask; | 317 PRUint32 bitMask; |
317 | 318 |
318 which &= 0x000f; | 319 which &= 0x000f; |
319 bitMask = 1 << which; | 320 bitMask = 1 << which; |
320 | 321 |
321 if (!(bitMask & SSL_CB_IMPLEMENTED)) { | 322 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
322 » PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); | 323 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
323 » return SECFailure; | 324 return SECFailure; |
324 } | 325 } |
325 | 326 |
326 if (enabled) | 327 if (enabled) |
327 » chosenPreference |= bitMask; | 328 chosenPreference |= bitMask; |
328 else | 329 else |
329 » chosenPreference &= ~bitMask; | 330 chosenPreference &= ~bitMask; |
330 chosenPreference &= SSL_CB_IMPLEMENTED; | 331 chosenPreference &= SSL_CB_IMPLEMENTED; |
331 | 332 |
332 return SECSuccess; | 333 return SECSuccess; |
333 } | 334 } |
334 | 335 |
335 SECStatus | 336 SECStatus |
336 ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled) | 337 ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled) |
337 { | 338 { |
338 PRBool rv = PR_FALSE; | 339 PRBool rv = PR_FALSE; |
339 PRUint32 bitMask; | 340 PRUint32 bitMask; |
340 | 341 |
341 which &= 0x000f; | 342 which &= 0x000f; |
342 bitMask = 1 << which; | 343 bitMask = 1 << which; |
343 | 344 |
344 if (!(bitMask & SSL_CB_IMPLEMENTED)) { | 345 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
345 » PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); | 346 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
346 » *enabled = PR_FALSE; | 347 *enabled = PR_FALSE; |
347 » return SECFailure; | 348 return SECFailure; |
348 } | 349 } |
349 | 350 |
350 rv = (PRBool)((chosenPreference & bitMask) != 0); | 351 rv = (PRBool)((chosenPreference & bitMask) != 0); |
351 *enabled = rv; | 352 *enabled = rv; |
352 return SECSuccess; | 353 return SECSuccess; |
353 } | 354 } |
354 | 355 |
355 SECStatus | 356 SECStatus |
356 ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled) | 357 ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled) |
357 { | 358 { |
358 PRUint32 bitMask; | 359 PRUint32 bitMask; |
359 | 360 |
360 which &= 0x000f; | 361 which &= 0x000f; |
361 bitMask = 1 << which; | 362 bitMask = 1 << which; |
362 | 363 |
363 if (!(bitMask & SSL_CB_IMPLEMENTED)) { | 364 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
364 » PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); | 365 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
365 » return SECFailure; | 366 return SECFailure; |
366 } | 367 } |
367 | 368 |
368 if (enabled) | 369 if (enabled) |
369 » ss->chosenPreference |= bitMask; | 370 ss->chosenPreference |= bitMask; |
370 else | 371 else |
371 » ss->chosenPreference &= ~bitMask; | 372 ss->chosenPreference &= ~bitMask; |
372 ss->chosenPreference &= SSL_CB_IMPLEMENTED; | 373 ss->chosenPreference &= SSL_CB_IMPLEMENTED; |
373 | 374 |
374 return SECSuccess; | 375 return SECSuccess; |
375 } | 376 } |
376 | 377 |
377 SECStatus | 378 SECStatus |
378 ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled) | 379 ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled) |
379 { | 380 { |
380 PRBool rv = PR_FALSE; | 381 PRBool rv = PR_FALSE; |
381 PRUint32 bitMask; | 382 PRUint32 bitMask; |
382 | 383 |
383 which &= 0x000f; | 384 which &= 0x000f; |
384 bitMask = 1 << which; | 385 bitMask = 1 << which; |
385 | 386 |
386 if (!(bitMask & SSL_CB_IMPLEMENTED)) { | 387 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
387 » PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); | 388 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
388 » *enabled = PR_FALSE; | 389 *enabled = PR_FALSE; |
389 » return SECFailure; | 390 return SECFailure; |
390 } | 391 } |
391 | 392 |
392 rv = (PRBool)((ss->chosenPreference & bitMask) != 0); | 393 rv = (PRBool)((ss->chosenPreference & bitMask) != 0); |
393 *enabled = rv; | 394 *enabled = rv; |
394 return SECSuccess; | 395 return SECSuccess; |
395 } | 396 } |
396 | 397 |
397 | |
398 /* copy global default policy into socket. */ | 398 /* copy global default policy into socket. */ |
399 void | 399 void |
400 ssl2_InitSocketPolicy(sslSocket *ss) | 400 ssl2_InitSocketPolicy(sslSocket *ss) |
401 { | 401 { |
402 ss->allowedByPolicy»» = allowedByPolicy; | 402 ss->allowedByPolicy = allowedByPolicy; |
403 ss->maybeAllowedByPolicy» = maybeAllowedByPolicy; | 403 ss->maybeAllowedByPolicy = maybeAllowedByPolicy; |
404 ss->chosenPreference » = chosenPreference; | 404 ss->chosenPreference = chosenPreference; |
405 } | 405 } |
406 | 406 |
407 | |
408 /************************************************************************/ | 407 /************************************************************************/ |
409 | 408 |
410 /* Called from ssl2_CreateSessionCypher(), which already holds handshake lock. | 409 /* Called from ssl2_CreateSessionCypher(), which already holds handshake lock. |
411 */ | 410 */ |
412 static SECStatus | 411 static SECStatus |
413 ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, | 412 ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, |
414 int cipherChoice) | 413 int cipherChoice) |
415 { | 414 { |
416 switch (cipherChoice) { | 415 switch (cipherChoice) { |
417 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: | 416 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
418 case SSL_CK_RC2_128_CBC_WITH_MD5: | 417 case SSL_CK_RC2_128_CBC_WITH_MD5: |
419 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: | 418 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
420 case SSL_CK_RC4_128_WITH_MD5: | 419 case SSL_CK_RC4_128_WITH_MD5: |
421 case SSL_CK_DES_64_CBC_WITH_MD5: | 420 case SSL_CK_DES_64_CBC_WITH_MD5: |
422 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: | 421 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: |
423 » sec->hash = HASH_GetHashObject(HASH_AlgMD5); | 422 sec->hash = HASH_GetHashObject(HASH_AlgMD5); |
424 » if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) || | 423 if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) || |
425 » SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) { | 424 SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) { |
426 » return SECFailure; | 425 return SECFailure; |
427 » } | 426 } |
428 » break; | 427 break; |
429 | 428 |
430 default: | 429 default: |
431 » PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 430 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
432 » return SECFailure; | 431 return SECFailure; |
433 } | 432 } |
434 sec->hashcx = (*sec->hash->create)(); | 433 sec->hashcx = (*sec->hash->create)(); |
435 if (sec->hashcx == NULL) | 434 if (sec->hashcx == NULL) |
436 » return SECFailure; | 435 return SECFailure; |
437 return SECSuccess; | 436 return SECSuccess; |
438 } | 437 } |
439 | 438 |
440 /************************************************************************ | 439 /************************************************************************ |
441 * All the Send functions below must acquire and release the socket's | 440 * All the Send functions below must acquire and release the socket's |
442 * xmitBufLock. | 441 * xmitBufLock. |
443 */ | 442 */ |
444 | 443 |
445 /* Called from all the Send* functions below. */ | 444 /* Called from all the Send* functions below. */ |
446 static SECStatus | 445 static SECStatus |
447 ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) | 446 ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) |
448 { | 447 { |
449 SECStatus rv = SECSuccess; | 448 SECStatus rv = SECSuccess; |
450 | 449 |
451 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 450 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
452 | 451 |
453 if (len < 128) { | 452 if (len < 128) { |
454 » len = 128; | 453 len = 128; |
455 } | 454 } |
456 if (len > ss->sec.ci.sendBuf.space) { | 455 if (len > ss->sec.ci.sendBuf.space) { |
457 » rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len); | 456 rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len); |
458 » if (rv != SECSuccess) { | 457 if (rv != SECSuccess) { |
459 » SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d by
tes", | 458 SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d by
tes", |
460 » » SSL_GETPID(), ss->fd, len)); | 459 SSL_GETPID(), ss->fd, len)); |
461 » rv = SECFailure; | 460 rv = SECFailure; |
462 » } | 461 } |
463 } | 462 } |
464 return rv; | 463 return rv; |
465 } | 464 } |
466 | 465 |
467 /* Called from: | 466 /* Called from: |
468 * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() | 467 * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() |
469 * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() <- | 468 * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() |
470 » » » » » ssl_Do1stHandshake() | 469 <- ssl_Do1stHandshake() |
471 * ssl2_HandleMessage() <- ssl_Do1stHandshake() | 470 * ssl2_HandleMessage() <- ssl_Do1stHandshake() |
472 * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake() | 471 * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake() |
473 after ssl2_BeginClientHandshake() | 472 after ssl2_BeginClientHandshake() |
474 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() | 473 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() |
475 after ssl2_BeginServerHandshake() | 474 after ssl2_BeginServerHandshake() |
476 * | 475 * |
477 * Acquires and releases the socket's xmitBufLock. | 476 * Acquires and releases the socket's xmitBufLock. |
478 */» | 477 */ |
479 int | 478 int |
480 ssl2_SendErrorMessage(sslSocket *ss, int error) | 479 ssl2_SendErrorMessage(sslSocket *ss, int error) |
481 { | 480 { |
482 int rv; | 481 int rv; |
483 PRUint8 msg[SSL_HL_ERROR_HBYTES]; | 482 PRUint8 msg[SSL_HL_ERROR_HBYTES]; |
484 | 483 |
485 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 484 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
486 | 485 |
487 msg[0] = SSL_MT_ERROR; | 486 msg[0] = SSL_MT_ERROR; |
488 msg[1] = MSB(error); | 487 msg[1] = MSB(error); |
489 msg[2] = LSB(error); | 488 msg[2] = LSB(error); |
490 | 489 |
491 ssl_GetXmitBufLock(ss); /***************************************/ | 490 ssl_GetXmitBufLock(ss); /***************************************/ |
492 | 491 |
493 SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error)); | 492 SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error)); |
494 | 493 |
495 ss->handshakeBegun = 1; | 494 ss->handshakeBegun = 1; |
496 rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0); | 495 rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0); |
497 if (rv >= 0) { | 496 if (rv >= 0) { |
498 » rv = SECSuccess; | 497 rv = SECSuccess; |
499 } | 498 } |
500 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 499 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
501 return rv; | 500 return rv; |
502 } | 501 } |
503 | 502 |
504 /* Called from ssl2_TryToFinish(). | 503 /* Called from ssl2_TryToFinish(). |
505 * Acquires and releases the socket's xmitBufLock. | 504 * Acquires and releases the socket's xmitBufLock. |
506 */ | 505 */ |
507 static SECStatus | 506 static SECStatus |
508 ssl2_SendClientFinishedMessage(sslSocket *ss) | 507 ssl2_SendClientFinishedMessage(sslSocket *ss) |
509 { | 508 { |
510 SECStatus rv = SECSuccess; | 509 SECStatus rv = SECSuccess; |
511 int sent; | 510 int sent; |
512 PRUint8 msg[1 + SSL_CONNECTIONID_BYTES]; | 511 PRUint8 msg[1 + SSL_CONNECTIONID_BYTES]; |
513 | 512 |
514 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 513 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
515 | 514 |
516 ssl_GetXmitBufLock(ss); /***************************************/ | 515 ssl_GetXmitBufLock(ss); /***************************************/ |
517 | 516 |
518 if (ss->sec.ci.sentFinished == 0) { | 517 if (ss->sec.ci.sentFinished == 0) { |
519 » ss->sec.ci.sentFinished = 1; | 518 ss->sec.ci.sentFinished = 1; |
520 | 519 |
521 » SSL_TRC(3, ("%d: SSL[%d]: sending client-finished", | 520 SSL_TRC(3, ("%d: SSL[%d]: sending client-finished", |
522 » » SSL_GETPID(), ss->fd)); | 521 SSL_GETPID(), ss->fd)); |
523 | 522 |
524 » msg[0] = SSL_MT_CLIENT_FINISHED; | 523 msg[0] = SSL_MT_CLIENT_FINISHED; |
525 » PORT_Memcpy(msg+1, ss->sec.ci.connectionID, | 524 PORT_Memcpy(msg + 1, ss->sec.ci.connectionID, |
526 » sizeof(ss->sec.ci.connectionID)); | 525 sizeof(ss->sec.ci.connectionID)); |
527 | 526 |
528 » DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID))); | 527 DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID))); |
529 » sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0); | 528 sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0); |
530 » rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; | 529 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
531 } | 530 } |
532 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 531 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
533 return rv; | 532 return rv; |
534 } | 533 } |
535 | 534 |
536 /* Called from | 535 /* Called from |
537 * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage() | 536 * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage() |
538 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() | 537 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() |
539 after ssl2_BeginServerHandshake() | 538 after ssl2_BeginServerHandshake() |
540 * Acquires and releases the socket's xmitBufLock. | 539 * Acquires and releases the socket's xmitBufLock. |
541 */ | 540 */ |
542 static SECStatus | 541 static SECStatus |
543 ssl2_SendServerVerifyMessage(sslSocket *ss) | 542 ssl2_SendServerVerifyMessage(sslSocket *ss) |
544 { | 543 { |
545 PRUint8 * msg; | 544 PRUint8 *msg; |
546 int sendLen; | 545 int sendLen; |
547 int sent; | 546 int sent; |
548 SECStatus rv; | 547 SECStatus rv; |
549 | 548 |
550 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 549 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
551 | 550 |
552 ssl_GetXmitBufLock(ss); /***************************************/ | 551 ssl_GetXmitBufLock(ss); /***************************************/ |
553 | 552 |
554 sendLen = 1 + SSL_CHALLENGE_BYTES; | 553 sendLen = 1 + SSL_CHALLENGE_BYTES; |
555 rv = ssl2_GetSendBuffer(ss, sendLen); | 554 rv = ssl2_GetSendBuffer(ss, sendLen); |
556 if (rv != SECSuccess) { | 555 if (rv != SECSuccess) { |
557 » goto done; | 556 goto done; |
558 } | 557 } |
559 | 558 |
560 msg = ss->sec.ci.sendBuf.buf; | 559 msg = ss->sec.ci.sendBuf.buf; |
561 msg[0] = SSL_MT_SERVER_VERIFY; | 560 msg[0] = SSL_MT_SERVER_VERIFY; |
562 PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); | 561 PORT_Memcpy(msg + 1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); |
563 | 562 |
564 DUMP_MSG(29, (ss, msg, sendLen)); | 563 DUMP_MSG(29, (ss, msg, sendLen)); |
565 sent = (*ss->sec.send)(ss, msg, sendLen, 0); | 564 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
566 | 565 |
567 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; | 566 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
568 | 567 |
569 done: | 568 done: |
570 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 569 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
571 return rv; | 570 return rv; |
572 } | 571 } |
573 | 572 |
574 /* Called from ssl2_TryToFinish(). | 573 /* Called from ssl2_TryToFinish(). |
575 * Acquires and releases the socket's xmitBufLock. | 574 * Acquires and releases the socket's xmitBufLock. |
576 */ | 575 */ |
577 static SECStatus | 576 static SECStatus |
578 ssl2_SendServerFinishedMessage(sslSocket *ss) | 577 ssl2_SendServerFinishedMessage(sslSocket *ss) |
579 { | 578 { |
580 sslSessionID * sid; | 579 sslSessionID *sid; |
581 PRUint8 * msg; | 580 PRUint8 *msg; |
582 int sendLen, sent; | 581 int sendLen, sent; |
583 SECStatus rv = SECSuccess; | 582 SECStatus rv = SECSuccess; |
584 | 583 |
585 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 584 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
586 | 585 |
587 ssl_GetXmitBufLock(ss); /***************************************/ | 586 ssl_GetXmitBufLock(ss); /***************************************/ |
588 | 587 |
589 if (ss->sec.ci.sentFinished == 0) { | 588 if (ss->sec.ci.sentFinished == 0) { |
590 » ss->sec.ci.sentFinished = 1; | 589 ss->sec.ci.sentFinished = 1; |
591 » PORT_Assert(ss->sec.ci.sid != 0); | 590 PORT_Assert(ss->sec.ci.sid != 0); |
592 » sid = ss->sec.ci.sid; | 591 sid = ss->sec.ci.sid; |
593 | 592 |
594 » SSL_TRC(3, ("%d: SSL[%d]: sending server-finished", | 593 SSL_TRC(3, ("%d: SSL[%d]: sending server-finished", |
595 » » SSL_GETPID(), ss->fd)); | 594 SSL_GETPID(), ss->fd)); |
596 | 595 |
597 » sendLen = 1 + sizeof(sid->u.ssl2.sessionID); | 596 sendLen = 1 + sizeof(sid->u.ssl2.sessionID); |
598 » rv = ssl2_GetSendBuffer(ss, sendLen); | 597 rv = ssl2_GetSendBuffer(ss, sendLen); |
599 » if (rv != SECSuccess) { | 598 if (rv != SECSuccess) { |
600 » goto done; | 599 goto done; |
601 » } | 600 } |
602 | 601 |
603 » msg = ss->sec.ci.sendBuf.buf; | 602 msg = ss->sec.ci.sendBuf.buf; |
604 » msg[0] = SSL_MT_SERVER_FINISHED; | 603 msg[0] = SSL_MT_SERVER_FINISHED; |
605 » PORT_Memcpy(msg+1, sid->u.ssl2.sessionID, | 604 PORT_Memcpy(msg + 1, sid->u.ssl2.sessionID, |
606 » » sizeof(sid->u.ssl2.sessionID)); | 605 sizeof(sid->u.ssl2.sessionID)); |
607 | 606 |
608 » DUMP_MSG(29, (ss, msg, sendLen)); | 607 DUMP_MSG(29, (ss, msg, sendLen)); |
609 » sent = (*ss->sec.send)(ss, msg, sendLen, 0); | 608 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
610 | 609 |
611 » if (sent < 0) { | 610 if (sent < 0) { |
612 » /* If send failed, it is now a bogus session-id */ | 611 /* If send failed, it is now a bogus session-id */ |
613 » if (ss->sec.uncache) | 612 if (ss->sec.uncache) |
614 » » (*ss->sec.uncache)(sid); | 613 (*ss->sec.uncache)(sid); |
615 » rv = (SECStatus)sent; | 614 rv = (SECStatus)sent; |
616 » } else if (!ss->opt.noCache) { | 615 } else if (!ss->opt.noCache) { |
617 » if (sid->cached == never_cached) { | 616 if (sid->cached == never_cached) { |
618 » » (*ss->sec.cache)(sid); | 617 (*ss->sec.cache)(sid); |
619 » } | 618 } |
620 » rv = SECSuccess; | 619 rv = SECSuccess; |
621 » } | 620 } |
622 » ssl_FreeSID(sid); | 621 ssl_FreeSID(sid); |
623 » ss->sec.ci.sid = 0; | 622 ss->sec.ci.sid = 0; |
624 } | 623 } |
625 done: | 624 done: |
626 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 625 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
627 return rv; | 626 return rv; |
628 } | 627 } |
629 | 628 |
630 /* Called from ssl2_ClientSetupSessionCypher() <- | 629 /* Called from ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage(
) |
631 *» » » » » » ssl2_HandleServerHelloMessage() | 630 * after ssl2_BeginClientHandshake() |
632 * after ssl2_BeginClientHandshake() | |
633 * Acquires and releases the socket's xmitBufLock. | 631 * Acquires and releases the socket's xmitBufLock. |
634 */ | 632 */ |
635 static SECStatus | 633 static SECStatus |
636 ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, | 634 ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, |
637 » » PRUint8 *ca, int caLen, | 635 PRUint8 *ca, int caLen, |
638 » » PRUint8 *ck, int ckLen, | 636 PRUint8 *ck, int ckLen, |
639 » » PRUint8 *ek, int ekLen) | 637 PRUint8 *ek, int ekLen) |
640 { | 638 { |
641 PRUint8 * msg; | 639 PRUint8 *msg; |
642 int sendLen; | 640 int sendLen; |
643 int sent; | 641 int sent; |
644 SECStatus rv; | 642 SECStatus rv; |
645 | 643 |
646 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 644 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
647 | 645 |
648 ssl_GetXmitBufLock(ss); /***************************************/ | 646 ssl_GetXmitBufLock(ss); /***************************************/ |
649 | 647 |
650 sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen; | 648 sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen; |
651 rv = ssl2_GetSendBuffer(ss, sendLen); | 649 rv = ssl2_GetSendBuffer(ss, sendLen); |
652 if (rv != SECSuccess) | 650 if (rv != SECSuccess) |
653 » goto done; | 651 goto done; |
654 | 652 |
655 SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key", | 653 SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key", |
656 » » SSL_GETPID(), ss->fd)); | 654 SSL_GETPID(), ss->fd)); |
657 | 655 |
658 msg = ss->sec.ci.sendBuf.buf; | 656 msg = ss->sec.ci.sendBuf.buf; |
659 msg[0] = SSL_MT_CLIENT_MASTER_KEY; | 657 msg[0] = SSL_MT_CLIENT_MASTER_KEY; |
660 msg[1] = cipher; | 658 msg[1] = cipher; |
661 msg[2] = MSB(keySize); | 659 msg[2] = MSB(keySize); |
662 msg[3] = LSB(keySize); | 660 msg[3] = LSB(keySize); |
663 msg[4] = MSB(ckLen); | 661 msg[4] = MSB(ckLen); |
664 msg[5] = LSB(ckLen); | 662 msg[5] = LSB(ckLen); |
665 msg[6] = MSB(ekLen); | 663 msg[6] = MSB(ekLen); |
666 msg[7] = LSB(ekLen); | 664 msg[7] = LSB(ekLen); |
667 msg[8] = MSB(caLen); | 665 msg[8] = MSB(caLen); |
668 msg[9] = LSB(caLen); | 666 msg[9] = LSB(caLen); |
669 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen); | 667 PORT_Memcpy(msg + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen); |
670 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen); | 668 PORT_Memcpy(msg + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ek, ekLen); |
671 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen); | 669 PORT_Memcpy(msg + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, ca, caLen
); |
672 | 670 |
673 DUMP_MSG(29, (ss, msg, sendLen)); | 671 DUMP_MSG(29, (ss, msg, sendLen)); |
674 sent = (*ss->sec.send)(ss, msg, sendLen, 0); | 672 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
675 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; | 673 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
676 done: | 674 done: |
677 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 675 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
678 return rv; | 676 return rv; |
679 } | 677 } |
680 | 678 |
681 /* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage() | 679 /* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage() |
682 * Acquires and releases the socket's xmitBufLock. | 680 * Acquires and releases the socket's xmitBufLock. |
683 */ | 681 */ |
684 static SECStatus | 682 static SECStatus |
685 ssl2_SendCertificateRequestMessage(sslSocket *ss) | 683 ssl2_SendCertificateRequestMessage(sslSocket *ss) |
686 { | 684 { |
687 PRUint8 * msg; | 685 PRUint8 *msg; |
688 int sent; | 686 int sent; |
689 int sendLen; | 687 int sendLen; |
690 SECStatus rv; | 688 SECStatus rv; |
691 | 689 |
692 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 690 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
693 | 691 |
694 ssl_GetXmitBufLock(ss); /***************************************/ | 692 ssl_GetXmitBufLock(ss); /***************************************/ |
695 | 693 |
696 sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES; | 694 sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES; |
697 rv = ssl2_GetSendBuffer(ss, sendLen); | 695 rv = ssl2_GetSendBuffer(ss, sendLen); |
698 if (rv != SECSuccess) | 696 if (rv != SECSuccess) |
699 » goto done; | 697 goto done; |
700 | 698 |
701 SSL_TRC(3, ("%d: SSL[%d]: sending certificate request", | 699 SSL_TRC(3, ("%d: SSL[%d]: sending certificate request", |
702 » » SSL_GETPID(), ss->fd)); | 700 SSL_GETPID(), ss->fd)); |
703 | 701 |
704 /* Generate random challenge for client to encrypt */ | 702 /* Generate random challenge for client to encrypt */ |
705 PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); | 703 PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); |
706 | 704 |
707 msg = ss->sec.ci.sendBuf.buf; | 705 msg = ss->sec.ci.sendBuf.buf; |
708 msg[0] = SSL_MT_REQUEST_CERTIFICATE; | 706 msg[0] = SSL_MT_REQUEST_CERTIFICATE; |
709 msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION; | 707 msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION; |
710 PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, | 708 PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, |
711 ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); | 709 ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); |
712 | 710 |
713 DUMP_MSG(29, (ss, msg, sendLen)); | 711 DUMP_MSG(29, (ss, msg, sendLen)); |
714 sent = (*ss->sec.send)(ss, msg, sendLen, 0); | 712 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
715 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; | 713 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
716 done: | 714 done: |
717 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 715 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
718 return rv; | 716 return rv; |
719 } | 717 } |
720 | 718 |
721 /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() | 719 /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() |
722 * Acquires and releases the socket's xmitBufLock. | 720 * Acquires and releases the socket's xmitBufLock. |
723 */ | 721 */ |
724 static int | 722 static int |
725 ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, | 723 ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, |
726 SECItem *encCode) | 724 SECItem *encCode) |
727 { | 725 { |
728 PRUint8 *msg; | 726 PRUint8 *msg; |
729 int rv, sendLen; | 727 int rv, sendLen; |
730 | 728 |
731 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 729 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
732 | 730 |
733 ssl_GetXmitBufLock(ss); /***************************************/ | 731 ssl_GetXmitBufLock(ss); /***************************************/ |
734 | 732 |
735 sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len; | 733 sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len; |
736 rv = ssl2_GetSendBuffer(ss, sendLen); | 734 rv = ssl2_GetSendBuffer(ss, sendLen); |
737 if (rv) | 735 if (rv) |
738 » goto done; | 736 goto done; |
739 | 737 |
740 SSL_TRC(3, ("%d: SSL[%d]: sending certificate response", | 738 SSL_TRC(3, ("%d: SSL[%d]: sending certificate response", |
741 » » SSL_GETPID(), ss->fd)); | 739 SSL_GETPID(), ss->fd)); |
742 | 740 |
743 msg = ss->sec.ci.sendBuf.buf; | 741 msg = ss->sec.ci.sendBuf.buf; |
744 msg[0] = SSL_MT_CLIENT_CERTIFICATE; | 742 msg[0] = SSL_MT_CLIENT_CERTIFICATE; |
745 msg[1] = SSL_CT_X509_CERTIFICATE; | 743 msg[1] = SSL_CT_X509_CERTIFICATE; |
746 msg[2] = MSB(cert->len); | 744 msg[2] = MSB(cert->len); |
747 msg[3] = LSB(cert->len); | 745 msg[3] = LSB(cert->len); |
748 msg[4] = MSB(encCode->len); | 746 msg[4] = MSB(encCode->len); |
749 msg[5] = LSB(encCode->len); | 747 msg[5] = LSB(encCode->len); |
750 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len); | 748 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len); |
751 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len, | 749 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len, |
752 » encCode->data, encCode->len); | 750 encCode->data, encCode->len); |
753 | 751 |
754 DUMP_MSG(29, (ss, msg, sendLen)); | 752 DUMP_MSG(29, (ss, msg, sendLen)); |
755 rv = (*ss->sec.send)(ss, msg, sendLen, 0); | 753 rv = (*ss->sec.send)(ss, msg, sendLen, 0); |
756 if (rv >= 0) { | 754 if (rv >= 0) { |
757 » rv = SECSuccess; | 755 rv = SECSuccess; |
758 } | 756 } |
759 done: | 757 done: |
760 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 758 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
761 return rv; | 759 return rv; |
762 } | 760 } |
763 | 761 |
764 /******************************************************************** | 762 /******************************************************************** |
765 ** Send functions above this line must aquire & release the socket's | 763 ** Send functions above this line must aquire & release the socket's |
766 **» xmitBufLock. | 764 ** xmitBufLock. |
767 ** All the ssl2_Send functions below this line are called vis ss->sec.send | 765 ** All the ssl2_Send functions below this line are called vis ss->sec.send |
768 **» and require that the caller hold the xmitBufLock. | 766 ** and require that the caller hold the xmitBufLock. |
769 */ | 767 */ |
770 | 768 |
771 /* | 769 /* |
772 ** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear. | 770 ** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear. |
773 */ | 771 */ |
774 static SECStatus | 772 static SECStatus |
775 ssl2_CalcMAC(PRUint8 * result, | 773 ssl2_CalcMAC(PRUint8 *result, |
776 » sslSecurityInfo * sec, | 774 sslSecurityInfo *sec, |
777 » const PRUint8 * data, | 775 const PRUint8 *data, |
778 » unsigned int dataLen, | 776 unsigned int dataLen, |
779 » unsigned int paddingLen) | 777 unsigned int paddingLen) |
780 { | 778 { |
781 const PRUint8 * secret»» = sec->sendSecret.data; | 779 const PRUint8 *secret = sec->sendSecret.data; |
782 unsigned int secretLen» = sec->sendSecret.len; | 780 unsigned int secretLen = sec->sendSecret.len; |
783 unsigned long sequenceNumber = sec->sendSequence; | 781 unsigned long sequenceNumber = sec->sendSequence; |
784 unsigned int nout; | 782 unsigned int nout; |
785 PRUint8 seq[4]; | 783 PRUint8 seq[4]; |
786 PRUint8 padding[32];/* XXX max blocksize? */ | 784 PRUint8 padding[32]; /* XXX max blocksize? */ |
787 | 785 |
788 if (!sec->hash || !sec->hash->length) | 786 if (!sec->hash || !sec->hash->length) |
789 » return SECSuccess; | 787 return SECSuccess; |
790 if (!sec->hashcx) | 788 if (!sec->hashcx) |
791 » return SECFailure; | 789 return SECFailure; |
792 | 790 |
793 /* Reset hash function */ | 791 /* Reset hash function */ |
794 (*sec->hash->begin)(sec->hashcx); | 792 (*sec->hash->begin)(sec->hashcx); |
795 | 793 |
796 /* Feed hash the data */ | 794 /* Feed hash the data */ |
797 (*sec->hash->update)(sec->hashcx, secret, secretLen); | 795 (*sec->hash->update)(sec->hashcx, secret, secretLen); |
798 (*sec->hash->update)(sec->hashcx, data, dataLen); | 796 (*sec->hash->update)(sec->hashcx, data, dataLen); |
799 PORT_Memset(padding, paddingLen, paddingLen); | 797 PORT_Memset(padding, paddingLen, paddingLen); |
800 (*sec->hash->update)(sec->hashcx, padding, paddingLen); | 798 (*sec->hash->update)(sec->hashcx, padding, paddingLen); |
801 | 799 |
802 seq[0] = (PRUint8) (sequenceNumber >> 24); | 800 seq[0] = (PRUint8)(sequenceNumber >> 24); |
803 seq[1] = (PRUint8) (sequenceNumber >> 16); | 801 seq[1] = (PRUint8)(sequenceNumber >> 16); |
804 seq[2] = (PRUint8) (sequenceNumber >> 8); | 802 seq[2] = (PRUint8)(sequenceNumber >> 8); |
805 seq[3] = (PRUint8) (sequenceNumber); | 803 seq[3] = (PRUint8)(sequenceNumber); |
806 | 804 |
807 PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen)); | 805 PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen)); |
808 PRINT_BUF(60, (0, "calc-mac data:", data, dataLen)); | 806 PRINT_BUF(60, (0, "calc-mac data:", data, dataLen)); |
809 PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen)); | 807 PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen)); |
810 PRINT_BUF(60, (0, "calc-mac seq:", seq, 4)); | 808 PRINT_BUF(60, (0, "calc-mac seq:", seq, 4)); |
811 | 809 |
812 (*sec->hash->update)(sec->hashcx, seq, 4); | 810 (*sec->hash->update)(sec->hashcx, seq, 4); |
813 | 811 |
814 /* Get result */ | 812 /* Get result */ |
815 (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length); | 813 (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length); |
816 | 814 |
817 return SECSuccess; | 815 return SECSuccess; |
818 } | 816 } |
819 | 817 |
820 /* | 818 /* |
821 ** Maximum transmission amounts. These are tiny bit smaller than they | 819 ** Maximum transmission amounts. These are tiny bit smaller than they |
822 ** need to be (they account for the MAC length plus some padding), | 820 ** need to be (they account for the MAC length plus some padding), |
823 ** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes | 821 ** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes |
824 ** long. This gives an additional 9 bytes of slop to work within. | 822 ** long. This gives an additional 9 bytes of slop to work within. |
825 */ | 823 */ |
826 #define MAX_STREAM_CYPHER_LEN» 0x7fe0 | 824 #define MAX_STREAM_CYPHER_LEN 0x7fe0 |
827 #define MAX_BLOCK_CYPHER_LEN» 0x3fe0 | 825 #define MAX_BLOCK_CYPHER_LEN 0x3fe0 |
828 | 826 |
829 /* | 827 /* |
830 ** Send some data in the clear. | 828 ** Send some data in the clear. |
831 ** Package up data with the length header and send it. | 829 ** Package up data with the length header and send it. |
832 ** | 830 ** |
833 ** Return count of bytes successfully written, or negative number (failure). | 831 ** Return count of bytes successfully written, or negative number (failure). |
834 */ | 832 */ |
835 static PRInt32 | 833 static PRInt32 |
836 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) | 834 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) |
837 { | 835 { |
838 PRUint8 * out; | 836 PRUint8 *out; |
839 int rv; | 837 int rv; |
840 unsigned int amount; | 838 unsigned int amount; |
841 int count» = 0; | 839 int count = 0; |
842 | 840 |
843 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 841 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
844 | 842 |
845 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear", | 843 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear", |
846 » » SSL_GETPID(), ss->fd, len)); | 844 SSL_GETPID(), ss->fd, len)); |
847 PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len)); | 845 PRINT_BUF(50, (ss, "clear data:", (PRUint8 *)in, len)); |
848 | 846 |
849 while (len) { | 847 while (len) { |
850 » amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); | 848 amount = PR_MIN(len, MAX_STREAM_CYPHER_LEN); |
851 » if (amount + 2 > ss->sec.writeBuf.space) { | 849 if (amount + 2 > ss->sec.writeBuf.space) { |
852 » rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2); | 850 rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2); |
853 » if (rv != SECSuccess) { | 851 if (rv != SECSuccess) { |
854 » » count = rv; | 852 count = rv; |
855 » » break; | 853 break; |
856 » } | 854 } |
857 » } | 855 } |
858 » out = ss->sec.writeBuf.buf; | 856 out = ss->sec.writeBuf.buf; |
859 | 857 |
860 » /* | 858 /* |
861 » ** Construct message. | 859 ** Construct message. |
862 » */ | 860 */ |
863 » out[0] = 0x80 | MSB(amount); | 861 out[0] = 0x80 | MSB(amount); |
864 » out[1] = LSB(amount); | 862 out[1] = LSB(amount); |
865 » PORT_Memcpy(&out[2], in, amount); | 863 PORT_Memcpy(&out[2], in, amount); |
866 | 864 |
867 » /* Now send the data */ | 865 /* Now send the data */ |
868 » rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK); | 866 rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK); |
869 » if (rv < 0) { | 867 if (rv < 0) { |
870 » if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { | 868 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { |
871 » » rv = 0; | 869 rv = 0; |
872 » } else { | 870 } else { |
873 » » /* Return short write if some data already went out... */ | 871 /* Return short write if some data already went out... */ |
874 » » if (count == 0) | 872 if (count == 0) |
875 » » count = rv; | 873 count = rv; |
876 » » break; | 874 break; |
877 » } | 875 } |
878 » } | 876 } |
879 | 877 |
880 » if ((unsigned)rv < (amount + 2)) { | 878 if ((unsigned)rv < (amount + 2)) { |
881 » /* Short write. Save the data and return. */ | 879 /* Short write. Save the data and return. */ |
882 » if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) | 880 if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) == |
883 » == SECFailure) { | 881 SECFailure) { |
884 » » count = SECFailure; | 882 count = SECFailure; |
885 » } else { | 883 } else { |
886 » » count += amount; | 884 count += amount; |
887 » » ss->sec.sendSequence++; | 885 ss->sec.sendSequence++; |
888 » } | 886 } |
889 » break; | 887 break; |
890 » } | 888 } |
891 | 889 |
892 » ss->sec.sendSequence++; | 890 ss->sec.sendSequence++; |
893 » in += amount; | 891 in += amount; |
894 » count += amount; | 892 count += amount; |
895 » len -= amount; | 893 len -= amount; |
896 } | 894 } |
897 | 895 |
898 return count; | 896 return count; |
899 } | 897 } |
900 | 898 |
901 /* | 899 /* |
902 ** Send some data, when using a stream cipher. Stream ciphers have a | 900 ** Send some data, when using a stream cipher. Stream ciphers have a |
903 ** block size of 1. Package up the data with the length header | 901 ** block size of 1. Package up the data with the length header |
904 ** and send it. | 902 ** and send it. |
905 */ | 903 */ |
906 static PRInt32 | 904 static PRInt32 |
907 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) | 905 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) |
908 { | 906 { |
909 PRUint8 * out; | 907 PRUint8 *out; |
910 int rv; | 908 int rv; |
911 int count» = 0; | 909 int count = 0; |
912 | 910 |
913 int amount; | 911 int amount; |
914 PRUint8 macLen; | 912 PRUint8 macLen; |
915 int nout; | 913 int nout; |
916 unsigned int buflen; | 914 unsigned int buflen; |
917 | 915 |
918 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 916 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
919 | 917 |
920 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher", | 918 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher", |
921 » » SSL_GETPID(), ss->fd, len)); | 919 SSL_GETPID(), ss->fd, len)); |
922 PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len)); | 920 PRINT_BUF(50, (ss, "clear data:", (PRUint8 *)in, len)); |
923 | 921 |
924 while (len) { | 922 while (len) { |
925 » ssl_GetSpecReadLock(ss); /*************************************/ | 923 ssl_GetSpecReadLock(ss); /*************************************/ |
926 | 924 |
927 » macLen = ss->sec.hash->length; | 925 macLen = ss->sec.hash->length; |
928 » amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); | 926 amount = PR_MIN(len, MAX_STREAM_CYPHER_LEN); |
929 » buflen = amount + 2 + macLen; | 927 buflen = amount + 2 + macLen; |
930 » if (buflen > ss->sec.writeBuf.space) { | 928 if (buflen > ss->sec.writeBuf.space) { |
931 » rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); | 929 rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); |
932 » if (rv != SECSuccess) { | 930 if (rv != SECSuccess) { |
933 » » goto loser; | 931 goto loser; |
934 » } | 932 } |
935 » } | 933 } |
936 » out = ss->sec.writeBuf.buf; | 934 out = ss->sec.writeBuf.buf; |
937 » nout = amount + macLen; | 935 nout = amount + macLen; |
938 » out[0] = 0x80 | MSB(nout); | 936 out[0] = 0x80 | MSB(nout); |
939 » out[1] = LSB(nout); | 937 out[1] = LSB(nout); |
940 | 938 |
941 » /* Calculate MAC */ | 939 /* Calculate MAC */ |
942 » rv = ssl2_CalcMAC(out+2, » » /* put MAC here */ | 940 rv = ssl2_CalcMAC(out + 2, /* put MAC here */ |
943 » &ss->sec, | 941 &ss->sec, |
944 » » in, amount, » » /* input addr & length */ | 942 in, amount, /* input addr & length */ |
945 » » » 0); » » » /* no padding */ | 943 0); /* no padding */ |
946 » if (rv != SECSuccess) | 944 if (rv != SECSuccess) |
947 » goto loser; | 945 goto loser; |
948 | 946 |
949 » /* Encrypt MAC */ | 947 /* Encrypt MAC */ |
950 » rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen
); | 948 rv = (*ss->sec.enc)(ss->sec.writecx, out + 2, &nout, macLen, out + 2, ma
cLen); |
951 » if (rv) goto loser; | 949 if (rv) |
| 950 goto loser; |
952 | 951 |
953 » /* Encrypt data from caller */ | 952 /* Encrypt data from caller */ |
954 » rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, am
ount); | 953 rv = (*ss->sec.enc)(ss->sec.writecx, out + 2 + macLen, &nout, amount, in
, amount); |
955 » if (rv) goto loser; | 954 if (rv) |
| 955 goto loser; |
956 | 956 |
957 » ssl_ReleaseSpecReadLock(ss); /*************************************/ | 957 ssl_ReleaseSpecReadLock(ss); /*************************************/ |
958 | 958 |
959 » PRINT_BUF(50, (ss, "encrypted data:", out, buflen)); | 959 PRINT_BUF(50, (ss, "encrypted data:", out, buflen)); |
960 | 960 |
961 » rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK); | 961 rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK); |
962 » if (rv < 0) { | 962 if (rv < 0) { |
963 » if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { | 963 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { |
964 » » SSL_TRC(50, ("%d: SSL[%d]: send stream would block, " | 964 SSL_TRC(50, ("%d: SSL[%d]: send stream would block, " |
965 » » » "saving data", SSL_GETPID(), ss->fd)); | 965 "saving data", |
966 » » rv = 0; | 966 SSL_GETPID(), ss->fd)); |
967 » } else { | 967 rv = 0; |
968 » » SSL_TRC(10, ("%d: SSL[%d]: send stream error %d", | 968 } else { |
969 » » » SSL_GETPID(), ss->fd, PORT_GetError())); | 969 SSL_TRC(10, ("%d: SSL[%d]: send stream error %d", |
970 » » /* Return short write if some data already went out... */ | 970 SSL_GETPID(), ss->fd, PORT_GetError())); |
971 » » if (count == 0) | 971 /* Return short write if some data already went out... */ |
972 » » count = rv; | 972 if (count == 0) |
973 » » goto done; | 973 count = rv; |
974 » } | 974 goto done; |
975 » } | 975 } |
| 976 } |
976 | 977 |
977 » if ((unsigned)rv < buflen) { | 978 if ((unsigned)rv < buflen) { |
978 » /* Short write. Save the data and return. */ | 979 /* Short write. Save the data and return. */ |
979 » if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) { | 980 if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) { |
980 » » count = SECFailure; | 981 count = SECFailure; |
981 » } else { | 982 } else { |
982 » » count += amount; | 983 count += amount; |
983 » » ss->sec.sendSequence++; | 984 ss->sec.sendSequence++; |
984 » } | 985 } |
985 » goto done; | 986 goto done; |
986 » } | 987 } |
987 | 988 |
988 » ss->sec.sendSequence++; | 989 ss->sec.sendSequence++; |
989 » in += amount; | 990 in += amount; |
990 » count += amount; | 991 count += amount; |
991 » len -= amount; | 992 len -= amount; |
992 } | 993 } |
993 | 994 |
994 done: | 995 done: |
995 return count; | 996 return count; |
996 | 997 |
997 loser: | 998 loser: |
998 ssl_ReleaseSpecReadLock(ss); | 999 ssl_ReleaseSpecReadLock(ss); |
999 return SECFailure; | 1000 return SECFailure; |
1000 } | 1001 } |
1001 | 1002 |
1002 /* | 1003 /* |
1003 ** Send some data, when using a block cipher. Package up the data with | 1004 ** Send some data, when using a block cipher. Package up the data with |
1004 ** the length header and send it. | 1005 ** the length header and send it. |
1005 */ | 1006 */ |
1006 /* XXX assumes blocksize is > 7 */ | 1007 /* XXX assumes blocksize is > 7 */ |
1007 static PRInt32 | 1008 static PRInt32 |
1008 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) | 1009 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) |
1009 { | 1010 { |
1010 PRUint8 * out; » » /* begining of output buffer. */ | 1011 PRUint8 *out; /* begining of output buffer. */ |
1011 PRUint8 * op;» » /* next output byte goes here. */ | 1012 PRUint8 *op; /* next output byte goes here. */ |
1012 int rv;» » /* value from funcs we called. */ | 1013 int rv; /* value from funcs we called. */ |
1013 int count» = 0; /* this function's return value. */ | 1014 int count = 0; /* this function's return value. */ |
1014 | 1015 |
1015 unsigned int hlen;» » /* output record hdr len, 2 or 3 */ | 1016 unsigned int hlen; /* output record hdr len, 2 or 3 */ |
1016 unsigned int macLen;» » /* MAC is this many bytes long. */ | 1017 unsigned int macLen; /* MAC is this many bytes long. */ |
1017 int amount;» » /* of plaintext to go in record. */ | 1018 int amount; /* of plaintext to go in record. */ |
1018 unsigned int padding;» » /* add this many padding byte. */ | 1019 unsigned int padding; /* add this many padding byte. */ |
1019 int nout;» » /* ciphertext size after header. */ | 1020 int nout; /* ciphertext size after header. */ |
1020 unsigned int buflen;» » /* size of generated record. */ | 1021 unsigned int buflen; /* size of generated record. */ |
1021 | 1022 |
1022 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 1023 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
1023 | 1024 |
1024 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher", | 1025 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher", |
1025 » » SSL_GETPID(), ss->fd, len)); | 1026 SSL_GETPID(), ss->fd, len)); |
1026 PRINT_BUF(50, (ss, "clear data:", in, len)); | 1027 PRINT_BUF(50, (ss, "clear data:", in, len)); |
1027 | 1028 |
1028 while (len) { | 1029 while (len) { |
1029 » ssl_GetSpecReadLock(ss); /*************************************/ | 1030 ssl_GetSpecReadLock(ss); /*************************************/ |
1030 | 1031 |
1031 » macLen = ss->sec.hash->length; | 1032 macLen = ss->sec.hash->length; |
1032 » /* Figure out how much to send, including mac and padding */ | 1033 /* Figure out how much to send, including mac and padding */ |
1033 » amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN ); | 1034 amount = PR_MIN(len, MAX_BLOCK_CYPHER_LEN); |
1034 » nout = amount + macLen; | 1035 nout = amount + macLen; |
1035 » padding = nout & (ss->sec.blockSize - 1); | 1036 padding = nout & (ss->sec.blockSize - 1); |
1036 » if (padding) { | 1037 if (padding) { |
1037 » hlen = 3; | 1038 hlen = 3; |
1038 » padding = ss->sec.blockSize - padding; | 1039 padding = ss->sec.blockSize - padding; |
1039 » nout += padding; | 1040 nout += padding; |
1040 » } else { | 1041 } else { |
1041 » hlen = 2; | 1042 hlen = 2; |
1042 » } | 1043 } |
1043 » buflen = hlen + nout; | 1044 buflen = hlen + nout; |
1044 » if (buflen > ss->sec.writeBuf.space) { | 1045 if (buflen > ss->sec.writeBuf.space) { |
1045 » rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); | 1046 rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); |
1046 » if (rv != SECSuccess) { | 1047 if (rv != SECSuccess) { |
1047 » » goto loser; | 1048 goto loser; |
1048 » } | 1049 } |
1049 » } | 1050 } |
1050 » out = ss->sec.writeBuf.buf; | 1051 out = ss->sec.writeBuf.buf; |
1051 | 1052 |
1052 » /* Construct header */ | 1053 /* Construct header */ |
1053 » op = out; | 1054 op = out; |
1054 » if (padding) { | 1055 if (padding) { |
1055 » *op++ = MSB(nout); | 1056 *op++ = MSB(nout); |
1056 » *op++ = LSB(nout); | 1057 *op++ = LSB(nout); |
1057 » *op++ = padding; | 1058 *op++ = padding; |
1058 » } else { | 1059 } else { |
1059 » *op++ = 0x80 | MSB(nout); | 1060 *op++ = 0x80 | MSB(nout); |
1060 » *op++ = LSB(nout); | 1061 *op++ = LSB(nout); |
1061 » } | 1062 } |
1062 | 1063 |
1063 » /* Calculate MAC */ | 1064 /* Calculate MAC */ |
1064 » rv = ssl2_CalcMAC(op, » » /* MAC goes here. */ | 1065 rv = ssl2_CalcMAC(op, /* MAC goes here. */ |
1065 » &ss->sec, | 1066 &ss->sec, |
1066 » » in, amount, » /* intput addr, len */ | 1067 in, amount, /* intput addr, len */ |
1067 » » » padding); | 1068 padding); |
1068 » if (rv != SECSuccess) | 1069 if (rv != SECSuccess) |
1069 » goto loser; | 1070 goto loser; |
1070 » op += macLen; | 1071 op += macLen; |
1071 | 1072 |
1072 » /* Copy in the input data */ | 1073 /* Copy in the input data */ |
1073 » /* XXX could eliminate the copy by folding it into the encryption */ | 1074 /* XXX could eliminate the copy by folding it into the encryption */ |
1074 » PORT_Memcpy(op, in, amount); | 1075 PORT_Memcpy(op, in, amount); |
1075 » op += amount; | 1076 op += amount; |
1076 » if (padding) { | 1077 if (padding) { |
1077 » PORT_Memset(op, padding, padding); | 1078 PORT_Memset(op, padding, padding); |
1078 » op += padding; | 1079 op += padding; |
1079 » } | 1080 } |
1080 | 1081 |
1081 » /* Encrypt result */ | 1082 /* Encrypt result */ |
1082 » rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen, | 1083 rv = (*ss->sec.enc)(ss->sec.writecx, out + hlen, &nout, buflen - hlen, |
1083 » » » out+hlen, op - (out + hlen)); | 1084 out + hlen, op - (out + hlen)); |
1084 » if (rv) | 1085 if (rv) |
1085 » goto loser; | 1086 goto loser; |
1086 | 1087 |
1087 » ssl_ReleaseSpecReadLock(ss); /*************************************/ | 1088 ssl_ReleaseSpecReadLock(ss); /*************************************/ |
1088 | 1089 |
1089 » PRINT_BUF(50, (ss, "final xmit data:", out, op - out)); | 1090 PRINT_BUF(50, (ss, "final xmit data:", out, op - out)); |
1090 | 1091 |
1091 » rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK); | 1092 rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK); |
1092 » if (rv < 0) { | 1093 if (rv < 0) { |
1093 » if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { | 1094 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { |
1094 » » rv = 0; | 1095 rv = 0; |
1095 » } else { | 1096 } else { |
1096 » » SSL_TRC(10, ("%d: SSL[%d]: send block error %d", | 1097 SSL_TRC(10, ("%d: SSL[%d]: send block error %d", |
1097 » » » SSL_GETPID(), ss->fd, PORT_GetError())); | 1098 SSL_GETPID(), ss->fd, PORT_GetError())); |
1098 » » /* Return short write if some data already went out... */ | 1099 /* Return short write if some data already went out... */ |
1099 » » if (count == 0) | 1100 if (count == 0) |
1100 » » count = rv; | 1101 count = rv; |
1101 » » goto done; | 1102 goto done; |
1102 » } | 1103 } |
1103 » } | 1104 } |
1104 | 1105 |
1105 » if (rv < (op - out)) { | 1106 if (rv < (op - out)) { |
1106 » /* Short write. Save the data and return. */ | 1107 /* Short write. Save the data and return. */ |
1107 » if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) { | 1108 if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) { |
1108 » » count = SECFailure; | 1109 count = SECFailure; |
1109 » } else { | 1110 } else { |
1110 » » count += amount; | 1111 count += amount; |
1111 » » ss->sec.sendSequence++; | 1112 ss->sec.sendSequence++; |
1112 » } | 1113 } |
1113 » goto done; | 1114 goto done; |
1114 » } | 1115 } |
1115 | 1116 |
1116 » ss->sec.sendSequence++; | 1117 ss->sec.sendSequence++; |
1117 » in += amount; | 1118 in += amount; |
1118 » count += amount; | 1119 count += amount; |
1119 » len -= amount; | 1120 len -= amount; |
1120 } | 1121 } |
1121 | 1122 |
1122 done: | 1123 done: |
1123 return count; | 1124 return count; |
1124 | 1125 |
1125 loser: | 1126 loser: |
1126 ssl_ReleaseSpecReadLock(ss); | 1127 ssl_ReleaseSpecReadLock(ss); |
1127 return SECFailure; | 1128 return SECFailure; |
1128 } | 1129 } |
1129 | 1130 |
1130 /* | 1131 /* |
1131 ** Called from: ssl2_HandleServerHelloMessage, | 1132 ** Called from: ssl2_HandleServerHelloMessage, |
1132 ** ssl2_HandleClientSessionKeyMessage, | 1133 ** ssl2_HandleClientSessionKeyMessage, |
1133 ** ssl2_HandleClientHelloMessage, | 1134 ** ssl2_HandleClientHelloMessage, |
1134 ** | 1135 ** |
1135 */ | 1136 */ |
1136 static void | 1137 static void |
1137 ssl2_UseEncryptedSendFunc(sslSocket *ss) | 1138 ssl2_UseEncryptedSendFunc(sslSocket *ss) |
1138 { | 1139 { |
1139 ssl_GetXmitBufLock(ss); | 1140 ssl_GetXmitBufLock(ss); |
1140 PORT_Assert(ss->sec.hashcx != 0); | 1141 PORT_Assert(ss->sec.hashcx != 0); |
1141 | 1142 |
1142 ss->gs.encrypted = 1; | 1143 ss->gs.encrypted = 1; |
1143 ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream; | 1144 ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream; |
1144 ssl_ReleaseXmitBufLock(ss); | 1145 ssl_ReleaseXmitBufLock(ss); |
1145 } | 1146 } |
1146 | 1147 |
1147 /* Called while initializing socket in ssl_CreateSecurityInfo(). | 1148 /* Called while initializing socket in ssl_CreateSecurityInfo(). |
1148 ** This function allows us to keep the name of ssl2_SendClear static. | 1149 ** This function allows us to keep the name of ssl2_SendClear static. |
1149 */ | 1150 */ |
1150 void | 1151 void |
1151 ssl2_UseClearSendFunc(sslSocket *ss) | 1152 ssl2_UseClearSendFunc(sslSocket *ss) |
1152 { | 1153 { |
1153 ss->sec.send = ssl2_SendClear; | 1154 ss->sec.send = ssl2_SendClear; |
1154 } | 1155 } |
1155 | 1156 |
1156 /************************************************************************ | 1157 /************************************************************************ |
1157 ** » » » END of Send functions. * | 1158 ** END of Send functions. * |
1158 *************************************************************************/ | 1159 *************************************************************************/ |
1159 | 1160 |
1160 /*********************************************************************** | 1161 /*********************************************************************** |
1161 * For SSL3, this gathers in and handles records/messages until either | 1162 * For SSL3, this gathers in and handles records/messages until either |
1162 *» the handshake is complete or application data is available. | 1163 * the handshake is complete or application data is available. |
1163 * | 1164 * |
1164 * For SSL2, this gathers in only the next SSLV2 record. | 1165 * For SSL2, this gathers in only the next SSLV2 record. |
1165 * | 1166 * |
1166 * Called from ssl_Do1stHandshake() via function pointer ss->handshake. | 1167 * Called from ssl_Do1stHandshake() via function pointer ss->handshake. |
1167 * Caller must hold handshake lock. | 1168 * Caller must hold handshake lock. |
1168 * This function acquires and releases the RecvBufLock. | 1169 * This function acquires and releases the RecvBufLock. |
1169 * | 1170 * |
1170 * returns SECSuccess for success. | 1171 * returns SECSuccess for success. |
1171 * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or | 1172 * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or |
1172 *» ssl3_GatherCompleteHandshake(). | 1173 * ssl3_GatherCompleteHandshake(). |
1173 * returns SECFailure on all other errors. | 1174 * returns SECFailure on all other errors. |
1174 * | 1175 * |
1175 * The gather functions called by ssl_GatherRecord1stHandshake are expected | 1176 * The gather functions called by ssl_GatherRecord1stHandshake are expected |
1176 * » to return values interpreted as follows: | 1177 * to return values interpreted as follows: |
1177 * 1 : the function completed without error. | 1178 * 1 : the function completed without error. |
1178 * 0 : the function read EOF. | 1179 * 0 : the function read EOF. |
1179 * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. | 1180 * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. |
1180 * -2 : the function wants ssl_GatherRecord1stHandshake to be called again | 1181 * -2 : the function wants ssl_GatherRecord1stHandshake to be called again |
1181 *» immediately, by ssl_Do1stHandshake. | 1182 * immediately, by ssl_Do1stHandshake. |
1182 * | 1183 * |
1183 * This code is similar to, and easily confused with, DoRecv() in sslsecur.c | 1184 * This code is similar to, and easily confused with, DoRecv() in sslsecur.c |
1184 * | 1185 * |
1185 * This function is called from ssl_Do1stHandshake(). | 1186 * This function is called from ssl_Do1stHandshake(). |
1186 * The following functions put ssl_GatherRecord1stHandshake into ss->handshake: | 1187 * The following functions put ssl_GatherRecord1stHandshake into ss->handshake: |
1187 *» ssl2_HandleMessage | 1188 * ssl2_HandleMessage |
1188 *» ssl2_HandleVerifyMessage | 1189 * ssl2_HandleVerifyMessage |
1189 *» ssl2_HandleServerHelloMessage | 1190 * ssl2_HandleServerHelloMessage |
1190 *» ssl2_BeginClientHandshake» | 1191 * ssl2_BeginClientHandshake |
1191 *» ssl2_HandleClientSessionKeyMessage | 1192 * ssl2_HandleClientSessionKeyMessage |
1192 *» ssl3_RestartHandshakeAfterCertReq | 1193 * ssl3_RestartHandshakeAfterCertReq |
1193 *» ssl3_RestartHandshakeAfterServerCert | 1194 * ssl3_RestartHandshakeAfterServerCert |
1194 *» ssl2_HandleClientHelloMessage | 1195 * ssl2_HandleClientHelloMessage |
1195 *» ssl2_BeginServerHandshake | 1196 * ssl2_BeginServerHandshake |
1196 */ | 1197 */ |
1197 SECStatus | 1198 SECStatus |
1198 ssl_GatherRecord1stHandshake(sslSocket *ss) | 1199 ssl_GatherRecord1stHandshake(sslSocket *ss) |
1199 { | 1200 { |
1200 int rv; | 1201 int rv; |
1201 | 1202 |
1202 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 1203 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
1203 | 1204 |
1204 ssl_GetRecvBufLock(ss); | 1205 ssl_GetRecvBufLock(ss); |
1205 | 1206 |
1206 /* The special case DTLS logic is needed here because the SSL/TLS | 1207 /* The special case DTLS logic is needed here because the SSL/TLS |
1207 * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake | 1208 * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake |
1208 * (ss->version == 0) but with DTLS it gets confused, so we force the | 1209 * (ss->version == 0) but with DTLS it gets confused, so we force the |
1209 * SSL3 version. | 1210 * SSL3 version. |
1210 */ | 1211 */ |
1211 if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) { | 1212 if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) { |
1212 » /* Wait for handshake to complete, or application data to arrive. */ | 1213 /* Wait for handshake to complete, or application data to arrive. */ |
1213 » rv = ssl3_GatherCompleteHandshake(ss, 0); | 1214 rv = ssl3_GatherCompleteHandshake(ss, 0); |
1214 } else { | 1215 } else { |
1215 » /* See if we have a complete record */ | 1216 /* See if we have a complete record */ |
1216 » rv = ssl2_GatherRecord(ss, 0); | 1217 rv = ssl2_GatherRecord(ss, 0); |
1217 } | 1218 } |
1218 SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d", | 1219 SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d", |
1219 » » SSL_GETPID(), ss->fd, rv)); | 1220 SSL_GETPID(), ss->fd, rv)); |
1220 | 1221 |
1221 ssl_ReleaseRecvBufLock(ss); | 1222 ssl_ReleaseRecvBufLock(ss); |
1222 | 1223 |
1223 if (rv <= 0) { | 1224 if (rv <= 0) { |
1224 » if (rv == SECWouldBlock) { | 1225 if (rv == SECWouldBlock) { |
1225 » /* Progress is blocked waiting for callback completion. */ | 1226 /* Progress is blocked waiting for callback completion. */ |
1226 » SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)", | 1227 SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)", |
1227 » » » SSL_GETPID(), ss->fd, ss->gs.remainder)); | 1228 SSL_GETPID(), ss->fd, ss->gs.remainder)); |
1228 » return SECWouldBlock; | 1229 return SECWouldBlock; |
1229 » } | 1230 } |
1230 » if (rv == 0) { | 1231 if (rv == 0) { |
1231 » /* EOF. Loser */ | 1232 /* EOF. Loser */ |
1232 » PORT_SetError(PR_END_OF_FILE_ERROR); | 1233 PORT_SetError(PR_END_OF_FILE_ERROR); |
1233 » } | 1234 } |
1234 » return SECFailure;» /* rv is < 0 here. */ | 1235 return SECFailure; /* rv is < 0 here. */ |
1235 } | 1236 } |
1236 | 1237 |
1237 SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes", | 1238 SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes", |
1238 » » SSL_GETPID(), ss->fd, ss->gs.recordLen)); | 1239 SSL_GETPID(), ss->fd, ss->gs.recordLen)); |
1239 | 1240 |
1240 ss->handshake = 0;» /* makes ssl_Do1stHandshake call ss->nextHandshake.*/ | 1241 ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/ |
1241 return SECSuccess; | 1242 return SECSuccess; |
1242 } | 1243 } |
1243 | 1244 |
1244 /************************************************************************/ | 1245 /************************************************************************/ |
1245 | 1246 |
1246 /* Called from ssl2_ServerSetupSessionCypher() | 1247 /* Called from ssl2_ServerSetupSessionCypher() |
1247 * ssl2_ClientSetupSessionCypher() | 1248 * ssl2_ClientSetupSessionCypher() |
1248 */ | 1249 */ |
1249 static SECStatus | 1250 static SECStatus |
1250 ssl2_FillInSID(sslSessionID * sid, | 1251 ssl2_FillInSID(sslSessionID *sid, |
1251 int cipher, | 1252 int cipher, |
1252 » PRUint8 *keyData, | 1253 PRUint8 *keyData, |
1253 » int keyLen, | 1254 int keyLen, |
1254 » PRUint8 *ca, | 1255 PRUint8 *ca, |
1255 » int caLen, | 1256 int caLen, |
1256 » int keyBits, | 1257 int keyBits, |
1257 » int secretKeyBits, | 1258 int secretKeyBits, |
1258 » SSLSignType authAlgorithm, | 1259 SSLSignType authAlgorithm, |
1259 » PRUint32 authKeyBits, | 1260 PRUint32 authKeyBits, |
1260 » SSLKEAType keaType, | 1261 SSLKEAType keaType, |
1261 » PRUint32 keaKeyBits) | 1262 PRUint32 keaKeyBits) |
1262 { | 1263 { |
1263 PORT_Assert(sid->references == 1); | 1264 PORT_Assert(sid->references == 1); |
1264 PORT_Assert(sid->cached == never_cached); | 1265 PORT_Assert(sid->cached == never_cached); |
1265 PORT_Assert(sid->u.ssl2.masterKey.data == 0); | 1266 PORT_Assert(sid->u.ssl2.masterKey.data == 0); |
1266 PORT_Assert(sid->u.ssl2.cipherArg.data == 0); | 1267 PORT_Assert(sid->u.ssl2.cipherArg.data == 0); |
1267 | 1268 |
1268 sid->version = SSL_LIBRARY_VERSION_2; | 1269 sid->version = SSL_LIBRARY_VERSION_2; |
1269 | 1270 |
1270 sid->u.ssl2.cipherType = cipher; | 1271 sid->u.ssl2.cipherType = cipher; |
1271 sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen); | 1272 sid->u.ssl2.masterKey.data = (PRUint8 *)PORT_Alloc(keyLen); |
1272 if (!sid->u.ssl2.masterKey.data) { | 1273 if (!sid->u.ssl2.masterKey.data) { |
1273 » return SECFailure; | 1274 return SECFailure; |
1274 } | 1275 } |
1275 PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen); | 1276 PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen); |
1276 sid->u.ssl2.masterKey.len = keyLen; | 1277 sid->u.ssl2.masterKey.len = keyLen; |
1277 sid->u.ssl2.keyBits = keyBits; | 1278 sid->u.ssl2.keyBits = keyBits; |
1278 sid->u.ssl2.secretKeyBits = secretKeyBits; | 1279 sid->u.ssl2.secretKeyBits = secretKeyBits; |
1279 sid->authAlgorithm = authAlgorithm; | 1280 sid->authAlgorithm = authAlgorithm; |
1280 sid->authKeyBits = authKeyBits; | 1281 sid->authKeyBits = authKeyBits; |
1281 sid->keaType = keaType; | 1282 sid->keaType = keaType; |
1282 sid->keaKeyBits = keaKeyBits; | 1283 sid->keaKeyBits = keaKeyBits; |
1283 sid->lastAccessTime = sid->creationTime = ssl_Time(); | 1284 sid->lastAccessTime = sid->creationTime = ssl_Time(); |
1284 sid->expirationTime = sid->creationTime + ssl_sid_timeout; | 1285 sid->expirationTime = sid->creationTime + ssl_sid_timeout; |
1285 | 1286 |
1286 if (caLen) { | 1287 if (caLen) { |
1287 » sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen); | 1288 sid->u.ssl2.cipherArg.data = (PRUint8 *)PORT_Alloc(caLen); |
1288 » if (!sid->u.ssl2.cipherArg.data) { | 1289 if (!sid->u.ssl2.cipherArg.data) { |
1289 » return SECFailure; | 1290 return SECFailure; |
1290 » } | 1291 } |
1291 » sid->u.ssl2.cipherArg.len = caLen; | 1292 sid->u.ssl2.cipherArg.len = caLen; |
1292 » PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen); | 1293 PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen); |
1293 } | 1294 } |
1294 return SECSuccess; | 1295 return SECSuccess; |
1295 } | 1296 } |
1296 | 1297 |
1297 /* | 1298 /* |
1298 ** Construct session keys given the masterKey (tied to the session-id), | 1299 ** Construct session keys given the masterKey (tied to the session-id), |
1299 ** the client's challenge and the server's nonce. | 1300 ** the client's challenge and the server's nonce. |
1300 ** | 1301 ** |
1301 ** Called from ssl2_CreateSessionCypher() <- | 1302 ** Called from ssl2_CreateSessionCypher() <- |
1302 */ | 1303 */ |
1303 static SECStatus | 1304 static SECStatus |
1304 ssl2_ProduceKeys(sslSocket * ss, | 1305 ssl2_ProduceKeys(sslSocket *ss, |
1305 SECItem * readKey, | 1306 SECItem *readKey, |
1306 » SECItem * writeKey, | 1307 SECItem *writeKey, |
1307 » SECItem * masterKey, | 1308 SECItem *masterKey, |
1308 » PRUint8 * challenge, | 1309 PRUint8 *challenge, |
1309 » PRUint8 * nonce, | 1310 PRUint8 *nonce, |
1310 » int cipherType) | 1311 int cipherType) |
1311 { | 1312 { |
1312 PK11Context * cx = 0; | 1313 PK11Context *cx = 0; |
1313 unsigned nkm = 0; /* number of hashes to generate key mat. */ | 1314 unsigned nkm = 0; /* number of hashes to generate key mat. */ |
1314 unsigned nkd = 0; /* size of readKey and writeKey. */ | 1315 unsigned nkd = 0; /* size of readKey and writeKey. */ |
1315 unsigned part; | 1316 unsigned part; |
1316 unsigned i; | 1317 unsigned i; |
1317 unsigned off; | 1318 unsigned off; |
1318 SECStatus rv; | 1319 SECStatus rv; |
1319 PRUint8 countChar; | 1320 PRUint8 countChar; |
1320 PRUint8 km[3*16];» /* buffer for key material. */ | 1321 PRUint8 km[3 * 16]; /* buffer for key material. */ |
1321 | 1322 |
1322 readKey->data = 0; | 1323 readKey->data = 0; |
1323 writeKey->data = 0; | 1324 writeKey->data = 0; |
1324 | 1325 |
1325 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 1326 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
1326 | 1327 |
1327 rv = SECSuccess; | 1328 rv = SECSuccess; |
1328 cx = PK11_CreateDigestContext(SEC_OID_MD5); | 1329 cx = PK11_CreateDigestContext(SEC_OID_MD5); |
1329 if (cx == NULL) { | 1330 if (cx == NULL) { |
1330 » ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); | 1331 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
1331 » return SECFailure; | 1332 return SECFailure; |
1332 } | 1333 } |
1333 | 1334 |
1334 nkm = ssl_Specs[cipherType].nkm; | 1335 nkm = ssl_Specs[cipherType].nkm; |
1335 nkd = ssl_Specs[cipherType].nkd; | 1336 nkd = ssl_Specs[cipherType].nkd; |
1336 | 1337 |
1337 readKey->data = (PRUint8*) PORT_Alloc(nkd); | 1338 readKey->data = (PRUint8 *)PORT_Alloc(nkd); |
1338 if (!readKey->data) | 1339 if (!readKey->data) |
1339 » goto loser; | 1340 goto loser; |
1340 readKey->len = nkd; | 1341 readKey->len = nkd; |
1341 | 1342 |
1342 writeKey->data = (PRUint8*) PORT_Alloc(nkd); | 1343 writeKey->data = (PRUint8 *)PORT_Alloc(nkd); |
1343 if (!writeKey->data) | 1344 if (!writeKey->data) |
1344 » goto loser; | 1345 goto loser; |
1345 writeKey->len = nkd; | 1346 writeKey->len = nkd; |
1346 | 1347 |
1347 /* Produce key material */ | 1348 /* Produce key material */ |
1348 countChar = '0'; | 1349 countChar = '0'; |
1349 for (i = 0, off = 0; i < nkm; i++, off += 16) { | 1350 for (i = 0, off = 0; i < nkm; i++, off += 16) { |
1350 » rv = PK11_DigestBegin(cx); | 1351 rv = PK11_DigestBegin(cx); |
1351 » rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len); | 1352 rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len); |
1352 » rv |= PK11_DigestOp(cx, &countChar, 1); | 1353 rv |= PK11_DigestOp(cx, &countChar, 1); |
1353 » rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES); | 1354 rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES); |
1354 » rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES); | 1355 rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES); |
1355 » rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH); | 1356 rv |= PK11_DigestFinal(cx, km + off, &part, MD5_LENGTH); |
1356 » if (rv != SECSuccess) { | 1357 if (rv != SECSuccess) { |
1357 » ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); | 1358 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
1358 » rv = SECFailure; | 1359 rv = SECFailure; |
1359 » goto loser; | 1360 goto loser; |
1360 » } | 1361 } |
1361 » countChar++; | 1362 countChar++; |
1362 } | 1363 } |
1363 | 1364 |
1364 /* Produce keys */ | 1365 /* Produce keys */ |
1365 PORT_Memcpy(readKey->data, km, nkd); | 1366 PORT_Memcpy(readKey->data, km, nkd); |
1366 PORT_Memcpy(writeKey->data, km + nkd, nkd); | 1367 PORT_Memcpy(writeKey->data, km + nkd, nkd); |
1367 | 1368 |
1368 loser: | 1369 loser: |
1369 PK11_DestroyContext(cx, PR_TRUE); | 1370 PK11_DestroyContext(cx, PR_TRUE); |
1370 return rv; | 1371 return rv; |
1371 } | 1372 } |
1372 | 1373 |
1373 /* Called from ssl2_ServerSetupSessionCypher() | 1374 /* Called from ssl2_ServerSetupSessionCypher() |
1374 ** <- ssl2_HandleClientSessionKeyMessage() | 1375 ** <- ssl2_HandleClientSessionKeyMessage() |
1375 ** <- ssl2_HandleClientHelloMessage() | 1376 ** <- ssl2_HandleClientHelloMessage() |
1376 ** and from ssl2_ClientSetupSessionCypher() | 1377 ** and from ssl2_ClientSetupSessionCypher() |
1377 ** <- ssl2_HandleServerHelloMessage() | 1378 ** <- ssl2_HandleServerHelloMessage() |
1378 */ | 1379 */ |
1379 static SECStatus | 1380 static SECStatus |
1380 ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) | 1381 ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) |
1381 { | 1382 { |
1382 SECItem * rk = NULL; | 1383 SECItem *rk = NULL; |
1383 SECItem * wk = NULL; | 1384 SECItem *wk = NULL; |
1384 SECItem * param; | 1385 SECItem *param; |
1385 SECStatus rv; | 1386 SECStatus rv; |
1386 int cipherType = sid->u.ssl2.cipherType; | 1387 int cipherType = sid->u.ssl2.cipherType; |
1387 PK11SlotInfo * slot = NULL; | 1388 PK11SlotInfo *slot = NULL; |
1388 CK_MECHANISM_TYPE mechanism; | 1389 CK_MECHANISM_TYPE mechanism; |
1389 SECItem readKey; | 1390 SECItem readKey; |
1390 SECItem writeKey; | 1391 SECItem writeKey; |
1391 | 1392 |
1392 void *readcx = 0; | 1393 void *readcx = 0; |
1393 void *writecx = 0; | 1394 void *writecx = 0; |
1394 readKey.data = 0; | 1395 readKey.data = 0; |
1395 writeKey.data = 0; | 1396 writeKey.data = 0; |
1396 | 1397 |
1397 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 1398 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
1398 if (ss->sec.ci.sid == 0) | 1399 if (ss->sec.ci.sid == 0) |
1399 » goto sec_loser;»/* don't crash if asserts are off */ | 1400 goto sec_loser; /* don't crash if asserts are off */ |
1400 | 1401 |
1401 /* Trying to cut down on all these switch statements that should be tables. | 1402 /* Trying to cut down on all these switch statements that should be tables. |
1402 * So, test cipherType once, here, and then use tables below. | 1403 * So, test cipherType once, here, and then use tables below. |
1403 */ | 1404 */ |
1404 switch (cipherType) { | 1405 switch (cipherType) { |
1405 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: | 1406 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
1406 case SSL_CK_RC4_128_WITH_MD5: | 1407 case SSL_CK_RC4_128_WITH_MD5: |
1407 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: | 1408 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
1408 case SSL_CK_RC2_128_CBC_WITH_MD5: | 1409 case SSL_CK_RC2_128_CBC_WITH_MD5: |
1409 case SSL_CK_DES_64_CBC_WITH_MD5: | 1410 case SSL_CK_DES_64_CBC_WITH_MD5: |
1410 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: | 1411 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: |
1411 » break; | 1412 break; |
1412 | 1413 |
1413 default: | 1414 default: |
1414 » SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d", | 1415 SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d", |
1415 » » SSL_GETPID(), ss->fd, cipherType)); | 1416 SSL_GETPID(), ss->fd, cipherType)); |
1416 » PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT); | 1417 PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT
); |
1417 » goto sec_loser; | 1418 goto sec_loser; |
1418 } | 1419 } |
1419 | 1420 |
1420 rk = isClient ? &readKey : &writeKey; | 1421 rk = isClient ? &readKey : &writeKey; |
1421 wk = isClient ? &writeKey : &readKey; | 1422 wk = isClient ? &writeKey : &readKey; |
1422 | 1423 |
1423 /* Produce the keys for this session */ | 1424 /* Produce the keys for this session */ |
1424 rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey, | 1425 rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey, |
1425 » » ss->sec.ci.clientChallenge, ss->sec.ci.connectionID, | 1426 ss->sec.ci.clientChallenge, ss->sec.ci.connectionID, |
1426 » » cipherType); | 1427 cipherType); |
1427 if (rv != SECSuccess) | 1428 if (rv != SECSuccess) |
1428 » goto loser; | 1429 goto loser; |
1429 PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len)); | 1430 PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len)); |
1430 PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len)); | 1431 PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len)); |
1431 | 1432 |
1432 PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len); | 1433 PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len); |
1433 PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len); | 1434 PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len); |
1434 ss->sec.ci.keySize = readKey.len; | 1435 ss->sec.ci.keySize = readKey.len; |
1435 | 1436 |
1436 /* Setup the MAC */ | 1437 /* Setup the MAC */ |
1437 rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType); | 1438 rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType); |
1438 if (rv != SECSuccess) | 1439 if (rv != SECSuccess) |
1439 » goto loser; | 1440 goto loser; |
1440 | 1441 |
1441 /* First create the session key object */ | 1442 /* First create the session key object */ |
1442 SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd, | 1443 SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd, |
1443 » ssl_cipherName[cipherType])); | 1444 ssl_cipherName[cipherType])); |
1444 | 1445 |
1445 | 1446 mechanism = ssl_Specs[cipherType].mechanism; |
1446 mechanism = ssl_Specs[cipherType].mechanism; | |
1447 | 1447 |
1448 /* set destructer before we call loser... */ | 1448 /* set destructer before we call loser... */ |
1449 ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext; | 1449 ss->sec.destroy = (void (*)(void *, PRBool))PK11_DestroyContext; |
1450 slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg); | 1450 slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg); |
1451 if (slot == NULL) | 1451 if (slot == NULL) |
1452 » goto loser; | 1452 goto loser; |
1453 | 1453 |
1454 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); | 1454 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); |
1455 if (param == NULL) | 1455 if (param == NULL) |
1456 » goto loser; | 1456 goto loser; |
1457 readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, | 1457 readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, |
1458 » » » » » CKA_DECRYPT, rk, param, | 1458 CKA_DECRYPT, rk, param, |
1459 » » » » » ss->pkcs11PinArg); | 1459 ss->pkcs11PinArg); |
1460 SECITEM_FreeItem(param, PR_TRUE); | 1460 SECITEM_FreeItem(param, PR_TRUE); |
1461 if (readcx == NULL) | 1461 if (readcx == NULL) |
1462 » goto loser; | 1462 goto loser; |
1463 | 1463 |
1464 /* build the client context */ | 1464 /* build the client context */ |
1465 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); | 1465 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); |
1466 if (param == NULL) | 1466 if (param == NULL) |
1467 » goto loser; | 1467 goto loser; |
1468 writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, | 1468 writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, |
1469 » » » » » CKA_ENCRYPT, wk, param, | 1469 CKA_ENCRYPT, wk, param, |
1470 » » » » » ss->pkcs11PinArg); | 1470 ss->pkcs11PinArg); |
1471 SECITEM_FreeItem(param,PR_TRUE); | 1471 SECITEM_FreeItem(param, PR_TRUE); |
1472 if (writecx == NULL) | 1472 if (writecx == NULL) |
1473 » goto loser; | 1473 goto loser; |
1474 PK11_FreeSlot(slot); | 1474 PK11_FreeSlot(slot); |
1475 | 1475 |
1476 rv = SECSuccess; | 1476 rv = SECSuccess; |
1477 ss->sec.enc = (SSLCipher) PK11_CipherOp; | 1477 ss->sec.enc = (SSLCipher)PK11_CipherOp; |
1478 ss->sec.dec = (SSLCipher) PK11_CipherOp; | 1478 ss->sec.dec = (SSLCipher)PK11_CipherOp; |
1479 ss->sec.readcx = (void *) readcx; | 1479 ss->sec.readcx = (void *)readcx; |
1480 ss->sec.writecx = (void *) writecx; | 1480 ss->sec.writecx = (void *)writecx; |
1481 ss->sec.blockSize = ssl_Specs[cipherType].blockSize; | 1481 ss->sec.blockSize = ssl_Specs[cipherType].blockSize; |
1482 ss->sec.blockShift = ssl_Specs[cipherType].blockShift; | 1482 ss->sec.blockShift = ssl_Specs[cipherType].blockShift; |
1483 ss->sec.cipherType = sid->u.ssl2.cipherType; | 1483 ss->sec.cipherType = sid->u.ssl2.cipherType; |
1484 ss->sec.keyBits = sid->u.ssl2.keyBits; | 1484 ss->sec.keyBits = sid->u.ssl2.keyBits; |
1485 ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits; | 1485 ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits; |
1486 goto done; | 1486 goto done; |
1487 | 1487 |
1488 loser: | 1488 loser: |
1489 if (ss->sec.destroy) { | 1489 if (ss->sec.destroy) { |
1490 » if (readcx) (*ss->sec.destroy)(readcx, PR_TRUE); | 1490 if (readcx) |
1491 » if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE); | 1491 (*ss->sec.destroy)(readcx, PR_TRUE); |
| 1492 if (writecx) |
| 1493 (*ss->sec.destroy)(writecx, PR_TRUE); |
1492 } | 1494 } |
1493 ss->sec.destroy = NULL; | 1495 ss->sec.destroy = NULL; |
1494 if (slot) PK11_FreeSlot(slot); | 1496 if (slot) |
| 1497 PK11_FreeSlot(slot); |
1495 | 1498 |
1496 sec_loser: | 1499 sec_loser: |
1497 rv = SECFailure; | 1500 rv = SECFailure; |
1498 | 1501 |
1499 done: | 1502 done: |
1500 if (rk) { | 1503 if (rk) { |
1501 » SECITEM_ZfreeItem(rk, PR_FALSE); | 1504 SECITEM_ZfreeItem(rk, PR_FALSE); |
1502 } | 1505 } |
1503 if (wk) { | 1506 if (wk) { |
1504 » SECITEM_ZfreeItem(wk, PR_FALSE); | 1507 SECITEM_ZfreeItem(wk, PR_FALSE); |
1505 } | 1508 } |
1506 return rv; | 1509 return rv; |
1507 } | 1510 } |
1508 | 1511 |
1509 /* | 1512 /* |
1510 ** Setup the server ciphers given information from a CLIENT-MASTER-KEY | 1513 ** Setup the server ciphers given information from a CLIENT-MASTER-KEY |
1511 ** message. | 1514 ** message. |
1512 ** » "ss" pointer to the ssl-socket object | 1515 ** "ss" pointer to the ssl-socket object |
1513 ** » "cipher" the cipher type to use | 1516 ** "cipher" the cipher type to use |
1514 ** » "keyBits" the size of the final cipher key | 1517 ** "keyBits" the size of the final cipher key |
1515 ** » "ck" the clear-key data | 1518 ** "ck" the clear-key data |
1516 ** » "ckLen" the number of bytes of clear-key data | 1519 ** "ckLen" the number of bytes of clear-key data |
1517 ** » "ek" the encrypted-key data | 1520 ** "ek" the encrypted-key data |
1518 ** » "ekLen" the number of bytes of encrypted-key data | 1521 ** "ekLen" the number of bytes of encrypted-key data |
1519 ** » "ca" the cipher-arg data | 1522 ** "ca" the cipher-arg data |
1520 ** » "caLen" the number of bytes of cipher-arg data | 1523 ** "caLen" the number of bytes of cipher-arg data |
1521 ** | 1524 ** |
1522 ** The MASTER-KEY is constructed by first decrypting the encrypted-key | 1525 ** The MASTER-KEY is constructed by first decrypting the encrypted-key |
1523 ** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by | 1526 ** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by |
1524 ** concatenating the clear-key data with the SECRET-KEY-DATA. This code | 1527 ** concatenating the clear-key data with the SECRET-KEY-DATA. This code |
1525 ** checks to make sure that the client didn't send us an improper amount | 1528 ** checks to make sure that the client didn't send us an improper amount |
1526 ** of SECRET-KEY-DATA (it restricts the length of that data to match the | 1529 ** of SECRET-KEY-DATA (it restricts the length of that data to match the |
1527 ** spec). | 1530 ** spec). |
1528 ** | 1531 ** |
1529 ** Called from ssl2_HandleClientSessionKeyMessage(). | 1532 ** Called from ssl2_HandleClientSessionKeyMessage(). |
1530 */ | 1533 */ |
1531 static SECStatus | 1534 static SECStatus |
1532 ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, | 1535 ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, |
1533 » » » PRUint8 *ck, unsigned int ckLen, | 1536 PRUint8 *ck, unsigned int ckLen, |
1534 » » » PRUint8 *ek, unsigned int ekLen, | 1537 PRUint8 *ek, unsigned int ekLen, |
1535 » » » PRUint8 *ca, unsigned int caLen) | 1538 PRUint8 *ca, unsigned int caLen) |
1536 { | 1539 { |
1537 PRUint8 * dk = NULL; /* decrypted master key */ | 1540 PRUint8 *dk = NULL; /* decrypted master key */ |
1538 sslSessionID * sid; | 1541 sslSessionID *sid; |
1539 sslServerCerts * sc = ss->serverCerts + kt_rsa; | 1542 sslServerCerts *sc = ss->serverCerts + kt_rsa; |
1540 PRUint8 * kbuf = 0;»/* buffer for RSA decrypted data. */ | 1543 PRUint8 *kbuf = 0; /* buffer for RSA decrypted data. */ |
1541 unsigned int ddLen;» /* length of RSA decrypted data in kbuf */ | 1544 unsigned int ddLen; /* length of RSA decrypted data in kbuf */ |
1542 unsigned int keySize; | 1545 unsigned int keySize; |
1543 unsigned int dkLen; /* decrypted key length in bytes */ | 1546 unsigned int dkLen; /* decrypted key length in bytes */ |
1544 int modulusLen; | 1547 int modulusLen; |
1545 SECStatus rv; | 1548 SECStatus rv; |
1546 PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ | 1549 PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ |
1547 PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; | 1550 PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; |
1548 | 1551 |
1549 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 1552 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
1550 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 1553 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
1551 PORT_Assert((sc->SERVERKEY != 0)); | 1554 PORT_Assert((sc->SERVERKEY != 0)); |
1552 PORT_Assert((ss->sec.ci.sid != 0)); | 1555 PORT_Assert((ss->sec.ci.sid != 0)); |
1553 sid = ss->sec.ci.sid; | 1556 sid = ss->sec.ci.sid; |
1554 | 1557 |
1555 /* Trying to cut down on all these switch statements that should be tables. | 1558 /* Trying to cut down on all these switch statements that should be tables. |
1556 * So, test cipherType once, here, and then use tables below. | 1559 * So, test cipherType once, here, and then use tables below. |
1557 */ | 1560 */ |
1558 switch (cipher) { | 1561 switch (cipher) { |
1559 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: | 1562 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
1560 case SSL_CK_RC4_128_WITH_MD5: | 1563 case SSL_CK_RC4_128_WITH_MD5: |
1561 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: | 1564 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
1562 case SSL_CK_RC2_128_CBC_WITH_MD5: | 1565 case SSL_CK_RC2_128_CBC_WITH_MD5: |
1563 case SSL_CK_DES_64_CBC_WITH_MD5: | 1566 case SSL_CK_DES_64_CBC_WITH_MD5: |
1564 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: | 1567 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: |
1565 » break; | 1568 break; |
1566 | 1569 |
1567 default: | 1570 default: |
1568 » SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d"
, | 1571 SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher
=%d", |
1569 » » SSL_GETPID(), ss->fd, cipher)); | 1572 SSL_GETPID(), ss->fd, cipher)); |
1570 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1573 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1571 » goto loser; | 1574 goto loser; |
1572 } | 1575 } |
1573 | 1576 |
1574 allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; | 1577 allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; |
1575 if (!(allowed & (1 << cipher))) { | 1578 if (!(allowed & (1 << cipher))) { |
1576 » /* client chose a kind we don't allow! */ | 1579 /* client chose a kind we don't allow! */ |
1577 » SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d", | 1580 SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d", |
1578 » » SSL_GETPID(), ss->fd, cipher)); | 1581 SSL_GETPID(), ss->fd, cipher)); |
1579 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1582 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1580 » goto loser; | 1583 goto loser; |
1581 } | 1584 } |
1582 | 1585 |
1583 keySize = ssl_Specs[cipher].keyLen; | 1586 keySize = ssl_Specs[cipher].keyLen; |
1584 if (keyBits != keySize * BPB) { | 1587 if (keyBits != keySize * BPB) { |
1585 » SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!", | 1588 SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!", |
1586 » » SSL_GETPID(), ss->fd, keyBits)); | 1589 SSL_GETPID(), ss->fd, keyBits)); |
1587 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1590 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1588 » goto loser; | 1591 goto loser; |
1589 } | 1592 } |
1590 | 1593 |
1591 if (ckLen != ssl_Specs[cipher].pubLen) { | 1594 if (ckLen != ssl_Specs[cipher].pubLen) { |
1592 » SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!", | 1595 SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!", |
1593 » » SSL_GETPID(), ss->fd, ckLen)); | 1596 SSL_GETPID(), ss->fd, ckLen)); |
1594 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1597 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1595 » goto loser; | 1598 goto loser; |
1596 } | 1599 } |
1597 | 1600 |
1598 if (caLen != ssl_Specs[cipher].ivLen) { | 1601 if (caLen != ssl_Specs[cipher].ivLen) { |
1599 » SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!", | 1602 SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!", |
1600 » » SSL_GETPID(), ss->fd, caLen)); | 1603 SSL_GETPID(), ss->fd, caLen)); |
1601 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1604 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1602 » goto loser; | 1605 goto loser; |
1603 } | 1606 } |
1604 | 1607 |
1605 modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); | 1608 modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); |
1606 if (modulusLen < 0) { | 1609 if (modulusLen < 0) { |
1607 » /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */ | 1610 /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */ |
1608 » modulusLen = ekLen; | 1611 modulusLen = ekLen; |
1609 } | 1612 } |
1610 if (ekLen > (unsigned int)modulusLen || ekLen + ckLen < keySize) { | 1613 if (ekLen > (unsigned int)modulusLen || ekLen + ckLen < keySize) { |
1611 » SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", | 1614 SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", |
1612 » » SSL_GETPID(), ss->fd, ekLen)); | 1615 SSL_GETPID(), ss->fd, ekLen)); |
1613 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1616 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1614 » goto loser; | 1617 goto loser; |
1615 } | 1618 } |
1616 | 1619 |
1617 /* allocate the buffer to hold the decrypted portion of the key. */ | 1620 /* allocate the buffer to hold the decrypted portion of the key. */ |
1618 kbuf = (PRUint8*)PORT_Alloc(modulusLen); | 1621 kbuf = (PRUint8 *)PORT_Alloc(modulusLen); |
1619 if (!kbuf) { | 1622 if (!kbuf) { |
1620 » goto loser; | 1623 goto loser; |
1621 } | 1624 } |
1622 dkLen = keySize - ckLen; | 1625 dkLen = keySize - ckLen; |
1623 dk = kbuf + modulusLen - dkLen; | 1626 dk = kbuf + modulusLen - dkLen; |
1624 | 1627 |
1625 /* Decrypt encrypted half of the key. | 1628 /* Decrypt encrypted half of the key. |
1626 ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is | 1629 ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is |
1627 ** desired behavior here. | 1630 ** desired behavior here. |
1628 */ | 1631 */ |
1629 rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen); | 1632 rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen); |
1630 if (rv != SECSuccess) | 1633 if (rv != SECSuccess) |
1631 » goto hide_loser; | 1634 goto hide_loser; |
1632 | 1635 |
1633 /* Is the length of the decrypted data (ddLen) the expected value? */ | 1636 /* Is the length of the decrypted data (ddLen) the expected value? */ |
1634 if (modulusLen != ddLen) | 1637 if (modulusLen != ddLen) |
1635 » goto hide_loser; | 1638 goto hide_loser; |
1636 | 1639 |
1637 /* Cheaply verify that PKCS#1 was used to format the encryption block */ | 1640 /* Cheaply verify that PKCS#1 was used to format the encryption block */ |
1638 if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) { | 1641 if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) { |
1639 » SSL_DBG(("%d: SSL[%d]: strange encryption block", | 1642 SSL_DBG(("%d: SSL[%d]: strange encryption block", |
1640 » » SSL_GETPID(), ss->fd)); | 1643 SSL_GETPID(), ss->fd)); |
1641 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1644 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1642 » goto hide_loser; | 1645 goto hide_loser; |
1643 } | 1646 } |
1644 | 1647 |
1645 /* Make sure we're not subject to a version rollback attack. */ | 1648 /* Make sure we're not subject to a version rollback attack. */ |
1646 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { | 1649 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
1647 » static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, | 1650 static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, |
1648 » » » 0x03, 0x03, 0x03, 0x03 }; | 1651 0x03, 0x03, 0x03, 0x03 }; |
1649 » | 1652 |
1650 » if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) { | 1653 if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) { |
1651 » PORT_SetError(SSL_ERROR_BAD_CLIENT); | 1654 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
1652 » goto hide_loser; | 1655 goto hide_loser; |
1653 » } | 1656 } |
1654 } | 1657 } |
1655 if (0) { | 1658 if (0) { |
1656 hide_loser: | 1659 hide_loser: |
1657 » /* Defense against the Bleichenbacher attack. | 1660 /* Defense against the Bleichenbacher attack. |
1658 » * Provide the client with NO CLUES that the decrypted master key | 1661 * Provide the client with NO CLUES that the decrypted master key |
1659 » * was erroneous. Don't send any error messages. | 1662 * was erroneous. Don't send any error messages. |
1660 » * Instead, Generate a completely bogus master key . | 1663 * Instead, Generate a completely bogus master key . |
1661 » */ | 1664 */ |
1662 » PK11_GenerateRandom(dk, dkLen); | 1665 PK11_GenerateRandom(dk, dkLen); |
1663 } | 1666 } |
1664 | 1667 |
1665 /* | 1668 /* |
1666 ** Construct master key out of the pieces. | 1669 ** Construct master key out of the pieces. |
1667 */ | 1670 */ |
1668 if (ckLen) { | 1671 if (ckLen) { |
1669 » PORT_Memcpy(mkbuf, ck, ckLen); | 1672 PORT_Memcpy(mkbuf, ck, ckLen); |
1670 } | 1673 } |
1671 PORT_Memcpy(mkbuf + ckLen, dk, dkLen); | 1674 PORT_Memcpy(mkbuf + ckLen, dk, dkLen); |
1672 | 1675 |
1673 /* Fill in session-id */ | 1676 /* Fill in session-id */ |
1674 rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, | 1677 rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, |
1675 » » keyBits, keyBits - (ckLen<<3), | 1678 keyBits, keyBits - (ckLen << 3), |
1676 » » ss->sec.authAlgorithm, ss->sec.authKeyBits, | 1679 ss->sec.authAlgorithm, ss->sec.authKeyBits, |
1677 » » ss->sec.keaType, ss->sec.keaKeyBits); | 1680 ss->sec.keaType, ss->sec.keaKeyBits); |
1678 if (rv != SECSuccess) { | 1681 if (rv != SECSuccess) { |
1679 » goto loser; | 1682 goto loser; |
1680 } | 1683 } |
1681 | 1684 |
1682 /* Create session ciphers */ | 1685 /* Create session ciphers */ |
1683 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); | 1686 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); |
1684 if (rv != SECSuccess) { | 1687 if (rv != SECSuccess) { |
1685 » goto loser; | 1688 goto loser; |
1686 } | 1689 } |
1687 | 1690 |
1688 SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d", | 1691 SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d", |
1689 » » SSL_GETPID(), ss->fd, ssl_cipherName[cipher], | 1692 SSL_GETPID(), ss->fd, ssl_cipherName[cipher], |
1690 » » ckLen<<3, keySize<<3)); | 1693 ckLen << 3, keySize << 3)); |
1691 rv = SECSuccess; | 1694 rv = SECSuccess; |
1692 goto done; | 1695 goto done; |
1693 | 1696 |
1694 loser: | 1697 loser: |
1695 rv = SECFailure; | 1698 rv = SECFailure; |
1696 | 1699 |
1697 done: | 1700 done: |
1698 PORT_Free(kbuf); | 1701 PORT_Free(kbuf); |
1699 return rv; | 1702 return rv; |
1700 } | 1703 } |
1701 | 1704 |
1702 /************************************************************************/ | 1705 /************************************************************************/ |
1703 | 1706 |
1704 /* | 1707 /* |
1705 ** Rewrite the incoming cipher specs, comparing to list of specs we support, | 1708 ** Rewrite the incoming cipher specs, comparing to list of specs we support, |
1706 ** (ss->cipherSpecs) and eliminating anything we don't support | 1709 ** (ss->cipherSpecs) and eliminating anything we don't support |
1707 ** | 1710 ** |
1708 * Note: Our list may contain SSL v3 ciphers. | 1711 * Note: Our list may contain SSL v3 ciphers. |
1709 * We MUST NOT match on any of those. | 1712 * We MUST NOT match on any of those. |
1710 * Fortunately, this is easy to detect because SSLv3 ciphers have zero | 1713 * Fortunately, this is easy to detect because SSLv3 ciphers have zero |
1711 * in the first byte, and none of the SSLv2 ciphers do. | 1714 * in the first byte, and none of the SSLv2 ciphers do. |
1712 * | 1715 * |
1713 * Called from ssl2_HandleClientHelloMessage(). | 1716 * Called from ssl2_HandleClientHelloMessage(). |
1714 * Returns the number of bytes of "qualified cipher specs", | 1717 * Returns the number of bytes of "qualified cipher specs", |
1715 * which is typically a multiple of 3, but will be zero if there are none. | 1718 * which is typically a multiple of 3, but will be zero if there are none. |
1716 */ | 1719 */ |
1717 static int | 1720 static int |
1718 ssl2_QualifyCypherSpecs(sslSocket *ss, | 1721 ssl2_QualifyCypherSpecs(sslSocket *ss, |
1719 PRUint8 * cs, /* cipher specs in client hello msg. */ | 1722 PRUint8 *cs, /* cipher specs in client hello msg. */ |
1720 » » int csLen) | 1723 int csLen) |
1721 { | 1724 { |
1722 PRUint8 * ms; | 1725 PRUint8 *ms; |
1723 PRUint8 * hs; | 1726 PRUint8 *hs; |
1724 PRUint8 * qs; | 1727 PRUint8 *qs; |
1725 int mc; | 1728 int mc; |
1726 int hc; | 1729 int hc; |
1727 PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3]; | 1730 PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3]; |
1728 | 1731 |
1729 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 1732 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
1730 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 1733 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
1731 | 1734 |
1732 if (!ss->cipherSpecs) { | 1735 if (!ss->cipherSpecs) { |
1733 » SECStatus rv = ssl2_ConstructCipherSpecs(ss); | 1736 SECStatus rv = ssl2_ConstructCipherSpecs(ss); |
1734 » if (rv != SECSuccess || !ss->cipherSpecs) | 1737 if (rv != SECSuccess || !ss->cipherSpecs) |
1735 » return 0; | 1738 return 0; |
1736 } | 1739 } |
1737 | 1740 |
1738 PRINT_BUF(10, (ss, "specs from client:", cs, csLen)); | 1741 PRINT_BUF(10, (ss, "specs from client:", cs, csLen)); |
1739 qs = qualifiedSpecs; | 1742 qs = qualifiedSpecs; |
1740 ms = ss->cipherSpecs; | 1743 ms = ss->cipherSpecs; |
1741 for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) { | 1744 for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) { |
1742 » if (ms[0] == 0) | 1745 if (ms[0] == 0) |
1743 » continue; | 1746 continue; |
1744 » for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) { | 1747 for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) { |
1745 » if ((hs[0] == ms[0]) && | 1748 if ((hs[0] == ms[0]) && |
1746 » » (hs[1] == ms[1]) && | 1749 (hs[1] == ms[1]) && |
1747 » » (hs[2] == ms[2])) { | 1750 (hs[2] == ms[2])) { |
1748 » » /* Copy this cipher spec into the "keep" section */ | 1751 /* Copy this cipher spec into the "keep" section */ |
1749 » » qs[0] = hs[0]; | 1752 qs[0] = hs[0]; |
1750 » » qs[1] = hs[1]; | 1753 qs[1] = hs[1]; |
1751 » » qs[2] = hs[2]; | 1754 qs[2] = hs[2]; |
1752 » » qs += 3; | 1755 qs += 3; |
1753 » » break; | 1756 break; |
1754 » } | 1757 } |
1755 » } | 1758 } |
1756 } | 1759 } |
1757 hc = qs - qualifiedSpecs; | 1760 hc = qs - qualifiedSpecs; |
1758 PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc)); | 1761 PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc)); |
1759 PORT_Memcpy(cs, qualifiedSpecs, hc); | 1762 PORT_Memcpy(cs, qualifiedSpecs, hc); |
1760 return hc; | 1763 return hc; |
1761 } | 1764 } |
1762 | 1765 |
1763 /* | 1766 /* |
1764 ** Pick the best cipher we can find, given the array of server cipher | 1767 ** Pick the best cipher we can find, given the array of server cipher |
1765 ** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap. | 1768 ** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap. |
1766 ** If successful, stores the master key size (bytes) in *pKeyLen. | 1769 ** If successful, stores the master key size (bytes) in *pKeyLen. |
1767 ** | 1770 ** |
1768 ** This is correct only for the client side, but presently | 1771 ** This is correct only for the client side, but presently |
1769 ** this function is only called from | 1772 ** this function is only called from |
1770 **» ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() | 1773 ** ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() |
1771 ** | 1774 ** |
1772 ** Note that most servers only return a single cipher suite in their | 1775 ** Note that most servers only return a single cipher suite in their |
1773 ** ServerHello messages. So, the code below for finding the "best" cipher | 1776 ** ServerHello messages. So, the code below for finding the "best" cipher |
1774 ** suite usually has only one choice. The client and server should send | 1777 ** suite usually has only one choice. The client and server should send |
1775 ** their cipher suite lists sorted in descending order by preference. | 1778 ** their cipher suite lists sorted in descending order by preference. |
1776 */ | 1779 */ |
1777 static int | 1780 static int |
1778 ssl2_ChooseSessionCypher(sslSocket *ss, | 1781 ssl2_ChooseSessionCypher(sslSocket *ss, |
1779 int hc, /* number of cs's in hs. */ | 1782 int hc, /* number of cs's in hs. */ |
1780 » » PRUint8 * hs, /* server hello's cipher suites. */ | 1783 PRUint8 *hs, /* server hello's cipher suites. */ |
1781 » » int * pKeyLen) /* out: sym key size in bytes. */ | 1784 int *pKeyLen) /* out: sym key size in bytes. */ |
1782 { | 1785 { |
1783 PRUint8 * ms; | 1786 PRUint8 *ms; |
1784 unsigned int i; | 1787 unsigned int i; |
1785 int bestKeySize; | 1788 int bestKeySize; |
1786 int bestRealKeySize; | 1789 int bestRealKeySize; |
1787 int bestCypher; | 1790 int bestCypher; |
1788 int keySize; | 1791 int keySize; |
1789 int realKeySize; | 1792 int realKeySize; |
1790 PRUint8 * ohs = hs; | 1793 PRUint8 *ohs = hs; |
1791 const PRUint8 * preferred; | 1794 const PRUint8 *preferred; |
1792 static const PRUint8 noneSuch[3] = { 0, 0, 0 }; | 1795 static const PRUint8 noneSuch[3] = { 0, 0, 0 }; |
1793 | 1796 |
1794 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 1797 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
1795 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 1798 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
1796 | 1799 |
1797 if (!ss->cipherSpecs) { | 1800 if (!ss->cipherSpecs) { |
1798 » SECStatus rv = ssl2_ConstructCipherSpecs(ss); | 1801 SECStatus rv = ssl2_ConstructCipherSpecs(ss); |
1799 » if (rv != SECSuccess || !ss->cipherSpecs) | 1802 if (rv != SECSuccess || !ss->cipherSpecs) |
1800 » goto loser; | 1803 goto loser; |
1801 } | 1804 } |
1802 | 1805 |
1803 if (!ss->preferredCipher) { | 1806 if (!ss->preferredCipher) { |
1804 » unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & | 1807 unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & |
1805 » SSL_CB_IMPLEMENTED; | 1808 SSL_CB_IMPLEMENTED; |
1806 » if (allowed) { | 1809 if (allowed) { |
1807 » preferred = implementedCipherSuites; | 1810 preferred = implementedCipherSuites; |
1808 » for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) { | 1811 for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) { |
1809 » » if (0 != (allowed & (1U << preferred[0]))) { | 1812 if (0 != (allowed & (1U << preferred[0]))) { |
1810 » » ss->preferredCipher = preferred; | 1813 ss->preferredCipher = preferred; |
1811 » » break; | 1814 break; |
1812 » » } | 1815 } |
1813 » » preferred += 3; | 1816 preferred += 3; |
1814 » } | 1817 } |
1815 » } | 1818 } |
1816 } | 1819 } |
1817 preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch; | 1820 preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch; |
1818 /* | 1821 /* |
1819 ** Scan list of ciphers received from peer and look for a match in | 1822 ** Scan list of ciphers received from peer and look for a match in |
1820 ** our list. | 1823 ** our list. |
1821 * Note: Our list may contain SSL v3 ciphers. | 1824 * Note: Our list may contain SSL v3 ciphers. |
1822 * We MUST NOT match on any of those. | 1825 * We MUST NOT match on any of those. |
1823 * Fortunately, this is easy to detect because SSLv3 ciphers have zero | 1826 * Fortunately, this is easy to detect because SSLv3 ciphers have zero |
1824 * in the first byte, and none of the SSLv2 ciphers do. | 1827 * in the first byte, and none of the SSLv2 ciphers do. |
1825 */ | 1828 */ |
1826 bestKeySize = bestRealKeySize = 0; | 1829 bestKeySize = bestRealKeySize = 0; |
1827 bestCypher = -1; | 1830 bestCypher = -1; |
1828 while (--hc >= 0) { | 1831 while (--hc >= 0) { |
1829 » for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms +=
3) { | 1832 for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms +=
3) { |
1830 » if ((hs[0] == preferred[0]) && | 1833 if ((hs[0] == preferred[0]) && |
1831 » » (hs[1] == preferred[1]) && | 1834 (hs[1] == preferred[1]) && |
1832 » » (hs[2] == preferred[2]) && | 1835 (hs[2] == preferred[2]) && |
1833 » » hs[0] != 0) { | 1836 hs[0] != 0) { |
1834 » » /* Pick this cipher immediately! */ | 1837 /* Pick this cipher immediately! */ |
1835 » » *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3; | 1838 *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3; |
1836 » » return hs[0]; | 1839 return hs[0]; |
1837 » } | 1840 } |
1838 » if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) && | 1841 if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) && |
1839 » hs[0] != 0) { | 1842 hs[0] != 0) { |
1840 » » /* Found a match */ | 1843 /* Found a match */ |
1841 | 1844 |
1842 » » /* Use secret keySize to determine which cipher is best */ | 1845 /* Use secret keySize to determine which cipher is best */ |
1843 » » realKeySize = (hs[1] << 8) | hs[2]; | 1846 realKeySize = (hs[1] << 8) | hs[2]; |
1844 » » switch (hs[0]) { | 1847 switch (hs[0]) { |
1845 » » case SSL_CK_RC4_128_EXPORT40_WITH_MD5: | 1848 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
1846 » » case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: | 1849 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
1847 » » keySize = 40; | 1850 keySize = 40; |
1848 » » break; | 1851 break; |
1849 » » default: | 1852 default: |
1850 » » keySize = realKeySize; | 1853 keySize = realKeySize; |
1851 » » break; | 1854 break; |
1852 » » } | 1855 } |
1853 » » if (keySize > bestKeySize) { | 1856 if (keySize > bestKeySize) { |
1854 » » bestCypher = hs[0]; | 1857 bestCypher = hs[0]; |
1855 » » bestKeySize = keySize; | 1858 bestKeySize = keySize; |
1856 » » bestRealKeySize = realKeySize; | 1859 bestRealKeySize = realKeySize; |
1857 » » } | 1860 } |
1858 » } | 1861 } |
1859 » } | 1862 } |
1860 » hs += 3; | 1863 hs += 3; |
1861 } | 1864 } |
1862 if (bestCypher < 0) { | 1865 if (bestCypher < 0) { |
1863 » /* | 1866 /* |
1864 » ** No overlap between server and client. Re-examine server list | 1867 ** No overlap between server and client. Re-examine server list |
1865 » ** to see what kind of ciphers it does support so that we can set | 1868 ** to see what kind of ciphers it does support so that we can set |
1866 » ** the error code appropriately. | 1869 ** the error code appropriately. |
1867 » */ | 1870 */ |
1868 » if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) || | 1871 if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) || |
1869 » (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) { | 1872 (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) { |
1870 » PORT_SetError(SSL_ERROR_US_ONLY_SERVER); | 1873 PORT_SetError(SSL_ERROR_US_ONLY_SERVER); |
1871 » } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) || | 1874 } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) || |
1872 » » (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) { | 1875 (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) { |
1873 » PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER); | 1876 PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER); |
1874 » } else { | 1877 } else { |
1875 » PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 1878 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
1876 » } | 1879 } |
1877 » SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd)); | 1880 SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd)); |
1878 » goto loser; | 1881 goto loser; |
1879 } | 1882 } |
1880 *pKeyLen = (bestRealKeySize + 7) >> 3; | 1883 *pKeyLen = (bestRealKeySize + 7) >> 3; |
1881 return bestCypher; | 1884 return bestCypher; |
1882 | 1885 |
1883 loser: | 1886 loser: |
1884 return -1; | 1887 return -1; |
1885 } | 1888 } |
1886 | 1889 |
1887 static SECStatus | 1890 static SECStatus |
1888 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen) | 1891 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen) |
1889 { | 1892 { |
1890 CERTCertificate *cert = NULL; | 1893 CERTCertificate *cert = NULL; |
1891 SECItem certItem; | 1894 SECItem certItem; |
1892 | 1895 |
1893 certItem.data = certData; | 1896 certItem.data = certData; |
1894 certItem.len = certLen; | 1897 certItem.len = certLen; |
1895 | 1898 |
1896 /* decode the certificate */ | 1899 /* decode the certificate */ |
1897 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | 1900 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
1898 » » » » PR_FALSE, PR_TRUE); | 1901 PR_FALSE, PR_TRUE); |
1899 | 1902 |
1900 if (cert == NULL) { | 1903 if (cert == NULL) { |
1901 » SSL_DBG(("%d: SSL[%d]: decode of server certificate fails", | 1904 SSL_DBG(("%d: SSL[%d]: decode of server certificate fails", |
1902 » » SSL_GETPID(), ss->fd)); | 1905 SSL_GETPID(), ss->fd)); |
1903 » PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); | 1906 PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); |
1904 » return SECFailure; | 1907 return SECFailure; |
1905 } | 1908 } |
1906 | 1909 |
1907 #ifdef TRACE | 1910 #ifdef TRACE |
1908 { | 1911 { |
1909 » if (ssl_trace >= 1) { | 1912 if (ssl_trace >= 1) { |
1910 » char *issuer; | 1913 char *issuer; |
1911 » char *subject; | 1914 char *subject; |
1912 » issuer = CERT_NameToAscii(&cert->issuer); | 1915 issuer = CERT_NameToAscii(&cert->issuer); |
1913 » subject = CERT_NameToAscii(&cert->subject); | 1916 subject = CERT_NameToAscii(&cert->subject); |
1914 » SSL_TRC(1,("%d: server certificate issuer: '%s'", | 1917 SSL_TRC(1, ("%d: server certificate issuer: '%s'", |
1915 » » SSL_GETPID(), issuer ? issuer : "OOPS")); | 1918 SSL_GETPID(), issuer ? issuer : "OOPS")); |
1916 » SSL_TRC(1,("%d: server name: '%s'", | 1919 SSL_TRC(1, ("%d: server name: '%s'", |
1917 » » SSL_GETPID(), subject ? subject : "OOPS")); | 1920 SSL_GETPID(), subject ? subject : "OOPS")); |
1918 » PORT_Free(issuer); | 1921 PORT_Free(issuer); |
1919 » PORT_Free(subject); | 1922 PORT_Free(subject); |
1920 » } | 1923 } |
1921 } | 1924 } |
1922 #endif | 1925 #endif |
1923 | 1926 |
1924 ss->sec.peerCert = cert; | 1927 ss->sec.peerCert = cert; |
1925 return SECSuccess; | 1928 return SECSuccess; |
1926 } | 1929 } |
1927 | 1930 |
1928 | |
1929 /* | 1931 /* |
1930 * Format one block of data for public/private key encryption using | 1932 * Format one block of data for public/private key encryption using |
1931 * the rules defined in PKCS #1. SSL2 does this itself to handle the | 1933 * the rules defined in PKCS #1. SSL2 does this itself to handle the |
1932 * rollback detection. | 1934 * rollback detection. |
1933 */ | 1935 */ |
1934 #define RSA_BLOCK_MIN_PAD_LEN 8 | 1936 #define RSA_BLOCK_MIN_PAD_LEN 8 |
1935 #define RSA_BLOCK_FIRST_OCTET 0x00 | 1937 #define RSA_BLOCK_FIRST_OCTET 0x00 |
1936 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00 | 1938 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00 |
1937 #define RSA_BLOCK_PUBLIC_OCTET » 0x02 | 1939 #define RSA_BLOCK_PUBLIC_OCTET 0x02 |
1938 unsigned char * | 1940 unsigned char * |
1939 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data) | 1941 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data) |
1940 { | 1942 { |
1941 unsigned char *block; | 1943 unsigned char *block; |
1942 unsigned char *bp; | 1944 unsigned char *bp; |
1943 int padLen; | 1945 int padLen; |
1944 SECStatus rv; | 1946 SECStatus rv; |
1945 int i; | 1947 int i; |
1946 | 1948 |
1947 if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) { | 1949 if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) { |
1948 » PORT_SetError(SEC_ERROR_BAD_KEY); | 1950 PORT_SetError(SEC_ERROR_BAD_KEY); |
1949 » return NULL; | 1951 return NULL; |
1950 } | 1952 } |
1951 block = (unsigned char *) PORT_Alloc(modulusLen); | 1953 block = (unsigned char *)PORT_Alloc(modulusLen); |
1952 if (block == NULL) | 1954 if (block == NULL) |
1953 » return NULL; | 1955 return NULL; |
1954 | 1956 |
1955 bp = block; | 1957 bp = block; |
1956 | 1958 |
1957 /* | 1959 /* |
1958 * All RSA blocks start with two octets: | 1960 * All RSA blocks start with two octets: |
1959 *» 0x00 || BlockType | 1961 * 0x00 || BlockType |
1960 */ | 1962 */ |
1961 *bp++ = RSA_BLOCK_FIRST_OCTET; | 1963 *bp++ = RSA_BLOCK_FIRST_OCTET; |
1962 *bp++ = RSA_BLOCK_PUBLIC_OCTET; | 1964 *bp++ = RSA_BLOCK_PUBLIC_OCTET; |
1963 | 1965 |
1964 /* | 1966 /* |
1965 * 0x00 || BT || Pad || 0x00 || ActualData | 1967 * 0x00 || BT || Pad || 0x00 || ActualData |
1966 * 1 1 padLen 1 data->len | 1968 * 1 1 padLen 1 data->len |
1967 * Pad is all non-zero random bytes. | 1969 * Pad is all non-zero random bytes. |
1968 */ | 1970 */ |
1969 padLen = modulusLen - data->len - 3; | 1971 padLen = modulusLen - data->len - 3; |
1970 PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN); | 1972 PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN); |
1971 rv = PK11_GenerateRandom(bp, padLen); | 1973 rv = PK11_GenerateRandom(bp, padLen); |
1972 if (rv == SECFailure) goto loser; | 1974 if (rv == SECFailure) |
| 1975 goto loser; |
1973 /* replace all the 'zero' bytes */ | 1976 /* replace all the 'zero' bytes */ |
1974 for (i = 0; i < padLen; i++) { | 1977 for (i = 0; i < padLen; i++) { |
1975 » while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) { | 1978 while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) { |
1976 » rv = PK11_GenerateRandom(bp+i, 1); | 1979 rv = PK11_GenerateRandom(bp + i, 1); |
1977 » if (rv == SECFailure) goto loser; | 1980 if (rv == SECFailure) |
1978 » } | 1981 goto loser; |
| 1982 } |
1979 } | 1983 } |
1980 bp += padLen; | 1984 bp += padLen; |
1981 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; | 1985 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; |
1982 PORT_Memcpy (bp, data->data, data->len); | 1986 PORT_Memcpy(bp, data->data, data->len); |
1983 | 1987 |
1984 return block; | 1988 return block; |
1985 loser: | 1989 loser: |
1986 if (block) PORT_Free(block); | 1990 if (block) |
| 1991 PORT_Free(block); |
1987 return NULL; | 1992 return NULL; |
1988 } | 1993 } |
1989 | 1994 |
1990 /* | 1995 /* |
1991 ** Given the server's public key and cipher specs, generate a session key | 1996 ** Given the server's public key and cipher specs, generate a session key |
1992 ** that is ready to use for encrypting/decrypting the byte stream. At | 1997 ** that is ready to use for encrypting/decrypting the byte stream. At |
1993 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and | 1998 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and |
1994 ** send it to the server. | 1999 ** send it to the server. |
1995 ** | 2000 ** |
1996 ** Called from ssl2_HandleServerHelloMessage() | 2001 ** Called from ssl2_HandleServerHelloMessage() |
1997 */ | 2002 */ |
1998 static SECStatus | 2003 static SECStatus |
1999 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) | 2004 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) |
2000 { | 2005 { |
2001 sslSessionID * sid; | 2006 sslSessionID *sid; |
2002 PRUint8 * ca;» /* points to iv data, or NULL if none. */ | 2007 PRUint8 *ca; /* points to iv data, or NULL if none. */ |
2003 PRUint8 * ekbuf » » = 0; | 2008 PRUint8 *ekbuf = 0; |
2004 CERTCertificate * cert » » = 0; | 2009 CERTCertificate *cert = 0; |
2005 SECKEYPublicKey * serverKey » = 0; | 2010 SECKEYPublicKey *serverKey = 0; |
2006 unsigned modulusLen » = 0; | 2011 unsigned modulusLen = 0; |
2007 SECStatus rv; | 2012 SECStatus rv; |
2008 int cipher; | 2013 int cipher; |
2009 int keyLen;» /* cipher symkey size in bytes. */ | 2014 int keyLen; /* cipher symkey size in bytes. */ |
2010 int ckLen;» /* publicly reveal this many bytes of key. */ | 2015 int ckLen; /* publicly reveal this many bytes of key. */ |
2011 int caLen;» /* length of IV data at *ca.» */ | 2016 int caLen; /* length of IV data at *ca. */ |
2012 int nc; | 2017 int nc; |
2013 | 2018 |
2014 unsigned char *eblock;» /* holds unencrypted PKCS#1 formatted key. */ | 2019 unsigned char *eblock; /* holds unencrypted PKCS#1 formatted key. */ |
2015 SECItem rek;» /* holds portion of symkey to be encrypted. */ | 2020 SECItem rek; /* holds portion of symkey to be encrypted. */ |
2016 | 2021 |
2017 PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES]; | 2022 PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES]; |
2018 PRUint8 iv [8]; | 2023 PRUint8 iv[8]; |
2019 | 2024 |
2020 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2025 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2021 | 2026 |
2022 eblock = NULL; | 2027 eblock = NULL; |
2023 | 2028 |
2024 sid = ss->sec.ci.sid; | 2029 sid = ss->sec.ci.sid; |
2025 PORT_Assert(sid != 0); | 2030 PORT_Assert(sid != 0); |
2026 | 2031 |
2027 cert = ss->sec.peerCert; | 2032 cert = ss->sec.peerCert; |
2028 | 2033 |
2029 serverKey = CERT_ExtractPublicKey(cert); | 2034 serverKey = CERT_ExtractPublicKey(cert); |
2030 if (!serverKey) { | 2035 if (!serverKey) { |
2031 » SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d", | 2036 SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d", |
2032 » » SSL_GETPID(), ss->fd, PORT_GetError())); | 2037 SSL_GETPID(), ss->fd, PORT_GetError())); |
2033 » PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); | 2038 PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); |
2034 » rv = SECFailure; | 2039 rv = SECFailure; |
2035 » goto loser2; | 2040 goto loser2; |
2036 } | 2041 } |
2037 | 2042 |
2038 ss->sec.authAlgorithm = ssl_sign_rsa; | 2043 ss->sec.authAlgorithm = ssl_sign_rsa; |
2039 ss->sec.keaType = ssl_kea_rsa; | 2044 ss->sec.keaType = ssl_kea_rsa; |
2040 ss->sec.keaKeyBits = \ | 2045 ss->sec.keaKeyBits = |
2041 ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey); | 2046 ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey); |
2042 | 2047 |
2043 /* Choose a compatible cipher with the server */ | 2048 /* Choose a compatible cipher with the server */ |
2044 nc = csLen / 3; | 2049 nc = csLen / 3; |
2045 cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen); | 2050 cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen); |
2046 if (cipher < 0) { | 2051 if (cipher < 0) { |
2047 » /* ssl2_ChooseSessionCypher has set error code. */ | 2052 /* ssl2_ChooseSessionCypher has set error code. */ |
2048 » ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); | 2053 ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); |
2049 » goto loser; | 2054 goto loser; |
2050 } | 2055 } |
2051 | 2056 |
2052 /* Generate the random keys */ | 2057 /* Generate the random keys */ |
2053 PK11_GenerateRandom(keyData, sizeof(keyData)); | 2058 PK11_GenerateRandom(keyData, sizeof(keyData)); |
2054 | 2059 |
2055 /* | 2060 /* |
2056 ** Next, carve up the keys into clear and encrypted portions. The | 2061 ** Next, carve up the keys into clear and encrypted portions. The |
2057 ** clear data is taken from the start of keyData and the encrypted | 2062 ** clear data is taken from the start of keyData and the encrypted |
2058 ** portion from the remainder. Note that each of these portions is | 2063 ** portion from the remainder. Note that each of these portions is |
2059 ** carved in half, one half for the read-key and one for the | 2064 ** carved in half, one half for the read-key and one for the |
2060 ** write-key. | 2065 ** write-key. |
2061 */ | 2066 */ |
2062 ca = 0; | 2067 ca = 0; |
2063 | 2068 |
2064 /* We know that cipher is a legit value here, because | 2069 /* We know that cipher is a legit value here, because |
2065 * ssl2_ChooseSessionCypher doesn't return bogus values. | 2070 * ssl2_ChooseSessionCypher doesn't return bogus values. |
2066 */ | 2071 */ |
2067 ckLen = ssl_Specs[cipher].pubLen;» /* cleartext key length. */ | 2072 ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */ |
2068 caLen = ssl_Specs[cipher].ivLen;» /* IV length.» » */ | 2073 caLen = ssl_Specs[cipher].ivLen; /* IV length. */ |
2069 if (caLen) { | 2074 if (caLen) { |
2070 » PORT_Assert(sizeof iv >= caLen); | 2075 PORT_Assert(sizeof iv >= caLen); |
2071 » PK11_GenerateRandom(iv, caLen); | 2076 PK11_GenerateRandom(iv, caLen); |
2072 » ca = iv; | 2077 ca = iv; |
2073 } | 2078 } |
2074 | 2079 |
2075 /* Fill in session-id */ | 2080 /* Fill in session-id */ |
2076 rv = ssl2_FillInSID(sid, cipher, keyData, keyLen, | 2081 rv = ssl2_FillInSID(sid, cipher, keyData, keyLen, |
2077 » » ca, caLen, keyLen << 3, (keyLen - ckLen) << 3, | 2082 ca, caLen, keyLen << 3, (keyLen - ckLen) << 3, |
2078 » » ss->sec.authAlgorithm, ss->sec.authKeyBits, | 2083 ss->sec.authAlgorithm, ss->sec.authKeyBits, |
2079 » » ss->sec.keaType, ss->sec.keaKeyBits); | 2084 ss->sec.keaType, ss->sec.keaKeyBits); |
2080 if (rv != SECSuccess) { | 2085 if (rv != SECSuccess) { |
2081 » goto loser; | 2086 goto loser; |
2082 } | 2087 } |
2083 | 2088 |
2084 SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d", | 2089 SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d", |
2085 » » SSL_GETPID(), ss->fd, ssl_cipherName[cipher], | 2090 SSL_GETPID(), ss->fd, ssl_cipherName[cipher], |
2086 » » ckLen<<3, keyLen<<3)); | 2091 ckLen << 3, keyLen << 3)); |
2087 | 2092 |
2088 /* Now setup read and write ciphers */ | 2093 /* Now setup read and write ciphers */ |
2089 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); | 2094 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); |
2090 if (rv != SECSuccess) { | 2095 if (rv != SECSuccess) { |
2091 » goto loser; | 2096 goto loser; |
2092 } | 2097 } |
2093 | 2098 |
2094 /* | 2099 /* |
2095 ** Fill in the encryption buffer with some random bytes. Then | 2100 ** Fill in the encryption buffer with some random bytes. Then |
2096 ** copy in the portion of the session key we are encrypting. | 2101 ** copy in the portion of the session key we are encrypting. |
2097 */ | 2102 */ |
2098 modulusLen = SECKEY_PublicKeyStrength(serverKey); | 2103 modulusLen = SECKEY_PublicKeyStrength(serverKey); |
2099 rek.data = keyData + ckLen; | 2104 rek.data = keyData + ckLen; |
2100 rek.len = keyLen - ckLen; | 2105 rek.len = keyLen - ckLen; |
2101 eblock = ssl_FormatSSL2Block(modulusLen, &rek); | 2106 eblock = ssl_FormatSSL2Block(modulusLen, &rek); |
2102 if (eblock == NULL) | 2107 if (eblock == NULL) |
2103 » goto loser; | 2108 goto loser; |
2104 | 2109 |
2105 /* Set up the padding for version 2 rollback detection. */ | 2110 /* Set up the padding for version 2 rollback detection. */ |
2106 /* XXX We should really use defines here */ | 2111 /* XXX We should really use defines here */ |
2107 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { | 2112 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
2108 » PORT_Assert((modulusLen - rek.len) > 12); | 2113 PORT_Assert((modulusLen - rek.len) > 12); |
2109 » PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8); | 2114 PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8); |
2110 } | 2115 } |
2111 ekbuf = (PRUint8*) PORT_Alloc(modulusLen); | 2116 ekbuf = (PRUint8 *)PORT_Alloc(modulusLen); |
2112 if (!ekbuf) | 2117 if (!ekbuf) |
2113 » goto loser; | 2118 goto loser; |
2114 PRINT_BUF(10, (ss, "master key encryption block:", | 2119 PRINT_BUF(10, (ss, "master key encryption block:", |
2115 » » eblock, modulusLen)); | 2120 eblock, modulusLen)); |
2116 | 2121 |
2117 /* Encrypt ekitem */ | 2122 /* Encrypt ekitem */ |
2118 rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen, | 2123 rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen, |
2119 » » » » » » ss->pkcs11PinArg); | 2124 ss->pkcs11PinArg); |
2120 if (rv) | 2125 if (rv) |
2121 » goto loser; | 2126 goto loser; |
2122 | 2127 |
2123 /* Now we have everything ready to send */ | 2128 /* Now we have everything ready to send */ |
2124 rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen, | 2129 rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen, |
2125 » » » keyData, ckLen, ekbuf, modulusLen); | 2130 keyData, ckLen, ekbuf, modulusLen); |
2126 if (rv != SECSuccess) { | 2131 if (rv != SECSuccess) { |
2127 » goto loser; | 2132 goto loser; |
2128 } | 2133 } |
2129 rv = SECSuccess; | 2134 rv = SECSuccess; |
2130 goto done; | 2135 goto done; |
2131 | 2136 |
2132 loser: | 2137 loser: |
2133 rv = SECFailure; | 2138 rv = SECFailure; |
2134 | 2139 |
2135 loser2: | 2140 loser2: |
2136 done: | 2141 done: |
2137 PORT_Memset(keyData, 0, sizeof(keyData)); | 2142 PORT_Memset(keyData, 0, sizeof(keyData)); |
2138 PORT_ZFree(ekbuf, modulusLen); | 2143 PORT_ZFree(ekbuf, modulusLen); |
2139 PORT_ZFree(eblock, modulusLen); | 2144 PORT_ZFree(eblock, modulusLen); |
2140 SECKEY_DestroyPublicKey(serverKey); | 2145 SECKEY_DestroyPublicKey(serverKey); |
2141 return rv; | 2146 return rv; |
2142 } | 2147 } |
2143 | 2148 |
2144 /************************************************************************/ | 2149 /************************************************************************/ |
2145 | 2150 |
2146 /* | 2151 /* |
2147 * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message. | 2152 * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message. |
2148 * Caller holds recvBufLock and handshakeLock | 2153 * Caller holds recvBufLock and handshakeLock |
2149 */ | 2154 */ |
2150 static void | 2155 static void |
2151 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s) | 2156 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s) |
2152 { | 2157 { |
2153 sslSessionID *sid = ss->sec.ci.sid; | 2158 sslSessionID *sid = ss->sec.ci.sid; |
2154 | 2159 |
2155 /* Record entry in nonce cache */ | 2160 /* Record entry in nonce cache */ |
2156 if (sid->peerCert == NULL) { | 2161 if (sid->peerCert == NULL) { |
2157 » PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID)); | 2162 PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID)); |
2158 » sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); | 2163 sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); |
2159 | |
2160 } | 2164 } |
2161 if (!ss->opt.noCache && sid->cached == never_cached) | 2165 if (!ss->opt.noCache && sid->cached == never_cached) |
2162 » (*ss->sec.cache)(sid); | 2166 (*ss->sec.cache)(sid); |
2163 } | 2167 } |
2164 | 2168 |
2165 /* Called from ssl2_HandleMessage() */ | 2169 /* Called from ssl2_HandleMessage() */ |
2166 static SECStatus | 2170 static SECStatus |
2167 ssl2_TriggerNextMessage(sslSocket *ss) | 2171 ssl2_TriggerNextMessage(sslSocket *ss) |
2168 { | 2172 { |
2169 SECStatus rv; | 2173 SECStatus rv; |
2170 | 2174 |
2171 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2175 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2172 | 2176 |
2173 if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) && | 2177 if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) && |
2174 » !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) { | 2178 !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) { |
2175 » ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE; | 2179 ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE; |
2176 » rv = ssl2_SendCertificateRequestMessage(ss); | 2180 rv = ssl2_SendCertificateRequestMessage(ss); |
2177 » return rv; | 2181 return rv; |
2178 } | 2182 } |
2179 return SECSuccess; | 2183 return SECSuccess; |
2180 } | 2184 } |
2181 | 2185 |
2182 /* See if it's time to send our finished message, or if the handshakes are | 2186 /* See if it's time to send our finished message, or if the handshakes are |
2183 ** complete. Send finished message if appropriate. | 2187 ** complete. Send finished message if appropriate. |
2184 ** Returns SECSuccess unless anything goes wrong. | 2188 ** Returns SECSuccess unless anything goes wrong. |
2185 ** | 2189 ** |
2186 ** Called from ssl2_HandleMessage, | 2190 ** Called from ssl2_HandleMessage, |
2187 ** ssl2_HandleVerifyMessage | 2191 ** ssl2_HandleVerifyMessage |
2188 ** ssl2_HandleServerHelloMessage | 2192 ** ssl2_HandleServerHelloMessage |
2189 ** ssl2_HandleClientSessionKeyMessage | 2193 ** ssl2_HandleClientSessionKeyMessage |
2190 */ | 2194 */ |
2191 static SECStatus | 2195 static SECStatus |
2192 ssl2_TryToFinish(sslSocket *ss) | 2196 ssl2_TryToFinish(sslSocket *ss) |
2193 { | 2197 { |
2194 SECStatus rv; | 2198 SECStatus rv; |
2195 char e, ef; | 2199 char e, ef; |
2196 | 2200 |
2197 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2201 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2198 | 2202 |
2199 e = ss->sec.ci.elements; | 2203 e = ss->sec.ci.elements; |
2200 ef = e | CIS_HAVE_FINISHED; | 2204 ef = e | CIS_HAVE_FINISHED; |
2201 if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { | 2205 if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { |
2202 » if (ss->sec.isServer) { | 2206 if (ss->sec.isServer) { |
2203 » /* Send server finished message if we already didn't */ | 2207 /* Send server finished message if we already didn't */ |
2204 » rv = ssl2_SendServerFinishedMessage(ss); | 2208 rv = ssl2_SendServerFinishedMessage(ss); |
2205 » } else { | 2209 } else { |
2206 » /* Send client finished message if we already didn't */ | 2210 /* Send client finished message if we already didn't */ |
2207 » rv = ssl2_SendClientFinishedMessage(ss); | 2211 rv = ssl2_SendClientFinishedMessage(ss); |
2208 » } | 2212 } |
2209 » if (rv != SECSuccess) { | 2213 if (rv != SECSuccess) { |
2210 » return rv; | 2214 return rv; |
2211 » } | 2215 } |
2212 » if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { | 2216 if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { |
2213 » /* Totally finished */ | 2217 /* Totally finished */ |
2214 » ss->handshake = 0; | 2218 ss->handshake = 0; |
2215 » return SECSuccess; | 2219 return SECSuccess; |
2216 » } | 2220 } |
2217 } | 2221 } |
2218 return SECSuccess; | 2222 return SECSuccess; |
2219 } | 2223 } |
2220 | 2224 |
2221 /* | 2225 /* |
2222 ** Called from ssl2_HandleRequestCertificate | 2226 ** Called from ssl2_HandleRequestCertificate |
2223 */ | 2227 */ |
2224 static SECStatus | 2228 static SECStatus |
2225 ssl2_SignResponse(sslSocket *ss, | 2229 ssl2_SignResponse(sslSocket *ss, |
2226 » SECKEYPrivateKey *key, | 2230 SECKEYPrivateKey *key, |
2227 » SECItem *response) | 2231 SECItem *response) |
2228 { | 2232 { |
2229 SGNContext * sgn = NULL; | 2233 SGNContext *sgn = NULL; |
2230 PRUint8 * challenge; | 2234 PRUint8 *challenge; |
2231 unsigned int len; | 2235 unsigned int len; |
2232 SECStatus rv»» = SECFailure; | 2236 SECStatus rv = SECFailure; |
2233 | 2237 |
2234 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2238 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2235 | 2239 |
2236 challenge = ss->sec.ci.serverChallenge; | 2240 challenge = ss->sec.ci.serverChallenge; |
2237 len = ss->sec.ci.serverChallengeLen; | 2241 len = ss->sec.ci.serverChallengeLen; |
2238 | 2242 |
2239 /* Sign the expected data... */ | 2243 /* Sign the expected data... */ |
2240 sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key); | 2244 sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, key); |
2241 if (!sgn) | 2245 if (!sgn) |
2242 » goto done; | 2246 goto done; |
2243 rv = SGN_Begin(sgn); | 2247 rv = SGN_Begin(sgn); |
2244 if (rv != SECSuccess) | 2248 if (rv != SECSuccess) |
2245 » goto done; | 2249 goto done; |
2246 rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize); | 2250 rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize); |
2247 if (rv != SECSuccess) | 2251 if (rv != SECSuccess) |
2248 » goto done; | 2252 goto done; |
2249 rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize); | 2253 rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize); |
2250 if (rv != SECSuccess) | 2254 if (rv != SECSuccess) |
2251 » goto done; | 2255 goto done; |
2252 rv = SGN_Update(sgn, challenge, len); | 2256 rv = SGN_Update(sgn, challenge, len); |
2253 if (rv != SECSuccess) | 2257 if (rv != SECSuccess) |
2254 » goto done; | 2258 goto done; |
2255 rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, | 2259 rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, |
2256 ss->sec.peerCert->derCert.len); | 2260 ss->sec.peerCert->derCert.len); |
2257 if (rv != SECSuccess) | 2261 if (rv != SECSuccess) |
2258 » goto done; | 2262 goto done; |
2259 rv = SGN_End(sgn, response); | 2263 rv = SGN_End(sgn, response); |
2260 if (rv != SECSuccess) | 2264 if (rv != SECSuccess) |
2261 » goto done; | 2265 goto done; |
2262 | 2266 |
2263 done: | 2267 done: |
2264 SGN_DestroyContext(sgn, PR_TRUE); | 2268 SGN_DestroyContext(sgn, PR_TRUE); |
2265 return rv == SECSuccess ? SECSuccess : SECFailure; | 2269 return rv == SECSuccess ? SECSuccess : SECFailure; |
2266 } | 2270 } |
2267 | 2271 |
2268 /* | 2272 /* |
2269 ** Try to handle a request-certificate message. Get client's certificate | 2273 ** Try to handle a request-certificate message. Get client's certificate |
2270 ** and private key and sign a message for the server to see. | 2274 ** and private key and sign a message for the server to see. |
2271 ** Caller must hold handshakeLock | 2275 ** Caller must hold handshakeLock |
2272 ** | 2276 ** |
2273 ** Called from ssl2_HandleMessage(). | 2277 ** Called from ssl2_HandleMessage(). |
2274 */ | 2278 */ |
2275 static int | 2279 static int |
2276 ssl2_HandleRequestCertificate(sslSocket *ss) | 2280 ssl2_HandleRequestCertificate(sslSocket *ss) |
2277 { | 2281 { |
2278 CERTCertificate * cert» = NULL;»/* app-selected client cert. */ | 2282 CERTCertificate *cert = NULL; /* app-selected client cert. */ |
2279 SECKEYPrivateKey *key» = NULL;»/* priv key for cert. */ | 2283 SECKEYPrivateKey *key = NULL; /* priv key for cert. */ |
2280 SECStatus rv; | 2284 SECStatus rv; |
2281 SECItem response; | 2285 SECItem response; |
2282 int ret» = 0; | 2286 int ret = 0; |
2283 PRUint8 authType; | 2287 PRUint8 authType; |
2284 | |
2285 | 2288 |
2286 /* | 2289 /* |
2287 * These things all need to be initialized before we can "goto loser". | 2290 * These things all need to be initialized before we can "goto loser". |
2288 */ | 2291 */ |
2289 response.data = NULL; | 2292 response.data = NULL; |
2290 | 2293 |
2291 /* get challenge info from connectionInfo */ | 2294 /* get challenge info from connectionInfo */ |
2292 authType = ss->sec.ci.authType; | 2295 authType = ss->sec.ci.authType; |
2293 | 2296 |
2294 if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) { | 2297 if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) { |
2295 » SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(), | 2298 SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(), |
2296 » » ss->fd, authType)); | 2299 ss->fd, authType)); |
2297 » goto no_cert_error; | 2300 goto no_cert_error; |
2298 } | 2301 } |
2299 | 2302 |
2300 /* Get certificate and private-key from client */ | 2303 /* Get certificate and private-key from client */ |
2301 if (!ss->getClientAuthData) { | 2304 if (!ss->getClientAuthData) { |
2302 » SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth", | 2305 SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth", |
2303 » » SSL_GETPID(), ss->fd)); | 2306 SSL_GETPID(), ss->fd)); |
2304 » goto no_cert_error; | 2307 goto no_cert_error; |
2305 } | 2308 } |
2306 ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd, | 2309 ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd, |
2307 » » » » NULL, &cert, &key); | 2310 NULL, &cert, &key); |
2308 if ( ret == SECWouldBlock ) { | 2311 if (ret == SECWouldBlock) { |
2309 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 2312 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
2310 » ret = -1; | 2313 ret = -1; |
2311 » goto loser; | 2314 goto loser; |
2312 } | 2315 } |
2313 | 2316 |
2314 if (ret) { | 2317 if (ret) { |
2315 » goto no_cert_error; | 2318 goto no_cert_error; |
2316 } | 2319 } |
2317 | 2320 |
2318 /* check what the callback function returned */ | 2321 /* check what the callback function returned */ |
2319 if ((!cert) || (!key)) { | 2322 if ((!cert) || (!key)) { |
2320 /* we are missing either the key or cert */ | 2323 /* we are missing either the key or cert */ |
2321 if (cert) { | 2324 if (cert) { |
2322 /* got a cert, but no key - free it */ | 2325 /* got a cert, but no key - free it */ |
2323 CERT_DestroyCertificate(cert); | 2326 CERT_DestroyCertificate(cert); |
2324 cert = NULL; | 2327 cert = NULL; |
2325 } | 2328 } |
2326 if (key) { | 2329 if (key) { |
2327 /* got a key, but no cert - free it */ | 2330 /* got a key, but no cert - free it */ |
2328 SECKEY_DestroyPrivateKey(key); | 2331 SECKEY_DestroyPrivateKey(key); |
2329 key = NULL; | 2332 key = NULL; |
2330 } | 2333 } |
2331 goto no_cert_error; | 2334 goto no_cert_error; |
2332 } | 2335 } |
2333 | 2336 |
2334 rv = ssl2_SignResponse(ss, key, &response); | 2337 rv = ssl2_SignResponse(ss, key, &response); |
2335 if ( rv != SECSuccess ) { | 2338 if (rv != SECSuccess) { |
2336 » ret = -1; | 2339 ret = -1; |
2337 » goto loser; | 2340 goto loser; |
2338 } | 2341 } |
2339 | 2342 |
2340 /* Send response message */ | 2343 /* Send response message */ |
2341 ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response); | 2344 ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response); |
2342 | 2345 |
2343 /* Now, remember the cert we sent. But first, forget any previous one. */ | 2346 /* Now, remember the cert we sent. But first, forget any previous one. */ |
2344 if (ss->sec.localCert) { | 2347 if (ss->sec.localCert) { |
2345 » CERT_DestroyCertificate(ss->sec.localCert); | 2348 CERT_DestroyCertificate(ss->sec.localCert); |
2346 } | 2349 } |
2347 ss->sec.localCert = CERT_DupCertificate(cert); | 2350 ss->sec.localCert = CERT_DupCertificate(cert); |
2348 PORT_Assert(!ss->sec.ci.sid->localCert); | 2351 PORT_Assert(!ss->sec.ci.sid->localCert); |
2349 if (ss->sec.ci.sid->localCert) { | 2352 if (ss->sec.ci.sid->localCert) { |
2350 » CERT_DestroyCertificate(ss->sec.ci.sid->localCert); | 2353 CERT_DestroyCertificate(ss->sec.ci.sid->localCert); |
2351 } | 2354 } |
2352 ss->sec.ci.sid->localCert = cert; | 2355 ss->sec.ci.sid->localCert = cert; |
2353 cert = NULL; | 2356 cert = NULL; |
2354 | 2357 |
2355 goto done; | 2358 goto done; |
2356 | 2359 |
2357 no_cert_error: | 2360 no_cert_error: |
2358 SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(), | 2361 SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(), |
2359 » » ss->fd, ret)); | 2362 ss->fd, ret)); |
2360 ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE); | 2363 ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE); |
2361 | 2364 |
2362 loser: | 2365 loser: |
2363 done: | 2366 done: |
2364 if ( cert ) { | 2367 if (cert) { |
2365 » CERT_DestroyCertificate(cert); | 2368 CERT_DestroyCertificate(cert); |
2366 } | 2369 } |
2367 if ( key ) { | 2370 if (key) { |
2368 » SECKEY_DestroyPrivateKey(key); | 2371 SECKEY_DestroyPrivateKey(key); |
2369 } | 2372 } |
2370 if ( response.data ) { | 2373 if (response.data) { |
2371 » PORT_Free(response.data); | 2374 PORT_Free(response.data); |
2372 } | 2375 } |
2373 | 2376 |
2374 return ret; | 2377 return ret; |
2375 } | 2378 } |
2376 | 2379 |
2377 /* | 2380 /* |
2378 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message. | 2381 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message. |
2379 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response | 2382 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response |
2380 ** are contained in the gathered input data. | 2383 ** are contained in the gathered input data. |
2381 */ | 2384 */ |
2382 static SECStatus | 2385 static SECStatus |
2383 ssl2_HandleClientCertificate(sslSocket * ss, | 2386 ssl2_HandleClientCertificate(sslSocket *ss, |
2384 PRUint8 certType,» /* XXX unused */ | 2387 PRUint8 certType, /* XXX unused */ |
2385 » » » PRUint8 * cd, | 2388 PRUint8 *cd, |
2386 » » » unsigned int cdLen, | 2389 unsigned int cdLen, |
2387 » » » PRUint8 * response, | 2390 PRUint8 *response, |
2388 » » » unsigned int responseLen) | 2391 unsigned int responseLen) |
2389 { | 2392 { |
2390 CERTCertificate *cert» = NULL; | 2393 CERTCertificate *cert = NULL; |
2391 SECKEYPublicKey *pubKey» = NULL; | 2394 SECKEYPublicKey *pubKey = NULL; |
2392 VFYContext * vfy» = NULL; | 2395 VFYContext *vfy = NULL; |
2393 SECItem * derCert; | 2396 SECItem *derCert; |
2394 SECStatus rv»» = SECFailure; | 2397 SECStatus rv = SECFailure; |
2395 SECItem certItem; | 2398 SECItem certItem; |
2396 SECItem rep; | 2399 SECItem rep; |
2397 | 2400 |
2398 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2401 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2399 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 2402 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
2400 | 2403 |
2401 /* Extract the certificate */ | 2404 /* Extract the certificate */ |
2402 certItem.data = cd; | 2405 certItem.data = cd; |
2403 certItem.len = cdLen; | 2406 certItem.len = cdLen; |
2404 | 2407 |
2405 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | 2408 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
2406 » » » » PR_FALSE, PR_TRUE); | 2409 PR_FALSE, PR_TRUE); |
2407 if (cert == NULL) { | 2410 if (cert == NULL) { |
2408 » goto loser; | 2411 goto loser; |
2409 } | 2412 } |
2410 | 2413 |
2411 /* save the certificate, since the auth routine will need it */ | 2414 /* save the certificate, since the auth routine will need it */ |
2412 ss->sec.peerCert = cert; | 2415 ss->sec.peerCert = cert; |
2413 | 2416 |
2414 /* Extract the public key */ | 2417 /* Extract the public key */ |
2415 pubKey = CERT_ExtractPublicKey(cert); | 2418 pubKey = CERT_ExtractPublicKey(cert); |
2416 if (!pubKey) | 2419 if (!pubKey) |
2417 » goto loser; | 2420 goto loser; |
2418 | 2421 |
2419 /* Verify the response data... */ | 2422 /* Verify the response data... */ |
2420 rep.data = response; | 2423 rep.data = response; |
2421 rep.len = responseLen; | 2424 rep.len = responseLen; |
2422 /* SSL 2.0 only supports RSA certs, so we don't have to worry about | 2425 /* SSL 2.0 only supports RSA certs, so we don't have to worry about |
2423 * DSA here. */ | 2426 * DSA here. */ |
2424 vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION, | 2427 vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION, |
2425 » » » ss->pkcs11PinArg); | 2428 ss->pkcs11PinArg); |
2426 if (!vfy) | 2429 if (!vfy) |
2427 » goto loser; | 2430 goto loser; |
2428 rv = VFY_Begin(vfy); | 2431 rv = VFY_Begin(vfy); |
2429 if (rv) | 2432 if (rv) |
2430 » goto loser; | 2433 goto loser; |
2431 | 2434 |
2432 rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize); | 2435 rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize); |
2433 if (rv) | 2436 if (rv) |
2434 » goto loser; | 2437 goto loser; |
2435 rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize); | 2438 rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize); |
2436 if (rv) | 2439 if (rv) |
2437 » goto loser; | 2440 goto loser; |
2438 rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); | 2441 rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); |
2439 if (rv) | 2442 if (rv) |
2440 » goto loser; | 2443 goto loser; |
2441 | 2444 |
2442 derCert = &ss->serverCerts[kt_rsa].serverCert->derCert; | 2445 derCert = &ss->serverCerts[kt_rsa].serverCert->derCert; |
2443 rv = VFY_Update(vfy, derCert->data, derCert->len); | 2446 rv = VFY_Update(vfy, derCert->data, derCert->len); |
2444 if (rv) | 2447 if (rv) |
2445 » goto loser; | 2448 goto loser; |
2446 rv = VFY_End(vfy); | 2449 rv = VFY_End(vfy); |
2447 if (rv) | 2450 if (rv) |
2448 » goto loser; | 2451 goto loser; |
2449 | 2452 |
2450 /* Now ask the server application if it likes the certificate... */ | 2453 /* Now ask the server application if it likes the certificate... */ |
2451 rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg, | 2454 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, |
2452 » » » » » ss->fd, PR_TRUE, PR_TRUE); | 2455 ss->fd, PR_TRUE, PR_TRUE); |
2453 /* Hey, it liked it. */ | 2456 /* Hey, it liked it. */ |
2454 if (SECSuccess == rv) | 2457 if (SECSuccess == rv) |
2455 » goto done; | 2458 goto done; |
2456 | 2459 |
2457 loser: | 2460 loser: |
2458 ss->sec.peerCert = NULL; | 2461 ss->sec.peerCert = NULL; |
2459 CERT_DestroyCertificate(cert); | 2462 CERT_DestroyCertificate(cert); |
2460 | 2463 |
2461 done: | 2464 done: |
2462 VFY_DestroyContext(vfy, PR_TRUE); | 2465 VFY_DestroyContext(vfy, PR_TRUE); |
2463 SECKEY_DestroyPublicKey(pubKey); | 2466 SECKEY_DestroyPublicKey(pubKey); |
2464 return rv; | 2467 return rv; |
2465 } | 2468 } |
2466 | 2469 |
2467 /* | 2470 /* |
2468 ** Handle remaining messages between client/server. Process finished | 2471 ** Handle remaining messages between client/server. Process finished |
2469 ** messages from either side and any authentication requests. | 2472 ** messages from either side and any authentication requests. |
2470 ** This should only be called for SSLv2 handshake messages, | 2473 ** This should only be called for SSLv2 handshake messages, |
2471 ** not for application data records. | 2474 ** not for application data records. |
2472 ** Caller must hold handshake lock. | 2475 ** Caller must hold handshake lock. |
2473 ** | 2476 ** |
2474 ** Called from ssl_Do1stHandshake(). | 2477 ** Called from ssl_Do1stHandshake(). |
2475 ** | 2478 ** |
2476 */ | 2479 */ |
2477 static SECStatus | 2480 static SECStatus |
2478 ssl2_HandleMessage(sslSocket *ss) | 2481 ssl2_HandleMessage(sslSocket *ss) |
2479 { | 2482 { |
2480 PRUint8 * data; | 2483 PRUint8 *data; |
2481 PRUint8 * cid; | 2484 PRUint8 *cid; |
2482 unsigned len, certType, certLen, responseLen; | 2485 unsigned len, certType, certLen, responseLen; |
2483 int rv; | 2486 int rv; |
2484 | 2487 |
2485 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2488 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2486 | 2489 |
2487 ssl_GetRecvBufLock(ss); | 2490 ssl_GetRecvBufLock(ss); |
2488 | 2491 |
2489 data = ss->gs.buf.buf + ss->gs.recordOffset; | 2492 data = ss->gs.buf.buf + ss->gs.recordOffset; |
2490 | 2493 |
2491 if (ss->gs.recordLen < 1) { | 2494 if (ss->gs.recordLen < 1) { |
2492 » goto bad_peer; | 2495 goto bad_peer; |
2493 } | 2496 } |
2494 SSL_TRC(3, ("%d: SSL[%d]: received %d message", | 2497 SSL_TRC(3, ("%d: SSL[%d]: received %d message", |
2495 » » SSL_GETPID(), ss->fd, data[0])); | 2498 SSL_GETPID(), ss->fd, data[0])); |
2496 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); | 2499 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
2497 | 2500 |
2498 switch (data[0]) { | 2501 switch (data[0]) { |
2499 case SSL_MT_CLIENT_FINISHED: | 2502 case SSL_MT_CLIENT_FINISHED: |
2500 » if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { | 2503 if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { |
2501 » SSL_DBG(("%d: SSL[%d]: dup client-finished message", | 2504 SSL_DBG(("%d: SSL[%d]: dup client-finished message", |
2502 » » SSL_GETPID(), ss->fd)); | 2505 SSL_GETPID(), ss->fd)); |
2503 » goto bad_peer; | 2506 goto bad_peer; |
2504 » } | 2507 } |
2505 | 2508 |
2506 » /* See if nonce matches */ | 2509 /* See if nonce matches */ |
2507 » len = ss->gs.recordLen - 1; | 2510 len = ss->gs.recordLen - 1; |
2508 » cid = data + 1; | 2511 cid = data + 1; |
2509 » if ((len != sizeof(ss->sec.ci.connectionID)) || | 2512 if ((len != sizeof(ss->sec.ci.connectionID)) || |
2510 » (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) { | 2513 (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) { |
2511 » SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd)); | 2514 SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd)
); |
2512 » PRINT_BUF(5, (ss, "sent connection-id", | 2515 PRINT_BUF(5, (ss, "sent connection-id", |
2513 » » » ss->sec.ci.connectionID, | 2516 ss->sec.ci.connectionID, |
2514 » » » sizeof(ss->sec.ci.connectionID))); | 2517 sizeof(ss->sec.ci.connectionID))); |
2515 » PRINT_BUF(5, (ss, "rcvd connection-id", cid, len)); | 2518 PRINT_BUF(5, (ss, "rcvd connection-id", cid, len)); |
2516 » goto bad_peer; | 2519 goto bad_peer; |
2517 » } | 2520 } |
2518 | 2521 |
2519 » SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d", | 2522 SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d", |
2520 » » SSL_GETPID(), ss->fd, | 2523 SSL_GETPID(), ss->fd, |
2521 » » ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); | 2524 ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); |
2522 » ss->sec.ci.elements |= CIS_HAVE_FINISHED; | 2525 ss->sec.ci.elements |= CIS_HAVE_FINISHED; |
2523 » break; | 2526 break; |
2524 | 2527 |
2525 case SSL_MT_SERVER_FINISHED: | 2528 case SSL_MT_SERVER_FINISHED: |
2526 » if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { | 2529 if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { |
2527 » SSL_DBG(("%d: SSL[%d]: dup server-finished message", | 2530 SSL_DBG(("%d: SSL[%d]: dup server-finished message", |
2528 » » SSL_GETPID(), ss->fd)); | 2531 SSL_GETPID(), ss->fd)); |
2529 » goto bad_peer; | 2532 goto bad_peer; |
2530 » } | 2533 } |
2531 | 2534 |
2532 » if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) { | 2535 if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) { |
2533 » SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d", | 2536 SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d", |
2534 » » SSL_GETPID(), ss->fd, ss->gs.recordLen)); | 2537 SSL_GETPID(), ss->fd, ss->gs.recordLen)); |
2535 » goto bad_peer; | 2538 goto bad_peer; |
2536 » } | 2539 } |
2537 » ssl2_ClientRegSessionID(ss, data+1); | 2540 ssl2_ClientRegSessionID(ss, data + 1); |
2538 » SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d", | 2541 SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d", |
2539 » » SSL_GETPID(), ss->fd, | 2542 SSL_GETPID(), ss->fd, |
2540 » » ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); | 2543 ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); |
2541 » ss->sec.ci.elements |= CIS_HAVE_FINISHED; | 2544 ss->sec.ci.elements |= CIS_HAVE_FINISHED; |
2542 » break; | 2545 break; |
2543 | 2546 |
2544 case SSL_MT_REQUEST_CERTIFICATE: | 2547 case SSL_MT_REQUEST_CERTIFICATE: |
2545 » len = ss->gs.recordLen - 2; | 2548 len = ss->gs.recordLen - 2; |
2546 » if ((len < SSL_MIN_CHALLENGE_BYTES) || | 2549 if ((len < SSL_MIN_CHALLENGE_BYTES) || |
2547 » (len > SSL_MAX_CHALLENGE_BYTES)) { | 2550 (len > SSL_MAX_CHALLENGE_BYTES)) { |
2548 » /* Bad challenge */ | 2551 /* Bad challenge */ |
2549 » SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d", | 2552 SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d", |
2550 » » SSL_GETPID(), ss->fd, len)); | 2553 SSL_GETPID(), ss->fd, len)); |
2551 » goto bad_peer; | 2554 goto bad_peer; |
2552 » } | 2555 } |
2553 » | 2556 |
2554 » /* save auth request info */ | 2557 /* save auth request info */ |
2555 » ss->sec.ci.authType = data[1]; | 2558 ss->sec.ci.authType = data[1]; |
2556 » ss->sec.ci.serverChallengeLen = len; | 2559 ss->sec.ci.serverChallengeLen = len; |
2557 » PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len); | 2560 PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len); |
2558 » | 2561 |
2559 » rv = ssl2_HandleRequestCertificate(ss); | 2562 rv = ssl2_HandleRequestCertificate(ss); |
2560 » if (rv == SECWouldBlock) { | 2563 if (rv == SECWouldBlock) { |
2561 » SSL_TRC(3, ("%d: SSL[%d]: async cert request", | 2564 SSL_TRC(3, ("%d: SSL[%d]: async cert request", |
2562 » » » SSL_GETPID(), ss->fd)); | 2565 SSL_GETPID(), ss->fd)); |
2563 » /* someone is handling this asynchronously */ | 2566 /* someone is handling this asynchronously */ |
2564 » ssl_ReleaseRecvBufLock(ss); | 2567 ssl_ReleaseRecvBufLock(ss); |
2565 » return SECWouldBlock; | 2568 return SECWouldBlock; |
2566 » } | 2569 } |
2567 » if (rv) { | 2570 if (rv) { |
2568 » SET_ERROR_CODE | 2571 SET_ERROR_CODE |
2569 » goto loser; | 2572 goto loser; |
2570 » } | 2573 } |
2571 » break; | 2574 break; |
2572 | 2575 |
2573 case SSL_MT_CLIENT_CERTIFICATE: | 2576 case SSL_MT_CLIENT_CERTIFICATE: |
2574 » if (!ss->authCertificate) { | 2577 if (!ss->authCertificate) { |
2575 » /* Server asked for authentication and can't handle it */ | 2578 /* Server asked for authentication and can't handle it */ |
2576 » PORT_SetError(SSL_ERROR_BAD_SERVER); | 2579 PORT_SetError(SSL_ERROR_BAD_SERVER); |
2577 » goto loser; | 2580 goto loser; |
2578 » } | 2581 } |
2579 » if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) { | 2582 if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) { |
2580 » SET_ERROR_CODE | 2583 SET_ERROR_CODE |
2581 » goto loser; | 2584 goto loser; |
2582 » } | 2585 } |
2583 » certType = data[1]; | 2586 certType = data[1]; |
2584 » certLen = (data[2] << 8) | data[3]; | 2587 certLen = (data[2] << 8) | data[3]; |
2585 » responseLen = (data[4] << 8) | data[5]; | 2588 responseLen = (data[4] << 8) | data[5]; |
2586 » if (certType != SSL_CT_X509_CERTIFICATE) { | 2589 if (certType != SSL_CT_X509_CERTIFICATE) { |
2587 » PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); | 2590 PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); |
2588 » goto loser; | 2591 goto loser; |
2589 » } | 2592 } |
2590 » if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES | 2593 if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES > |
2591 » > ss->gs.recordLen) { | 2594 ss->gs.recordLen) { |
2592 » /* prevent overflow crash. */ | 2595 /* prevent overflow crash. */ |
2593 » rv = SECFailure; | 2596 rv = SECFailure; |
2594 » } else | 2597 } else |
2595 » rv = ssl2_HandleClientCertificate(ss, data[1], | 2598 rv = ssl2_HandleClientCertificate(ss, data[1], |
2596 » » data + SSL_HL_CLIENT_CERTIFICATE_HBYTES, | 2599 data + SSL_HL_CLIENT_CERTIFICA
TE_HBYTES, |
2597 » » certLen, | 2600 certLen, |
2598 » » data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen, | 2601 data + SSL_HL_CLIENT_CERTIFICA
TE_HBYTES + certLen, |
2599 » » responseLen); | 2602 responseLen); |
2600 » if (rv) { | 2603 if (rv) { |
2601 » (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); | 2604 (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); |
2602 » SET_ERROR_CODE | 2605 SET_ERROR_CODE |
2603 » goto loser; | 2606 goto loser; |
2604 » } | 2607 } |
2605 » ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE; | 2608 ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE; |
2606 » break; | 2609 break; |
2607 | 2610 |
2608 case SSL_MT_ERROR: | 2611 case SSL_MT_ERROR: |
2609 » rv = (data[1] << 8) | data[2]; | 2612 rv = (data[1] << 8) | data[2]; |
2610 » SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x", | 2613 SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x", |
2611 » » SSL_GETPID(), ss->fd, rv)); | 2614 SSL_GETPID(), ss->fd, rv)); |
2612 | 2615 |
2613 » /* Convert protocol error number into API error number */ | 2616 /* Convert protocol error number into API error number */ |
2614 » switch (rv) { | 2617 switch (rv) { |
2615 » case SSL_PE_NO_CYPHERS: | 2618 case SSL_PE_NO_CYPHERS: |
2616 » rv = SSL_ERROR_NO_CYPHER_OVERLAP; | 2619 rv = SSL_ERROR_NO_CYPHER_OVERLAP; |
2617 » break; | 2620 break; |
2618 » case SSL_PE_NO_CERTIFICATE: | 2621 case SSL_PE_NO_CERTIFICATE: |
2619 » rv = SSL_ERROR_NO_CERTIFICATE; | 2622 rv = SSL_ERROR_NO_CERTIFICATE; |
2620 » break; | 2623 break; |
2621 » case SSL_PE_BAD_CERTIFICATE: | 2624 case SSL_PE_BAD_CERTIFICATE: |
2622 » rv = SSL_ERROR_BAD_CERTIFICATE; | 2625 rv = SSL_ERROR_BAD_CERTIFICATE; |
2623 » break; | 2626 break; |
2624 » case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE: | 2627 case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE: |
2625 » rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; | 2628 rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; |
2626 » break; | 2629 break; |
2627 » default: | 2630 default: |
2628 » goto bad_peer; | 2631 goto bad_peer; |
2629 » } | 2632 } |
2630 » /* XXX make certificate-request optionally fail... */ | 2633 /* XXX make certificate-request optionally fail... */ |
2631 » PORT_SetError(rv); | 2634 PORT_SetError(rv); |
2632 » goto loser; | 2635 goto loser; |
2633 | 2636 |
2634 default: | 2637 default: |
2635 » SSL_DBG(("%d: SSL[%d]: unknown message %d", | 2638 SSL_DBG(("%d: SSL[%d]: unknown message %d", |
2636 » » SSL_GETPID(), ss->fd, data[0])); | 2639 SSL_GETPID(), ss->fd, data[0])); |
2637 » goto loser; | 2640 goto loser; |
2638 } | 2641 } |
2639 | 2642 |
2640 SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x", | 2643 SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x", |
2641 » » SSL_GETPID(), ss->fd, data[0], | 2644 SSL_GETPID(), ss->fd, data[0], |
2642 » » ss->sec.ci.requiredElements, ss->sec.ci.elements)); | 2645 ss->sec.ci.requiredElements, ss->sec.ci.elements)); |
2643 | 2646 |
2644 rv = ssl2_TryToFinish(ss); | 2647 rv = ssl2_TryToFinish(ss); |
2645 if (rv != SECSuccess) | 2648 if (rv != SECSuccess) |
2646 » goto loser; | 2649 goto loser; |
2647 | 2650 |
2648 ss->gs.recordLen = 0; | 2651 ss->gs.recordLen = 0; |
2649 ssl_ReleaseRecvBufLock(ss); | 2652 ssl_ReleaseRecvBufLock(ss); |
2650 | 2653 |
2651 if (ss->handshake == 0) { | 2654 if (ss->handshake == 0) { |
2652 » return SECSuccess; | 2655 return SECSuccess; |
2653 } | 2656 } |
2654 | 2657 |
2655 ss->handshake = ssl_GatherRecord1stHandshake; | 2658 ss->handshake = ssl_GatherRecord1stHandshake; |
2656 ss->nextHandshake = ssl2_HandleMessage; | 2659 ss->nextHandshake = ssl2_HandleMessage; |
2657 return ssl2_TriggerNextMessage(ss); | 2660 return ssl2_TriggerNextMessage(ss); |
2658 | 2661 |
2659 bad_peer: | 2662 bad_peer: |
2660 PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER
); | 2663 PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER
); |
2661 /* FALL THROUGH */ | 2664 /* FALL THROUGH */ |
2662 | 2665 |
2663 loser: | 2666 loser: |
2664 ssl_ReleaseRecvBufLock(ss); | 2667 ssl_ReleaseRecvBufLock(ss); |
2665 return SECFailure; | 2668 return SECFailure; |
2666 } | 2669 } |
2667 | 2670 |
2668 /************************************************************************/ | 2671 /************************************************************************/ |
2669 | 2672 |
2670 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage. | 2673 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage. |
2671 */ | 2674 */ |
2672 static SECStatus | 2675 static SECStatus |
2673 ssl2_HandleVerifyMessage(sslSocket *ss) | 2676 ssl2_HandleVerifyMessage(sslSocket *ss) |
2674 { | 2677 { |
2675 PRUint8 * data; | 2678 PRUint8 *data; |
2676 SECStatus rv; | 2679 SECStatus rv; |
2677 | 2680 |
2678 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2681 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2679 ssl_GetRecvBufLock(ss); | 2682 ssl_GetRecvBufLock(ss); |
2680 | 2683 |
2681 data = ss->gs.buf.buf + ss->gs.recordOffset; | 2684 data = ss->gs.buf.buf + ss->gs.recordOffset; |
2682 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); | 2685 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
2683 if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || | 2686 if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || |
2684 » (data[0] != SSL_MT_SERVER_VERIFY) || | 2687 (data[0] != SSL_MT_SERVER_VERIFY) || |
2685 » NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge, | 2688 NSS_SecureMemcmp(data + 1, ss->sec.ci.clientChallenge, |
2686 » SSL_CHALLENGE_BYTES)) { | 2689 SSL_CHALLENGE_BYTES)) { |
2687 » /* Bad server */ | 2690 /* Bad server */ |
2688 » PORT_SetError(SSL_ERROR_BAD_SERVER); | 2691 PORT_SetError(SSL_ERROR_BAD_SERVER); |
2689 » goto loser; | 2692 goto loser; |
2690 } | 2693 } |
2691 ss->sec.ci.elements |= CIS_HAVE_VERIFY; | 2694 ss->sec.ci.elements |= CIS_HAVE_VERIFY; |
2692 | 2695 |
2693 SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x", | 2696 SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x", |
2694 » » SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, | 2697 SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, |
2695 » » ss->sec.ci.elements)); | 2698 ss->sec.ci.elements)); |
2696 | 2699 |
2697 rv = ssl2_TryToFinish(ss); | 2700 rv = ssl2_TryToFinish(ss); |
2698 if (rv) | 2701 if (rv) |
2699 » goto loser; | 2702 goto loser; |
2700 | 2703 |
2701 ss->gs.recordLen = 0; | 2704 ss->gs.recordLen = 0; |
2702 ssl_ReleaseRecvBufLock(ss); | 2705 ssl_ReleaseRecvBufLock(ss); |
2703 | 2706 |
2704 if (ss->handshake == 0) { | 2707 if (ss->handshake == 0) { |
2705 » return SECSuccess; | 2708 return SECSuccess; |
2706 } | 2709 } |
2707 ss->handshake = ssl_GatherRecord1stHandshake; | 2710 ss->handshake = ssl_GatherRecord1stHandshake; |
2708 ss->nextHandshake = ssl2_HandleMessage; | 2711 ss->nextHandshake = ssl2_HandleMessage; |
2709 return SECSuccess; | 2712 return SECSuccess; |
2710 | 2713 |
2711 | 2714 loser: |
2712 loser: | |
2713 ssl_ReleaseRecvBufLock(ss); | 2715 ssl_ReleaseRecvBufLock(ss); |
2714 return SECFailure; | 2716 return SECFailure; |
2715 } | 2717 } |
2716 | 2718 |
2717 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value. | 2719 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value. |
2718 * ICK! | 2720 * ICK! |
2719 * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake() | 2721 * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake() |
2720 */ | 2722 */ |
2721 SECStatus | 2723 SECStatus |
2722 ssl2_HandleServerHelloMessage(sslSocket *ss) | 2724 ssl2_HandleServerHelloMessage(sslSocket *ss) |
2723 { | 2725 { |
2724 sslSessionID * sid; | 2726 sslSessionID *sid; |
2725 PRUint8 * cert; | 2727 PRUint8 *cert; |
2726 PRUint8 * cs; | 2728 PRUint8 *cs; |
2727 PRUint8 * data; | 2729 PRUint8 *data; |
2728 SECStatus rv; | 2730 SECStatus rv; |
2729 unsigned int needed, sidHit, certLen, csLen, cidLen, certType, err; | 2731 unsigned int needed, sidHit, certLen, csLen, cidLen, certType, err; |
2730 | 2732 |
2731 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2733 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2732 | 2734 |
2733 if (!ss->opt.enableSSL2) { | 2735 if (!ss->opt.enableSSL2) { |
2734 » PORT_SetError(SSL_ERROR_SSL2_DISABLED); | 2736 PORT_SetError(SSL_ERROR_SSL2_DISABLED); |
2735 » return SECFailure; | 2737 return SECFailure; |
2736 } | 2738 } |
2737 | 2739 |
2738 ssl_GetRecvBufLock(ss); | 2740 ssl_GetRecvBufLock(ss); |
2739 | 2741 |
2740 PORT_Assert(ss->sec.ci.sid != 0); | 2742 PORT_Assert(ss->sec.ci.sid != 0); |
2741 sid = ss->sec.ci.sid; | 2743 sid = ss->sec.ci.sid; |
2742 | 2744 |
2743 data = ss->gs.buf.buf + ss->gs.recordOffset; | 2745 data = ss->gs.buf.buf + ss->gs.recordOffset; |
2744 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); | 2746 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
2745 | 2747 |
2746 /* Make sure first message has some data and is the server hello message */ | 2748 /* Make sure first message has some data and is the server hello message */ |
2747 if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES) | 2749 if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES) || |
2748 » || (data[0] != SSL_MT_SERVER_HELLO)) { | 2750 (data[0] != SSL_MT_SERVER_HELLO)) { |
2749 » if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) { | 2751 if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) { |
2750 » err = (data[1] << 8) | data[2]; | 2752 err = (data[1] << 8) | data[2]; |
2751 » if (err == SSL_PE_NO_CYPHERS) { | 2753 if (err == SSL_PE_NO_CYPHERS) { |
2752 » » PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 2754 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
2753 » » goto loser; | 2755 goto loser; |
2754 » } | 2756 } |
2755 » } | 2757 } |
2756 » goto bad_server; | 2758 goto bad_server; |
2757 } | 2759 } |
2758 | 2760 |
2759 sidHit = data[1]; | 2761 sidHit = data[1]; |
2760 certType = data[2]; | 2762 certType = data[2]; |
2761 ss->version = (data[3] << 8) | data[4]; | 2763 ss->version = (data[3] << 8) | data[4]; |
2762 certLen = (data[5] << 8) | data[6]; | 2764 certLen = (data[5] << 8) | data[6]; |
2763 csLen = (data[7] << 8) | data[8]; | 2765 csLen = (data[7] << 8) | data[8]; |
2764 cidLen = (data[9] << 8) | data[10]; | 2766 cidLen = (data[9] << 8) | data[10]; |
2765 cert = data + SSL_HL_SERVER_HELLO_HBYTES; | 2767 cert = data + SSL_HL_SERVER_HELLO_HBYTES; |
2766 cs = cert + certLen; | 2768 cs = cert + certLen; |
2767 | 2769 |
2768 SSL_TRC(5, | 2770 SSL_TRC(5, |
2769 » ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidL
en=%d", | 2771 ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidL
en=%d", |
2770 » SSL_GETPID(), ss->fd, sidHit, ss->version, certLen, | 2772 SSL_GETPID(), ss->fd, sidHit, ss->version, certLen, |
2771 » csLen, cidLen)); | 2773 csLen, cidLen)); |
2772 if (ss->version != SSL_LIBRARY_VERSION_2) { | 2774 if (ss->version != SSL_LIBRARY_VERSION_2) { |
2773 if (ss->version < SSL_LIBRARY_VERSION_2) { | 2775 if (ss->version < SSL_LIBRARY_VERSION_2) { |
2774 » SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)", | 2776 SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)"
, |
2775 » » SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2, | 2777 SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2, |
2776 » » ss->version)); | 2778 ss->version)); |
2777 » } else { | 2779 } else { |
2778 » SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)", | 2780 SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)", |
2779 » » SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2)); | 2781 SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2
)); |
2780 » /* server claims to be newer but does not follow protocol */ | 2782 /* server claims to be newer but does not follow protocol */ |
2781 » PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); | 2783 PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); |
2782 » goto loser; | 2784 goto loser; |
2783 » } | 2785 } |
2784 } | 2786 } |
2785 | 2787 |
2786 if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen | 2788 if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen > |
2787 > ss->gs.recordLen) | 2789 ss->gs.recordLen) || |
2788 » || (csLen % 3) != 0 | 2790 (csLen % 3) != 0 |
2789 » /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32 */ | 2791 /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32 */ |
2790 » ) { | 2792 ) { |
2791 » goto bad_server; | 2793 goto bad_server; |
2792 } | 2794 } |
2793 | 2795 |
2794 /* Save connection-id. | 2796 /* Save connection-id. |
2795 ** This code only saves the first 16 byte of the connectionID. | 2797 ** This code only saves the first 16 byte of the connectionID. |
2796 ** If the connectionID is shorter than 16 bytes, it is zero-padded. | 2798 ** If the connectionID is shorter than 16 bytes, it is zero-padded. |
2797 */ | 2799 */ |
2798 if (cidLen < sizeof ss->sec.ci.connectionID) | 2800 if (cidLen < sizeof ss->sec.ci.connectionID) |
2799 » memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID); | 2801 memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID); |
2800 cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID); | 2802 cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID); |
2801 PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen); | 2803 PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen); |
2802 | 2804 |
2803 /* See if session-id hit */ | 2805 /* See if session-id hit */ |
2804 needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY; | 2806 needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY; |
2805 if (sidHit) { | 2807 if (sidHit) { |
2806 » if (certLen || csLen) { | 2808 if (certLen || csLen) { |
2807 » /* Uh oh - bogus server */ | 2809 /* Uh oh - bogus server */ |
2808 » SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d", | 2810 SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d", |
2809 » » SSL_GETPID(), ss->fd, sidHit, certLen, csLen)); | 2811 SSL_GETPID(), ss->fd, sidHit, certLen, csLen)); |
2810 » goto bad_server; | 2812 goto bad_server; |
2811 » } | 2813 } |
2812 | 2814 |
2813 » /* Total winner. */ | 2815 /* Total winner. */ |
2814 » SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x " | 2816 SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x " |
2815 » » "port=0x%04x", | 2817 "port=0x%04x", |
2816 » » SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port)); | 2818 SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port)); |
2817 » ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); | 2819 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
2818 ss->sec.authAlgorithm = sid->authAlgorithm; | 2820 ss->sec.authAlgorithm = sid->authAlgorithm; |
2819 » ss->sec.authKeyBits = sid->authKeyBits; | 2821 ss->sec.authKeyBits = sid->authKeyBits; |
2820 » ss->sec.keaType = sid->keaType; | 2822 ss->sec.keaType = sid->keaType; |
2821 » ss->sec.keaKeyBits = sid->keaKeyBits; | 2823 ss->sec.keaKeyBits = sid->keaKeyBits; |
2822 » rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); | 2824 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); |
2823 » if (rv != SECSuccess) { | 2825 if (rv != SECSuccess) { |
2824 » goto loser; | 2826 goto loser; |
2825 » } | 2827 } |
2826 } else { | 2828 } else { |
2827 » if (certType != SSL_CT_X509_CERTIFICATE) { | 2829 if (certType != SSL_CT_X509_CERTIFICATE) { |
2828 » PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); | 2830 PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); |
2829 » goto loser; | 2831 goto loser; |
2830 » } | 2832 } |
2831 » if (csLen == 0) { | 2833 if (csLen == 0) { |
2832 » PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 2834 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
2833 » SSL_DBG(("%d: SSL[%d]: no cipher overlap", | 2835 SSL_DBG(("%d: SSL[%d]: no cipher overlap", |
2834 » » SSL_GETPID(), ss->fd)); | 2836 SSL_GETPID(), ss->fd)); |
2835 » goto loser; | 2837 goto loser; |
2836 » } | 2838 } |
2837 » if (certLen == 0) { | 2839 if (certLen == 0) { |
2838 » SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d", | 2840 SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d", |
2839 » » SSL_GETPID(), ss->fd, certLen, csLen)); | 2841 SSL_GETPID(), ss->fd, certLen, csLen)); |
2840 » goto bad_server; | 2842 goto bad_server; |
2841 » } | 2843 } |
2842 | 2844 |
2843 » if (sid->cached != never_cached) { | 2845 if (sid->cached != never_cached) { |
2844 » /* Forget our session-id - server didn't like it */ | 2846 /* Forget our session-id - server didn't like it */ |
2845 » SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id", | 2847 SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id", |
2846 » » » SSL_GETPID(), ss->fd)); | 2848 SSL_GETPID(), ss->fd)); |
2847 » if (ss->sec.uncache) | 2849 if (ss->sec.uncache) |
2848 » » (*ss->sec.uncache)(sid); | 2850 (*ss->sec.uncache)(sid); |
2849 » ssl_FreeSID(sid); | 2851 ssl_FreeSID(sid); |
2850 » ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID); | 2852 ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID); |
2851 » if (!sid) { | 2853 if (!sid) { |
2852 » » goto loser; | 2854 goto loser; |
2853 » } | 2855 } |
2854 » sid->references = 1; | 2856 sid->references = 1; |
2855 » sid->addr = ss->sec.ci.peer; | 2857 sid->addr = ss->sec.ci.peer; |
2856 » sid->port = ss->sec.ci.port; | 2858 sid->port = ss->sec.ci.port; |
2857 » } | 2859 } |
2858 | 2860 |
2859 » /* decode the server's certificate */ | 2861 /* decode the server's certificate */ |
2860 » rv = ssl2_ClientHandleServerCert(ss, cert, certLen); | 2862 rv = ssl2_ClientHandleServerCert(ss, cert, certLen); |
2861 » if (rv != SECSuccess) { | 2863 if (rv != SECSuccess) { |
2862 » if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { | 2864 if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { |
2863 » » (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); | 2865 (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); |
2864 » } | 2866 } |
2865 » goto loser; | 2867 goto loser; |
2866 » } | 2868 } |
2867 | 2869 |
2868 » /* Setup new session cipher */ | 2870 /* Setup new session cipher */ |
2869 » rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen); | 2871 rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen); |
2870 » if (rv != SECSuccess) { | 2872 if (rv != SECSuccess) { |
2871 » if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { | 2873 if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { |
2872 » » (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); | 2874 (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); |
2873 » } | 2875 } |
2874 » goto loser; | 2876 goto loser; |
2875 » } | 2877 } |
2876 } | 2878 } |
2877 | 2879 |
2878 /* Build up final list of required elements */ | 2880 /* Build up final list of required elements */ |
2879 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; | 2881 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; |
2880 ss->sec.ci.requiredElements = needed; | 2882 ss->sec.ci.requiredElements = needed; |
2881 | 2883 |
2882 if (!sidHit) { | 2884 if (!sidHit) { |
2883 /* verify the server's certificate. if sidHit, don't check signatures */ | 2885 /* verify the server's certificate. if sidHit, don't check signatures */ |
2884 rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd, | 2886 rv = (*ss->authCertificate)(ss->authCertificateArg, ss->fd, |
2885 » » » » (PRBool)(!sidHit), PR_FALSE); | 2887 (PRBool)(!sidHit), PR_FALSE); |
2886 if (rv) { | 2888 if (rv) { |
2887 » if (ss->handleBadCert) { | 2889 if (ss->handleBadCert) { |
2888 » rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); | 2890 rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); |
2889 » if ( rv ) { | 2891 if (rv) { |
2890 » » if ( rv == SECWouldBlock ) { | 2892 if (rv == SECWouldBlock) { |
2891 » » SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned " | 2893 SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned " |
2892 » » » "SECWouldBlock", SSL_GETPID(), ss->fd)); | 2894 "SECWouldBlock", |
2893 » » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 2895 SSL_GETPID(), ss->fd)); |
2894 » » rv = SECFailure; | 2896 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
2895 » » } else { | 2897 rv = SECFailure; |
2896 » » /* cert is bad */ | 2898 } else { |
2897 » » SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=
%d", | 2899 /* cert is bad */ |
2898 » » » SSL_GETPID(), ss->fd, PORT_GetError())); | 2900 SSL_DBG(("%d: SSL[%d]: server certificate is no good: er
ror=%d", |
2899 » » } | 2901 SSL_GETPID(), ss->fd, PORT_GetError())); |
2900 » » goto loser; | 2902 } |
2901 » } | 2903 goto loser; |
2902 » /* cert is good */ | 2904 } |
2903 » } else { | 2905 /* cert is good */ |
2904 » SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", | 2906 } else { |
2905 » » SSL_GETPID(), ss->fd, PORT_GetError())); | 2907 SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", |
2906 » goto loser; | 2908 SSL_GETPID(), ss->fd, PORT_GetError())); |
2907 » } | 2909 goto loser; |
| 2910 } |
| 2911 } |
2908 } | 2912 } |
2909 } | |
2910 /* | 2913 /* |
2911 ** At this point we have a completed session key and our session | 2914 ** At this point we have a completed session key and our session |
2912 ** cipher is setup and ready to go. Switch to encrypted write routine | 2915 ** cipher is setup and ready to go. Switch to encrypted write routine |
2913 ** as all future message data is to be encrypted. | 2916 ** as all future message data is to be encrypted. |
2914 */ | 2917 */ |
2915 ssl2_UseEncryptedSendFunc(ss); | 2918 ssl2_UseEncryptedSendFunc(ss); |
2916 | 2919 |
2917 rv = ssl2_TryToFinish(ss); | 2920 rv = ssl2_TryToFinish(ss); |
2918 if (rv != SECSuccess) | 2921 if (rv != SECSuccess) |
2919 » goto loser; | 2922 goto loser; |
2920 | 2923 |
2921 ss->gs.recordLen = 0; | 2924 ss->gs.recordLen = 0; |
2922 | 2925 |
2923 ssl_ReleaseRecvBufLock(ss); | 2926 ssl_ReleaseRecvBufLock(ss); |
2924 | 2927 |
2925 if (ss->handshake == 0) { | 2928 if (ss->handshake == 0) { |
2926 » return SECSuccess; | 2929 return SECSuccess; |
2927 } | 2930 } |
2928 | 2931 |
2929 SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", | 2932 SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", |
2930 » » SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, | 2933 SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, |
2931 » » ss->sec.ci.elements)); | 2934 ss->sec.ci.elements)); |
2932 ss->handshake = ssl_GatherRecord1stHandshake; | 2935 ss->handshake = ssl_GatherRecord1stHandshake; |
2933 ss->nextHandshake = ssl2_HandleVerifyMessage; | 2936 ss->nextHandshake = ssl2_HandleVerifyMessage; |
2934 return SECSuccess; | 2937 return SECSuccess; |
2935 | 2938 |
2936 bad_server: | 2939 bad_server: |
2937 PORT_SetError(SSL_ERROR_BAD_SERVER); | 2940 PORT_SetError(SSL_ERROR_BAD_SERVER); |
2938 /* FALL THROUGH */ | 2941 /* FALL THROUGH */ |
2939 | 2942 |
2940 loser: | 2943 loser: |
2941 ssl_ReleaseRecvBufLock(ss); | 2944 ssl_ReleaseRecvBufLock(ss); |
2942 return SECFailure; | 2945 return SECFailure; |
2943 } | 2946 } |
2944 | 2947 |
2945 /* Sends out the initial client Hello message on the connection. | 2948 /* Sends out the initial client Hello message on the connection. |
2946 * Acquires and releases the socket's xmitBufLock. | 2949 * Acquires and releases the socket's xmitBufLock. |
2947 */ | 2950 */ |
2948 SECStatus | 2951 SECStatus |
2949 ssl2_BeginClientHandshake(sslSocket *ss) | 2952 ssl2_BeginClientHandshake(sslSocket *ss) |
2950 { | 2953 { |
2951 sslSessionID *sid; | 2954 sslSessionID *sid; |
2952 PRUint8 *msg; | 2955 PRUint8 *msg; |
2953 PRUint8 *cp; | 2956 PRUint8 *cp; |
2954 PRUint8 *localCipherSpecs = NULL; | 2957 PRUint8 *localCipherSpecs = NULL; |
2955 unsigned int localCipherSize; | 2958 unsigned int localCipherSize; |
2956 unsigned int i; | 2959 unsigned int i; |
2957 int sendLen, sidLen = 0; | 2960 int sendLen, sidLen = 0; |
2958 SECStatus rv; | 2961 SECStatus rv; |
2959 TLSExtensionData *xtnData; | 2962 TLSExtensionData *xtnData; |
2960 | 2963 |
2961 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 2964 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
2962 | 2965 |
2963 ss->sec.isServer = 0; | 2966 ss->sec.isServer = 0; |
2964 ss->sec.sendSequence = 0; | 2967 ss->sec.sendSequence = 0; |
2965 ss->sec.rcvSequence = 0; | 2968 ss->sec.rcvSequence = 0; |
2966 ssl_ChooseSessionIDProcs(&ss->sec); | 2969 ssl_ChooseSessionIDProcs(&ss->sec); |
2967 | 2970 |
2968 if (!ss->cipherSpecs) { | 2971 if (!ss->cipherSpecs) { |
2969 » rv = ssl2_ConstructCipherSpecs(ss); | 2972 rv = ssl2_ConstructCipherSpecs(ss); |
2970 » if (rv != SECSuccess) | 2973 if (rv != SECSuccess) |
2971 » goto loser; | 2974 goto loser; |
2972 } | 2975 } |
2973 | 2976 |
2974 /* count the SSL2 and SSL3 enabled ciphers. | 2977 /* count the SSL2 and SSL3 enabled ciphers. |
2975 * if either is zero, clear the socket's enable for that protocol. | 2978 * if either is zero, clear the socket's enable for that protocol. |
2976 */ | 2979 */ |
2977 rv = ssl2_CheckConfigSanity(ss); | 2980 rv = ssl2_CheckConfigSanity(ss); |
2978 if (rv != SECSuccess) | 2981 if (rv != SECSuccess) |
2979 » goto loser; | 2982 goto loser; |
2980 | 2983 |
2981 /* Get peer name of server */ | 2984 /* Get peer name of server */ |
2982 rv = ssl_GetPeerInfo(ss); | 2985 rv = ssl_GetPeerInfo(ss); |
2983 if (rv < 0) { | 2986 if (rv < 0) { |
2984 #ifdef HPUX11 | 2987 #ifdef HPUX11 |
2985 /* | 2988 /* |
2986 * On some HP-UX B.11.00 systems, getpeername() occasionally | 2989 * On some HP-UX B.11.00 systems, getpeername() occasionally |
2987 * fails with ENOTCONN after a successful completion of | 2990 * fails with ENOTCONN after a successful completion of |
2988 * non-blocking connect. I found that if we do a write() | 2991 * non-blocking connect. I found that if we do a write() |
2989 * and then retry getpeername(), it will work. | 2992 * and then retry getpeername(), it will work. |
2990 */ | 2993 */ |
2991 if (PR_GetError() == PR_NOT_CONNECTED_ERROR) { | 2994 if (PR_GetError() == PR_NOT_CONNECTED_ERROR) { |
2992 char dummy; | 2995 char dummy; |
2993 (void) PR_Write(ss->fd->lower, &dummy, 0); | 2996 (void)PR_Write(ss->fd->lower, &dummy, 0); |
2994 rv = ssl_GetPeerInfo(ss); | 2997 rv = ssl_GetPeerInfo(ss); |
2995 if (rv < 0) { | 2998 if (rv < 0) { |
2996 goto loser; | 2999 goto loser; |
2997 } | 3000 } |
2998 } | 3001 } |
2999 #else | 3002 #else |
3000 » goto loser; | 3003 goto loser; |
3001 #endif | 3004 #endif |
3002 } | 3005 } |
3003 | 3006 |
3004 SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd)); | 3007 SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd)); |
3005 | 3008 |
3006 /* Try to find server in our session-id cache */ | 3009 /* Try to find server in our session-id cache */ |
3007 if (ss->opt.noCache) { | 3010 if (ss->opt.noCache) { |
3008 » sid = NULL; | 3011 sid = NULL; |
3009 } else { | 3012 } else { |
3010 » sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, | 3013 sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, |
3011 » ss->url); | 3014 ss->url); |
3012 } | 3015 } |
3013 while (sid) { /* this isn't really a loop */ | 3016 while (sid) { /* this isn't really a loop */ |
3014 » PRBool sidVersionEnabled = | 3017 PRBool sidVersionEnabled = |
3015 » (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && | 3018 (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && |
3016 » sid->version >= ss->vrange.min && | 3019 sid->version >= ss->vrange.min && |
3017 » sid->version <= ss->vrange.max) || | 3020 sid->version <= ss->vrange.max) || |
3018 » (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2); | 3021 (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2); |
3019 | 3022 |
3020 » /* if we're not doing this SID's protocol any more, drop it. */ | 3023 /* if we're not doing this SID's protocol any more, drop it. */ |
3021 » if (!sidVersionEnabled) { | 3024 if (!sidVersionEnabled) { |
3022 » if (ss->sec.uncache) | 3025 if (ss->sec.uncache) |
3023 » » ss->sec.uncache(sid); | 3026 ss->sec.uncache(sid); |
3024 » ssl_FreeSID(sid); | 3027 ssl_FreeSID(sid); |
3025 » sid = NULL; | 3028 sid = NULL; |
3026 » break; | 3029 break; |
3027 » } | 3030 } |
3028 » if (sid->version < SSL_LIBRARY_VERSION_3_0) { | 3031 if (sid->version < SSL_LIBRARY_VERSION_3_0) { |
3029 » /* If the cipher in this sid is not enabled, drop it. */ | 3032 /* If the cipher in this sid is not enabled, drop it. */ |
3030 » for (i = 0; i < ss->sizeCipherSpecs; i += 3) { | 3033 for (i = 0; i < ss->sizeCipherSpecs; i += 3) { |
3031 » » if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType) | 3034 if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType) |
3032 » » break; | 3035 break; |
3033 » } | 3036 } |
3034 » if (i >= ss->sizeCipherSpecs) { | 3037 if (i >= ss->sizeCipherSpecs) { |
3035 » » if (ss->sec.uncache) | 3038 if (ss->sec.uncache) |
3036 » » ss->sec.uncache(sid); | 3039 ss->sec.uncache(sid); |
3037 » » ssl_FreeSID(sid); | 3040 ssl_FreeSID(sid); |
3038 » » sid = NULL; | 3041 sid = NULL; |
3039 » » break; | 3042 break; |
3040 » } | 3043 } |
3041 » } | 3044 } |
3042 » sidLen = sizeof(sid->u.ssl2.sessionID); | 3045 sidLen = sizeof(sid->u.ssl2.sessionID); |
3043 » PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID, | 3046 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID, |
3044 » » sidLen)); | 3047 sidLen)); |
3045 » ss->version = sid->version; | 3048 ss->version = sid->version; |
3046 » PORT_Assert(!ss->sec.localCert); | 3049 PORT_Assert(!ss->sec.localCert); |
3047 » if (ss->sec.localCert) { | 3050 if (ss->sec.localCert) { |
3048 » CERT_DestroyCertificate(ss->sec.localCert); | 3051 CERT_DestroyCertificate(ss->sec.localCert); |
3049 » } | 3052 } |
3050 » ss->sec.localCert = CERT_DupCertificate(sid->localCert); | 3053 ss->sec.localCert = CERT_DupCertificate(sid->localCert); |
3051 » break; /* this isn't really a loop */ | 3054 break; /* this isn't really a loop */ |
3052 } | 3055 } |
3053 if (!sid) { | 3056 if (!sid) { |
3054 » sidLen = 0; | 3057 sidLen = 0; |
3055 » sid = PORT_ZNew(sslSessionID); | 3058 sid = PORT_ZNew(sslSessionID); |
3056 » if (!sid) { | 3059 if (!sid) { |
3057 » goto loser; | 3060 goto loser; |
3058 » } | 3061 } |
3059 » sid->references = 1; | 3062 sid->references = 1; |
3060 » sid->cached = never_cached; | 3063 sid->cached = never_cached; |
3061 » sid->addr = ss->sec.ci.peer; | 3064 sid->addr = ss->sec.ci.peer; |
3062 » sid->port = ss->sec.ci.port; | 3065 sid->port = ss->sec.ci.port; |
3063 » if (ss->peerID != NULL) { | 3066 if (ss->peerID != NULL) { |
3064 » sid->peerID = PORT_Strdup(ss->peerID); | 3067 sid->peerID = PORT_Strdup(ss->peerID); |
3065 » } | 3068 } |
3066 » if (ss->url != NULL) { | 3069 if (ss->url != NULL) { |
3067 » sid->urlSvrName = PORT_Strdup(ss->url); | 3070 sid->urlSvrName = PORT_Strdup(ss->url); |
3068 » } | 3071 } |
3069 } | 3072 } |
3070 ss->sec.ci.sid = sid; | 3073 ss->sec.ci.sid = sid; |
3071 | 3074 |
3072 PORT_Assert(sid != NULL); | 3075 PORT_Assert(sid != NULL); |
3073 | 3076 |
3074 if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello)
&& | 3077 if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello)
&& |
3075 » !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { | 3078 !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
3076 » ss->gs.state = GS_INIT; | 3079 ss->gs.state = GS_INIT; |
3077 » ss->handshake = ssl_GatherRecord1stHandshake; | 3080 ss->handshake = ssl_GatherRecord1stHandshake; |
3078 | 3081 |
3079 » /* ssl3_SendClientHello will override this if it succeeds. */ | 3082 /* ssl3_SendClientHello will override this if it succeeds. */ |
3080 » ss->version = SSL_LIBRARY_VERSION_3_0; | 3083 ss->version = SSL_LIBRARY_VERSION_3_0; |
3081 | 3084 |
3082 » ssl_GetSSL3HandshakeLock(ss); | 3085 ssl_GetSSL3HandshakeLock(ss); |
3083 » ssl_GetXmitBufLock(ss); | 3086 ssl_GetXmitBufLock(ss); |
3084 » rv = ssl3_SendClientHello(ss, PR_FALSE); | 3087 rv = ssl3_SendClientHello(ss, PR_FALSE); |
3085 » ssl_ReleaseXmitBufLock(ss); | 3088 ssl_ReleaseXmitBufLock(ss); |
3086 » ssl_ReleaseSSL3HandshakeLock(ss); | 3089 ssl_ReleaseSSL3HandshakeLock(ss); |
3087 | 3090 |
3088 » return rv; | 3091 return rv; |
3089 } | 3092 } |
3090 #ifndef NSS_DISABLE_ECC | 3093 #ifndef NSS_DISABLE_ECC |
3091 /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ | 3094 /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ |
3092 ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ | 3095 ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ |
3093 if (ss->cipherSpecs != NULL) { | 3096 if (ss->cipherSpecs != NULL) { |
3094 » PORT_Free(ss->cipherSpecs); | 3097 PORT_Free(ss->cipherSpecs); |
3095 » ss->cipherSpecs = NULL; | 3098 ss->cipherSpecs = NULL; |
3096 » ss->sizeCipherSpecs = 0; | 3099 ss->sizeCipherSpecs = 0; |
3097 } | 3100 } |
3098 #endif /* NSS_DISABLE_ECC */ | 3101 #endif /* NSS_DISABLE_ECC */ |
3099 | 3102 |
3100 if (!ss->cipherSpecs) { | 3103 if (!ss->cipherSpecs) { |
3101 rv = ssl2_ConstructCipherSpecs(ss); | 3104 rv = ssl2_ConstructCipherSpecs(ss); |
3102 » if (rv < 0) { | 3105 if (rv < 0) { |
3103 » return rv; | 3106 return rv; |
3104 » } | 3107 } |
3105 } | 3108 } |
3106 localCipherSpecs = ss->cipherSpecs; | 3109 localCipherSpecs = ss->cipherSpecs; |
3107 localCipherSize = ss->sizeCipherSpecs; | 3110 localCipherSize = ss->sizeCipherSpecs; |
3108 | 3111 |
3109 /* Add 3 for SCSV */ | 3112 /* Add 3 for SCSV */ |
3110 sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen + | 3113 sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen + |
3111 » SSL_CHALLENGE_BYTES; | 3114 SSL_CHALLENGE_BYTES; |
3112 | 3115 |
3113 /* Generate challenge bytes for server */ | 3116 /* Generate challenge bytes for server */ |
3114 PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); | 3117 PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); |
3115 | 3118 |
3116 ssl_GetXmitBufLock(ss); /***************************************/ | 3119 ssl_GetXmitBufLock(ss); /***************************************/ |
3117 | 3120 |
3118 rv = ssl2_GetSendBuffer(ss, sendLen); | 3121 rv = ssl2_GetSendBuffer(ss, sendLen); |
3119 if (rv) | 3122 if (rv) |
3120 » goto unlock_loser; | 3123 goto unlock_loser; |
3121 | 3124 |
3122 /* Construct client-hello message */ | 3125 /* Construct client-hello message */ |
3123 cp = msg = ss->sec.ci.sendBuf.buf; | 3126 cp = msg = ss->sec.ci.sendBuf.buf; |
3124 msg[0] = SSL_MT_CLIENT_HELLO; | 3127 msg[0] = SSL_MT_CLIENT_HELLO; |
3125 ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ? | 3128 ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ? SSL_LIBRA
RY_VERSION_2 |
3126 » SSL_LIBRARY_VERSION_2 : ss->vrange.max; | 3129 : ss->vrang
e.max; |
3127 | 3130 |
3128 msg[1] = MSB(ss->clientHelloVersion); | 3131 msg[1] = MSB(ss->clientHelloVersion); |
3129 msg[2] = LSB(ss->clientHelloVersion); | 3132 msg[2] = LSB(ss->clientHelloVersion); |
3130 /* Add 3 for SCSV */ | 3133 /* Add 3 for SCSV */ |
3131 msg[3] = MSB(localCipherSize + 3); | 3134 msg[3] = MSB(localCipherSize + 3); |
3132 msg[4] = LSB(localCipherSize + 3); | 3135 msg[4] = LSB(localCipherSize + 3); |
3133 msg[5] = MSB(sidLen); | 3136 msg[5] = MSB(sidLen); |
3134 msg[6] = LSB(sidLen); | 3137 msg[6] = LSB(sidLen); |
3135 msg[7] = MSB(SSL_CHALLENGE_BYTES); | 3138 msg[7] = MSB(SSL_CHALLENGE_BYTES); |
3136 msg[8] = LSB(SSL_CHALLENGE_BYTES); | 3139 msg[8] = LSB(SSL_CHALLENGE_BYTES); |
3137 cp += SSL_HL_CLIENT_HELLO_HBYTES; | 3140 cp += SSL_HL_CLIENT_HELLO_HBYTES; |
3138 PORT_Memcpy(cp, localCipherSpecs, localCipherSize); | 3141 PORT_Memcpy(cp, localCipherSpecs, localCipherSize); |
3139 cp += localCipherSize; | 3142 cp += localCipherSize; |
3140 /* | 3143 /* |
3141 * Add SCSV. SSL 2.0 cipher suites are listed before SSL 3.0 cipher | 3144 * Add SCSV. SSL 2.0 cipher suites are listed before SSL 3.0 cipher |
3142 * suites in localCipherSpecs for compatibility with SSL 2.0 servers. | 3145 * suites in localCipherSpecs for compatibility with SSL 2.0 servers. |
3143 * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at | 3146 * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at |
3144 * the beginning. | 3147 * the beginning. |
3145 */ | 3148 */ |
3146 cp[0] = 0x00; | 3149 cp[0] = 0x00; |
3147 cp[1] = 0x00; | 3150 cp[1] = 0x00; |
3148 cp[2] = 0xff; | 3151 cp[2] = 0xff; |
3149 cp += 3; | 3152 cp += 3; |
3150 if (sidLen) { | 3153 if (sidLen) { |
3151 » PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); | 3154 PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); |
3152 » cp += sidLen; | 3155 cp += sidLen; |
3153 } | 3156 } |
3154 PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); | 3157 PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); |
3155 | 3158 |
3156 /* Send it to the server */ | 3159 /* Send it to the server */ |
3157 DUMP_MSG(29, (ss, msg, sendLen)); | 3160 DUMP_MSG(29, (ss, msg, sendLen)); |
3158 ss->handshakeBegun = 1; | 3161 ss->handshakeBegun = 1; |
3159 rv = (*ss->sec.send)(ss, msg, sendLen, 0); | 3162 rv = (*ss->sec.send)(ss, msg, sendLen, 0); |
3160 | 3163 |
3161 ssl_ReleaseXmitBufLock(ss); /***************************************/ | 3164 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
3162 | 3165 |
3163 if (rv < 0) { | 3166 if (rv < 0) { |
3164 » goto loser; | 3167 goto loser; |
3165 } | 3168 } |
3166 | 3169 |
3167 rv = ssl3_StartHandshakeHash(ss, msg, sendLen); | 3170 rv = ssl3_StartHandshakeHash(ss, msg, sendLen); |
3168 if (rv < 0) { | 3171 if (rv < 0) { |
3169 » goto loser; | 3172 goto loser; |
3170 } | 3173 } |
3171 | 3174 |
3172 /* | 3175 /* |
3173 * Since we sent the SCSV, pretend we sent empty RI extension. We need | 3176 * Since we sent the SCSV, pretend we sent empty RI extension. We need |
3174 * to record the extension has been advertised after ssl3_InitState has | 3177 * to record the extension has been advertised after ssl3_InitState has |
3175 * been called, which ssl3_StartHandshakeHash took care for us above. | 3178 * been called, which ssl3_StartHandshakeHash took care for us above. |
3176 */ | 3179 */ |
3177 xtnData = &ss->xtnData; | 3180 xtnData = &ss->xtnData; |
3178 xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn; | 3181 xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn; |
3179 | 3182 |
3180 /* Setup to receive servers hello message */ | 3183 /* Setup to receive servers hello message */ |
3181 ssl_GetRecvBufLock(ss); | 3184 ssl_GetRecvBufLock(ss); |
3182 ss->gs.recordLen = 0; | 3185 ss->gs.recordLen = 0; |
3183 ssl_ReleaseRecvBufLock(ss); | 3186 ssl_ReleaseRecvBufLock(ss); |
3184 | 3187 |
3185 ss->handshake = ssl_GatherRecord1stHandshake; | 3188 ss->handshake = ssl_GatherRecord1stHandshake; |
3186 ss->nextHandshake = ssl2_HandleServerHelloMessage; | 3189 ss->nextHandshake = ssl2_HandleServerHelloMessage; |
3187 return SECSuccess; | 3190 return SECSuccess; |
3188 | 3191 |
3189 unlock_loser: | 3192 unlock_loser: |
3190 ssl_ReleaseXmitBufLock(ss); | 3193 ssl_ReleaseXmitBufLock(ss); |
3191 loser: | 3194 loser: |
3192 return SECFailure; | 3195 return SECFailure; |
3193 } | 3196 } |
3194 | 3197 |
3195 /************************************************************************/ | 3198 /************************************************************************/ |
3196 | 3199 |
3197 /* Handle the CLIENT-MASTER-KEY message. | 3200 /* Handle the CLIENT-MASTER-KEY message. |
3198 ** Acquires and releases RecvBufLock. | 3201 ** Acquires and releases RecvBufLock. |
3199 ** Called from ssl2_HandleClientHelloMessage(). | 3202 ** Called from ssl2_HandleClientHelloMessage(). |
3200 */ | 3203 */ |
3201 static SECStatus | 3204 static SECStatus |
3202 ssl2_HandleClientSessionKeyMessage(sslSocket *ss) | 3205 ssl2_HandleClientSessionKeyMessage(sslSocket *ss) |
3203 { | 3206 { |
3204 PRUint8 * data; | 3207 PRUint8 *data; |
3205 unsigned int caLen; | 3208 unsigned int caLen; |
3206 unsigned int ckLen; | 3209 unsigned int ckLen; |
3207 unsigned int ekLen; | 3210 unsigned int ekLen; |
3208 unsigned int keyBits; | 3211 unsigned int keyBits; |
3209 int cipher; | 3212 int cipher; |
3210 SECStatus rv; | 3213 SECStatus rv; |
3211 | |
3212 | 3214 |
3213 ssl_GetRecvBufLock(ss); | 3215 ssl_GetRecvBufLock(ss); |
3214 | 3216 |
3215 data = ss->gs.buf.buf + ss->gs.recordOffset; | 3217 data = ss->gs.buf.buf + ss->gs.recordOffset; |
3216 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); | 3218 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
3217 | 3219 |
3218 if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) | 3220 if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) || |
3219 » || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) { | 3221 (data[0] != SSL_MT_CLIENT_MASTER_KEY)) { |
3220 » goto bad_client; | 3222 goto bad_client; |
3221 } | 3223 } |
3222 cipher = data[1]; | 3224 cipher = data[1]; |
3223 keyBits = (data[2] << 8) | data[3]; | 3225 keyBits = (data[2] << 8) | data[3]; |
3224 ckLen = (data[4] << 8) | data[5]; | 3226 ckLen = (data[4] << 8) | data[5]; |
3225 ekLen = (data[6] << 8) | data[7]; | 3227 ekLen = (data[6] << 8) | data[7]; |
3226 caLen = (data[8] << 8) | data[9]; | 3228 caLen = (data[8] << 8) | data[9]; |
3227 | 3229 |
3228 SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%
d caLen=%d", | 3230 SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%
d caLen=%d", |
3229 » » SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen)); | 3231 SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen)); |
3230 | 3232 |
3231 if (ss->gs.recordLen < | 3233 if (ss->gs.recordLen < |
3232 » SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { | 3234 SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { |
3233 » SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d", | 3235 SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d", |
3234 » » SSL_GETPID(), ss->fd, ss->gs.recordLen)); | 3236 SSL_GETPID(), ss->fd, ss->gs.recordLen)); |
3235 » goto bad_client; | 3237 goto bad_client; |
3236 } | 3238 } |
3237 | 3239 |
3238 /* Use info from client to setup session key */ | 3240 /* Use info from client to setup session key */ |
3239 rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits, | 3241 rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits, |
3240 » » data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen, | 3242 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, |
3241 » » data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen, | 3243 ckLen, |
3242 » » data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen); | 3244 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES +
ckLen, |
3243 ss->gs.recordLen = 0;» /* we're done with this record. */ | 3245 ekLen, |
| 3246 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES +
ckLen + ekLen, |
| 3247 caLen); |
| 3248 ss->gs.recordLen = 0; /* we're done with this record. */ |
3244 | 3249 |
3245 ssl_ReleaseRecvBufLock(ss); | 3250 ssl_ReleaseRecvBufLock(ss); |
3246 | 3251 |
3247 if (rv != SECSuccess) { | 3252 if (rv != SECSuccess) { |
3248 » goto loser; | 3253 goto loser; |
3249 } | 3254 } |
3250 ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY; | 3255 ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY; |
3251 ssl2_UseEncryptedSendFunc(ss); | 3256 ssl2_UseEncryptedSendFunc(ss); |
3252 | 3257 |
3253 /* Send server verify message now that keys are established */ | 3258 /* Send server verify message now that keys are established */ |
3254 rv = ssl2_SendServerVerifyMessage(ss); | 3259 rv = ssl2_SendServerVerifyMessage(ss); |
3255 if (rv != SECSuccess) | 3260 if (rv != SECSuccess) |
3256 » goto loser; | 3261 goto loser; |
3257 | 3262 |
3258 rv = ssl2_TryToFinish(ss); | 3263 rv = ssl2_TryToFinish(ss); |
3259 if (rv != SECSuccess) | 3264 if (rv != SECSuccess) |
3260 » goto loser; | 3265 goto loser; |
3261 if (ss->handshake == 0) { | 3266 if (ss->handshake == 0) { |
3262 » return SECSuccess; | 3267 return SECSuccess; |
3263 } | 3268 } |
3264 | 3269 |
3265 SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", | 3270 SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", |
3266 » » SSL_GETPID(), ss->fd, | 3271 SSL_GETPID(), ss->fd, |
3267 » » ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); | 3272 ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); |
3268 ss->handshake = ssl_GatherRecord1stHandshake; | 3273 ss->handshake = ssl_GatherRecord1stHandshake; |
3269 ss->nextHandshake = ssl2_HandleMessage; | 3274 ss->nextHandshake = ssl2_HandleMessage; |
3270 | 3275 |
3271 return ssl2_TriggerNextMessage(ss); | 3276 return ssl2_TriggerNextMessage(ss); |
3272 | 3277 |
3273 bad_client: | 3278 bad_client: |
3274 ssl_ReleaseRecvBufLock(ss); | 3279 ssl_ReleaseRecvBufLock(ss); |
3275 PORT_SetError(SSL_ERROR_BAD_CLIENT); | 3280 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
3276 /* FALLTHROUGH */ | 3281 /* FALLTHROUGH */ |
3277 | 3282 |
3278 loser: | 3283 loser: |
3279 return SECFailure; | 3284 return SECFailure; |
3280 } | 3285 } |
3281 | 3286 |
3282 /* | 3287 /* |
3283 ** Handle the initial hello message from the client | 3288 ** Handle the initial hello message from the client |
3284 ** | 3289 ** |
3285 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value. | 3290 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value. |
3286 */ | 3291 */ |
3287 SECStatus | 3292 SECStatus |
3288 ssl2_HandleClientHelloMessage(sslSocket *ss) | 3293 ssl2_HandleClientHelloMessage(sslSocket *ss) |
3289 { | 3294 { |
3290 sslSessionID *sid; | 3295 sslSessionID *sid; |
3291 sslServerCerts * sc; | 3296 sslServerCerts *sc; |
3292 CERTCertificate *serverCert; | 3297 CERTCertificate *serverCert; |
3293 PRUint8 *msg; | 3298 PRUint8 *msg; |
3294 PRUint8 *data; | 3299 PRUint8 *data; |
3295 PRUint8 *cs; | 3300 PRUint8 *cs; |
3296 PRUint8 *sd; | 3301 PRUint8 *sd; |
3297 PRUint8 *cert = NULL; | 3302 PRUint8 *cert = NULL; |
3298 PRUint8 *challenge; | 3303 PRUint8 *challenge; |
3299 unsigned int challengeLen; | 3304 unsigned int challengeLen; |
3300 SECStatus rv; | 3305 SECStatus rv; |
3301 int csLen; | 3306 int csLen; |
3302 int sendLen; | 3307 int sendLen; |
3303 int sdLen; | 3308 int sdLen; |
3304 int certLen; | 3309 int certLen; |
3305 int pid; | 3310 int pid; |
3306 int sent; | 3311 int sent; |
3307 int gotXmitBufLock = 0; | 3312 int gotXmitBufLock = 0; |
3308 #if defined(SOLARIS) && defined(i386) | 3313 #if defined(SOLARIS) && defined(i386) |
3309 volatile PRUint8 hit; | 3314 volatile PRUint8 hit; |
3310 #else | 3315 #else |
3311 int hit; | 3316 int hit; |
3312 #endif | 3317 #endif |
3313 PRUint8 csImpl[sizeof implementedCipherSuites]; | 3318 PRUint8 csImpl[sizeof implementedCipherSuites]; |
3314 | 3319 |
3315 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 3320 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
3316 | 3321 |
3317 sc = ss->serverCerts + kt_rsa; | 3322 sc = ss->serverCerts + kt_rsa; |
3318 serverCert = sc->serverCert; | 3323 serverCert = sc->serverCert; |
3319 | 3324 |
3320 ssl_GetRecvBufLock(ss); | 3325 ssl_GetRecvBufLock(ss); |
3321 | 3326 |
3322 | |
3323 data = ss->gs.buf.buf + ss->gs.recordOffset; | 3327 data = ss->gs.buf.buf + ss->gs.recordOffset; |
3324 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); | 3328 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
3325 | 3329 |
3326 /* Make sure first message has some data and is the client hello message */ | 3330 /* Make sure first message has some data and is the client hello message */ |
3327 if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES) | 3331 if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES) || |
3328 » || (data[0] != SSL_MT_CLIENT_HELLO)) { | 3332 (data[0] != SSL_MT_CLIENT_HELLO)) { |
3329 » goto bad_client; | 3333 goto bad_client; |
3330 } | 3334 } |
3331 | 3335 |
3332 /* Get peer name of client */ | 3336 /* Get peer name of client */ |
3333 rv = ssl_GetPeerInfo(ss); | 3337 rv = ssl_GetPeerInfo(ss); |
3334 if (rv != SECSuccess) { | 3338 if (rv != SECSuccess) { |
3335 » goto loser; | 3339 goto loser; |
3336 } | 3340 } |
3337 | 3341 |
3338 /* Examine version information */ | 3342 /* Examine version information */ |
3339 /* | 3343 /* |
3340 * See if this might be a V2 client hello asking to use the V3 protocol | 3344 * See if this might be a V2 client hello asking to use the V3 protocol |
3341 */ | 3345 */ |
3342 if ((data[0] == SSL_MT_CLIENT_HELLO) && | 3346 if ((data[0] == SSL_MT_CLIENT_HELLO) && |
3343 (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && | 3347 (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && |
3344 » !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { | 3348 !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
3345 » rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen); | 3349 rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen); |
3346 » if (rv != SECFailure) { /* Success */ | 3350 if (rv != SECFailure) { /* Success */ |
3347 » ss->handshake = NULL; | 3351 ss->handshake = NULL; |
3348 » ss->nextHandshake = ssl_GatherRecord1stHandshake; | 3352 ss->nextHandshake = ssl_GatherRecord1stHandshake; |
3349 » ss->securityHandshake = NULL; | 3353 ss->securityHandshake = NULL; |
3350 » ss->gs.state = GS_INIT; | 3354 ss->gs.state = GS_INIT; |
3351 | 3355 |
3352 » /* ssl3_HandleV3ClientHello has set ss->version, | 3356 /* ssl3_HandleV3ClientHello has set ss->version, |
3353 » ** and has gotten us a brand new sid. | 3357 ** and has gotten us a brand new sid. |
3354 » */ | 3358 */ |
3355 » ss->sec.ci.sid->version = ss->version; | 3359 ss->sec.ci.sid->version = ss->version; |
3356 » } | 3360 } |
3357 » ssl_ReleaseRecvBufLock(ss); | 3361 ssl_ReleaseRecvBufLock(ss); |
3358 » return rv; | 3362 return rv; |
3359 } | 3363 } |
3360 /* Previously, there was a test here to see if SSL2 was enabled. | 3364 /* Previously, there was a test here to see if SSL2 was enabled. |
3361 ** If not, an error code was set, and SECFailure was returned, | 3365 ** If not, an error code was set, and SECFailure was returned, |
3362 ** without sending any error code to the other end of the connection. | 3366 ** without sending any error code to the other end of the connection. |
3363 ** That test has been removed. If SSL2 has been disabled, there | 3367 ** That test has been removed. If SSL2 has been disabled, there |
3364 ** should be no SSL2 ciphers enabled, and consequently, the code | 3368 ** should be no SSL2 ciphers enabled, and consequently, the code |
3365 ** below should send the ssl2 error message SSL_PE_NO_CYPHERS. | 3369 ** below should send the ssl2 error message SSL_PE_NO_CYPHERS. |
3366 ** We now believe this is the correct thing to do, even when SSL2 | 3370 ** We now believe this is the correct thing to do, even when SSL2 |
3367 ** has been explicitly disabled by the application. | 3371 ** has been explicitly disabled by the application. |
3368 */ | 3372 */ |
3369 | 3373 |
3370 /* Extract info from message */ | 3374 /* Extract info from message */ |
3371 ss->version = (data[1] << 8) | data[2]; | 3375 ss->version = (data[1] << 8) | data[2]; |
3372 | 3376 |
3373 /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */ | 3377 /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */ |
3374 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { | 3378 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
3375 » ss->version = SSL_LIBRARY_VERSION_2; | 3379 ss->version = SSL_LIBRARY_VERSION_2; |
3376 } | 3380 } |
3377 | 3381 |
3378 csLen = (data[3] << 8) | data[4]; | 3382 csLen = (data[3] << 8) | data[4]; |
3379 sdLen = (data[5] << 8) | data[6]; | 3383 sdLen = (data[5] << 8) | data[6]; |
3380 challengeLen = (data[7] << 8) | data[8]; | 3384 challengeLen = (data[7] << 8) | data[8]; |
3381 cs = data + SSL_HL_CLIENT_HELLO_HBYTES; | 3385 cs = data + SSL_HL_CLIENT_HELLO_HBYTES; |
3382 sd = cs + csLen; | 3386 sd = cs + csLen; |
3383 challenge = sd + sdLen; | 3387 challenge = sd + sdLen; |
3384 PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen)); | 3388 PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen)); |
3385 | 3389 |
3386 if (!csLen || (csLen % 3) != 0 || | 3390 if (!csLen || (csLen % 3) != 0 || |
3387 (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) || | 3391 (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) || |
3388 » challengeLen < SSL_MIN_CHALLENGE_BYTES || | 3392 challengeLen < SSL_MIN_CHALLENGE_BYTES || |
3389 » challengeLen > SSL_MAX_CHALLENGE_BYTES || | 3393 challengeLen > SSL_MAX_CHALLENGE_BYTES || |
3390 (unsigned)ss->gs.recordLen != | 3394 (unsigned)ss->gs.recordLen != |
3391 SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) { | 3395 SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) { |
3392 » SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d", | 3396 SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d", |
3393 » » SSL_GETPID(), ss->fd, ss->gs.recordLen, | 3397 SSL_GETPID(), ss->fd, ss->gs.recordLen, |
3394 » » SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen)); | 3398 SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen)); |
3395 » goto bad_client; | 3399 goto bad_client; |
3396 } | 3400 } |
3397 | 3401 |
3398 SSL_TRC(3, ("%d: SSL[%d]: client version is %x", | 3402 SSL_TRC(3, ("%d: SSL[%d]: client version is %x", |
3399 » » SSL_GETPID(), ss->fd, ss->version)); | 3403 SSL_GETPID(), ss->fd, ss->version)); |
3400 if (ss->version != SSL_LIBRARY_VERSION_2) { | 3404 if (ss->version != SSL_LIBRARY_VERSION_2) { |
3401 » if (ss->version > SSL_LIBRARY_VERSION_2) { | 3405 if (ss->version > SSL_LIBRARY_VERSION_2) { |
3402 » /* | 3406 /* |
3403 » ** Newer client than us. Things are ok because new clients | 3407 ** Newer client than us. Things are ok because new clients |
3404 » ** are required to be backwards compatible with old servers. | 3408 ** are required to be backwards compatible with old servers. |
3405 » ** Change version number to our version number so that client | 3409 ** Change version number to our version number so that client |
3406 » ** knows whats up. | 3410 ** knows whats up. |
3407 » */ | 3411 */ |
3408 » ss->version = SSL_LIBRARY_VERSION_2; | 3412 ss->version = SSL_LIBRARY_VERSION_2; |
3409 » } else { | 3413 } else { |
3410 » SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)", | 3414 SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)", |
3411 » » SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2)); | 3415 SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2
)); |
3412 » PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); | 3416 PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); |
3413 » goto loser; | 3417 goto loser; |
3414 » } | 3418 } |
3415 } | 3419 } |
3416 | 3420 |
3417 /* Qualify cipher specs before returning them to client */ | 3421 /* Qualify cipher specs before returning them to client */ |
3418 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); | 3422 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); |
3419 if (csLen == 0) { | 3423 if (csLen == 0) { |
3420 » /* no overlap, send client our list of supported SSL v2 ciphers. */ | 3424 /* no overlap, send client our list of supported SSL v2 ciphers. */ |
3421 cs = csImpl; | 3425 cs = csImpl; |
3422 » csLen = sizeof implementedCipherSuites; | 3426 csLen = sizeof implementedCipherSuites; |
3423 » PORT_Memcpy(cs, implementedCipherSuites, csLen); | 3427 PORT_Memcpy(cs, implementedCipherSuites, csLen); |
3424 » csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); | 3428 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); |
3425 » if (csLen == 0) { | 3429 if (csLen == 0) { |
3426 » /* We don't support any SSL v2 ciphers! */ | 3430 /* We don't support any SSL v2 ciphers! */ |
3427 » ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); | 3431 ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); |
3428 » PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 3432 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
3429 » goto loser; | 3433 goto loser; |
3430 » } | 3434 } |
3431 » /* Since this handhsake is going to fail, don't cache it. */ | 3435 /* Since this handhsake is going to fail, don't cache it. */ |
3432 » ss->opt.noCache = 1; | 3436 ss->opt.noCache = 1; |
3433 } | 3437 } |
3434 | 3438 |
3435 /* Squirrel away the challenge for later */ | 3439 /* Squirrel away the challenge for later */ |
3436 PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen); | 3440 PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen); |
3437 | 3441 |
3438 /* Examine message and see if session-id is good */ | 3442 /* Examine message and see if session-id is good */ |
3439 ss->sec.ci.elements = 0; | 3443 ss->sec.ci.elements = 0; |
3440 if (sdLen > 0 && !ss->opt.noCache) { | 3444 if (sdLen > 0 && !ss->opt.noCache) { |
3441 » SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08
x%08x%08x", | 3445 SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08
x%08x%08x", |
3442 » » SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0], | 3446 SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0], |
3443 » » ss->sec.ci.peer.pr_s6_addr32[1], | 3447 ss->sec.ci.peer.pr_s6_addr32[1], |
3444 » » ss->sec.ci.peer.pr_s6_addr32[2], | 3448 ss->sec.ci.peer.pr_s6_addr32[2], |
3445 » » ss->sec.ci.peer.pr_s6_addr32[3])); | 3449 ss->sec.ci.peer.pr_s6_addr32[3])); |
3446 » sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle); | 3450 sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle); |
3447 } else { | 3451 } else { |
3448 » sid = NULL; | 3452 sid = NULL; |
3449 } | 3453 } |
3450 if (sid) { | 3454 if (sid) { |
3451 » /* Got a good session-id. Short cut! */ | 3455 /* Got a good session-id. Short cut! */ |
3452 » SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)", | 3456 SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)", |
3453 » » SSL_GETPID(), ss->fd, ss->sec.ci.peer, | 3457 SSL_GETPID(), ss->fd, ss->sec.ci.peer, |
3454 » » ssl_Time() - sid->creationTime)); | 3458 ssl_Time() - sid->creationTime)); |
3455 » PRINT_BUF(1, (ss, "session-id value:", sd, sdLen)); | 3459 PRINT_BUF(1, (ss, "session-id value:", sd, sdLen)); |
3456 » ss->sec.ci.sid = sid; | 3460 ss->sec.ci.sid = sid; |
3457 » ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; | 3461 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; |
3458 » hit = 1; | 3462 hit = 1; |
3459 » certLen = 0; | 3463 certLen = 0; |
3460 » csLen = 0; | 3464 csLen = 0; |
3461 | 3465 |
3462 ss->sec.authAlgorithm = sid->authAlgorithm; | 3466 ss->sec.authAlgorithm = sid->authAlgorithm; |
3463 » ss->sec.authKeyBits = sid->authKeyBits; | 3467 ss->sec.authKeyBits = sid->authKeyBits; |
3464 » ss->sec.keaType = sid->keaType; | 3468 ss->sec.keaType = sid->keaType; |
3465 » ss->sec.keaKeyBits = sid->keaKeyBits; | 3469 ss->sec.keaKeyBits = sid->keaKeyBits; |
3466 | 3470 |
3467 » rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); | 3471 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); |
3468 » if (rv != SECSuccess) { | 3472 if (rv != SECSuccess) { |
3469 » goto loser; | 3473 goto loser; |
3470 » } | 3474 } |
3471 } else { | 3475 } else { |
3472 » SECItem * derCert = &serverCert->derCert; | 3476 SECItem *derCert = &serverCert->derCert; |
3473 | 3477 |
3474 » SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed", | 3478 SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed", |
3475 » » SSL_GETPID(), ss->fd)); | 3479 SSL_GETPID(), ss->fd)); |
3476 » if (!serverCert) { | 3480 if (!serverCert) { |
3477 » SET_ERROR_CODE | 3481 SET_ERROR_CODE |
3478 » goto loser; | 3482 goto loser; |
3479 » } | 3483 } |
3480 » hit = 0; | 3484 hit = 0; |
3481 » sid = PORT_ZNew(sslSessionID); | 3485 sid = PORT_ZNew(sslSessionID); |
3482 » if (!sid) { | 3486 if (!sid) { |
3483 » goto loser; | 3487 goto loser; |
3484 » } | 3488 } |
3485 » sid->references = 1; | 3489 sid->references = 1; |
3486 » sid->addr = ss->sec.ci.peer; | 3490 sid->addr = ss->sec.ci.peer; |
3487 » sid->port = ss->sec.ci.port; | 3491 sid->port = ss->sec.ci.port; |
3488 | 3492 |
3489 » /* Invent a session-id */ | 3493 /* Invent a session-id */ |
3490 » ss->sec.ci.sid = sid; | 3494 ss->sec.ci.sid = sid; |
3491 » PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2); | 3495 PK11_GenerateRandom(sid->u.ssl2.sessionID + 2, SSL2_SESSIONID_BYTES - 2)
; |
3492 | 3496 |
3493 » pid = SSL_GETPID(); | 3497 pid = SSL_GETPID(); |
3494 » sid->u.ssl2.sessionID[0] = MSB(pid); | 3498 sid->u.ssl2.sessionID[0] = MSB(pid); |
3495 » sid->u.ssl2.sessionID[1] = LSB(pid); | 3499 sid->u.ssl2.sessionID[1] = LSB(pid); |
3496 » cert = derCert->data; | 3500 cert = derCert->data; |
3497 » certLen = derCert->len; | 3501 certLen = derCert->len; |
3498 | 3502 |
3499 » /* pretend that server sids remember the local cert. */ | 3503 /* pretend that server sids remember the local cert. */ |
3500 » PORT_Assert(!sid->localCert); | 3504 PORT_Assert(!sid->localCert); |
3501 » if (sid->localCert) { | 3505 if (sid->localCert) { |
3502 » CERT_DestroyCertificate(sid->localCert); | 3506 CERT_DestroyCertificate(sid->localCert); |
3503 » } | 3507 } |
3504 » sid->localCert = CERT_DupCertificate(serverCert); | 3508 sid->localCert = CERT_DupCertificate(serverCert); |
3505 | 3509 |
3506 » ss->sec.authAlgorithm = ssl_sign_rsa; | 3510 ss->sec.authAlgorithm = ssl_sign_rsa; |
3507 » ss->sec.keaType = ssl_kea_rsa; | 3511 ss->sec.keaType = ssl_kea_rsa; |
3508 » ss->sec.keaKeyBits = \ | 3512 ss->sec.keaKeyBits = |
3509 » ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits; | 3513 ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits; |
3510 } | 3514 } |
3511 | 3515 |
3512 /* server sids don't remember the local cert, so whether we found | 3516 /* server sids don't remember the local cert, so whether we found |
3513 ** a sid or not, just "remember" we used the rsa server cert. | 3517 ** a sid or not, just "remember" we used the rsa server cert. |
3514 */ | 3518 */ |
3515 if (ss->sec.localCert) { | 3519 if (ss->sec.localCert) { |
3516 » CERT_DestroyCertificate(ss->sec.localCert); | 3520 CERT_DestroyCertificate(ss->sec.localCert); |
3517 } | 3521 } |
3518 ss->sec.localCert = CERT_DupCertificate(serverCert); | 3522 ss->sec.localCert = CERT_DupCertificate(serverCert); |
3519 | 3523 |
3520 /* Build up final list of required elements */ | 3524 /* Build up final list of required elements */ |
3521 ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED; | 3525 ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED; |
3522 if (ss->opt.requestCertificate) { | 3526 if (ss->opt.requestCertificate) { |
3523 » ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE; | 3527 ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE; |
3524 } | 3528 } |
3525 ss->sec.ci.sentElements = 0; | 3529 ss->sec.ci.sentElements = 0; |
3526 | 3530 |
3527 /* Send hello message back to client */ | 3531 /* Send hello message back to client */ |
3528 sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen | 3532 sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + |
3529 » + SSL_CONNECTIONID_BYTES; | 3533 SSL_CONNECTIONID_BYTES; |
3530 | 3534 |
3531 ssl_GetXmitBufLock(ss); gotXmitBufLock = 1; | 3535 ssl_GetXmitBufLock(ss); |
| 3536 gotXmitBufLock = 1; |
3532 rv = ssl2_GetSendBuffer(ss, sendLen); | 3537 rv = ssl2_GetSendBuffer(ss, sendLen); |
3533 if (rv != SECSuccess) { | 3538 if (rv != SECSuccess) { |
3534 » goto loser; | 3539 goto loser; |
3535 } | 3540 } |
3536 | 3541 |
3537 SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)", | 3542 SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)", |
3538 » » SSL_GETPID(), ss->fd, sendLen)); | 3543 SSL_GETPID(), ss->fd, sendLen)); |
3539 | 3544 |
3540 msg = ss->sec.ci.sendBuf.buf; | 3545 msg = ss->sec.ci.sendBuf.buf; |
3541 msg[0] = SSL_MT_SERVER_HELLO; | 3546 msg[0] = SSL_MT_SERVER_HELLO; |
3542 msg[1] = hit; | 3547 msg[1] = hit; |
3543 msg[2] = SSL_CT_X509_CERTIFICATE; | 3548 msg[2] = SSL_CT_X509_CERTIFICATE; |
3544 msg[3] = MSB(ss->version); | 3549 msg[3] = MSB(ss->version); |
3545 msg[4] = LSB(ss->version); | 3550 msg[4] = LSB(ss->version); |
3546 msg[5] = MSB(certLen); | 3551 msg[5] = MSB(certLen); |
3547 msg[6] = LSB(certLen); | 3552 msg[6] = LSB(certLen); |
3548 msg[7] = MSB(csLen); | 3553 msg[7] = MSB(csLen); |
3549 msg[8] = LSB(csLen); | 3554 msg[8] = LSB(csLen); |
3550 msg[9] = MSB(SSL_CONNECTIONID_BYTES); | 3555 msg[9] = MSB(SSL_CONNECTIONID_BYTES); |
3551 msg[10] = LSB(SSL_CONNECTIONID_BYTES); | 3556 msg[10] = LSB(SSL_CONNECTIONID_BYTES); |
3552 if (certLen) { | 3557 if (certLen) { |
3553 » PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen); | 3558 PORT_Memcpy(msg + SSL_HL_SERVER_HELLO_HBYTES, cert, certLen); |
3554 } | 3559 } |
3555 if (csLen) { | 3560 if (csLen) { |
3556 » PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen); | 3561 PORT_Memcpy(msg + SSL_HL_SERVER_HELLO_HBYTES + certLen, cs, csLen); |
3557 } | 3562 } |
3558 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, | 3563 PORT_Memcpy(msg + SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen, |
3559 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES); | 3564 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES); |
3560 | 3565 |
3561 DUMP_MSG(29, (ss, msg, sendLen)); | 3566 DUMP_MSG(29, (ss, msg, sendLen)); |
3562 | 3567 |
3563 ss->handshakeBegun = 1; | 3568 ss->handshakeBegun = 1; |
3564 sent = (*ss->sec.send)(ss, msg, sendLen, 0); | 3569 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
3565 if (sent < 0) { | 3570 if (sent < 0) { |
3566 » goto loser; | 3571 goto loser; |
3567 } | 3572 } |
3568 ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; | 3573 ssl_ReleaseXmitBufLock(ss); |
| 3574 gotXmitBufLock = 0; |
3569 | 3575 |
3570 ss->gs.recordLen = 0; | 3576 ss->gs.recordLen = 0; |
3571 ss->handshake = ssl_GatherRecord1stHandshake; | 3577 ss->handshake = ssl_GatherRecord1stHandshake; |
3572 if (hit) { | 3578 if (hit) { |
3573 » /* Old SID Session key is good. Go encrypted */ | 3579 /* Old SID Session key is good. Go encrypted */ |
3574 » ssl2_UseEncryptedSendFunc(ss); | 3580 ssl2_UseEncryptedSendFunc(ss); |
3575 | 3581 |
3576 » /* Send server verify message now that keys are established */ | 3582 /* Send server verify message now that keys are established */ |
3577 » rv = ssl2_SendServerVerifyMessage(ss); | 3583 rv = ssl2_SendServerVerifyMessage(ss); |
3578 » if (rv != SECSuccess) | 3584 if (rv != SECSuccess) |
3579 » goto loser; | 3585 goto loser; |
3580 | 3586 |
3581 » ss->nextHandshake = ssl2_HandleMessage; | 3587 ss->nextHandshake = ssl2_HandleMessage; |
3582 » ssl_ReleaseRecvBufLock(ss); | 3588 ssl_ReleaseRecvBufLock(ss); |
3583 » rv = ssl2_TriggerNextMessage(ss); | 3589 rv = ssl2_TriggerNextMessage(ss); |
3584 » return rv; | 3590 return rv; |
3585 } | 3591 } |
3586 ss->nextHandshake = ssl2_HandleClientSessionKeyMessage; | 3592 ss->nextHandshake = ssl2_HandleClientSessionKeyMessage; |
3587 ssl_ReleaseRecvBufLock(ss); | 3593 ssl_ReleaseRecvBufLock(ss); |
3588 return SECSuccess; | 3594 return SECSuccess; |
3589 | 3595 |
3590 bad_client: | 3596 bad_client: |
3591 PORT_SetError(SSL_ERROR_BAD_CLIENT); | 3597 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
3592 /* FALLTHROUGH */ | 3598 /* FALLTHROUGH */ |
3593 | 3599 |
3594 loser: | 3600 loser: |
3595 if (gotXmitBufLock) { | 3601 if (gotXmitBufLock) { |
3596 » ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; | 3602 ssl_ReleaseXmitBufLock(ss); |
| 3603 gotXmitBufLock = 0; |
3597 } | 3604 } |
3598 SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage", | 3605 SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage", |
3599 » » SSL_GETPID(), ss->fd)); | 3606 SSL_GETPID(), ss->fd)); |
3600 ssl_ReleaseRecvBufLock(ss); | 3607 ssl_ReleaseRecvBufLock(ss); |
3601 return SECFailure; | 3608 return SECFailure; |
3602 } | 3609 } |
3603 | 3610 |
3604 SECStatus | 3611 SECStatus |
3605 ssl2_BeginServerHandshake(sslSocket *ss) | 3612 ssl2_BeginServerHandshake(sslSocket *ss) |
3606 { | 3613 { |
3607 SECStatus rv; | 3614 SECStatus rv; |
3608 sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa; | 3615 sslServerCerts *rsaAuth = ss->serverCerts + kt_rsa; |
3609 | 3616 |
3610 ss->sec.isServer = 1; | 3617 ss->sec.isServer = 1; |
3611 ssl_ChooseSessionIDProcs(&ss->sec); | 3618 ssl_ChooseSessionIDProcs(&ss->sec); |
3612 ss->sec.sendSequence = 0; | 3619 ss->sec.sendSequence = 0; |
3613 ss->sec.rcvSequence = 0; | 3620 ss->sec.rcvSequence = 0; |
3614 | 3621 |
3615 /* don't turn on SSL2 if we don't have an RSA key and cert */ | 3622 /* don't turn on SSL2 if we don't have an RSA key and cert */ |
3616 if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || | 3623 if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || |
3617 !rsaAuth->serverCert) { | 3624 !rsaAuth->serverCert) { |
3618 » ss->opt.enableSSL2 = PR_FALSE; | 3625 ss->opt.enableSSL2 = PR_FALSE; |
3619 } | 3626 } |
3620 | 3627 |
3621 if (!ss->cipherSpecs) { | 3628 if (!ss->cipherSpecs) { |
3622 » rv = ssl2_ConstructCipherSpecs(ss); | 3629 rv = ssl2_ConstructCipherSpecs(ss); |
3623 » if (rv != SECSuccess) | 3630 if (rv != SECSuccess) |
3624 » goto loser; | 3631 goto loser; |
3625 } | 3632 } |
3626 | 3633 |
3627 /* count the SSL2 and SSL3 enabled ciphers. | 3634 /* count the SSL2 and SSL3 enabled ciphers. |
3628 * if either is zero, clear the socket's enable for that protocol. | 3635 * if either is zero, clear the socket's enable for that protocol. |
3629 */ | 3636 */ |
3630 rv = ssl2_CheckConfigSanity(ss); | 3637 rv = ssl2_CheckConfigSanity(ss); |
3631 if (rv != SECSuccess) | 3638 if (rv != SECSuccess) |
3632 » goto loser; | 3639 goto loser; |
3633 | 3640 |
3634 /* | 3641 /* |
3635 ** Generate connection-id. Always do this, even if things fail | 3642 ** Generate connection-id. Always do this, even if things fail |
3636 ** immediately. This way the random number generator is always | 3643 ** immediately. This way the random number generator is always |
3637 ** rolling around, every time we get a connection. | 3644 ** rolling around, every time we get a connection. |
3638 */ | 3645 */ |
3639 PK11_GenerateRandom(ss->sec.ci.connectionID, | 3646 PK11_GenerateRandom(ss->sec.ci.connectionID, |
3640 sizeof(ss->sec.ci.connectionID)); | 3647 sizeof(ss->sec.ci.connectionID)); |
3641 | 3648 |
3642 ss->gs.recordLen = 0; | 3649 ss->gs.recordLen = 0; |
3643 ss->handshake = ssl_GatherRecord1stHandshake; | 3650 ss->handshake = ssl_GatherRecord1stHandshake; |
3644 ss->nextHandshake = ssl2_HandleClientHelloMessage; | 3651 ss->nextHandshake = ssl2_HandleClientHelloMessage; |
3645 return SECSuccess; | 3652 return SECSuccess; |
3646 | 3653 |
3647 loser: | 3654 loser: |
3648 return SECFailure; | 3655 return SECFailure; |
3649 } | 3656 } |
3650 | 3657 |
3651 /* This function doesn't really belong in this file. | 3658 /* This function doesn't really belong in this file. |
3652 ** It's here to keep AIX compilers from optimizing it away, | 3659 ** It's here to keep AIX compilers from optimizing it away, |
3653 ** and not including it in the DSO. | 3660 ** and not including it in the DSO. |
3654 */ | 3661 */ |
3655 | 3662 |
3656 #include "nss.h" | 3663 #include "nss.h" |
3657 extern const char __nss_ssl_version[]; | 3664 extern const char __nss_ssl_version[]; |
3658 | 3665 |
3659 PRBool | 3666 PRBool |
3660 NSSSSL_VersionCheck(const char *importedVersion) | 3667 NSSSSL_VersionCheck(const char *importedVersion) |
3661 { | 3668 { |
3662 #define NSS_VERSION_VARIABLE __nss_ssl_version | 3669 #define NSS_VERSION_VARIABLE __nss_ssl_version |
3663 #include "verref.h" | 3670 #include "verref.h" |
3664 | 3671 |
3665 /* | 3672 /* |
3666 * This is the secret handshake algorithm. | 3673 * This is the secret handshake algorithm. |
3667 * | 3674 * |
3668 * This release has a simple version compatibility | 3675 * This release has a simple version compatibility |
3669 * check algorithm. This release is not backward | 3676 * check algorithm. This release is not backward |
3670 * compatible with previous major releases. It is | 3677 * compatible with previous major releases. It is |
3671 * not compatible with future major, minor, or | 3678 * not compatible with future major, minor, or |
3672 * patch releases. | 3679 * patch releases. |
3673 */ | 3680 */ |
3674 return NSS_VersionCheck(importedVersion); | 3681 return NSS_VersionCheck(importedVersion); |
3675 } | 3682 } |
3676 | 3683 |
3677 const char * | 3684 const char * |
3678 NSSSSL_GetVersion(void) | 3685 NSSSSL_GetVersion(void) |
3679 { | 3686 { |
3680 return NSS_VERSION; | 3687 return NSS_VERSION; |
3681 } | 3688 } |
OLD | NEW |