2 * Gather (Read) entire SSL3 records from socket into buffer.
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
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
14 * Attempt to read in an entire SSL3 record.
15 * Blocks here for blocking sockets, otherwise returns -1 with
16 * PR_WOULD_BLOCK_ERROR when socket would block.
18 * returns 1 if received a complete SSL3 record.
19 * returns 0 if recv returns EOF
20 * returns -1 if recv returns < 0
21 * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
23 * Caller must hold the recv buf lock.
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.
27 * GS_DATA: waiting for the body of the SSL3 record to come in.
29 * This loop returns when either
30 * (a) an error or EOF occurs,
31 * (b) PR_WOULD_BLOCK_ERROR,
32 * (c) data (entire SSL3 record) has been received.
35 ssl3_GatherData(sslSocket
*ss
, sslGather
*gs
, int flags
)
43 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveRecvBufLock(ss
) );
44 if (gs
->state
== GS_INIT
) {
45 gs
->state
= GS_HEADER
;
55 SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
56 SSL_GETPID(), ss
->fd
, gs
->state
, gs
->remainder
));
57 bp
= ((gs
->state
!= GS_HEADER
) ? lbp
: gs
->hdr
) + gs
->offset
;
58 nb
= ssl_DefRecv(ss
, bp
, gs
->remainder
, flags
);
61 PRINT_BUF(60, (ss
, "raw gather data:", bp
, nb
));
64 SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss
->fd
));
67 } else /* if (nb < 0) */ {
68 SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss
->fd
,
74 PORT_Assert( nb
<= gs
->remainder
);
75 if (nb
> gs
->remainder
) {
76 /* ssl_DefRecv is misbehaving! this error is fatal to SSL. */
77 gs
->state
= GS_INIT
; /* so we don't crash next time */
84 if (gs
->state
== GS_DATA
)
87 /* if there's more to go, read some more. */
88 if (gs
->remainder
> 0) {
92 /* have received entire record header, or entire record. */
96 ** Have received SSL3 record header in gs->hdr.
97 ** Now extract the length of the following encrypted data,
98 ** and then read in the rest of the SSL3 record into gs->inbuf.
100 gs
->remainder
= (gs
->hdr
[3] << 8) | gs
->hdr
[4];
102 /* This is the max fragment length for an encrypted fragment
103 ** plus the size of the record header.
105 if(gs
->remainder
> (MAX_FRAGMENT_LENGTH
+ 2048 + 5)) {
106 SSL3_SendAlert(ss
, alert_fatal
, unexpected_message
);
108 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG
);
116 if (gs
->remainder
> gs
->inbuf
.space
) {
117 err
= sslBuffer_Grow(&gs
->inbuf
, gs
->remainder
);
118 if (err
) { /* realloc has set error code to no mem. */
123 break; /* End this case. Continue around the loop. */
128 ** SSL3 record has been completely received.
139 * Read in an entire DTLS record.
141 * Blocks here for blocking sockets, otherwise returns -1 with
142 * PR_WOULD_BLOCK_ERROR when socket would block.
144 * This is simpler than SSL because we are reading on a datagram socket
145 * and datagrams must contain >=1 complete records.
147 * returns 1 if received a complete DTLS record.
148 * returns 0 if recv returns EOF
149 * returns -1 if recv returns < 0
150 * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
152 * Caller must hold the recv buf lock.
154 * This loop returns when either
155 * (a) an error or EOF occurs,
156 * (b) PR_WOULD_BLOCK_ERROR,
157 * (c) data (entire DTLS record) has been received.
160 dtls_GatherData(sslSocket
*ss
, sslGather
*gs
, int flags
)
166 SSL_TRC(30, ("dtls_GatherData"));
168 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveRecvBufLock(ss
) );
170 gs
->state
= GS_HEADER
;
173 if (gs
->dtlsPacketOffset
== gs
->dtlsPacket
.len
) { /* No data left */
174 gs
->dtlsPacketOffset
= 0;
175 gs
->dtlsPacket
.len
= 0;
177 /* Resize to the maximum possible size so we can fit a full datagram */
178 /* This is the max fragment length for an encrypted fragment
179 ** plus the size of the record header.
180 ** This magic constant is copied from ssl3_GatherData, with 5 changed
181 ** to 13 (the size of the record header).
183 if (gs
->dtlsPacket
.space
< MAX_FRAGMENT_LENGTH
+ 2048 + 13) {
184 err
= sslBuffer_Grow(&gs
->dtlsPacket
,
185 MAX_FRAGMENT_LENGTH
+ 2048 + 13);
186 if (err
) { /* realloc has set error code to no mem. */
191 /* recv() needs to read a full datagram at a time */
192 nb
= ssl_DefRecv(ss
, gs
->dtlsPacket
.buf
, gs
->dtlsPacket
.space
, flags
);
195 PRINT_BUF(60, (ss
, "raw gather data:", gs
->dtlsPacket
.buf
, nb
));
196 } else if (nb
== 0) {
198 SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss
->fd
));
201 } else /* if (nb < 0) */ {
202 SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss
->fd
,
208 gs
->dtlsPacket
.len
= nb
;
211 /* At this point we should have >=1 complete records lined up in
212 * dtlsPacket. Read off the header.
214 if ((gs
->dtlsPacket
.len
- gs
->dtlsPacketOffset
) < 13) {
215 SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
216 "too short to contain header", SSL_GETPID(), ss
->fd
));
217 PR_SetError(PR_WOULD_BLOCK_ERROR
, 0);
218 gs
->dtlsPacketOffset
= 0;
219 gs
->dtlsPacket
.len
= 0;
223 memcpy(gs
->hdr
, gs
->dtlsPacket
.buf
+ gs
->dtlsPacketOffset
, 13);
224 gs
->dtlsPacketOffset
+= 13;
226 /* Have received SSL3 record header in gs->hdr. */
227 gs
->remainder
= (gs
->hdr
[11] << 8) | gs
->hdr
[12];
229 if ((gs
->dtlsPacket
.len
- gs
->dtlsPacketOffset
) < gs
->remainder
) {
230 SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
231 "to contain rest of body", SSL_GETPID(), ss
->fd
));
232 PR_SetError(PR_WOULD_BLOCK_ERROR
, 0);
233 gs
->dtlsPacketOffset
= 0;
234 gs
->dtlsPacket
.len
= 0;
239 /* OK, we have at least one complete packet, copy into inbuf */
240 if (gs
->remainder
> gs
->inbuf
.space
) {
241 err
= sslBuffer_Grow(&gs
->inbuf
, gs
->remainder
);
242 if (err
) { /* realloc has set error code to no mem. */
247 memcpy(gs
->inbuf
.buf
, gs
->dtlsPacket
.buf
+ gs
->dtlsPacketOffset
,
249 gs
->inbuf
.len
= gs
->remainder
;
250 gs
->offset
= gs
->remainder
;
251 gs
->dtlsPacketOffset
+= gs
->remainder
;
257 /* Gather in a record and when complete, Handle that record.
258 * Repeat this until the handshake is complete,
259 * or until application data is available.
261 * Returns 1 when the handshake is completed without error, or
262 * application data is available.
263 * Returns 0 if ssl3_GatherData hits EOF.
264 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
265 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
267 * Called from ssl_GatherRecord1stHandshake in sslcon.c,
268 * and from SSL_ForceHandshake in sslsecur.c
269 * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
271 * Caller must hold the recv buf lock.
274 ssl3_GatherCompleteHandshake(sslSocket
*ss
, int flags
)
276 SSL3Ciphertext cText
;
278 PRBool keepGoing
= PR_TRUE
;
280 SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
282 /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
283 * which requires the 1stHandshakeLock, which must be acquired before the
286 PORT_Assert( ss
->opt
.noLocks
|| ssl_Have1stHandshakeLock(ss
) );
287 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveRecvBufLock(ss
) );
290 PRBool handleRecordNow
= PR_FALSE
;
292 ssl_GetSSL3HandshakeLock(ss
);
294 /* Without this, we may end up wrongly reporting
295 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
296 * peer while we are waiting to be restarted.
298 if (ss
->ssl3
.hs
.restartTarget
) {
299 ssl_ReleaseSSL3HandshakeLock(ss
);
300 PORT_SetError(PR_WOULD_BLOCK_ERROR
);
301 return (int) SECFailure
;
304 /* Treat an empty msgState like a NULL msgState. (Most of the time
305 * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
306 * behind a non-NULL but zero-length msgState).
307 * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
309 if (ss
->ssl3
.hs
.msgState
.buf
) {
310 if (ss
->ssl3
.hs
.msgState
.len
== 0) {
311 ss
->ssl3
.hs
.msgState
.buf
= NULL
;
313 handleRecordNow
= PR_TRUE
;
317 ssl_ReleaseSSL3HandshakeLock(ss
);
319 if (handleRecordNow
) {
320 /* ssl3_HandleHandshake previously returned SECWouldBlock and the
321 * as-yet-unprocessed plaintext of that previous handshake record.
322 * We need to process it now before we overwrite it with the next
325 rv
= ssl3_HandleRecord(ss
, NULL
, &ss
->gs
.buf
);
327 /* bring in the next sslv3 record. */
328 if (ss
->recvdCloseNotify
) {
329 /* RFC 5246 Section 7.2.1:
330 * Any data received after a closure alert is ignored.
335 rv
= ssl3_GatherData(ss
, &ss
->gs
, flags
);
337 rv
= dtls_GatherData(ss
, &ss
->gs
, flags
);
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
342 if (rv
== SECFailure
&&
343 (PORT_GetError() == PR_WOULD_BLOCK_ERROR
)) {
344 ssl_GetSSL3HandshakeLock(ss
);
346 ssl_ReleaseSSL3HandshakeLock(ss
);
347 /* Restore the error in case something succeeded */
348 PORT_SetError(PR_WOULD_BLOCK_ERROR
);
356 /* decipher it, and handle it if it's a handshake.
357 * If it's application data, ss->gs.buf will not be empty upon return.
358 * If it's a change cipher spec, alert, or handshake message,
359 * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
361 cText
.type
= (SSL3ContentType
)ss
->gs
.hdr
[0];
362 cText
.version
= (ss
->gs
.hdr
[1] << 8) | ss
->gs
.hdr
[2];
367 cText
.version
= dtls_DTLSVersionToTLSVersion(cText
.version
);
368 /* DTLS sequence number */
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
];
377 cText
.buf
= &ss
->gs
.inbuf
;
378 rv
= ssl3_HandleRecord(ss
, &cText
, &ss
->gs
.buf
);
381 return ss
->recvdCloseNotify
? 0 : rv
;
383 if (ss
->gs
.buf
.len
> 0) {
384 /* We have application data to return to the application. This
385 * prioritizes returning application data to the application over
386 * completing any renegotiation handshake we may be doing.
388 PORT_Assert(ss
->firstHsDone
);
389 PORT_Assert(cText
.type
== content_application_data
);
393 PORT_Assert(keepGoing
);
394 ssl_GetSSL3HandshakeLock(ss
);
395 if (ss
->ssl3
.hs
.ws
== idle_handshake
) {
396 /* We are done with the current handshake so stop trying to
397 * handshake. Note that it would be safe to test ss->firstHsDone
398 * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
399 * we prioritize completing a renegotiation handshake over sending
402 PORT_Assert(ss
->firstHsDone
);
403 PORT_Assert(!ss
->ssl3
.hs
.canFalseStart
);
404 keepGoing
= PR_FALSE
;
405 } else if (ss
->ssl3
.hs
.canFalseStart
) {
406 /* Prioritize sending application data over trying to complete
407 * the handshake if we're false starting.
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.
414 PORT_Assert(!ss
->firstHsDone
);
416 if (ssl3_WaitingForStartOfServerSecondRound(ss
)) {
417 keepGoing
= PR_FALSE
;
419 ss
->ssl3
.hs
.canFalseStart
= PR_FALSE
;
422 ssl_ReleaseSSL3HandshakeLock(ss
);
425 ss
->gs
.readOffset
= 0;
426 ss
->gs
.writeOffset
= ss
->gs
.buf
.len
;
430 /* Repeatedly gather in a record and when complete, Handle that record.
431 * Repeat this until some application data is received.
433 * Returns 1 when application data is available.
434 * Returns 0 if ssl3_GatherData hits EOF.
435 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
436 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
438 * Called from DoRecv in sslsecur.c
439 * Caller must hold the recv buf lock.
442 ssl3_GatherAppDataRecord(sslSocket
*ss
, int flags
)
446 /* ssl3_GatherCompleteHandshake requires both of these locks. */
447 PORT_Assert( ss
->opt
.noLocks
|| ssl_Have1stHandshakeLock(ss
) );
448 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveRecvBufLock(ss
) );
451 rv
= ssl3_GatherCompleteHandshake(ss
, flags
);
452 } while (rv
> 0 && ss
->gs
.buf
.len
== 0);