OLD | NEW |
1 /* | 1 /* |
2 * Various SSL functions. | 2 * Various SSL functions. |
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 #include "cert.h" | 7 #include "cert.h" |
8 #include "secitem.h" | 8 #include "secitem.h" |
9 #include "keyhi.h" | 9 #include "keyhi.h" |
10 #include "ssl.h" | 10 #include "ssl.h" |
11 #include "sslimpl.h" | 11 #include "sslimpl.h" |
12 #include "sslproto.h" | 12 #include "sslproto.h" |
13 #include "secoid.h"» /* for SECOID_GetALgorithmTag */ | 13 #include "secoid.h" /* for SECOID_GetALgorithmTag */ |
14 #include "pk11func.h"» /* for PK11_GenerateRandom */ | 14 #include "pk11func.h" /* for PK11_GenerateRandom */ |
15 #include "nss.h" /* for NSS_RegisterShutdown */ | 15 #include "nss.h" /* for NSS_RegisterShutdown */ |
16 #include "prinit.h" /* for PR_CallOnceWithArg */ | 16 #include "prinit.h" /* for PR_CallOnceWithArg */ |
17 | 17 |
18 #define MAX_BLOCK_CYPHER_SIZE» 32 | 18 #define MAX_BLOCK_CYPHER_SIZE 32 |
19 | 19 |
20 #define TEST_FOR_FAILURE» /* reminder */ | 20 #define TEST_FOR_FAILURE /* reminder */ |
21 #define SET_ERROR_CODE» » /* reminder */ | 21 #define SET_ERROR_CODE /* reminder */ |
22 | 22 |
23 /* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock. | 23 /* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock. |
24 * | 24 * |
25 * Currently, the list of functions called through ss->handshake is: | 25 * Currently, the list of functions called through ss->handshake is: |
26 * | 26 * |
27 * In sslsocks.c: | 27 * In sslsocks.c: |
28 * SocksGatherRecord | 28 * SocksGatherRecord |
29 * SocksHandleReply» | 29 * SocksHandleReply |
30 * SocksStartGather | 30 * SocksStartGather |
31 * | 31 * |
32 * In sslcon.c: | 32 * In sslcon.c: |
33 * ssl_GatherRecord1stHandshake | 33 * ssl_GatherRecord1stHandshake |
34 * ssl2_HandleClientSessionKeyMessage | 34 * ssl2_HandleClientSessionKeyMessage |
35 * ssl2_HandleMessage | 35 * ssl2_HandleMessage |
36 * ssl2_HandleVerifyMessage | 36 * ssl2_HandleVerifyMessage |
37 * ssl2_BeginClientHandshake | 37 * ssl2_BeginClientHandshake |
38 * ssl2_BeginServerHandshake | 38 * ssl2_BeginServerHandshake |
39 * ssl2_HandleClientHelloMessage | 39 * ssl2_HandleClientHelloMessage |
40 * ssl2_HandleServerHelloMessage | 40 * ssl2_HandleServerHelloMessage |
41 * | 41 * |
42 * The ss->handshake function returns SECWouldBlock under these conditions: | 42 * The ss->handshake function returns SECWouldBlock under these conditions: |
43 * 1.» ssl_GatherRecord1stHandshake called ssl2_GatherData which read in | 43 * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in |
44 *» the beginning of an SSL v3 hello message and returned SECWouldBlock | 44 * the beginning of an SSL v3 hello message and returned SECWouldBlock |
45 *» to switch to SSL v3 handshake processing. | 45 * to switch to SSL v3 handshake processing. |
46 * | 46 * |
47 * 2.» ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming | 47 * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming |
48 *» v2 client hello msg, and called ssl3_HandleV2ClientHello which | 48 * v2 client hello msg, and called ssl3_HandleV2ClientHello which |
49 *» returned SECWouldBlock. | 49 * returned SECWouldBlock. |
50 * | 50 * |
51 * 3. SECWouldBlock was returned by one of the callback functions, via | 51 * 3. SECWouldBlock was returned by one of the callback functions, via |
52 *» one of these paths: | 52 * one of these paths: |
53 * -» ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> | 53 * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> |
54 *» ss->getClientAuthData() | 54 * ss->getClientAuthData() |
55 * | 55 * |
56 * -» ssl2_HandleServerHelloMessage() -> ss->handleBadCert() | 56 * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert() |
57 * | 57 * |
58 * -» ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> | 58 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> |
59 *» ssl3_HandleRecord() -> ssl3_HandleHandshake() -> | 59 * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> |
60 *» ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() -> | 60 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() -> |
61 *» ss->handleBadCert() | 61 * ss->handleBadCert() |
62 * | 62 * |
63 * -» ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> | 63 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> |
64 *» ssl3_HandleRecord() -> ssl3_HandleHandshake() -> | 64 * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> |
65 *» ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() -> | 65 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() -> |
66 *» ss->getClientAuthData() | 66 * ss->getClientAuthData() |
67 * | 67 * |
68 * Called from: SSL_ForceHandshake» (below), | 68 * Called from: SSL_ForceHandshake (below), |
69 * ssl_SecureRecv »» (below) and | 69 * ssl_SecureRecv (below) and |
70 * ssl_SecureSend» » (below) | 70 * ssl_SecureSend (below) |
71 *» from: WaitForResponse » in sslsocks.c | 71 * from: WaitForResponse in sslsocks.c |
72 *» ssl_SocksRecv » in sslsocks.c | 72 * ssl_SocksRecv in sslsocks.c |
73 * ssl_SocksSend » in sslsocks.c | 73 * ssl_SocksSend in sslsocks.c |
74 * | 74 * |
75 * Caller must hold the (write) handshakeLock. | 75 * Caller must hold the (write) handshakeLock. |
76 */ | 76 */ |
77 int | 77 int |
78 ssl_Do1stHandshake(sslSocket *ss) | 78 ssl_Do1stHandshake(sslSocket *ss) |
79 { | 79 { |
80 int rv = SECSuccess; | 80 int rv = SECSuccess; |
81 int loopCount = 0; | 81 int loopCount = 0; |
82 | 82 |
83 do { | 83 do { |
84 » PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 84 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
85 » PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); | 85 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); |
86 » PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); | 86 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); |
87 » PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); | 87 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); |
88 | 88 |
89 » if (ss->handshake == 0) { | 89 if (ss->handshake == 0) { |
90 » /* Previous handshake finished. Switch to next one */ | 90 /* Previous handshake finished. Switch to next one */ |
91 » ss->handshake = ss->nextHandshake; | 91 ss->handshake = ss->nextHandshake; |
92 » ss->nextHandshake = 0; | 92 ss->nextHandshake = 0; |
93 » } | 93 } |
94 » if (ss->handshake == 0) { | 94 if (ss->handshake == 0) { |
95 » /* Previous handshake finished. Switch to security handshake */ | 95 /* Previous handshake finished. Switch to security handshake */ |
96 » ss->handshake = ss->securityHandshake; | 96 ss->handshake = ss->securityHandshake; |
97 » ss->securityHandshake = 0; | 97 ss->securityHandshake = 0; |
98 » } | 98 } |
99 » if (ss->handshake == 0) { | 99 if (ss->handshake == 0) { |
100 » /* for v3 this is done in ssl3_FinishHandshake */ | 100 /* for v3 this is done in ssl3_FinishHandshake */ |
101 » if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) { | 101 if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) { |
102 » » ssl_GetRecvBufLock(ss); | 102 ssl_GetRecvBufLock(ss); |
103 » » ss->gs.recordLen = 0; | 103 ss->gs.recordLen = 0; |
104 » » ssl_FinishHandshake(ss); | 104 ssl_FinishHandshake(ss); |
105 » » ssl_ReleaseRecvBufLock(ss); | 105 ssl_ReleaseRecvBufLock(ss); |
106 » } | 106 } |
107 » break; | 107 break; |
108 » } | 108 } |
109 » rv = (*ss->handshake)(ss); | 109 rv = (*ss->handshake)(ss); |
110 » ++loopCount; | 110 ++loopCount; |
111 /* This code must continue to loop on SECWouldBlock, | 111 /* This code must continue to loop on SECWouldBlock, |
112 * or any positive value.» See XXX_1 comments. | 112 * or any positive value. See XXX_1 comments. |
113 */ | 113 */ |
114 } while (rv != SECFailure); » /* was (rv >= 0); XXX_1 */ | 114 } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */ |
115 | 115 |
116 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); | 116 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); |
117 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); | 117 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); |
118 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); | 118 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); |
119 | 119 |
120 if (rv == SECWouldBlock) { | 120 if (rv == SECWouldBlock) { |
121 » PORT_SetError(PR_WOULD_BLOCK_ERROR); | 121 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
122 » rv = SECFailure; | 122 rv = SECFailure; |
123 } | 123 } |
124 return rv; | 124 return rv; |
125 } | 125 } |
126 | 126 |
127 void | 127 void |
128 ssl_FinishHandshake(sslSocket *ss) | 128 ssl_FinishHandshake(sslSocket *ss) |
129 { | 129 { |
130 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 130 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
131 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 131 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); |
132 | 132 |
133 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd)); | 133 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd)); |
134 | 134 |
135 ss->firstHsDone = PR_TRUE; | 135 ss->firstHsDone = PR_TRUE; |
136 ss->enoughFirstHsDone = PR_TRUE; | 136 ss->enoughFirstHsDone = PR_TRUE; |
137 ss->gs.writeOffset = 0; | 137 ss->gs.writeOffset = 0; |
138 ss->gs.readOffset = 0; | 138 ss->gs.readOffset = 0; |
139 | 139 |
140 if (ss->handshakeCallback) { | 140 if (ss->handshakeCallback) { |
141 PORT_Assert(ss->version < SSL_LIBRARY_VERSION_3_0 || | 141 PORT_Assert(ss->version < SSL_LIBRARY_VERSION_3_0 || |
142 (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == | 142 (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) == |
143 ssl_preinfo_all); | 143 ssl_preinfo_all); |
144 » (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); | 144 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
145 } | 145 } |
146 } | 146 } |
147 | 147 |
148 /* | 148 /* |
149 * Handshake function that blocks. Used to force a | 149 * Handshake function that blocks. Used to force a |
150 * retry on a connection on the next read/write. | 150 * retry on a connection on the next read/write. |
151 */ | 151 */ |
152 static SECStatus | 152 static SECStatus |
153 ssl3_AlwaysBlock(sslSocket *ss) | 153 ssl3_AlwaysBlock(sslSocket *ss) |
154 { | 154 { |
155 PORT_SetError(PR_WOULD_BLOCK_ERROR);» /* perhaps redundant. */ | 155 PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */ |
156 return SECWouldBlock; | 156 return SECWouldBlock; |
157 } | 157 } |
158 | 158 |
159 /* | 159 /* |
160 * set the initial handshake state machine to block | 160 * set the initial handshake state machine to block |
161 */ | 161 */ |
162 void | 162 void |
163 ssl3_SetAlwaysBlock(sslSocket *ss) | 163 ssl3_SetAlwaysBlock(sslSocket *ss) |
164 { | 164 { |
165 if (!ss->firstHsDone) { | 165 if (!ss->firstHsDone) { |
166 » ss->handshake = ssl3_AlwaysBlock; | 166 ss->handshake = ssl3_AlwaysBlock; |
167 » ss->nextHandshake = 0; | 167 ss->nextHandshake = 0; |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 static SECStatus | 171 static SECStatus |
172 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout) | 172 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout) |
173 { | 173 { |
174 sslSocket *ss; | 174 sslSocket *ss; |
175 | 175 |
176 ss = ssl_FindSocket(fd); | 176 ss = ssl_FindSocket(fd); |
177 if (!ss) { | 177 if (!ss) { |
178 » SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd)); | 178 SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd)); |
179 » return SECFailure; | 179 return SECFailure; |
180 } | 180 } |
181 SSL_LOCK_READER(ss); | 181 SSL_LOCK_READER(ss); |
182 ss->rTimeout = timeout; | 182 ss->rTimeout = timeout; |
183 if (ss->opt.fdx) { | 183 if (ss->opt.fdx) { |
184 SSL_LOCK_WRITER(ss); | 184 SSL_LOCK_WRITER(ss); |
185 } | 185 } |
186 ss->wTimeout = timeout; | 186 ss->wTimeout = timeout; |
187 if (ss->opt.fdx) { | 187 if (ss->opt.fdx) { |
188 SSL_UNLOCK_WRITER(ss); | 188 SSL_UNLOCK_WRITER(ss); |
189 } | 189 } |
190 SSL_UNLOCK_READER(ss); | 190 SSL_UNLOCK_READER(ss); |
191 return SECSuccess; | 191 return SECSuccess; |
192 } | 192 } |
193 | 193 |
194 /* Acquires and releases HandshakeLock. | 194 /* Acquires and releases HandshakeLock. |
195 */ | 195 */ |
196 SECStatus | 196 SECStatus |
197 SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) | 197 SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) |
198 { | 198 { |
199 sslSocket *ss; | 199 sslSocket *ss; |
200 SECStatus status; | 200 SECStatus status; |
201 PRNetAddr addr; | 201 PRNetAddr addr; |
202 | 202 |
203 ss = ssl_FindSocket(s); | 203 ss = ssl_FindSocket(s); |
204 if (!ss) { | 204 if (!ss) { |
205 » SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s)); | 205 SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s)); |
206 » return SECFailure; | 206 return SECFailure; |
207 } | 207 } |
208 | 208 |
209 /* Don't waste my time */ | 209 /* Don't waste my time */ |
210 if (!ss->opt.useSecurity) | 210 if (!ss->opt.useSecurity) |
211 » return SECSuccess; | 211 return SECSuccess; |
212 | 212 |
213 SSL_LOCK_READER(ss); | 213 SSL_LOCK_READER(ss); |
214 SSL_LOCK_WRITER(ss); | 214 SSL_LOCK_WRITER(ss); |
215 | 215 |
216 /* Reset handshake state */ | 216 /* Reset handshake state */ |
217 ssl_Get1stHandshakeLock(ss); | 217 ssl_Get1stHandshakeLock(ss); |
218 | 218 |
219 ss->firstHsDone = PR_FALSE; | 219 ss->firstHsDone = PR_FALSE; |
220 ss->enoughFirstHsDone = PR_FALSE; | 220 ss->enoughFirstHsDone = PR_FALSE; |
221 if ( asServer ) { | 221 if (asServer) { |
222 » ss->handshake = ssl2_BeginServerHandshake; | 222 ss->handshake = ssl2_BeginServerHandshake; |
223 » ss->handshaking = sslHandshakingAsServer; | 223 ss->handshaking = sslHandshakingAsServer; |
224 } else { | 224 } else { |
225 » ss->handshake = ssl2_BeginClientHandshake; | 225 ss->handshake = ssl2_BeginClientHandshake; |
226 » ss->handshaking = sslHandshakingAsClient; | 226 ss->handshaking = sslHandshakingAsClient; |
227 } | 227 } |
228 ss->nextHandshake = 0; | 228 ss->nextHandshake = 0; |
229 ss->securityHandshake = 0; | 229 ss->securityHandshake = 0; |
230 | 230 |
231 ssl_GetRecvBufLock(ss); | 231 ssl_GetRecvBufLock(ss); |
232 status = ssl_InitGather(&ss->gs); | 232 status = ssl_InitGather(&ss->gs); |
233 ssl_ReleaseRecvBufLock(ss); | 233 ssl_ReleaseRecvBufLock(ss); |
234 | 234 |
235 ssl_GetSSL3HandshakeLock(ss); | 235 ssl_GetSSL3HandshakeLock(ss); |
236 ss->ssl3.hs.canFalseStart = PR_FALSE; | 236 ss->ssl3.hs.canFalseStart = PR_FALSE; |
237 ss->ssl3.hs.restartTarget = NULL; | 237 ss->ssl3.hs.restartTarget = NULL; |
238 | 238 |
239 /* | 239 /* |
240 ** Blow away old security state and get a fresh setup. | 240 ** Blow away old security state and get a fresh setup. |
241 */ | 241 */ |
242 ssl_GetXmitBufLock(ss); | 242 ssl_GetXmitBufLock(ss); |
243 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE); | 243 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE); |
244 status = ssl_CreateSecurityInfo(ss); | 244 status = ssl_CreateSecurityInfo(ss); |
245 ssl_ReleaseXmitBufLock(ss); | 245 ssl_ReleaseXmitBufLock(ss); |
246 | 246 |
247 ssl_ReleaseSSL3HandshakeLock(ss); | 247 ssl_ReleaseSSL3HandshakeLock(ss); |
248 ssl_Release1stHandshakeLock(ss); | 248 ssl_Release1stHandshakeLock(ss); |
249 | 249 |
250 if (!ss->TCPconnected) | 250 if (!ss->TCPconnected) |
251 » ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); | 251 ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); |
252 | 252 |
253 SSL_UNLOCK_WRITER(ss); | 253 SSL_UNLOCK_WRITER(ss); |
254 SSL_UNLOCK_READER(ss); | 254 SSL_UNLOCK_READER(ss); |
255 | 255 |
256 return status; | 256 return status; |
257 } | 257 } |
258 | 258 |
259 /* For SSLv2, does nothing but return an error. | 259 /* For SSLv2, does nothing but return an error. |
260 ** For SSLv3, flushes SID cache entry (if requested), | 260 ** For SSLv3, flushes SID cache entry (if requested), |
261 ** and then starts new client hello or hello request. | 261 ** and then starts new client hello or hello request. |
262 ** Acquires and releases HandshakeLock. | 262 ** Acquires and releases HandshakeLock. |
263 */ | 263 */ |
264 SECStatus | 264 SECStatus |
265 SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache) | 265 SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache) |
266 { | 266 { |
267 sslSocket *ss; | 267 sslSocket *ss; |
268 SECStatus rv; | 268 SECStatus rv; |
269 | 269 |
270 ss = ssl_FindSocket(fd); | 270 ss = ssl_FindSocket(fd); |
271 if (!ss) { | 271 if (!ss) { |
272 » SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd)); | 272 SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd)); |
273 » return SECFailure; | 273 return SECFailure; |
274 } | 274 } |
275 | 275 |
276 if (!ss->opt.useSecurity) | 276 if (!ss->opt.useSecurity) |
277 » return SECSuccess; | 277 return SECSuccess; |
278 | 278 |
279 ssl_Get1stHandshakeLock(ss); | 279 ssl_Get1stHandshakeLock(ss); |
280 | 280 |
281 /* SSL v2 protocol does not support subsequent handshakes. */ | 281 /* SSL v2 protocol does not support subsequent handshakes. */ |
282 if (ss->version < SSL_LIBRARY_VERSION_3_0) { | 282 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
283 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 283 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
284 » rv = SECFailure; | 284 rv = SECFailure; |
285 } else { | 285 } else { |
286 » ssl_GetSSL3HandshakeLock(ss); | 286 ssl_GetSSL3HandshakeLock(ss); |
287 » rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */ | 287 rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */ |
288 » ssl_ReleaseSSL3HandshakeLock(ss); | 288 ssl_ReleaseSSL3HandshakeLock(ss); |
289 } | 289 } |
290 | 290 |
291 ssl_Release1stHandshakeLock(ss); | 291 ssl_Release1stHandshakeLock(ss); |
292 | 292 |
293 return rv; | 293 return rv; |
294 } | 294 } |
295 | 295 |
296 /* | 296 /* |
297 ** Same as above, but with an I/O timeout. | 297 ** Same as above, but with an I/O timeout. |
298 */ | 298 */ |
299 SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, | 299 SSL_IMPORT SECStatus |
300 PRBool flushCache, | 300 SSL_ReHandshakeWithTimeout(PRFileDesc *fd, |
301 PRIntervalTime timeout) | 301 PRBool flushCache, |
| 302 PRIntervalTime timeout) |
302 { | 303 { |
303 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { | 304 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { |
304 return SECFailure; | 305 return SECFailure; |
305 } | 306 } |
306 return SSL_ReHandshake(fd, flushCache); | 307 return SSL_ReHandshake(fd, flushCache); |
307 } | 308 } |
308 | 309 |
309 SECStatus | 310 SECStatus |
310 SSL_RedoHandshake(PRFileDesc *fd) | 311 SSL_RedoHandshake(PRFileDesc *fd) |
311 { | 312 { |
312 return SSL_ReHandshake(fd, PR_TRUE); | 313 return SSL_ReHandshake(fd, PR_TRUE); |
313 } | 314 } |
314 | 315 |
315 /* Register an application callback to be called when SSL handshake completes. | 316 /* Register an application callback to be called when SSL handshake completes. |
316 ** Acquires and releases HandshakeLock. | 317 ** Acquires and releases HandshakeLock. |
317 */ | 318 */ |
318 SECStatus | 319 SECStatus |
319 SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb, | 320 SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb, |
320 » » void *client_data) | 321 void *client_data) |
321 { | 322 { |
322 sslSocket *ss; | 323 sslSocket *ss; |
323 | 324 |
324 ss = ssl_FindSocket(fd); | 325 ss = ssl_FindSocket(fd); |
325 if (!ss) { | 326 if (!ss) { |
326 » SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback", | 327 SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback", |
327 » » SSL_GETPID(), fd)); | 328 SSL_GETPID(), fd)); |
328 » return SECFailure; | 329 return SECFailure; |
329 } | 330 } |
330 | 331 |
331 if (!ss->opt.useSecurity) { | 332 if (!ss->opt.useSecurity) { |
332 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 333 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
333 » return SECFailure; | 334 return SECFailure; |
334 } | 335 } |
335 | 336 |
336 ssl_Get1stHandshakeLock(ss); | 337 ssl_Get1stHandshakeLock(ss); |
337 ssl_GetSSL3HandshakeLock(ss); | 338 ssl_GetSSL3HandshakeLock(ss); |
338 | 339 |
339 ss->handshakeCallback = cb; | 340 ss->handshakeCallback = cb; |
340 ss->handshakeCallbackData = client_data; | 341 ss->handshakeCallbackData = client_data; |
341 | 342 |
342 ssl_ReleaseSSL3HandshakeLock(ss); | 343 ssl_ReleaseSSL3HandshakeLock(ss); |
343 ssl_Release1stHandshakeLock(ss); | 344 ssl_Release1stHandshakeLock(ss); |
344 | 345 |
345 return SECSuccess; | 346 return SECSuccess; |
346 } | 347 } |
347 | 348 |
348 /* Register an application callback to be called when false start may happen. | 349 /* Register an application callback to be called when false start may happen. |
349 ** Acquires and releases HandshakeLock. | 350 ** Acquires and releases HandshakeLock. |
350 */ | 351 */ |
351 SECStatus | 352 SECStatus |
352 SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb, | 353 SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb, |
353 » » » void *arg) | 354 void *arg) |
354 { | 355 { |
355 sslSocket *ss; | 356 sslSocket *ss; |
356 | 357 |
357 ss = ssl_FindSocket(fd); | 358 ss = ssl_FindSocket(fd); |
358 if (!ss) { | 359 if (!ss) { |
359 » SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback", | 360 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback", |
360 » » SSL_GETPID(), fd)); | 361 SSL_GETPID(), fd)); |
361 » return SECFailure; | 362 return SECFailure; |
362 } | 363 } |
363 | 364 |
364 if (!ss->opt.useSecurity) { | 365 if (!ss->opt.useSecurity) { |
365 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 366 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
366 » return SECFailure; | 367 return SECFailure; |
367 } | 368 } |
368 | 369 |
369 ssl_Get1stHandshakeLock(ss); | 370 ssl_Get1stHandshakeLock(ss); |
370 ssl_GetSSL3HandshakeLock(ss); | 371 ssl_GetSSL3HandshakeLock(ss); |
371 | 372 |
372 ss->canFalseStartCallback = cb; | 373 ss->canFalseStartCallback = cb; |
373 ss->canFalseStartCallbackData = arg; | 374 ss->canFalseStartCallbackData = arg; |
374 | 375 |
375 ssl_ReleaseSSL3HandshakeLock(ss); | 376 ssl_ReleaseSSL3HandshakeLock(ss); |
376 ssl_Release1stHandshakeLock(ss); | 377 ssl_Release1stHandshakeLock(ss); |
377 | 378 |
378 return SECSuccess; | 379 return SECSuccess; |
379 } | 380 } |
380 | 381 |
381 SECStatus | 382 SECStatus |
382 SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart) | 383 SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart) |
383 { | 384 { |
384 sslSocket *ss; | 385 sslSocket *ss; |
385 | 386 |
386 *canFalseStart = PR_FALSE; | 387 *canFalseStart = PR_FALSE; |
387 ss = ssl_FindSocket(fd); | 388 ss = ssl_FindSocket(fd); |
388 if (!ss) { | 389 if (!ss) { |
389 » SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart", | 390 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart", |
390 » » SSL_GETPID(), fd)); | 391 SSL_GETPID(), fd)); |
391 » return SECFailure; | 392 return SECFailure; |
392 } | 393 } |
393 | 394 |
394 if (!ss->ssl3.initialized) { | 395 if (!ss->ssl3.initialized) { |
395 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 396 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
396 » return SECFailure; | 397 return SECFailure; |
397 } | 398 } |
398 | 399 |
399 if (ss->version < SSL_LIBRARY_VERSION_3_0) { | 400 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
400 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 401 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
401 » return SECFailure; | 402 return SECFailure; |
402 } | 403 } |
403 | 404 |
404 /* Require a forward-secret key exchange. */ | 405 /* Require a forward-secret key exchange. */ |
405 *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss || | 406 *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss || |
406 » » ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || | 407 ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || |
407 » » ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || | 408 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
408 » » ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa; | 409 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa; |
409 | 410 |
410 return SECSuccess; | 411 return SECSuccess; |
411 } | 412 } |
412 | 413 |
413 /* Try to make progress on an SSL handshake by attempting to read the | 414 /* Try to make progress on an SSL handshake by attempting to read the |
414 ** next handshake from the peer, and sending any responses. | 415 ** next handshake from the peer, and sending any responses. |
415 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot | 416 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot |
416 ** read the next handshake from the underlying socket. | 417 ** read the next handshake from the underlying socket. |
417 ** For SSLv2, returns when handshake is complete or fatal error occurs. | 418 ** For SSLv2, returns when handshake is complete or fatal error occurs. |
418 ** For SSLv3, returns when handshake is complete, or application data has | 419 ** For SSLv3, returns when handshake is complete, or application data has |
419 ** arrived that must be taken by application before handshake can continue, | 420 ** arrived that must be taken by application before handshake can continue, |
420 ** or a fatal error occurs. | 421 ** or a fatal error occurs. |
421 ** Application should use handshake completion callback to tell which. | 422 ** Application should use handshake completion callback to tell which. |
422 */ | 423 */ |
423 SECStatus | 424 SECStatus |
424 SSL_ForceHandshake(PRFileDesc *fd) | 425 SSL_ForceHandshake(PRFileDesc *fd) |
425 { | 426 { |
426 sslSocket *ss; | 427 sslSocket *ss; |
427 SECStatus rv = SECFailure; | 428 SECStatus rv = SECFailure; |
428 | 429 |
429 ss = ssl_FindSocket(fd); | 430 ss = ssl_FindSocket(fd); |
430 if (!ss) { | 431 if (!ss) { |
431 » SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake", | 432 SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake", |
432 » » SSL_GETPID(), fd)); | 433 SSL_GETPID(), fd)); |
433 » return rv; | 434 return rv; |
434 } | 435 } |
435 | 436 |
436 /* Don't waste my time */ | 437 /* Don't waste my time */ |
437 if (!ss->opt.useSecurity) | 438 if (!ss->opt.useSecurity) |
438 » return SECSuccess; | 439 return SECSuccess; |
439 | 440 |
440 if (!ssl_SocketIsBlocking(ss)) { | 441 if (!ssl_SocketIsBlocking(ss)) { |
441 » ssl_GetXmitBufLock(ss); | 442 ssl_GetXmitBufLock(ss); |
442 » if (ss->pendingBuf.len != 0) { | 443 if (ss->pendingBuf.len != 0) { |
443 » int sent = ssl_SendSavedWriteData(ss); | 444 int sent = ssl_SendSavedWriteData(ss); |
444 » if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { | 445 if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { |
445 » » ssl_ReleaseXmitBufLock(ss); | 446 ssl_ReleaseXmitBufLock(ss); |
446 » » return SECFailure; | 447 return SECFailure; |
447 » } | 448 } |
448 » } | 449 } |
449 » ssl_ReleaseXmitBufLock(ss); | 450 ssl_ReleaseXmitBufLock(ss); |
450 } | 451 } |
451 | 452 |
452 ssl_Get1stHandshakeLock(ss); | 453 ssl_Get1stHandshakeLock(ss); |
453 | 454 |
454 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { | 455 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
455 » int gatherResult; | 456 int gatherResult; |
456 | 457 |
457 » ssl_GetRecvBufLock(ss); | 458 ssl_GetRecvBufLock(ss); |
458 » gatherResult = ssl3_GatherCompleteHandshake(ss, 0); | 459 gatherResult = ssl3_GatherCompleteHandshake(ss, 0); |
459 » ssl_ReleaseRecvBufLock(ss); | 460 ssl_ReleaseRecvBufLock(ss); |
460 » if (gatherResult > 0) { | 461 if (gatherResult > 0) { |
461 » rv = SECSuccess; | 462 rv = SECSuccess; |
462 » } else if (gatherResult == 0) { | 463 } else if (gatherResult == 0) { |
463 » PORT_SetError(PR_END_OF_FILE_ERROR); | 464 PORT_SetError(PR_END_OF_FILE_ERROR); |
464 » } else if (gatherResult == SECWouldBlock) { | 465 } else if (gatherResult == SECWouldBlock) { |
465 » PORT_SetError(PR_WOULD_BLOCK_ERROR); | 466 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
466 » } | 467 } |
467 } else if (!ss->firstHsDone) { | 468 } else if (!ss->firstHsDone) { |
468 » rv = ssl_Do1stHandshake(ss); | 469 rv = ssl_Do1stHandshake(ss); |
469 } else { | 470 } else { |
470 » /* tried to force handshake on an SSL 2 socket that has | 471 /* tried to force handshake on an SSL 2 socket that has |
471 » ** already completed the handshake. */ | 472 ** already completed the handshake. */ |
472 » rv = SECSuccess;» /* just pretend we did it. */ | 473 rv = SECSuccess; /* just pretend we did it. */ |
473 } | 474 } |
474 | 475 |
475 ssl_Release1stHandshakeLock(ss); | 476 ssl_Release1stHandshakeLock(ss); |
476 | 477 |
477 return rv; | 478 return rv; |
478 } | 479 } |
479 | 480 |
480 /* | 481 /* |
481 ** Same as above, but with an I/O timeout. | 482 ** Same as above, but with an I/O timeout. |
482 */ | 483 */ |
483 SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, | 484 SSL_IMPORT SECStatus |
484 PRIntervalTime timeout) | 485 SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, |
| 486 PRIntervalTime timeout) |
485 { | 487 { |
486 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { | 488 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { |
487 return SECFailure; | 489 return SECFailure; |
488 } | 490 } |
489 return SSL_ForceHandshake(fd); | 491 return SSL_ForceHandshake(fd); |
490 } | 492 } |
491 | 493 |
492 | |
493 /************************************************************************/ | 494 /************************************************************************/ |
494 | 495 |
495 /* | 496 /* |
496 ** Grow a buffer to hold newLen bytes of data. | 497 ** Grow a buffer to hold newLen bytes of data. |
497 ** Called for both recv buffers and xmit buffers. | 498 ** Called for both recv buffers and xmit buffers. |
498 ** Caller must hold xmitBufLock or recvBufLock, as appropriate. | 499 ** Caller must hold xmitBufLock or recvBufLock, as appropriate. |
499 */ | 500 */ |
500 SECStatus | 501 SECStatus |
501 sslBuffer_Grow(sslBuffer *b, unsigned int newLen) | 502 sslBuffer_Grow(sslBuffer *b, unsigned int newLen) |
502 { | 503 { |
503 newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); | 504 newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); |
504 if (newLen > b->space) { | 505 if (newLen > b->space) { |
505 » unsigned char *newBuf; | 506 unsigned char *newBuf; |
506 » if (b->buf) { | 507 if (b->buf) { |
507 » newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen); | 508 newBuf = (unsigned char *)PORT_Realloc(b->buf, newLen); |
508 » } else { | 509 } else { |
509 » newBuf = (unsigned char *) PORT_Alloc(newLen); | 510 newBuf = (unsigned char *)PORT_Alloc(newLen); |
510 » } | 511 } |
511 » if (!newBuf) { | 512 if (!newBuf) { |
512 » return SECFailure; | 513 return SECFailure; |
513 » } | 514 } |
514 » SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", | 515 SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", |
515 » » SSL_GETPID(), b->space, newLen)); | 516 SSL_GETPID(), b->space, newLen)); |
516 » b->buf = newBuf; | 517 b->buf = newBuf; |
517 » b->space = newLen; | 518 b->space = newLen; |
518 } | 519 } |
519 return SECSuccess; | 520 return SECSuccess; |
520 } | 521 } |
521 | 522 |
522 SECStatus | 523 SECStatus |
523 sslBuffer_Append(sslBuffer *b, const void * data, unsigned int len) | 524 sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len) |
524 { | 525 { |
525 unsigned int newLen = b->len + len; | 526 unsigned int newLen = b->len + len; |
526 SECStatus rv; | 527 SECStatus rv; |
527 | 528 |
528 rv = sslBuffer_Grow(b, newLen); | 529 rv = sslBuffer_Grow(b, newLen); |
529 if (rv != SECSuccess) | 530 if (rv != SECSuccess) |
530 » return rv; | 531 return rv; |
531 PORT_Memcpy(b->buf + b->len, data, len); | 532 PORT_Memcpy(b->buf + b->len, data, len); |
532 b->len += len; | 533 b->len += len; |
533 return SECSuccess; | 534 return SECSuccess; |
534 } | 535 } |
535 | 536 |
536 /* | 537 /* |
537 ** Save away write data that is trying to be written before the security | 538 ** Save away write data that is trying to be written before the security |
538 ** handshake has been completed. When the handshake is completed, we will | 539 ** handshake has been completed. When the handshake is completed, we will |
539 ** flush this data out. | 540 ** flush this data out. |
540 ** Caller must hold xmitBufLock | 541 ** Caller must hold xmitBufLock |
541 */ | 542 */ |
542 SECStatus | 543 SECStatus |
543 ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) | 544 ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) |
544 { | 545 { |
545 SECStatus rv; | 546 SECStatus rv; |
546 | 547 |
547 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 548 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
548 rv = sslBuffer_Append(&ss->pendingBuf, data, len); | 549 rv = sslBuffer_Append(&ss->pendingBuf, data, len); |
549 SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)", | 550 SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)", |
550 » » SSL_GETPID(), ss->fd, len, ss->pendingBuf.len)); | 551 SSL_GETPID(), ss->fd, len, ss->pendingBuf.len)); |
551 return rv; | 552 return rv; |
552 } | 553 } |
553 | 554 |
554 /* | 555 /* |
555 ** Send saved write data. This will flush out data sent prior to a | 556 ** Send saved write data. This will flush out data sent prior to a |
556 ** complete security handshake. Hopefully there won't be too much of it. | 557 ** complete security handshake. Hopefully there won't be too much of it. |
557 ** Returns count of the bytes sent, NOT a SECStatus. | 558 ** Returns count of the bytes sent, NOT a SECStatus. |
558 ** Caller must hold xmitBufLock | 559 ** Caller must hold xmitBufLock |
559 */ | 560 */ |
560 int | 561 int |
561 ssl_SendSavedWriteData(sslSocket *ss) | 562 ssl_SendSavedWriteData(sslSocket *ss) |
562 { | 563 { |
563 int rv» = 0; | 564 int rv = 0; |
564 | 565 |
565 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 566 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
566 if (ss->pendingBuf.len != 0) { | 567 if (ss->pendingBuf.len != 0) { |
567 » SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", | 568 SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", |
568 » » SSL_GETPID(), ss->fd, ss->pendingBuf.len)); | 569 SSL_GETPID(), ss->fd, ss->pendingBuf.len)); |
569 » rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); | 570 rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); |
570 » if (rv < 0) { | 571 if (rv < 0) { |
571 » return rv; | 572 return rv; |
572 » } | 573 } |
573 » ss->pendingBuf.len -= rv; | 574 ss->pendingBuf.len -= rv; |
574 » if (ss->pendingBuf.len > 0 && rv > 0) { | 575 if (ss->pendingBuf.len > 0 && rv > 0) { |
575 » /* UGH !! This shifts the whole buffer down by copying it */ | 576 /* UGH !! This shifts the whole buffer down by copying it */ |
576 » PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, | 577 PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, |
577 » ss->pendingBuf.len); | 578 ss->pendingBuf.len); |
578 » } | 579 } |
579 } | 580 } |
580 return rv; | 581 return rv; |
581 } | 582 } |
582 | 583 |
583 /************************************************************************/ | 584 /************************************************************************/ |
584 | 585 |
585 /* | 586 /* |
586 ** Receive some application data on a socket. Reads SSL records from the input | 587 ** Receive some application data on a socket. Reads SSL records from the input |
587 ** stream, decrypts them and then copies them to the output buffer. | 588 ** stream, decrypts them and then copies them to the output buffer. |
588 ** Called from ssl_SecureRecv() below. | 589 ** Called from ssl_SecureRecv() below. |
589 ** | 590 ** |
590 ** Caller does NOT hold 1stHandshakeLock because that handshake is over. | 591 ** Caller does NOT hold 1stHandshakeLock because that handshake is over. |
591 ** Caller doesn't call this until initial handshake is complete. | 592 ** Caller doesn't call this until initial handshake is complete. |
592 ** For SSLv2, there is no subsequent handshake. | 593 ** For SSLv2, there is no subsequent handshake. |
593 ** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake | 594 ** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake |
594 ** messages from a subsequent handshake. | 595 ** messages from a subsequent handshake. |
595 ** | 596 ** |
596 ** This code is similar to, and easily confused with, | 597 ** This code is similar to, and easily confused with, |
597 ** ssl_GatherRecord1stHandshake() in sslcon.c | 598 ** ssl_GatherRecord1stHandshake() in sslcon.c |
598 */ | 599 */ |
599 static int | 600 static int |
600 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) | 601 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) |
601 { | 602 { |
602 int rv; | 603 int rv; |
603 int amount; | 604 int amount; |
604 int available; | 605 int available; |
605 | 606 |
606 /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the | 607 /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the |
607 * 1stHandshakeLock. */ | 608 * 1stHandshakeLock. */ |
608 ssl_Get1stHandshakeLock(ss); | 609 ssl_Get1stHandshakeLock(ss); |
609 ssl_GetRecvBufLock(ss); | 610 ssl_GetRecvBufLock(ss); |
610 | 611 |
611 available = ss->gs.writeOffset - ss->gs.readOffset; | 612 available = ss->gs.writeOffset - ss->gs.readOffset; |
612 if (available == 0) { | 613 if (available == 0) { |
613 » /* Get some more data */ | 614 /* Get some more data */ |
614 » if (ss->version >= SSL_LIBRARY_VERSION_3_0) { | 615 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
615 » /* Wait for application data to arrive. */ | 616 /* Wait for application data to arrive. */ |
616 » rv = ssl3_GatherAppDataRecord(ss, 0); | 617 rv = ssl3_GatherAppDataRecord(ss, 0); |
617 » } else { | 618 } else { |
618 » /* See if we have a complete record */ | 619 /* See if we have a complete record */ |
619 » rv = ssl2_GatherRecord(ss, 0); | 620 rv = ssl2_GatherRecord(ss, 0); |
620 » } | 621 } |
621 » if (rv <= 0) { | 622 if (rv <= 0) { |
622 » if (rv == 0) { | 623 if (rv == 0) { |
623 » » /* EOF */ | 624 /* EOF */ |
624 » » SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF", | 625 SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF", |
625 » » » SSL_GETPID(), ss->fd)); | 626 SSL_GETPID(), ss->fd)); |
626 » » goto done; | 627 goto done; |
627 » } | 628 } |
628 » if ((rv != SECWouldBlock) && | 629 if ((rv != SECWouldBlock) && |
629 » (PR_GetError() != PR_WOULD_BLOCK_ERROR)) { | 630 (PR_GetError() != PR_WOULD_BLOCK_ERROR)) { |
630 » » /* Some random error */ | 631 /* Some random error */ |
631 » » goto done; | 632 goto done; |
632 » } | 633 } |
633 | 634 |
634 » /* | 635 /* |
635 » ** Gather record is blocked waiting for more record data to | 636 ** Gather record is blocked waiting for more record data to |
636 » ** arrive. Try to process what we have already received | 637 ** arrive. Try to process what we have already received |
637 » */ | 638 */ |
638 » } else { | 639 } else { |
639 » /* Gather record has finished getting a complete record */ | 640 /* Gather record has finished getting a complete record */ |
640 » } | 641 } |
641 | 642 |
642 » /* See if any clear data is now available */ | 643 /* See if any clear data is now available */ |
643 » available = ss->gs.writeOffset - ss->gs.readOffset; | 644 available = ss->gs.writeOffset - ss->gs.readOffset; |
644 » if (available == 0) { | 645 if (available == 0) { |
645 » /* | 646 /* |
646 » ** No partial data is available. Force error code to | 647 ** No partial data is available. Force error code to |
647 » ** EWOULDBLOCK so that caller will try again later. Note | 648 ** EWOULDBLOCK so that caller will try again later. Note |
648 » ** that the error code is probably EWOULDBLOCK already, | 649 ** that the error code is probably EWOULDBLOCK already, |
649 » ** but if it isn't (for example, if we received a zero | 650 ** but if it isn't (for example, if we received a zero |
650 » ** length record) then this will force it to be correct. | 651 ** length record) then this will force it to be correct. |
651 » */ | 652 */ |
652 » PORT_SetError(PR_WOULD_BLOCK_ERROR); | 653 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
653 » rv = SECFailure; | 654 rv = SECFailure; |
654 » goto done; | 655 goto done; |
655 » } | 656 } |
656 » SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d", | 657 SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d", |
657 » » SSL_GETPID(), ss->fd, available)); | 658 SSL_GETPID(), ss->fd, available)); |
658 } | 659 } |
659 | 660 |
660 if (IS_DTLS(ss) && (len < available)) { | 661 if (IS_DTLS(ss) && (len < available)) { |
661 /* DTLS does not allow you to do partial reads */ | 662 /* DTLS does not allow you to do partial reads */ |
662 SSL_TRC(30, ("%d: SSL[%d]: DTLS short read. len=%d available=%d", | 663 SSL_TRC(30, ("%d: SSL[%d]: DTLS short read. len=%d available=%d", |
663 SSL_GETPID(), ss->fd, len, available)); | 664 SSL_GETPID(), ss->fd, len, available)); |
664 ss->gs.readOffset += available; | 665 ss->gs.readOffset += available; |
665 PORT_SetError(SSL_ERROR_RX_SHORT_DTLS_READ); | 666 PORT_SetError(SSL_ERROR_RX_SHORT_DTLS_READ); |
666 rv = SECFailure; | 667 rv = SECFailure; |
667 goto done; | 668 goto done; |
668 } | 669 } |
669 | 670 |
670 /* Dole out clear data to reader */ | 671 /* Dole out clear data to reader */ |
671 amount = PR_MIN(len, available); | 672 amount = PR_MIN(len, available); |
672 PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); | 673 PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); |
673 if (!(flags & PR_MSG_PEEK)) { | 674 if (!(flags & PR_MSG_PEEK)) { |
674 » ss->gs.readOffset += amount; | 675 ss->gs.readOffset += amount; |
675 } | 676 } |
676 PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset); | 677 PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset); |
677 rv = amount; | 678 rv = amount; |
678 | 679 |
679 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d", | 680 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d", |
680 » » SSL_GETPID(), ss->fd, amount, available)); | 681 SSL_GETPID(), ss->fd, amount, available)); |
681 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount)); | 682 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount)); |
682 | 683 |
683 done: | 684 done: |
684 ssl_ReleaseRecvBufLock(ss); | 685 ssl_ReleaseRecvBufLock(ss); |
685 ssl_Release1stHandshakeLock(ss); | 686 ssl_Release1stHandshakeLock(ss); |
686 return rv; | 687 return rv; |
687 } | 688 } |
688 | 689 |
689 /************************************************************************/ | 690 /************************************************************************/ |
690 | 691 |
691 /* | 692 /* |
692 ** Return SSLKEAType derived from cert's Public Key algorithm info. | 693 ** Return SSLKEAType derived from cert's Public Key algorithm info. |
693 */ | 694 */ |
694 SSLKEAType | 695 SSLKEAType |
695 NSS_FindCertKEAType(CERTCertificate * cert) | 696 NSS_FindCertKEAType(CERTCertificate *cert) |
696 { | 697 { |
697 SSLKEAType keaType = kt_null; | 698 SSLKEAType keaType = kt_null; |
698 int tag; | 699 int tag; |
699 | 700 |
700 if (!cert) goto loser; | 701 if (!cert) |
701 | 702 goto loser; |
702 tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); | 703 |
703 | 704 tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); |
704 switch (tag) { | 705 |
705 case SEC_OID_X500_RSA_ENCRYPTION: | 706 switch (tag) { |
706 case SEC_OID_PKCS1_RSA_ENCRYPTION: | 707 case SEC_OID_X500_RSA_ENCRYPTION: |
707 keaType = kt_rsa; | 708 case SEC_OID_PKCS1_RSA_ENCRYPTION: |
708 break; | 709 keaType = kt_rsa; |
709 case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */ | 710 break; |
710 case SEC_OID_X942_DIFFIE_HELMAN_KEY: | 711 case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */ |
711 keaType = kt_dh; | 712 case SEC_OID_X942_DIFFIE_HELMAN_KEY: |
712 break; | 713 keaType = kt_dh; |
| 714 break; |
713 #ifndef NSS_DISABLE_ECC | 715 #ifndef NSS_DISABLE_ECC |
714 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: | 716 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: |
715 keaType = kt_ecdh; | 717 keaType = kt_ecdh; |
716 break; | 718 break; |
717 #endif /* NSS_DISABLE_ECC */ | 719 #endif /* NSS_DISABLE_ECC */ |
718 default: | 720 default: |
719 keaType = kt_null; | 721 keaType = kt_null; |
720 } | 722 } |
721 | 723 |
722 loser: | 724 loser: |
723 | 725 |
724 return keaType; | 726 return keaType; |
725 } | 727 } |
726 | 728 |
727 static const PRCallOnceType pristineCallOnce; | 729 static const PRCallOnceType pristineCallOnce; |
728 static PRCallOnceType setupServerCAListOnce; | 730 static PRCallOnceType setupServerCAListOnce; |
729 | 731 |
730 static SECStatus serverCAListShutdown(void* appData, void* nssData) | 732 static SECStatus |
| 733 serverCAListShutdown(void *appData, void *nssData) |
731 { | 734 { |
732 PORT_Assert(ssl3_server_ca_list); | 735 PORT_Assert(ssl3_server_ca_list); |
733 if (ssl3_server_ca_list) { | 736 if (ssl3_server_ca_list) { |
734 » CERT_FreeDistNames(ssl3_server_ca_list); | 737 CERT_FreeDistNames(ssl3_server_ca_list); |
735 » ssl3_server_ca_list = NULL; | 738 ssl3_server_ca_list = NULL; |
736 } | 739 } |
737 setupServerCAListOnce = pristineCallOnce; | 740 setupServerCAListOnce = pristineCallOnce; |
738 return SECSuccess; | 741 return SECSuccess; |
739 } | 742 } |
740 | 743 |
741 static PRStatus serverCAListSetup(void *arg) | 744 static PRStatus |
| 745 serverCAListSetup(void *arg) |
742 { | 746 { |
743 CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg; | 747 CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg; |
744 SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL); | 748 SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL); |
745 PORT_Assert(SECSuccess == rv); | 749 PORT_Assert(SECSuccess == rv); |
746 if (SECSuccess == rv) { | 750 if (SECSuccess == rv) { |
747 » ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle); | 751 ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle); |
748 » return PR_SUCCESS; | 752 return PR_SUCCESS; |
749 } | 753 } |
750 return PR_FAILURE; | 754 return PR_FAILURE; |
751 } | 755 } |
752 | 756 |
753 SECStatus | 757 SECStatus |
754 ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, | 758 ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, |
755 const CERTCertificateList *certChain, | 759 const CERTCertificateList *certChain, |
756 ssl3KeyPair *keyPair, SSLKEAType kea) | 760 ssl3KeyPair *keyPair, SSLKEAType kea) |
757 { | 761 { |
758 CERTCertificateList *localCertChain = NULL; | 762 CERTCertificateList *localCertChain = NULL; |
759 sslServerCerts *sc = ss->serverCerts + kea; | 763 sslServerCerts *sc = ss->serverCerts + kea; |
760 | 764 |
761 /* load the server certificate */ | 765 /* load the server certificate */ |
762 if (sc->serverCert != NULL) { | 766 if (sc->serverCert != NULL) { |
763 » CERT_DestroyCertificate(sc->serverCert); | 767 CERT_DestroyCertificate(sc->serverCert); |
764 » sc->serverCert = NULL; | 768 sc->serverCert = NULL; |
765 sc->serverKeyBits = 0; | 769 sc->serverKeyBits = 0; |
766 } | 770 } |
767 /* load the server cert chain */ | 771 /* load the server cert chain */ |
768 if (sc->serverCertChain != NULL) { | 772 if (sc->serverCertChain != NULL) { |
769 » CERT_DestroyCertificateList(sc->serverCertChain); | 773 CERT_DestroyCertificateList(sc->serverCertChain); |
770 » sc->serverCertChain = NULL; | 774 sc->serverCertChain = NULL; |
771 } | 775 } |
772 if (cert) { | 776 if (cert) { |
773 sc->serverCert = CERT_DupCertificate(cert); | 777 sc->serverCert = CERT_DupCertificate(cert); |
774 /* get the size of the cert's public key, and remember it */ | 778 /* get the size of the cert's public key, and remember it */ |
775 sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey); | 779 sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey); |
776 if (!certChain) { | 780 if (!certChain) { |
777 localCertChain = | 781 localCertChain = |
778 CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer, | 782 CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer, |
779 PR_TRUE); | 783 PR_TRUE); |
780 if (!localCertChain) | 784 if (!localCertChain) |
781 goto loser; | 785 goto loser; |
782 } | 786 } |
783 sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) : | 787 sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) : |
784 localCertChain; | 788 localCertChain; |
785 if (!sc->serverCertChain) { | 789 if (!sc->serverCertChain) { |
786 goto loser; | 790 goto loser; |
787 } | 791 } |
788 localCertChain = NULL; /* consumed */ | 792 localCertChain = NULL; /* consumed */ |
789 } | 793 } |
790 | 794 |
791 /* get keyPair */ | 795 /* get keyPair */ |
792 if (sc->serverKeyPair != NULL) { | 796 if (sc->serverKeyPair != NULL) { |
793 ssl3_FreeKeyPair(sc->serverKeyPair); | 797 ssl3_FreeKeyPair(sc->serverKeyPair); |
794 sc->serverKeyPair = NULL; | 798 sc->serverKeyPair = NULL; |
795 } | 799 } |
796 if (keyPair) { | 800 if (keyPair) { |
797 SECKEY_CacheStaticFlags(keyPair->privKey); | 801 SECKEY_CacheStaticFlags(keyPair->privKey); |
798 sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair); | 802 sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair); |
799 } | 803 } |
800 if (kea == kt_rsa && cert && sc->serverKeyBits > 512 && | 804 if (kea == kt_rsa && cert && sc->serverKeyBits > 512 && |
801 !ss->opt.noStepDown && !ss->stepDownKeyPair) { | 805 !ss->opt.noStepDown && !ss->stepDownKeyPair) { |
802 if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) { | 806 if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) { |
803 goto loser; | 807 goto loser; |
804 } | 808 } |
805 } | 809 } |
806 if (kea == ssl_kea_dh || kea == ssl_kea_rsa) { | 810 if (kea == ssl_kea_dh || kea == ssl_kea_rsa) { |
807 if (ssl3_SelectDHParams(ss) != SECSuccess) { | 811 if (ssl3_SelectDHParams(ss) != SECSuccess) { |
808 goto loser; | 812 goto loser; |
809 } | 813 } |
810 } | 814 } |
811 return SECSuccess; | 815 return SECSuccess; |
812 | 816 |
813 loser: | 817 loser: |
814 if (localCertChain) { | 818 if (localCertChain) { |
815 CERT_DestroyCertificateList(localCertChain); | 819 CERT_DestroyCertificateList(localCertChain); |
816 } | 820 } |
817 if (sc->serverCert != NULL) { | 821 if (sc->serverCert != NULL) { |
818 » CERT_DestroyCertificate(sc->serverCert); | 822 CERT_DestroyCertificate(sc->serverCert); |
819 » sc->serverCert = NULL; | 823 sc->serverCert = NULL; |
820 } | 824 } |
821 if (sc->serverCertChain != NULL) { | 825 if (sc->serverCertChain != NULL) { |
822 » CERT_DestroyCertificateList(sc->serverCertChain); | 826 CERT_DestroyCertificateList(sc->serverCertChain); |
823 » sc->serverCertChain = NULL; | 827 sc->serverCertChain = NULL; |
824 } | 828 } |
825 if (sc->serverKeyPair != NULL) { | 829 if (sc->serverKeyPair != NULL) { |
826 » ssl3_FreeKeyPair(sc->serverKeyPair); | 830 ssl3_FreeKeyPair(sc->serverKeyPair); |
827 » sc->serverKeyPair = NULL; | 831 sc->serverKeyPair = NULL; |
828 } | 832 } |
829 return SECFailure; | 833 return SECFailure; |
830 } | 834 } |
831 | 835 |
832 /* XXX need to protect the data that gets changed here.!! */ | 836 /* XXX need to protect the data that gets changed here.!! */ |
833 | 837 |
834 SECStatus | 838 SECStatus |
835 SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, | 839 SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, |
836 » » SECKEYPrivateKey *key, SSL3KEAType kea) | 840 SECKEYPrivateKey *key, SSL3KEAType kea) |
837 { | 841 { |
838 | 842 |
839 return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea); | 843 return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea); |
840 } | 844 } |
841 | 845 |
842 SECStatus | 846 SECStatus |
843 SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, | 847 SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, |
844 const CERTCertificateList *certChainOpt, | 848 const CERTCertificateList *certChainOpt, |
845 SECKEYPrivateKey *key, SSL3KEAType kea) | 849 SECKEYPrivateKey *key, SSL3KEAType kea) |
846 { | 850 { |
847 sslSocket *ss; | 851 sslSocket *ss; |
848 SECKEYPublicKey *pubKey = NULL; | 852 SECKEYPublicKey *pubKey = NULL; |
849 ssl3KeyPair *keyPair = NULL; | 853 ssl3KeyPair *keyPair = NULL; |
850 SECStatus rv = SECFailure; | 854 SECStatus rv = SECFailure; |
851 | 855 |
852 ss = ssl_FindSocket(fd); | 856 ss = ssl_FindSocket(fd); |
853 if (!ss) { | 857 if (!ss) { |
854 » return SECFailure; | 858 return SECFailure; |
855 } | 859 } |
856 | 860 |
857 /* Both key and cert must have a value or be NULL */ | 861 /* Both key and cert must have a value or be NULL */ |
858 /* Passing a value of NULL will turn off key exchange algorithms that were | 862 /* Passing a value of NULL will turn off key exchange algorithms that were |
859 * previously turned on */ | 863 * previously turned on */ |
860 if (!cert != !key) { | 864 if (!cert != !key) { |
861 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 865 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
862 » return SECFailure; | 866 return SECFailure; |
863 } | 867 } |
864 | 868 |
865 /* make sure the key exchange is recognized */ | 869 /* make sure the key exchange is recognized */ |
866 if ((kea >= kt_kea_size) || (kea < kt_null)) { | 870 if ((kea >= kt_kea_size) || (kea < kt_null)) { |
867 » PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); | 871 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); |
868 » return SECFailure; | 872 return SECFailure; |
869 } | 873 } |
870 | 874 |
871 if (kea != NSS_FindCertKEAType(cert)) { | 875 if (kea != NSS_FindCertKEAType(cert)) { |
872 » PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); | 876 PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); |
873 » return SECFailure; | 877 return SECFailure; |
874 } | 878 } |
875 | 879 |
876 if (cert) { | 880 if (cert) { |
877 » /* get the size of the cert's public key, and remember it */ | 881 /* get the size of the cert's public key, and remember it */ |
878 » pubKey = CERT_ExtractPublicKey(cert); | 882 pubKey = CERT_ExtractPublicKey(cert); |
879 » if (!pubKey) | 883 if (!pubKey) |
880 return SECFailure; | 884 return SECFailure; |
881 } | 885 } |
882 | 886 |
883 if (key) { | 887 if (key) { |
884 » SECKEYPrivateKey * keyCopy» = NULL; | 888 SECKEYPrivateKey *keyCopy = NULL; |
885 » CK_MECHANISM_TYPE keyMech» = CKM_INVALID_MECHANISM; | 889 CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM; |
886 | 890 |
887 » if (key->pkcs11Slot) { | 891 if (key->pkcs11Slot) { |
888 » PK11SlotInfo * bestSlot; | 892 PK11SlotInfo *bestSlot; |
889 » bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); | 893 bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); |
890 » if (bestSlot) { | 894 if (bestSlot) { |
891 » » keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); | 895 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); |
892 » » PK11_FreeSlot(bestSlot); | 896 PK11_FreeSlot(bestSlot); |
893 » } | 897 } |
894 » } | 898 } |
895 » if (keyCopy == NULL) | 899 if (keyCopy == NULL) |
896 » keyMech = PK11_MapSignKeyType(key->keyType); | 900 keyMech = PK11_MapSignKeyType(key->keyType); |
897 » if (keyMech != CKM_INVALID_MECHANISM) { | 901 if (keyMech != CKM_INVALID_MECHANISM) { |
898 » PK11SlotInfo * bestSlot; | 902 PK11SlotInfo *bestSlot; |
899 » /* XXX Maybe should be bestSlotMultiple? */ | 903 /* XXX Maybe should be bestSlotMultiple? */ |
900 » bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */); | 904 bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */); |
901 » if (bestSlot) { | 905 if (bestSlot) { |
902 » » keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); | 906 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); |
903 » » PK11_FreeSlot(bestSlot); | 907 PK11_FreeSlot(bestSlot); |
904 » } | 908 } |
905 » } | 909 } |
906 » if (keyCopy == NULL) | 910 if (keyCopy == NULL) |
907 » keyCopy = SECKEY_CopyPrivateKey(key); | 911 keyCopy = SECKEY_CopyPrivateKey(key); |
908 » if (keyCopy == NULL) | 912 if (keyCopy == NULL) |
909 » goto loser; | 913 goto loser; |
910 keyPair = ssl3_NewKeyPair(keyCopy, pubKey); | 914 keyPair = ssl3_NewKeyPair(keyCopy, pubKey); |
911 if (keyPair == NULL) { | 915 if (keyPair == NULL) { |
912 SECKEY_DestroyPrivateKey(keyCopy); | 916 SECKEY_DestroyPrivateKey(keyCopy); |
913 goto loser; | 917 goto loser; |
914 } | 918 } |
915 » pubKey = NULL; /* adopted by serverKeyPair */ | 919 pubKey = NULL; /* adopted by serverKeyPair */ |
916 } | 920 } |
917 if (ssl_ConfigSecureServer(ss, cert, certChainOpt, | 921 if (ssl_ConfigSecureServer(ss, cert, certChainOpt, |
918 keyPair, kea) == SECFailure) { | 922 keyPair, kea) == SECFailure) { |
919 goto loser; | 923 goto loser; |
920 } | 924 } |
921 | 925 |
922 /* Only do this once because it's global. */ | 926 /* Only do this once because it's global. */ |
923 if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, | 927 if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, |
924 &serverCAListSetup, | 928 &serverCAListSetup, |
925 (void *)(ss->dbHandle))) { | 929 (void *)(ss->dbHandle))) { |
926 rv = SECSuccess; | 930 rv = SECSuccess; |
927 } | 931 } |
928 | 932 |
929 loser: | 933 loser: |
930 if (keyPair) { | 934 if (keyPair) { |
931 ssl3_FreeKeyPair(keyPair); | 935 ssl3_FreeKeyPair(keyPair); |
932 } | 936 } |
933 if (pubKey) { | 937 if (pubKey) { |
934 » SECKEY_DestroyPublicKey(pubKey); | 938 SECKEY_DestroyPublicKey(pubKey); |
935 » pubKey = NULL; | 939 pubKey = NULL; |
936 } | 940 } |
937 return rv; | 941 return rv; |
938 } | 942 } |
939 | 943 |
940 /************************************************************************/ | 944 /************************************************************************/ |
941 | 945 |
942 SECStatus | 946 SECStatus |
943 ssl_CreateSecurityInfo(sslSocket *ss) | 947 ssl_CreateSecurityInfo(sslSocket *ss) |
944 { | 948 { |
945 SECStatus status; | 949 SECStatus status; |
946 | 950 |
947 /* initialize sslv2 socket to send data in the clear. */ | 951 /* initialize sslv2 socket to send data in the clear. */ |
948 ssl2_UseClearSendFunc(ss); | 952 ssl2_UseClearSendFunc(ss); |
949 | 953 |
950 ss->sec.blockSize = 1; | 954 ss->sec.blockSize = 1; |
951 ss->sec.blockShift = 0; | 955 ss->sec.blockShift = 0; |
952 | 956 |
953 ssl_GetXmitBufLock(ss); | 957 ssl_GetXmitBufLock(ss); |
954 status = sslBuffer_Grow(&ss->sec.writeBuf, 4096); | 958 status = sslBuffer_Grow(&ss->sec.writeBuf, 4096); |
955 ssl_ReleaseXmitBufLock(ss); | 959 ssl_ReleaseXmitBufLock(ss); |
956 | 960 |
957 return status; | 961 return status; |
958 } | 962 } |
959 | 963 |
960 SECStatus | 964 SECStatus |
961 ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) | 965 ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) |
962 { | 966 { |
963 ss->sec.send » » = os->sec.send; | 967 ss->sec.send = os->sec.send; |
964 ss->sec.isServer » » = os->sec.isServer; | 968 ss->sec.isServer = os->sec.isServer; |
965 ss->sec.keyBits »» = os->sec.keyBits; | 969 ss->sec.keyBits = os->sec.keyBits; |
966 ss->sec.secretKeyBits » = os->sec.secretKeyBits; | 970 ss->sec.secretKeyBits = os->sec.secretKeyBits; |
967 | 971 |
968 ss->sec.peerCert »» = CERT_DupCertificate(os->sec.peerCert); | 972 ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert); |
969 if (os->sec.peerCert && !ss->sec.peerCert) | 973 if (os->sec.peerCert && !ss->sec.peerCert) |
970 » goto loser; | 974 goto loser; |
971 | 975 |
972 ss->sec.cache »» = os->sec.cache; | 976 ss->sec.cache = os->sec.cache; |
973 ss->sec.uncache »» = os->sec.uncache; | 977 ss->sec.uncache = os->sec.uncache; |
974 | 978 |
975 /* we don't dup the connection info. */ | 979 /* we don't dup the connection info. */ |
976 | 980 |
977 ss->sec.sendSequence » = os->sec.sendSequence; | 981 ss->sec.sendSequence = os->sec.sendSequence; |
978 ss->sec.rcvSequence » = os->sec.rcvSequence; | 982 ss->sec.rcvSequence = os->sec.rcvSequence; |
979 | 983 |
980 if (os->sec.hash && os->sec.hashcx) { | 984 if (os->sec.hash && os->sec.hashcx) { |
981 » ss->sec.hash » » = os->sec.hash; | 985 ss->sec.hash = os->sec.hash; |
982 » ss->sec.hashcx »» = os->sec.hash->clone(os->sec.hashcx); | 986 ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx); |
983 » if (os->sec.hashcx && !ss->sec.hashcx) | 987 if (os->sec.hashcx && !ss->sec.hashcx) |
984 » goto loser; | 988 goto loser; |
985 } else { | 989 } else { |
986 » ss->sec.hash » » = NULL; | 990 ss->sec.hash = NULL; |
987 » ss->sec.hashcx »» = NULL; | 991 ss->sec.hashcx = NULL; |
988 } | 992 } |
989 | 993 |
990 if (SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret)) | 994 if (SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret)) |
991 » goto loser; | 995 goto loser; |
992 if (SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret)) | 996 if (SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret)) |
993 » goto loser; | 997 goto loser; |
994 | 998 |
995 /* XXX following code is wrong if either cx != 0 */ | 999 /* XXX following code is wrong if either cx != 0 */ |
996 PORT_Assert(os->sec.readcx == 0); | 1000 PORT_Assert(os->sec.readcx == 0); |
997 PORT_Assert(os->sec.writecx == 0); | 1001 PORT_Assert(os->sec.writecx == 0); |
998 ss->sec.readcx »» = os->sec.readcx; | 1002 ss->sec.readcx = os->sec.readcx; |
999 ss->sec.writecx »» = os->sec.writecx; | 1003 ss->sec.writecx = os->sec.writecx; |
1000 ss->sec.destroy »» = 0;» | 1004 ss->sec.destroy = 0; |
1001 | 1005 |
1002 ss->sec.enc »» = os->sec.enc; | 1006 ss->sec.enc = os->sec.enc; |
1003 ss->sec.dec »» = os->sec.dec; | 1007 ss->sec.dec = os->sec.dec; |
1004 | 1008 |
1005 ss->sec.blockShift »» = os->sec.blockShift; | 1009 ss->sec.blockShift = os->sec.blockShift; |
1006 ss->sec.blockSize »» = os->sec.blockSize; | 1010 ss->sec.blockSize = os->sec.blockSize; |
1007 | 1011 |
1008 return SECSuccess; | 1012 return SECSuccess; |
1009 | 1013 |
1010 loser: | 1014 loser: |
1011 return SECFailure; | 1015 return SECFailure; |
1012 } | 1016 } |
1013 | 1017 |
1014 /* Reset sec back to its initial state. | 1018 /* Reset sec back to its initial state. |
1015 ** Caller holds any relevant locks. | 1019 ** Caller holds any relevant locks. |
1016 */ | 1020 */ |
1017 void | 1021 void |
1018 ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) | 1022 ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) |
1019 { | 1023 { |
1020 /* Destroy MAC */ | 1024 /* Destroy MAC */ |
1021 if (sec->hash && sec->hashcx) { | 1025 if (sec->hash && sec->hashcx) { |
1022 » (*sec->hash->destroy)(sec->hashcx, PR_TRUE); | 1026 (*sec->hash->destroy)(sec->hashcx, PR_TRUE); |
1023 » sec->hashcx = NULL; | 1027 sec->hashcx = NULL; |
1024 » sec->hash = NULL; | 1028 sec->hash = NULL; |
1025 } | 1029 } |
1026 SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); | 1030 SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); |
1027 SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); | 1031 SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); |
1028 | 1032 |
1029 /* Destroy ciphers */ | 1033 /* Destroy ciphers */ |
1030 if (sec->destroy) { | 1034 if (sec->destroy) { |
1031 » (*sec->destroy)(sec->readcx, PR_TRUE); | 1035 (*sec->destroy)(sec->readcx, PR_TRUE); |
1032 » (*sec->destroy)(sec->writecx, PR_TRUE); | 1036 (*sec->destroy)(sec->writecx, PR_TRUE); |
1033 » sec->readcx = NULL; | 1037 sec->readcx = NULL; |
1034 » sec->writecx = NULL; | 1038 sec->writecx = NULL; |
1035 } else { | 1039 } else { |
1036 » PORT_Assert(sec->readcx == 0); | 1040 PORT_Assert(sec->readcx == 0); |
1037 » PORT_Assert(sec->writecx == 0); | 1041 PORT_Assert(sec->writecx == 0); |
1038 } | 1042 } |
1039 sec->readcx = 0; | 1043 sec->readcx = 0; |
1040 sec->writecx = 0; | 1044 sec->writecx = 0; |
1041 | 1045 |
1042 if (sec->localCert) { | 1046 if (sec->localCert) { |
1043 » CERT_DestroyCertificate(sec->localCert); | 1047 CERT_DestroyCertificate(sec->localCert); |
1044 » sec->localCert = NULL; | 1048 sec->localCert = NULL; |
1045 } | 1049 } |
1046 if (sec->peerCert) { | 1050 if (sec->peerCert) { |
1047 » CERT_DestroyCertificate(sec->peerCert); | 1051 CERT_DestroyCertificate(sec->peerCert); |
1048 » sec->peerCert = NULL; | 1052 sec->peerCert = NULL; |
1049 } | 1053 } |
1050 if (sec->peerKey) { | 1054 if (sec->peerKey) { |
1051 » SECKEY_DestroyPublicKey(sec->peerKey); | 1055 SECKEY_DestroyPublicKey(sec->peerKey); |
1052 » sec->peerKey = NULL; | 1056 sec->peerKey = NULL; |
1053 } | 1057 } |
1054 | 1058 |
1055 /* cleanup the ci */ | 1059 /* cleanup the ci */ |
1056 if (sec->ci.sid != NULL) { | 1060 if (sec->ci.sid != NULL) { |
1057 » ssl_FreeSID(sec->ci.sid); | 1061 ssl_FreeSID(sec->ci.sid); |
1058 } | 1062 } |
1059 PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); | 1063 PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); |
1060 if (doMemset) { | 1064 if (doMemset) { |
1061 memset(&sec->ci, 0, sizeof sec->ci); | 1065 memset(&sec->ci, 0, sizeof sec->ci); |
1062 } | 1066 } |
1063 | |
1064 } | 1067 } |
1065 | 1068 |
1066 /* | 1069 /* |
1067 ** Called from SSL_ResetHandshake (above), and | 1070 ** Called from SSL_ResetHandshake (above), and |
1068 ** from ssl_FreeSocket in sslsock.c | 1071 ** from ssl_FreeSocket in sslsock.c |
1069 ** Caller should hold relevant locks (e.g. XmitBufLock) | 1072 ** Caller should hold relevant locks (e.g. XmitBufLock) |
1070 */ | 1073 */ |
1071 void | 1074 void |
1072 ssl_DestroySecurityInfo(sslSecurityInfo *sec) | 1075 ssl_DestroySecurityInfo(sslSecurityInfo *sec) |
1073 { | 1076 { |
1074 ssl_ResetSecurityInfo(sec, PR_FALSE); | 1077 ssl_ResetSecurityInfo(sec, PR_FALSE); |
1075 | 1078 |
1076 PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); | 1079 PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); |
1077 sec->writeBuf.buf = 0; | 1080 sec->writeBuf.buf = 0; |
1078 | 1081 |
1079 memset(sec, 0, sizeof *sec); | 1082 memset(sec, 0, sizeof *sec); |
1080 } | 1083 } |
1081 | 1084 |
1082 /************************************************************************/ | 1085 /************************************************************************/ |
1083 | 1086 |
1084 int | 1087 int |
1085 ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa) | 1088 ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa) |
1086 { | 1089 { |
1087 PRFileDesc *osfd = ss->fd->lower; | 1090 PRFileDesc *osfd = ss->fd->lower; |
1088 int rv; | 1091 int rv; |
1089 | 1092 |
1090 if ( ss->opt.handshakeAsServer ) { | 1093 if (ss->opt.handshakeAsServer) { |
1091 » ss->securityHandshake = ssl2_BeginServerHandshake; | 1094 ss->securityHandshake = ssl2_BeginServerHandshake; |
1092 » ss->handshaking = sslHandshakingAsServer; | 1095 ss->handshaking = sslHandshakingAsServer; |
1093 } else { | 1096 } else { |
1094 » ss->securityHandshake = ssl2_BeginClientHandshake; | 1097 ss->securityHandshake = ssl2_BeginClientHandshake; |
1095 » ss->handshaking = sslHandshakingAsClient; | 1098 ss->handshaking = sslHandshakingAsClient; |
1096 } | 1099 } |
1097 | 1100 |
1098 /* connect to server */ | 1101 /* connect to server */ |
1099 rv = osfd->methods->connect(osfd, sa, ss->cTimeout); | 1102 rv = osfd->methods->connect(osfd, sa, ss->cTimeout); |
1100 if (rv == PR_SUCCESS) { | 1103 if (rv == PR_SUCCESS) { |
1101 » ss->TCPconnected = 1; | 1104 ss->TCPconnected = 1; |
1102 } else { | 1105 } else { |
1103 » int err = PR_GetError(); | 1106 int err = PR_GetError(); |
1104 » SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d", | 1107 SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d", |
1105 » » SSL_GETPID(), ss->fd, err)); | 1108 SSL_GETPID(), ss->fd, err)); |
1106 » if (err == PR_IS_CONNECTED_ERROR) { | 1109 if (err == PR_IS_CONNECTED_ERROR) { |
1107 » ss->TCPconnected = 1; | 1110 ss->TCPconnected = 1; |
1108 » } | 1111 } |
1109 } | 1112 } |
1110 | 1113 |
1111 SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d", | 1114 SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d", |
1112 » » SSL_GETPID(), ss->fd, rv)); | 1115 SSL_GETPID(), ss->fd, rv)); |
1113 return rv; | 1116 return rv; |
1114 } | 1117 } |
1115 | 1118 |
1116 /* | 1119 /* |
1117 * The TLS 1.2 RFC 5246, Section 7.2.1 says: | 1120 * The TLS 1.2 RFC 5246, Section 7.2.1 says: |
1118 * | 1121 * |
1119 * Unless some other fatal alert has been transmitted, each party is | 1122 * Unless some other fatal alert has been transmitted, each party is |
1120 * required to send a close_notify alert before closing the write side | 1123 * required to send a close_notify alert before closing the write side |
1121 * of the connection. The other party MUST respond with a close_notify | 1124 * of the connection. The other party MUST respond with a close_notify |
1122 * alert of its own and close down the connection immediately, | 1125 * alert of its own and close down the connection immediately, |
(...skipping 12 matching lines...) Expand all Loading... |
1135 * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown | 1138 * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown |
1136 * may block indefinitely in blocking mode, and may fail (without retrying) | 1139 * may block indefinitely in blocking mode, and may fail (without retrying) |
1137 * in non-blocking mode. | 1140 * in non-blocking mode. |
1138 */ | 1141 */ |
1139 | 1142 |
1140 int | 1143 int |
1141 ssl_SecureClose(sslSocket *ss) | 1144 ssl_SecureClose(sslSocket *ss) |
1142 { | 1145 { |
1143 int rv; | 1146 int rv; |
1144 | 1147 |
1145 if (ss->version >= SSL_LIBRARY_VERSION_3_0 »&& | 1148 if (ss->version >= SSL_LIBRARY_VERSION_3_0 && |
1146 » !(ss->shutdownHow & ssl_SHUTDOWN_SEND)» && | 1149 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && |
1147 » ss->firstHsDone » » » && | 1150 ss->firstHsDone && |
1148 » !ss->recvdCloseNotify && | 1151 !ss->recvdCloseNotify && |
1149 » ss->ssl3.initialized) { | 1152 ss->ssl3.initialized) { |
1150 | 1153 |
1151 » /* We don't want the final alert to be Nagle delayed. */ | 1154 /* We don't want the final alert to be Nagle delayed. */ |
1152 » if (!ss->delayDisabled) { | 1155 if (!ss->delayDisabled) { |
1153 » ssl_EnableNagleDelay(ss, PR_FALSE); | 1156 ssl_EnableNagleDelay(ss, PR_FALSE); |
1154 » ss->delayDisabled = 1; | 1157 ss->delayDisabled = 1; |
1155 » } | 1158 } |
1156 | 1159 |
1157 » (void) SSL3_SendAlert(ss, alert_warning, close_notify); | 1160 (void)SSL3_SendAlert(ss, alert_warning, close_notify); |
1158 } | 1161 } |
1159 rv = ssl_DefClose(ss); | 1162 rv = ssl_DefClose(ss); |
1160 return rv; | 1163 return rv; |
1161 } | 1164 } |
1162 | 1165 |
1163 /* Caller handles all locking */ | 1166 /* Caller handles all locking */ |
1164 int | 1167 int |
1165 ssl_SecureShutdown(sslSocket *ss, int nsprHow) | 1168 ssl_SecureShutdown(sslSocket *ss, int nsprHow) |
1166 { | 1169 { |
1167 PRFileDesc *osfd = ss->fd->lower; | 1170 PRFileDesc *osfd = ss->fd->lower; |
1168 int » rv; | 1171 int rv; |
1169 PRIntn» sslHow» = nsprHow + 1; | 1172 PRIntn sslHow = nsprHow + 1; |
1170 | 1173 |
1171 if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) { | 1174 if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) { |
1172 » PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 1175 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
1173 » return PR_FAILURE; | 1176 return PR_FAILURE; |
1174 } | 1177 } |
1175 | 1178 |
1176 if ((sslHow & ssl_SHUTDOWN_SEND) != 0 » » && | 1179 if ((sslHow & ssl_SHUTDOWN_SEND) != 0 && |
1177 » ss->version >= SSL_LIBRARY_VERSION_3_0» » && | 1180 ss->version >= SSL_LIBRARY_VERSION_3_0 && |
1178 » !(ss->shutdownHow & ssl_SHUTDOWN_SEND)» » && | 1181 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && |
1179 » ss->firstHsDone » » » » && | 1182 ss->firstHsDone && |
1180 » !ss->recvdCloseNotify » && | 1183 !ss->recvdCloseNotify && |
1181 » ss->ssl3.initialized) { | 1184 ss->ssl3.initialized) { |
1182 | 1185 |
1183 » (void) SSL3_SendAlert(ss, alert_warning, close_notify); | 1186 (void)SSL3_SendAlert(ss, alert_warning, close_notify); |
1184 } | 1187 } |
1185 | 1188 |
1186 rv = osfd->methods->shutdown(osfd, nsprHow); | 1189 rv = osfd->methods->shutdown(osfd, nsprHow); |
1187 | 1190 |
1188 ss->shutdownHow |= sslHow; | 1191 ss->shutdownHow |= sslHow; |
1189 | 1192 |
1190 return rv; | 1193 return rv; |
1191 } | 1194 } |
1192 | 1195 |
1193 /************************************************************************/ | 1196 /************************************************************************/ |
1194 | 1197 |
1195 | |
1196 int | 1198 int |
1197 ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) | 1199 ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) |
1198 { | 1200 { |
1199 int rv = 0; | 1201 int rv = 0; |
1200 | 1202 |
1201 if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { | 1203 if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { |
1202 » PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); | 1204 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); |
1203 » return PR_FAILURE; | 1205 return PR_FAILURE; |
1204 } | 1206 } |
1205 if (flags & ~PR_MSG_PEEK) { | 1207 if (flags & ~PR_MSG_PEEK) { |
1206 » PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 1208 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
1207 » return PR_FAILURE; | 1209 return PR_FAILURE; |
1208 } | 1210 } |
1209 | 1211 |
1210 if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { | 1212 if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { |
1211 » ssl_GetXmitBufLock(ss); | 1213 ssl_GetXmitBufLock(ss); |
1212 » if (ss->pendingBuf.len != 0) { | 1214 if (ss->pendingBuf.len != 0) { |
1213 » rv = ssl_SendSavedWriteData(ss); | 1215 rv = ssl_SendSavedWriteData(ss); |
1214 » if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { | 1216 if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { |
1215 » » ssl_ReleaseXmitBufLock(ss); | 1217 ssl_ReleaseXmitBufLock(ss); |
1216 » » return SECFailure; | 1218 return SECFailure; |
1217 » } | 1219 } |
1218 » } | 1220 } |
1219 » ssl_ReleaseXmitBufLock(ss); | 1221 ssl_ReleaseXmitBufLock(ss); |
1220 } | 1222 } |
1221 | 1223 |
1222 rv = 0; | 1224 rv = 0; |
1223 /* If any of these is non-zero, the initial handshake is not done. */ | 1225 /* If any of these is non-zero, the initial handshake is not done. */ |
1224 if (!ss->firstHsDone) { | 1226 if (!ss->firstHsDone) { |
1225 » ssl_Get1stHandshakeLock(ss); | 1227 ssl_Get1stHandshakeLock(ss); |
1226 » if (ss->handshake || ss->nextHandshake || ss->securityHandshake) { | 1228 if (ss->handshake || ss->nextHandshake || ss->securityHandshake) { |
1227 » rv = ssl_Do1stHandshake(ss); | 1229 rv = ssl_Do1stHandshake(ss); |
1228 » } | 1230 } |
1229 » ssl_Release1stHandshakeLock(ss); | 1231 ssl_Release1stHandshakeLock(ss); |
1230 } | 1232 } |
1231 if (rv < 0) { | 1233 if (rv < 0) { |
1232 » return rv; | 1234 return rv; |
1233 } | 1235 } |
1234 | 1236 |
1235 if (len == 0) return 0; | 1237 if (len == 0) |
| 1238 return 0; |
1236 | 1239 |
1237 rv = DoRecv(ss, (unsigned char*) buf, len, flags); | 1240 rv = DoRecv(ss, (unsigned char *)buf, len, flags); |
1238 SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)", | 1241 SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)", |
1239 » » SSL_GETPID(), ss->fd, rv, PORT_GetError())); | 1242 SSL_GETPID(), ss->fd, rv, PORT_GetError())); |
1240 return rv; | 1243 return rv; |
1241 } | 1244 } |
1242 | 1245 |
1243 int | 1246 int |
1244 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) | 1247 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) |
1245 { | 1248 { |
1246 return ssl_SecureRecv(ss, buf, len, 0); | 1249 return ssl_SecureRecv(ss, buf, len, 0); |
1247 } | 1250 } |
1248 | 1251 |
1249 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */ | 1252 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */ |
1250 int | 1253 int |
1251 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) | 1254 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) |
1252 { | 1255 { |
1253 int rv = 0; | 1256 int rv = 0; |
1254 | 1257 |
1255 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", | 1258 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", |
1256 » » SSL_GETPID(), ss->fd, len)); | 1259 SSL_GETPID(), ss->fd, len)); |
1257 | 1260 |
1258 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { | 1261 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { |
1259 » PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); | 1262 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); |
1260 » rv = PR_FAILURE; | 1263 rv = PR_FAILURE; |
1261 » goto done; | 1264 goto done; |
1262 } | 1265 } |
1263 if (flags) { | 1266 if (flags) { |
1264 » PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 1267 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
1265 » rv = PR_FAILURE; | 1268 rv = PR_FAILURE; |
1266 » goto done; | 1269 goto done; |
1267 } | 1270 } |
1268 | 1271 |
1269 ssl_GetXmitBufLock(ss); | 1272 ssl_GetXmitBufLock(ss); |
1270 if (ss->pendingBuf.len != 0) { | 1273 if (ss->pendingBuf.len != 0) { |
1271 » PORT_Assert(ss->pendingBuf.len > 0); | 1274 PORT_Assert(ss->pendingBuf.len > 0); |
1272 » rv = ssl_SendSavedWriteData(ss); | 1275 rv = ssl_SendSavedWriteData(ss); |
1273 » if (rv >= 0 && ss->pendingBuf.len != 0) { | 1276 if (rv >= 0 && ss->pendingBuf.len != 0) { |
1274 » PORT_Assert(ss->pendingBuf.len > 0); | 1277 PORT_Assert(ss->pendingBuf.len > 0); |
1275 » PORT_SetError(PR_WOULD_BLOCK_ERROR); | 1278 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
1276 » rv = SECFailure; | 1279 rv = SECFailure; |
1277 » } | 1280 } |
1278 } | 1281 } |
1279 ssl_ReleaseXmitBufLock(ss); | 1282 ssl_ReleaseXmitBufLock(ss); |
1280 if (rv < 0) { | 1283 if (rv < 0) { |
1281 » goto done; | 1284 goto done; |
1282 } | 1285 } |
1283 | 1286 |
1284 if (len > 0) | 1287 if (len > 0) |
1285 » ss->writerThread = PR_GetCurrentThread(); | 1288 ss->writerThread = PR_GetCurrentThread(); |
1286 /* If any of these is non-zero, the initial handshake is not done. */ | 1289 /* If any of these is non-zero, the initial handshake is not done. */ |
1287 if (!ss->firstHsDone) { | 1290 if (!ss->firstHsDone) { |
1288 » PRBool falseStart = PR_FALSE; | 1291 PRBool falseStart = PR_FALSE; |
1289 » ssl_Get1stHandshakeLock(ss); | 1292 ssl_Get1stHandshakeLock(ss); |
1290 » if (ss->opt.enableFalseStart && | 1293 if (ss->opt.enableFalseStart && |
1291 » ss->version >= SSL_LIBRARY_VERSION_3_0) { | 1294 ss->version >= SSL_LIBRARY_VERSION_3_0) { |
1292 » ssl_GetSSL3HandshakeLock(ss); | 1295 ssl_GetSSL3HandshakeLock(ss); |
1293 » falseStart = ss->ssl3.hs.canFalseStart; | 1296 falseStart = ss->ssl3.hs.canFalseStart; |
1294 » ssl_ReleaseSSL3HandshakeLock(ss); | 1297 ssl_ReleaseSSL3HandshakeLock(ss); |
1295 » } | 1298 } |
1296 » if (!falseStart && | 1299 if (!falseStart && |
1297 » (ss->handshake || ss->nextHandshake || ss->securityHandshake)) { | 1300 (ss->handshake || ss->nextHandshake || ss->securityHandshake)) { |
1298 » rv = ssl_Do1stHandshake(ss); | 1301 rv = ssl_Do1stHandshake(ss); |
1299 » } | 1302 } |
1300 » ssl_Release1stHandshakeLock(ss); | 1303 ssl_Release1stHandshakeLock(ss); |
1301 } | 1304 } |
1302 if (rv < 0) { | 1305 if (rv < 0) { |
1303 » ss->writerThread = NULL; | 1306 ss->writerThread = NULL; |
1304 » goto done; | 1307 goto done; |
1305 } | 1308 } |
1306 | 1309 |
1307 /* Check for zero length writes after we do housekeeping so we make forward | 1310 /* Check for zero length writes after we do housekeeping so we make forward |
1308 * progress. | 1311 * progress. |
1309 */ | 1312 */ |
1310 if (len == 0) { | 1313 if (len == 0) { |
1311 » rv = 0; | 1314 rv = 0; |
1312 » goto done; | 1315 goto done; |
1313 } | 1316 } |
1314 PORT_Assert(buf != NULL); | 1317 PORT_Assert(buf != NULL); |
1315 if (!buf) { | 1318 if (!buf) { |
1316 » PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 1319 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
1317 » rv = PR_FAILURE; | 1320 rv = PR_FAILURE; |
1318 » goto done; | 1321 goto done; |
1319 } | 1322 } |
1320 | 1323 |
1321 if (!ss->firstHsDone) { | 1324 if (!ss->firstHsDone) { |
1322 » PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0); | 1325 PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0); |
1323 #ifdef DEBUG | 1326 #ifdef DEBUG |
1324 » ssl_GetSSL3HandshakeLock(ss); | 1327 ssl_GetSSL3HandshakeLock(ss); |
1325 » PORT_Assert(ss->ssl3.hs.canFalseStart); | 1328 PORT_Assert(ss->ssl3.hs.canFalseStart); |
1326 » ssl_ReleaseSSL3HandshakeLock(ss); | 1329 ssl_ReleaseSSL3HandshakeLock(ss); |
1327 #endif | 1330 #endif |
1328 » SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start", | 1331 SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start", |
1329 » » SSL_GETPID(), ss->fd)); | 1332 SSL_GETPID(), ss->fd)); |
1330 } | 1333 } |
1331 | 1334 |
1332 /* Send out the data using one of these functions: | 1335 /* Send out the data using one of these functions: |
1333 *» ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, | 1336 * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, |
1334 * ssl3_SendApplicationData | 1337 * ssl3_SendApplicationData |
1335 */ | 1338 */ |
1336 ssl_GetXmitBufLock(ss); | 1339 ssl_GetXmitBufLock(ss); |
1337 rv = (*ss->sec.send)(ss, buf, len, flags); | 1340 rv = (*ss->sec.send)(ss, buf, len, flags); |
1338 ssl_ReleaseXmitBufLock(ss); | 1341 ssl_ReleaseXmitBufLock(ss); |
1339 ss->writerThread = NULL; | 1342 ss->writerThread = NULL; |
1340 done: | 1343 done: |
1341 if (rv < 0) { | 1344 if (rv < 0) { |
1342 » SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d", | 1345 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d", |
1343 » » SSL_GETPID(), ss->fd, rv, PORT_GetError())); | 1346 SSL_GETPID(), ss->fd, rv, PORT_GetError())); |
1344 } else { | 1347 } else { |
1345 » SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count", | 1348 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count", |
1346 » » SSL_GETPID(), ss->fd, rv)); | 1349 SSL_GETPID(), ss->fd, rv)); |
1347 } | 1350 } |
1348 return rv; | 1351 return rv; |
1349 } | 1352 } |
1350 | 1353 |
1351 int | 1354 int |
1352 ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len) | 1355 ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len) |
1353 { | 1356 { |
1354 return ssl_SecureSend(ss, buf, len, 0); | 1357 return ssl_SecureSend(ss, buf, len, 0); |
1355 } | 1358 } |
1356 | 1359 |
1357 SECStatus | 1360 SECStatus |
1358 SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) | 1361 SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) |
1359 { | 1362 { |
1360 sslSocket *ss; | 1363 sslSocket *ss; |
1361 | 1364 |
1362 ss = ssl_FindSocket(fd); | 1365 ss = ssl_FindSocket(fd); |
1363 if (!ss) { | 1366 if (!ss) { |
1364 » SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook", | 1367 SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook", |
1365 » » SSL_GETPID(), fd)); | 1368 SSL_GETPID(), fd)); |
1366 » return SECFailure; | 1369 return SECFailure; |
1367 } | 1370 } |
1368 | 1371 |
1369 ss->handleBadCert = f; | 1372 ss->handleBadCert = f; |
1370 ss->badCertArg = arg; | 1373 ss->badCertArg = arg; |
1371 | 1374 |
1372 return SECSuccess; | 1375 return SECSuccess; |
1373 } | 1376 } |
1374 | 1377 |
1375 /* | 1378 /* |
1376 * Allow the application to pass the url or hostname into the SSL library | 1379 * Allow the application to pass the url or hostname into the SSL library |
1377 * so that we can do some checking on it. It will be used for the value in | 1380 * so that we can do some checking on it. It will be used for the value in |
1378 * SNI extension of client hello message. | 1381 * SNI extension of client hello message. |
1379 */ | 1382 */ |
1380 SECStatus | 1383 SECStatus |
1381 SSL_SetURL(PRFileDesc *fd, const char *url) | 1384 SSL_SetURL(PRFileDesc *fd, const char *url) |
1382 { | 1385 { |
1383 sslSocket * ss = ssl_FindSocket(fd); | 1386 sslSocket *ss = ssl_FindSocket(fd); |
1384 SECStatus rv = SECSuccess; | 1387 SECStatus rv = SECSuccess; |
1385 | 1388 |
1386 if (!ss) { | 1389 if (!ss) { |
1387 » SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL", | 1390 SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL", |
1388 » » SSL_GETPID(), fd)); | 1391 SSL_GETPID(), fd)); |
1389 » return SECFailure; | 1392 return SECFailure; |
1390 } | 1393 } |
1391 ssl_Get1stHandshakeLock(ss); | 1394 ssl_Get1stHandshakeLock(ss); |
1392 ssl_GetSSL3HandshakeLock(ss); | 1395 ssl_GetSSL3HandshakeLock(ss); |
1393 | 1396 |
1394 if ( ss->url ) { | 1397 if (ss->url) { |
1395 » PORT_Free((void *)ss->url);» /* CONST */ | 1398 PORT_Free((void *)ss->url); /* CONST */ |
1396 } | 1399 } |
1397 | 1400 |
1398 ss->url = (const char *)PORT_Strdup(url); | 1401 ss->url = (const char *)PORT_Strdup(url); |
1399 if ( ss->url == NULL ) { | 1402 if (ss->url == NULL) { |
1400 » rv = SECFailure; | 1403 rv = SECFailure; |
1401 } | 1404 } |
1402 | 1405 |
1403 ssl_ReleaseSSL3HandshakeLock(ss); | 1406 ssl_ReleaseSSL3HandshakeLock(ss); |
1404 ssl_Release1stHandshakeLock(ss); | 1407 ssl_Release1stHandshakeLock(ss); |
1405 | 1408 |
1406 return rv; | 1409 return rv; |
1407 } | 1410 } |
1408 | 1411 |
1409 /* | 1412 /* |
1410 * Allow the application to pass the set of trust anchors | 1413 * Allow the application to pass the set of trust anchors |
1411 */ | 1414 */ |
1412 SECStatus | 1415 SECStatus |
1413 SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList) | 1416 SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList) |
1414 { | 1417 { |
1415 sslSocket * ss = ssl_FindSocket(fd); | 1418 sslSocket *ss = ssl_FindSocket(fd); |
1416 CERTDistNames *names = NULL; | 1419 CERTDistNames *names = NULL; |
1417 | 1420 |
1418 if (!certList) { | 1421 if (!certList) { |
1419 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1422 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1420 return SECFailure; | 1423 return SECFailure; |
1421 } | 1424 } |
1422 if (!ss) { | 1425 if (!ss) { |
1423 » SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors", | 1426 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors", |
1424 » » SSL_GETPID(), fd)); | 1427 SSL_GETPID(), fd)); |
1425 » return SECFailure; | 1428 return SECFailure; |
1426 } | 1429 } |
1427 | 1430 |
1428 names = CERT_DistNamesFromCertList(certList); | 1431 names = CERT_DistNamesFromCertList(certList); |
1429 if (names == NULL) { | 1432 if (names == NULL) { |
1430 return SECFailure; | 1433 return SECFailure; |
1431 } | 1434 } |
1432 ssl_Get1stHandshakeLock(ss); | 1435 ssl_Get1stHandshakeLock(ss); |
1433 ssl_GetSSL3HandshakeLock(ss); | 1436 ssl_GetSSL3HandshakeLock(ss); |
1434 if (ss->ssl3.ca_list) { | 1437 if (ss->ssl3.ca_list) { |
1435 CERT_FreeDistNames(ss->ssl3.ca_list); | 1438 CERT_FreeDistNames(ss->ssl3.ca_list); |
1436 } | 1439 } |
1437 ss->ssl3.ca_list = names; | 1440 ss->ssl3.ca_list = names; |
1438 ssl_ReleaseSSL3HandshakeLock(ss); | 1441 ssl_ReleaseSSL3HandshakeLock(ss); |
1439 ssl_Release1stHandshakeLock(ss); | 1442 ssl_Release1stHandshakeLock(ss); |
1440 | 1443 |
1441 return SECSuccess; | 1444 return SECSuccess; |
1442 } | 1445 } |
1443 | 1446 |
1444 /* | 1447 /* |
1445 ** Returns Negative number on error, zero or greater on success. | 1448 ** Returns Negative number on error, zero or greater on success. |
1446 ** Returns the amount of data immediately available to be read. | 1449 ** Returns the amount of data immediately available to be read. |
1447 */ | 1450 */ |
1448 int | 1451 int |
1449 SSL_DataPending(PRFileDesc *fd) | 1452 SSL_DataPending(PRFileDesc *fd) |
1450 { | 1453 { |
1451 sslSocket *ss; | 1454 sslSocket *ss; |
1452 int rv = 0; | 1455 int rv = 0; |
1453 | 1456 |
1454 ss = ssl_FindSocket(fd); | 1457 ss = ssl_FindSocket(fd); |
1455 | 1458 |
1456 if (ss && ss->opt.useSecurity) { | 1459 if (ss && ss->opt.useSecurity) { |
1457 » ssl_GetRecvBufLock(ss); | 1460 ssl_GetRecvBufLock(ss); |
1458 » rv = ss->gs.writeOffset - ss->gs.readOffset; | 1461 rv = ss->gs.writeOffset - ss->gs.readOffset; |
1459 » ssl_ReleaseRecvBufLock(ss); | 1462 ssl_ReleaseRecvBufLock(ss); |
1460 } | 1463 } |
1461 | 1464 |
1462 return rv; | 1465 return rv; |
1463 } | 1466 } |
1464 | 1467 |
1465 SECStatus | 1468 SECStatus |
1466 SSL_InvalidateSession(PRFileDesc *fd) | 1469 SSL_InvalidateSession(PRFileDesc *fd) |
1467 { | 1470 { |
1468 sslSocket * ss = ssl_FindSocket(fd); | 1471 sslSocket *ss = ssl_FindSocket(fd); |
1469 SECStatus rv = SECFailure; | 1472 SECStatus rv = SECFailure; |
1470 | 1473 |
1471 if (ss) { | 1474 if (ss) { |
1472 » ssl_Get1stHandshakeLock(ss); | 1475 ssl_Get1stHandshakeLock(ss); |
1473 » ssl_GetSSL3HandshakeLock(ss); | 1476 ssl_GetSSL3HandshakeLock(ss); |
1474 | 1477 |
1475 » if (ss->sec.ci.sid && ss->sec.uncache) { | 1478 if (ss->sec.ci.sid && ss->sec.uncache) { |
1476 » ss->sec.uncache(ss->sec.ci.sid); | 1479 ss->sec.uncache(ss->sec.ci.sid); |
1477 » rv = SECSuccess; | 1480 rv = SECSuccess; |
1478 » } | 1481 } |
1479 | 1482 |
1480 » ssl_ReleaseSSL3HandshakeLock(ss); | 1483 ssl_ReleaseSSL3HandshakeLock(ss); |
1481 » ssl_Release1stHandshakeLock(ss); | 1484 ssl_Release1stHandshakeLock(ss); |
1482 } | 1485 } |
1483 return rv; | 1486 return rv; |
1484 } | 1487 } |
1485 | 1488 |
1486 static void | 1489 static void |
1487 ssl3_CacheSessionUnlocked(sslSocket *ss) | 1490 ssl3_CacheSessionUnlocked(sslSocket *ss) |
1488 { | 1491 { |
1489 PORT_Assert(!ss->sec.isServer); | 1492 PORT_Assert(!ss->sec.isServer); |
1490 | 1493 |
1491 if (ss->ssl3.hs.cacheSID) { | 1494 if (ss->ssl3.hs.cacheSID) { |
1492 » ss->sec.cache(ss->sec.ci.sid); | 1495 ss->sec.cache(ss->sec.ci.sid); |
1493 » ss->ssl3.hs.cacheSID = PR_FALSE; | 1496 ss->ssl3.hs.cacheSID = PR_FALSE; |
1494 } | 1497 } |
1495 } | 1498 } |
1496 | 1499 |
1497 SECStatus | 1500 SECStatus |
1498 SSL_CacheSession(PRFileDesc *fd) | 1501 SSL_CacheSession(PRFileDesc *fd) |
1499 { | 1502 { |
1500 sslSocket * ss = ssl_FindSocket(fd); | 1503 sslSocket *ss = ssl_FindSocket(fd); |
1501 SECStatus rv = SECFailure; | 1504 SECStatus rv = SECFailure; |
1502 | 1505 |
1503 if (ss) { | 1506 if (ss) { |
1504 » ssl_Get1stHandshakeLock(ss); | 1507 ssl_Get1stHandshakeLock(ss); |
1505 » ssl_GetSSL3HandshakeLock(ss); | 1508 ssl_GetSSL3HandshakeLock(ss); |
1506 | 1509 |
1507 » ssl3_CacheSessionUnlocked(ss); | 1510 ssl3_CacheSessionUnlocked(ss); |
1508 » rv = SECSuccess; | 1511 rv = SECSuccess; |
1509 | 1512 |
1510 » ssl_ReleaseSSL3HandshakeLock(ss); | 1513 ssl_ReleaseSSL3HandshakeLock(ss); |
1511 » ssl_Release1stHandshakeLock(ss); | 1514 ssl_Release1stHandshakeLock(ss); |
1512 } | 1515 } |
1513 return rv; | 1516 return rv; |
1514 } | 1517 } |
1515 | 1518 |
1516 SECStatus | 1519 SECStatus |
1517 SSL_CacheSessionUnlocked(PRFileDesc *fd) | 1520 SSL_CacheSessionUnlocked(PRFileDesc *fd) |
1518 { | 1521 { |
1519 sslSocket * ss = ssl_FindSocket(fd); | 1522 sslSocket *ss = ssl_FindSocket(fd); |
1520 SECStatus rv = SECFailure; | 1523 SECStatus rv = SECFailure; |
1521 | 1524 |
1522 if (ss) { | 1525 if (ss) { |
1523 » ssl3_CacheSessionUnlocked(ss); | 1526 ssl3_CacheSessionUnlocked(ss); |
1524 » rv = SECSuccess; | 1527 rv = SECSuccess; |
1525 } | 1528 } |
1526 return rv; | 1529 return rv; |
1527 } | 1530 } |
1528 | 1531 |
1529 SECItem * | 1532 SECItem * |
1530 SSL_GetSessionID(PRFileDesc *fd) | 1533 SSL_GetSessionID(PRFileDesc *fd) |
1531 { | 1534 { |
1532 sslSocket * ss; | 1535 sslSocket *ss; |
1533 SECItem * item = NULL; | 1536 SECItem *item = NULL; |
1534 | 1537 |
1535 ss = ssl_FindSocket(fd); | 1538 ss = ssl_FindSocket(fd); |
1536 if (ss) { | 1539 if (ss) { |
1537 » ssl_Get1stHandshakeLock(ss); | 1540 ssl_Get1stHandshakeLock(ss); |
1538 » ssl_GetSSL3HandshakeLock(ss); | 1541 ssl_GetSSL3HandshakeLock(ss); |
1539 | 1542 |
1540 » if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) { | 1543 if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) { |
1541 » item = (SECItem *)PORT_Alloc(sizeof(SECItem)); | 1544 item = (SECItem *)PORT_Alloc(sizeof(SECItem)); |
1542 » if (item) { | 1545 if (item) { |
1543 » » sslSessionID * sid = ss->sec.ci.sid; | 1546 sslSessionID *sid = ss->sec.ci.sid; |
1544 » » if (sid->version < SSL_LIBRARY_VERSION_3_0) { | 1547 if (sid->version < SSL_LIBRARY_VERSION_3_0) { |
1545 » » item->len = SSL2_SESSIONID_BYTES; | 1548 item->len = SSL2_SESSIONID_BYTES; |
1546 » » item->data = (unsigned char*)PORT_Alloc(item->len); | 1549 item->data = (unsigned char *)PORT_Alloc(item->len); |
1547 » » PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); | 1550 PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); |
1548 » » } else { | 1551 } else { |
1549 » » item->len = sid->u.ssl3.sessionIDLength; | 1552 item->len = sid->u.ssl3.sessionIDLength; |
1550 » » item->data = (unsigned char*)PORT_Alloc(item->len); | 1553 item->data = (unsigned char *)PORT_Alloc(item->len); |
1551 » » PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); | 1554 PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); |
1552 » » } | 1555 } |
1553 » } | 1556 } |
1554 » } | 1557 } |
1555 | 1558 |
1556 » ssl_ReleaseSSL3HandshakeLock(ss); | 1559 ssl_ReleaseSSL3HandshakeLock(ss); |
1557 » ssl_Release1stHandshakeLock(ss); | 1560 ssl_Release1stHandshakeLock(ss); |
1558 } | 1561 } |
1559 return item; | 1562 return item; |
1560 } | 1563 } |
1561 | 1564 |
1562 SECStatus | 1565 SECStatus |
1563 SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) | 1566 SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) |
1564 { | 1567 { |
1565 sslSocket * ss; | 1568 sslSocket *ss; |
1566 | 1569 |
1567 ss = ssl_FindSocket(fd); | 1570 ss = ssl_FindSocket(fd); |
1568 if (!ss) | 1571 if (!ss) |
1569 » return SECFailure; | 1572 return SECFailure; |
1570 if (!dbHandle) { | 1573 if (!dbHandle) { |
1571 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1574 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1572 » return SECFailure; | 1575 return SECFailure; |
1573 } | 1576 } |
1574 ss->dbHandle = dbHandle; | 1577 ss->dbHandle = dbHandle; |
1575 return SECSuccess; | 1578 return SECSuccess; |
1576 } | 1579 } |
1577 | 1580 |
1578 /* | 1581 /* |
1579 * attempt to restart the handshake after asynchronously handling | 1582 * attempt to restart the handshake after asynchronously handling |
1580 * a request for the client's certificate. | 1583 * a request for the client's certificate. |
1581 * | 1584 * |
1582 * inputs: | 1585 * inputs: |
(...skipping 10 matching lines...) Expand all Loading... |
1593 * | 1596 * |
1594 * certChain Chain of signers for cert. | 1597 * certChain Chain of signers for cert. |
1595 * Note: ssl takes this reference, and does not copy the chain. | 1598 * Note: ssl takes this reference, and does not copy the chain. |
1596 * The caller should drop its reference without destroying the | 1599 * The caller should drop its reference without destroying the |
1597 * chain. SSL will free the chain when it is done with it. | 1600 * chain. SSL will free the chain when it is done with it. |
1598 * | 1601 * |
1599 * Return value: XXX | 1602 * Return value: XXX |
1600 * | 1603 * |
1601 * XXX This code only works on the initial handshake on a connection, XXX | 1604 * XXX This code only works on the initial handshake on a connection, XXX |
1602 * It does not work on a subsequent handshake (redo). | 1605 * It does not work on a subsequent handshake (redo). |
1603 */ | 1606 */ |
1604 SECStatus | 1607 SECStatus |
1605 SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd, | 1608 SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd, |
1606 » » » » CERTCertificate * cert, | 1609 CERTCertificate *cert, |
1607 » » » » SECKEYPrivateKey * key, | 1610 SECKEYPrivateKey *key, |
1608 » » » » CERTCertificateList *certChain) | 1611 CERTCertificateList *certChain) |
1609 { | 1612 { |
1610 sslSocket * ss = ssl_FindSocket(fd); | 1613 sslSocket *ss = ssl_FindSocket(fd); |
1611 SECStatus ret; | 1614 SECStatus ret; |
1612 | 1615 |
1613 if (!ss) { | 1616 if (!ss) { |
1614 » SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq", | 1617 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq", |
1615 » » SSL_GETPID(), fd)); | 1618 SSL_GETPID(), fd)); |
1616 » if (cert) { | 1619 if (cert) { |
1617 » CERT_DestroyCertificate(cert); | 1620 CERT_DestroyCertificate(cert); |
1618 » } | 1621 } |
1619 » if (key) { | 1622 if (key) { |
1620 » SECKEY_DestroyPrivateKey(key); | 1623 SECKEY_DestroyPrivateKey(key); |
1621 » } | 1624 } |
1622 » if (certChain) { | 1625 if (certChain) { |
1623 » CERT_DestroyCertificateList(certChain); | 1626 CERT_DestroyCertificateList(certChain); |
1624 » } | 1627 } |
1625 » return SECFailure; | 1628 return SECFailure; |
1626 } | 1629 } |
1627 | 1630 |
1628 ssl_Get1stHandshakeLock(ss); /************************************/ | 1631 ssl_Get1stHandshakeLock(ss); /************************************/ |
1629 | 1632 |
1630 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { | 1633 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
1631 » ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); | 1634 ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); |
1632 } else { | 1635 } else { |
1633 » if (certChain != NULL) { | 1636 if (certChain != NULL) { |
1634 » CERT_DestroyCertificateList(certChain); | 1637 CERT_DestroyCertificateList(certChain); |
1635 » } | 1638 } |
1636 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 1639 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
1637 » ret = SECFailure; | 1640 ret = SECFailure; |
1638 } | 1641 } |
1639 | 1642 |
1640 ssl_Release1stHandshakeLock(ss); /************************************/ | 1643 ssl_Release1stHandshakeLock(ss); /************************************/ |
1641 return ret; | 1644 return ret; |
1642 } | 1645 } |
1643 | 1646 |
1644 SECStatus | 1647 SECStatus |
1645 SSL_RestartHandshakeAfterChannelIDReq(PRFileDesc * fd, | 1648 SSL_RestartHandshakeAfterChannelIDReq(PRFileDesc *fd, |
1646 » » » » SECKEYPublicKey * channelIDPub, | 1649 SECKEYPublicKey *channelIDPub, |
1647 » » » » SECKEYPrivateKey *channelID) | 1650 SECKEYPrivateKey *channelID) |
1648 { | 1651 { |
1649 sslSocket * ss = ssl_FindSocket(fd); | 1652 sslSocket *ss = ssl_FindSocket(fd); |
1650 SECStatus ret; | 1653 SECStatus ret; |
1651 | 1654 |
1652 if (!ss) { | 1655 if (!ss) { |
1653 » SSL_DBG(("%d: SSL[%d]: bad socket in" | 1656 SSL_DBG(("%d: SSL[%d]: bad socket in" |
1654 » » " SSL_RestartHandshakeAfterChannelIDReq", | 1657 " SSL_RestartHandshakeAfterChannelIDReq", |
1655 » » SSL_GETPID(), fd)); | 1658 SSL_GETPID(), fd)); |
1656 » goto loser; | 1659 goto loser; |
1657 } | 1660 } |
1658 | 1661 |
1659 | |
1660 ssl_Get1stHandshakeLock(ss); | 1662 ssl_Get1stHandshakeLock(ss); |
1661 | 1663 |
1662 if (ss->version < SSL_LIBRARY_VERSION_3_0) { | 1664 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
1663 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 1665 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
1664 » ssl_Release1stHandshakeLock(ss); | 1666 ssl_Release1stHandshakeLock(ss); |
1665 » goto loser; | 1667 goto loser; |
1666 } | 1668 } |
1667 | 1669 |
1668 ret = ssl3_RestartHandshakeAfterChannelIDReq(ss, channelIDPub, | 1670 ret = ssl3_RestartHandshakeAfterChannelIDReq(ss, channelIDPub, |
1669 » » » » » » channelID); | 1671 channelID); |
1670 ssl_Release1stHandshakeLock(ss); | 1672 ssl_Release1stHandshakeLock(ss); |
1671 | 1673 |
1672 return ret; | 1674 return ret; |
1673 | 1675 |
1674 loser: | 1676 loser: |
1675 SECKEY_DestroyPublicKey(channelIDPub); | 1677 SECKEY_DestroyPublicKey(channelIDPub); |
1676 SECKEY_DestroyPrivateKey(channelID); | 1678 SECKEY_DestroyPrivateKey(channelID); |
1677 return SECFailure; | 1679 return SECFailure; |
1678 } | 1680 } |
1679 | 1681 |
1680 /* DO NOT USE. This function was exported in ssl.def with the wrong signature; | 1682 /* DO NOT USE. This function was exported in ssl.def with the wrong signature; |
1681 * this implementation exists to maintain link-time compatibility. | 1683 * this implementation exists to maintain link-time compatibility. |
1682 */ | 1684 */ |
1683 int | 1685 int |
1684 SSL_RestartHandshakeAfterServerCert(sslSocket * ss) | 1686 SSL_RestartHandshakeAfterServerCert(sslSocket *ss) |
1685 { | 1687 { |
1686 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | 1688 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1687 return -1; | 1689 return -1; |
1688 } | 1690 } |
1689 | 1691 |
1690 /* See documentation in ssl.h */ | 1692 /* See documentation in ssl.h */ |
1691 SECStatus | 1693 SECStatus |
1692 SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error) | 1694 SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error) |
1693 { | 1695 { |
1694 SECStatus rv; | 1696 SECStatus rv; |
1695 sslSocket *ss = ssl_FindSocket(fd); | 1697 sslSocket *ss = ssl_FindSocket(fd); |
1696 | 1698 |
1697 if (!ss) { | 1699 if (!ss) { |
1698 » SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete", | 1700 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete", |
1699 » » SSL_GETPID(), fd)); | 1701 SSL_GETPID(), fd)); |
1700 » return SECFailure; | 1702 return SECFailure; |
1701 } | 1703 } |
1702 | 1704 |
1703 ssl_Get1stHandshakeLock(ss); | 1705 ssl_Get1stHandshakeLock(ss); |
1704 | 1706 |
1705 if (!ss->ssl3.initialized) { | 1707 if (!ss->ssl3.initialized) { |
1706 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1708 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1707 » rv = SECFailure; | 1709 rv = SECFailure; |
1708 } else if (ss->version < SSL_LIBRARY_VERSION_3_0) { | 1710 } else if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
1709 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); | 1711 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
1710 » rv = SECFailure; | 1712 rv = SECFailure; |
1711 } else { | 1713 } else { |
1712 » rv = ssl3_AuthCertificateComplete(ss, error); | 1714 rv = ssl3_AuthCertificateComplete(ss, error); |
1713 } | 1715 } |
1714 | 1716 |
1715 ssl_Release1stHandshakeLock(ss); | 1717 ssl_Release1stHandshakeLock(ss); |
1716 | 1718 |
1717 return rv; | 1719 return rv; |
1718 } | 1720 } |
1719 | 1721 |
1720 /* For more info see ssl.h */ | 1722 /* For more info see ssl.h */ |
1721 SECStatus | 1723 SECStatus |
1722 SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func, | 1724 SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func, |
1723 void *arg) | 1725 void *arg) |
1724 { | 1726 { |
1725 sslSocket *ss; | 1727 sslSocket *ss; |
1726 | 1728 |
1727 ss = ssl_FindSocket(fd); | 1729 ss = ssl_FindSocket(fd); |
1728 if (!ss) { | 1730 if (!ss) { |
1729 » SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook", | 1731 SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook", |
1730 » » SSL_GETPID(), fd)); | 1732 SSL_GETPID(), fd)); |
1731 » return SECFailure; | 1733 return SECFailure; |
1732 } | 1734 } |
1733 | 1735 |
1734 ss->sniSocketConfig = func; | 1736 ss->sniSocketConfig = func; |
1735 ss->sniSocketConfigArg = arg; | 1737 ss->sniSocketConfigArg = arg; |
1736 return SECSuccess; | 1738 return SECSuccess; |
1737 } | 1739 } |
OLD | NEW |