Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: net/third_party/nss/ssl/ssl3gthr.c

Issue 1844813002: Uprev NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: One more GN fix Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/third_party/nss/ssl/ssl3ext.c ('k') | net/third_party/nss/ssl/ssl3prot.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Gather (Read) entire SSL3 records from socket into buffer. 2 * Gather (Read) entire SSL3 records from socket into buffer.
3 * 3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public 4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 7
8 #include "cert.h" 8 #include "cert.h"
9 #include "ssl.h" 9 #include "ssl.h"
10 #include "sslimpl.h" 10 #include "sslimpl.h"
11 #include "ssl3prot.h" 11 #include "ssl3prot.h"
12 12
13 /* 13 /*
14 * Attempt to read in an entire SSL3 record. 14 * Attempt to read in an entire SSL3 record.
15 * Blocks here for blocking sockets, otherwise returns -1 with 15 * Blocks here for blocking sockets, otherwise returns -1 with
16 * » PR_WOULD_BLOCK_ERROR when socket would block. 16 * PR_WOULD_BLOCK_ERROR when socket would block.
17 * 17 *
18 * returns 1 if received a complete SSL3 record. 18 * returns 1 if received a complete SSL3 record.
19 * returns 0 if recv returns EOF 19 * returns 0 if recv returns EOF
20 * returns -1 if recv returns < 0 20 * returns -1 if recv returns < 0
21 *» (The error value may have already been set to PR_WOULD_BLOCK_ERROR) 21 * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
22 * 22 *
23 * Caller must hold the recv buf lock. 23 * Caller must hold the recv buf lock.
24 * 24 *
25 * The Gather state machine has 3 states: GS_INIT, GS_HEADER, GS_DATA. 25 * The Gather state machine has 3 states: GS_INIT, GS_HEADER, GS_DATA.
26 * GS_HEADER: waiting for the 5-byte SSL3 record header to come in. 26 * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
27 * GS_DATA: waiting for the body of the SSL3 record to come in. 27 * GS_DATA: waiting for the body of the SSL3 record to come in.
28 * 28 *
29 * This loop returns when either 29 * This loop returns when either
30 * (a) an error or EOF occurs, 30 * (a) an error or EOF occurs,
31 *» (b) PR_WOULD_BLOCK_ERROR, 31 * (b) PR_WOULD_BLOCK_ERROR,
32 * » (c) data (entire SSL3 record) has been received. 32 * (c) data (entire SSL3 record) has been received.
33 */ 33 */
34 static int 34 static int
35 ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags) 35 ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
36 { 36 {
37 unsigned char *bp; 37 unsigned char *bp;
38 unsigned char *lbp; 38 unsigned char *lbp;
39 int nb; 39 int nb;
40 int err; 40 int err;
41 int rv» » = 1; 41 int rv = 1;
42 42
43 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 43 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
44 if (gs->state == GS_INIT) { 44 if (gs->state == GS_INIT) {
45 » gs->state = GS_HEADER; 45 gs->state = GS_HEADER;
46 » gs->remainder = 5; 46 gs->remainder = 5;
47 » gs->offset = 0; 47 gs->offset = 0;
48 » gs->writeOffset = 0; 48 gs->writeOffset = 0;
49 » gs->readOffset = 0; 49 gs->readOffset = 0;
50 » gs->inbuf.len = 0; 50 gs->inbuf.len = 0;
51 } 51 }
52 52
53 lbp = gs->inbuf.buf; 53 lbp = gs->inbuf.buf;
54 for(;;) { 54 for (;;) {
55 » SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)", 55 SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
56 » » SSL_GETPID(), ss->fd, gs->state, gs->remainder)); 56 SSL_GETPID(), ss->fd, gs->state, gs->remainder));
57 » bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset; 57 bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
58 » nb = ssl_DefRecv(ss, bp, gs->remainder, flags); 58 nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
59 59
60 » if (nb > 0) { 60 if (nb > 0) {
61 » PRINT_BUF(60, (ss, "raw gather data:", bp, nb)); 61 PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
62 » } else if (nb == 0) { 62 } else if (nb == 0) {
63 » /* EOF */ 63 /* EOF */
64 » SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd)); 64 SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
65 » rv = 0; 65 rv = 0;
66 » break; 66 break;
67 » } else /* if (nb < 0) */ { 67 } else /* if (nb < 0) */ {
68 » SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd, 68 SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
69 » » PR_GetError())); 69 PR_GetError()));
70 » rv = SECFailure; 70 rv = SECFailure;
71 » break; 71 break;
72 » } 72 }
73 73
74 » PORT_Assert( (unsigned int)nb <= gs->remainder ); 74 PORT_Assert((unsigned int)nb <= gs->remainder);
75 » if ((unsigned int)nb > gs->remainder) { 75 if ((unsigned int)nb > gs->remainder) {
76 » /* ssl_DefRecv is misbehaving! this error is fatal to SSL. */ 76 /* ssl_DefRecv is misbehaving! this error is fatal to SSL. */
77 » gs->state = GS_INIT; /* so we don't crash next time */ 77 gs->state = GS_INIT; /* so we don't crash next time */
78 » rv = SECFailure; 78 rv = SECFailure;
79 » break; 79 break;
80 » } 80 }
81 81
82 » gs->offset += nb; 82 gs->offset += nb;
83 » gs->remainder -= nb; 83 gs->remainder -= nb;
84 » if (gs->state == GS_DATA) 84 if (gs->state == GS_DATA)
85 » gs->inbuf.len += nb; 85 gs->inbuf.len += nb;
86 86
87 » /* if there's more to go, read some more. */ 87 /* if there's more to go, read some more. */
88 » if (gs->remainder > 0) { 88 if (gs->remainder > 0) {
89 » continue; 89 continue;
90 » } 90 }
91 91
92 » /* have received entire record header, or entire record. */ 92 /* have received entire record header, or entire record. */
93 » switch (gs->state) { 93 switch (gs->state) {
94 » case GS_HEADER: 94 case GS_HEADER:
95 » /* 95 /*
96 » ** Have received SSL3 record header in gs->hdr. 96 ** Have received SSL3 record header in gs->hdr.
97 » ** Now extract the length of the following encrypted data, 97 ** Now extract the length of the following encrypted data,
98 » ** and then read in the rest of the SSL3 record into gs->inbuf. 98 ** and then read in the rest of the SSL3 record into gs->inbuf.
99 » */ 99 */
100 » gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4]; 100 gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
101 101
102 » /* This is the max fragment length for an encrypted fragment 102 /* This is the max fragment length for an encrypted fragment
103 » ** plus the size of the record header. 103 ** plus the size of the record header.
104 » */ 104 */
105 » if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) { 105 if (gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
106 » » SSL3_SendAlert(ss, alert_fatal, unexpected_message); 106 SSL3_SendAlert(ss, alert_fatal, unexpected_message);
107 » » gs->state = GS_INIT; 107 gs->state = GS_INIT;
108 » » PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); 108 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
109 » » return SECFailure; 109 return SECFailure;
110 » } 110 }
111 111
112 » gs->state = GS_DATA; 112 gs->state = GS_DATA;
113 » gs->offset = 0; 113 gs->offset = 0;
114 » gs->inbuf.len = 0; 114 gs->inbuf.len = 0;
115 115
116 » if (gs->remainder > gs->inbuf.space) { 116 if (gs->remainder > gs->inbuf.space) {
117 » » err = sslBuffer_Grow(&gs->inbuf, gs->remainder); 117 err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
118 » » if (err) {» /* realloc has set error code to no mem. */ 118 if (err) { /* realloc has set error code to no mem. */
119 » » return err; 119 return err;
120 » » } 120 }
121 » » lbp = gs->inbuf.buf; 121 lbp = gs->inbuf.buf;
122 » } 122 }
123 » break;» /* End this case. Continue around the loop. */ 123 break; /* End this case. Continue around the loop. */
124 124
125 125 case GS_DATA:
126 » case GS_DATA: 126 /*
127 » /* 127 ** SSL3 record has been completely received.
128 » ** SSL3 record has been completely received. 128 */
129 » */ 129 gs->state = GS_INIT;
130 » gs->state = GS_INIT; 130 return 1;
131 » return 1; 131 }
132 » }
133 } 132 }
134 133
135 return rv; 134 return rv;
136 } 135 }
137 136
138 /* 137 /*
139 * Read in an entire DTLS record. 138 * Read in an entire DTLS record.
140 * 139 *
141 * Blocks here for blocking sockets, otherwise returns -1 with 140 * Blocks here for blocking sockets, otherwise returns -1 with
142 * » PR_WOULD_BLOCK_ERROR when socket would block. 141 * PR_WOULD_BLOCK_ERROR when socket would block.
143 * 142 *
144 * This is simpler than SSL because we are reading on a datagram socket 143 * This is simpler than SSL because we are reading on a datagram socket
145 * and datagrams must contain >=1 complete records. 144 * and datagrams must contain >=1 complete records.
146 * 145 *
147 * returns 1 if received a complete DTLS record. 146 * returns 1 if received a complete DTLS record.
148 * returns 0 if recv returns EOF 147 * returns 0 if recv returns EOF
149 * returns -1 if recv returns < 0 148 * returns -1 if recv returns < 0
150 *» (The error value may have already been set to PR_WOULD_BLOCK_ERROR) 149 * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
151 * 150 *
152 * Caller must hold the recv buf lock. 151 * Caller must hold the recv buf lock.
153 * 152 *
154 * This loop returns when either 153 * This loop returns when either
155 * (a) an error or EOF occurs, 154 * (a) an error or EOF occurs,
156 *» (b) PR_WOULD_BLOCK_ERROR, 155 * (b) PR_WOULD_BLOCK_ERROR,
157 * » (c) data (entire DTLS record) has been received. 156 * (c) data (entire DTLS record) has been received.
158 */ 157 */
159 static int 158 static int
160 dtls_GatherData(sslSocket *ss, sslGather *gs, int flags) 159 dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
161 { 160 {
162 int nb; 161 int nb;
163 int err; 162 int err;
164 int rv» » = 1; 163 int rv = 1;
165 164
166 SSL_TRC(30, ("dtls_GatherData")); 165 SSL_TRC(30, ("dtls_GatherData"));
167 166
168 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 167 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
169 168
170 gs->state = GS_HEADER; 169 gs->state = GS_HEADER;
171 gs->offset = 0; 170 gs->offset = 0;
172 171
173 if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */ 172 if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
174 gs->dtlsPacketOffset = 0; 173 gs->dtlsPacketOffset = 0;
175 gs->dtlsPacket.len = 0; 174 gs->dtlsPacket.len = 0;
176 175
177 /* Resize to the maximum possible size so we can fit a full datagram */ 176 /* Resize to the maximum possible size so we can fit a full datagram */
178 » /* This is the max fragment length for an encrypted fragment 177 /* This is the max fragment length for an encrypted fragment
179 » ** plus the size of the record header. 178 ** plus the size of the record header.
180 » ** This magic constant is copied from ssl3_GatherData, with 5 changed 179 ** This magic constant is copied from ssl3_GatherData, with 5 changed
181 » ** to 13 (the size of the record header). 180 ** to 13 (the size of the record header).
182 » */ 181 */
183 if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) { 182 if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
184 err = sslBuffer_Grow(&gs->dtlsPacket, 183 err = sslBuffer_Grow(&gs->dtlsPacket,
185 » » » » MAX_FRAGMENT_LENGTH + 2048 + 13); 184 MAX_FRAGMENT_LENGTH + 2048 + 13);
186 if (err) {» /* realloc has set error code to no mem. */ 185 if (err) { /* realloc has set error code to no mem. */
187 return err; 186 return err;
188 } 187 }
189 } 188 }
190 189
191 /* recv() needs to read a full datagram at a time */ 190 /* recv() needs to read a full datagram at a time */
192 nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags); 191 nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
193 192
194 if (nb > 0) { 193 if (nb > 0) {
195 PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb)); 194 PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
196 } else if (nb == 0) { 195 } else if (nb == 0) {
197 /* EOF */ 196 /* EOF */
198 SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd)); 197 SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
199 rv = 0; 198 rv = 0;
200 return rv; 199 return rv;
201 } else /* if (nb < 0) */ { 200 } else /* if (nb < 0) */ {
202 SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd, 201 SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
203 PR_GetError())); 202 PR_GetError()));
204 rv = SECFailure; 203 rv = SECFailure;
205 return rv; 204 return rv;
206 } 205 }
207 206
208 gs->dtlsPacket.len = nb; 207 gs->dtlsPacket.len = nb;
209 } 208 }
210 209
211 /* At this point we should have >=1 complete records lined up in 210 /* At this point we should have >=1 complete records lined up in
212 * dtlsPacket. Read off the header. 211 * dtlsPacket. Read off the header.
213 */ 212 */
214 if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) { 213 if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) {
215 SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet " 214 SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
216 » » "too short to contain header", SSL_GETPID(), ss->fd)); 215 "too short to contain header",
216 SSL_GETPID(), ss->fd));
217 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 217 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
218 gs->dtlsPacketOffset = 0; 218 gs->dtlsPacketOffset = 0;
219 gs->dtlsPacket.len = 0; 219 gs->dtlsPacket.len = 0;
220 rv = SECFailure; 220 rv = SECFailure;
221 return rv; 221 return rv;
222 } 222 }
223 memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13); 223 memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13);
224 gs->dtlsPacketOffset += 13; 224 gs->dtlsPacketOffset += 13;
225 225
226 /* Have received SSL3 record header in gs->hdr. */ 226 /* Have received SSL3 record header in gs->hdr. */
227 gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12]; 227 gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
228 228
229 if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) { 229 if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
230 SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short " 230 SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
231 » » "to contain rest of body", SSL_GETPID(), ss->fd)); 231 "to contain rest of body",
232 SSL_GETPID(), ss->fd));
232 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 233 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
233 gs->dtlsPacketOffset = 0; 234 gs->dtlsPacketOffset = 0;
234 gs->dtlsPacket.len = 0; 235 gs->dtlsPacket.len = 0;
235 rv = SECFailure; 236 rv = SECFailure;
236 return rv; 237 return rv;
237 } 238 }
238 239
239 /* OK, we have at least one complete packet, copy into inbuf */ 240 /* OK, we have at least one complete packet, copy into inbuf */
240 if (gs->remainder > gs->inbuf.space) { 241 if (gs->remainder > gs->inbuf.space) {
241 » err = sslBuffer_Grow(&gs->inbuf, gs->remainder); 242 err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
242 » if (err) {» /* realloc has set error code to no mem. */ 243 if (err) { /* realloc has set error code to no mem. */
243 » return err; 244 return err;
244 » } 245 }
245 } 246 }
246 247
247 memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 248 memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
248 » gs->remainder); 249 gs->remainder);
249 gs->inbuf.len = gs->remainder; 250 gs->inbuf.len = gs->remainder;
250 gs->offset = gs->remainder; 251 gs->offset = gs->remainder;
251 gs->dtlsPacketOffset += gs->remainder; 252 gs->dtlsPacketOffset += gs->remainder;
252 gs->state = GS_INIT; 253 gs->state = GS_INIT;
253 254
254 return 1; 255 return 1;
255 } 256 }
256 257
257 /* Gather in a record and when complete, Handle that record. 258 /* Gather in a record and when complete, Handle that record.
258 * Repeat this until the handshake is complete, 259 * Repeat this until the handshake is complete,
259 * or until application data is available. 260 * or until application data is available.
260 * 261 *
261 * Returns 1 when the handshake is completed without error, or 262 * Returns 1 when the handshake is completed without error, or
262 * application data is available. 263 * application data is available.
263 * Returns 0 if ssl3_GatherData hits EOF. 264 * Returns 0 if ssl3_GatherData hits EOF.
264 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. 265 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
265 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord. 266 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
266 * 267 *
267 * Called from ssl_GatherRecord1stHandshake in sslcon.c, 268 * Called from ssl_GatherRecord1stHandshake in sslcon.c,
268 * and from SSL_ForceHandshake in sslsecur.c 269 * and from SSL_ForceHandshake in sslsecur.c
269 * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c). 270 * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
270 * 271 *
271 * Caller must hold the recv buf lock. 272 * Caller must hold the recv buf lock.
272 */ 273 */
273 int 274 int
274 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) 275 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
275 { 276 {
276 SSL3Ciphertext cText; 277 SSL3Ciphertext cText;
277 int rv; 278 int rv;
278 PRBool keepGoing = PR_TRUE; 279 PRBool keepGoing = PR_TRUE;
279 280
280 SSL_TRC(30, ("ssl3_GatherCompleteHandshake")); 281 SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
281 282
282 /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake, 283 /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
283 * which requires the 1stHandshakeLock, which must be acquired before the 284 * which requires the 1stHandshakeLock, which must be acquired before the
284 * RecvBufLock. 285 * RecvBufLock.
285 */ 286 */
286 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 287 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
287 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 288 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
288 289
289 do { 290 do {
290 » PRBool handleRecordNow = PR_FALSE; 291 PRBool handleRecordNow = PR_FALSE;
291 292
292 » ssl_GetSSL3HandshakeLock(ss); 293 ssl_GetSSL3HandshakeLock(ss);
293 294
294 » /* Without this, we may end up wrongly reporting 295 /* Without this, we may end up wrongly reporting
295 » * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the 296 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
296 » * peer while we are waiting to be restarted. 297 * peer while we are waiting to be restarted.
297 » */ 298 */
298 » if (ss->ssl3.hs.restartTarget) { 299 if (ss->ssl3.hs.restartTarget) {
299 » ssl_ReleaseSSL3HandshakeLock(ss); 300 ssl_ReleaseSSL3HandshakeLock(ss);
300 » PORT_SetError(PR_WOULD_BLOCK_ERROR); 301 PORT_SetError(PR_WOULD_BLOCK_ERROR);
301 » return (int) SECFailure; 302 return (int)SECFailure;
302 » } 303 }
303 304
304 » /* Treat an empty msgState like a NULL msgState. (Most of the time 305 /* Treat an empty msgState like a NULL msgState. (Most of the time
305 » * when ssl3_HandleHandshake returns SECWouldBlock, it leaves 306 * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
306 » * behind a non-NULL but zero-length msgState). 307 * behind a non-NULL but zero-length msgState).
307 » * Test: async_cert_restart_server_sends_hello_request_first_in_separate _record 308 * Test: async_cert_restart_server_sends_hello_request_first_in_separate _record
308 » */ 309 */
309 » if (ss->ssl3.hs.msgState.buf) { 310 if (ss->ssl3.hs.msgState.buf) {
310 » if (ss->ssl3.hs.msgState.len == 0) { 311 if (ss->ssl3.hs.msgState.len == 0) {
311 » » ss->ssl3.hs.msgState.buf = NULL; 312 ss->ssl3.hs.msgState.buf = NULL;
312 » } else { 313 } else {
313 » » handleRecordNow = PR_TRUE; 314 handleRecordNow = PR_TRUE;
314 » } 315 }
315 » } 316 }
316 317
317 » ssl_ReleaseSSL3HandshakeLock(ss); 318 ssl_ReleaseSSL3HandshakeLock(ss);
318 319
319 » if (handleRecordNow) { 320 if (handleRecordNow) {
320 » /* ssl3_HandleHandshake previously returned SECWouldBlock and the 321 /* ssl3_HandleHandshake previously returned SECWouldBlock and the
321 » * as-yet-unprocessed plaintext of that previous handshake record. 322 * as-yet-unprocessed plaintext of that previous handshake record.
322 » * We need to process it now before we overwrite it with the next 323 * We need to process it now before we overwrite it with the next
323 » * handshake record. 324 * handshake record.
324 » */ 325 */
325 » rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); 326 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
326 » } else { 327 } else {
327 » /* bring in the next sslv3 record. */ 328 /* bring in the next sslv3 record. */
328 » if (ss->recvdCloseNotify) { 329 if (ss->recvdCloseNotify) {
329 » » /* RFC 5246 Section 7.2.1: 330 /* RFC 5246 Section 7.2.1:
330 » » * Any data received after a closure alert is ignored. 331 * Any data received after a closure alert is ignored.
331 » » */ 332 */
332 » » return 0; 333 return 0;
333 » } 334 }
334 » if (!IS_DTLS(ss)) { 335 if (!IS_DTLS(ss)) {
335 » » rv = ssl3_GatherData(ss, &ss->gs, flags); 336 rv = ssl3_GatherData(ss, &ss->gs, flags);
336 » } else { 337 } else {
337 » » rv = dtls_GatherData(ss, &ss->gs, flags); 338 rv = dtls_GatherData(ss, &ss->gs, flags);
338 » »
339 » » /* If we got a would block error, that means that no data was
340 » » * available, so we check the timer to see if it's time to
341 » » * retransmit */
342 » » if (rv == SECFailure &&
343 » » (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
344 » » ssl_GetSSL3HandshakeLock(ss);
345 » » dtls_CheckTimer(ss);
346 » » ssl_ReleaseSSL3HandshakeLock(ss);
347 » » /* Restore the error in case something succeeded */
348 » » PORT_SetError(PR_WOULD_BLOCK_ERROR);
349 » » }
350 » }
351 339
352 » if (rv <= 0) { 340 /* If we got a would block error, that means that no data was
353 » » return rv; 341 * available, so we check the timer to see if it's time to
354 » } 342 * retransmit */
343 if (rv == SECFailure &&
344 (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
345 ssl_GetSSL3HandshakeLock(ss);
346 dtls_CheckTimer(ss);
347 ssl_ReleaseSSL3HandshakeLock(ss);
348 /* Restore the error in case something succeeded */
349 PORT_SetError(PR_WOULD_BLOCK_ERROR);
350 }
351 }
355 352
356 » /* decipher it, and handle it if it's a handshake. 353 if (rv <= 0) {
357 » * If it's application data, ss->gs.buf will not be empty upon retur n. 354 return rv;
358 » * If it's a change cipher spec, alert, or handshake message, 355 }
359 » * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSucces s.
360 » */
361 » cText.type = (SSL3ContentType)ss->gs.hdr[0];
362 » cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
363 356
364 » if (IS_DTLS(ss)) { 357 /* decipher it, and handle it if it's a handshake.
365 » » int i; 358 * If it's application data, ss->gs.buf will not be empty upon retur n.
359 * If it's a change cipher spec, alert, or handshake message,
360 * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSucces s.
361 */
362 cText.type = (SSL3ContentType)ss->gs.hdr[0];
363 cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
366 364
367 » » cText.version = dtls_DTLSVersionToTLSVersion(cText.version); 365 if (IS_DTLS(ss)) {
368 » » /* DTLS sequence number */ 366 int i;
369 » » cText.seq_num.high = 0; cText.seq_num.low = 0;
370 » » for (i = 0; i < 4; i++) {
371 » » cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
372 » » cText.seq_num.high |= ss->gs.hdr[3 + i];
373 » » cText.seq_num.low |= ss->gs.hdr[7 + i];
374 » » }
375 » }
376 367
377 » cText.buf = &ss->gs.inbuf; 368 cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
378 » rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); 369 /* DTLS sequence number */
379 » } 370 cText.seq_num.high = 0;
380 » if (rv < 0) { 371 cText.seq_num.low = 0;
381 » return ss->recvdCloseNotify ? 0 : rv; 372 for (i = 0; i < 4; i++) {
382 » } 373 cText.seq_num.high <<= 8;
383 » if (ss->gs.buf.len > 0) { 374 cText.seq_num.low <<= 8;
384 » /* We have application data to return to the application. This 375 cText.seq_num.high |= ss->gs.hdr[3 + i];
385 » * prioritizes returning application data to the application over 376 cText.seq_num.low |= ss->gs.hdr[7 + i];
386 » * completing any renegotiation handshake we may be doing. 377 }
387 » */ 378 }
388 » PORT_Assert(ss->firstHsDone);
389 » PORT_Assert(cText.type == content_application_data);
390 » break;
391 » }
392 379
393 » PORT_Assert(keepGoing); 380 cText.buf = &ss->gs.inbuf;
394 » ssl_GetSSL3HandshakeLock(ss); 381 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
395 » if (ss->ssl3.hs.ws == idle_handshake) { 382 }
396 » /* We are done with the current handshake so stop trying to 383 if (rv < 0) {
397 » * handshake. Note that it would be safe to test ss->firstHsDone 384 return ss->recvdCloseNotify ? 0 : rv;
398 » * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead, 385 }
399 » * we prioritize completing a renegotiation handshake over sending 386 if (ss->gs.buf.len > 0) {
400 » * application data. 387 /* We have application data to return to the application. This
401 » */ 388 * prioritizes returning application data to the application over
402 » PORT_Assert(ss->firstHsDone); 389 * completing any renegotiation handshake we may be doing.
403 » PORT_Assert(!ss->ssl3.hs.canFalseStart); 390 */
404 » keepGoing = PR_FALSE; 391 PORT_Assert(ss->firstHsDone);
405 » } else if (ss->ssl3.hs.canFalseStart) { 392 PORT_Assert(cText.type == content_application_data);
406 » /* Prioritize sending application data over trying to complete 393 break;
407 » * the handshake if we're false starting. 394 }
408 » *
409 » * If we were to do this check at the beginning of the loop instead
410 » * of here, then this function would become be a no-op after
411 » * receiving the ServerHelloDone in the false start case, and we
412 » * would never complete the handshake.
413 » */
414 » PORT_Assert(!ss->firstHsDone);
415 395
416 » if (ssl3_WaitingForStartOfServerSecondRound(ss)) { 396 PORT_Assert(keepGoing);
417 » » keepGoing = PR_FALSE; 397 ssl_GetSSL3HandshakeLock(ss);
418 » } else { 398 if (ss->ssl3.hs.ws == idle_handshake) {
419 » » ss->ssl3.hs.canFalseStart = PR_FALSE; 399 /* We are done with the current handshake so stop trying to
420 » } 400 * handshake. Note that it would be safe to test ss->firstHsDone
421 » } 401 * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
422 » ssl_ReleaseSSL3HandshakeLock(ss); 402 * we prioritize completing a renegotiation handshake over sending
403 * application data.
404 */
405 PORT_Assert(ss->firstHsDone);
406 PORT_Assert(!ss->ssl3.hs.canFalseStart);
407 keepGoing = PR_FALSE;
408 } else if (ss->ssl3.hs.canFalseStart) {
409 /* Prioritize sending application data over trying to complete
410 * the handshake if we're false starting.
411 *
412 * If we were to do this check at the beginning of the loop instead
413 * of here, then this function would become be a no-op after
414 * receiving the ServerHelloDone in the false start case, and we
415 * would never complete the handshake.
416 */
417 PORT_Assert(!ss->firstHsDone);
418
419 if (ssl3_WaitingForServerSecondRound(ss)) {
420 keepGoing = PR_FALSE;
421 } else {
422 ss->ssl3.hs.canFalseStart = PR_FALSE;
423 }
424 }
425 ssl_ReleaseSSL3HandshakeLock(ss);
423 } while (keepGoing); 426 } while (keepGoing);
424 427
425 ss->gs.readOffset = 0; 428 ss->gs.readOffset = 0;
426 ss->gs.writeOffset = ss->gs.buf.len; 429 ss->gs.writeOffset = ss->gs.buf.len;
427 return 1; 430 return 1;
428 } 431 }
429 432
430 /* Repeatedly gather in a record and when complete, Handle that record. 433 /* Repeatedly gather in a record and when complete, Handle that record.
431 * Repeat this until some application data is received. 434 * Repeat this until some application data is received.
432 * 435 *
433 * Returns 1 when application data is available. 436 * Returns 1 when application data is available.
434 * Returns 0 if ssl3_GatherData hits EOF. 437 * Returns 0 if ssl3_GatherData hits EOF.
435 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. 438 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
436 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord. 439 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
437 * 440 *
438 * Called from DoRecv in sslsecur.c 441 * Called from DoRecv in sslsecur.c
439 * Caller must hold the recv buf lock. 442 * Caller must hold the recv buf lock.
440 */ 443 */
441 int 444 int
442 ssl3_GatherAppDataRecord(sslSocket *ss, int flags) 445 ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
443 { 446 {
444 int rv; 447 int rv;
445 448
446 /* ssl3_GatherCompleteHandshake requires both of these locks. */ 449 /* ssl3_GatherCompleteHandshake requires both of these locks. */
447 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 450 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
448 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 451 PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
449 452
450 do { 453 do {
451 » rv = ssl3_GatherCompleteHandshake(ss, flags); 454 rv = ssl3_GatherCompleteHandshake(ss, flags);
452 } while (rv > 0 && ss->gs.buf.len == 0); 455 } while (rv > 0 && ss->gs.buf.len == 0);
453 456
454 return rv; 457 return rv;
455 } 458 }
OLDNEW
« no previous file with comments | « net/third_party/nss/ssl/ssl3ext.c ('k') | net/third_party/nss/ssl/ssl3prot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698