Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/nss/lib/ssl/ssl3gthr.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * Gather (Read) entire SSL3 records from socket into buffer.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8
9
#include "cert.h"
10
#include "ssl.h"
11
#include "sslimpl.h"
12
#include "sslproto.h"
13
#include "ssl3prot.h"
14
15
struct ssl2GatherStr {
16
    /* true when ssl3_GatherData encounters an SSLv2 handshake */
17
    PRBool isV2;
18
19
    /* number of bytes of padding appended to the message content */
20
    PRUint8 padding;
21
};
22
23
typedef struct ssl2GatherStr ssl2Gather;
24
25
/* Caller should hold RecvBufLock. */
26
SECStatus
27
ssl3_InitGather(sslGather *gs)
28
0
{
29
0
    SECStatus status;
30
0
31
0
    gs->state = GS_INIT;
32
0
    gs->writeOffset = 0;
33
0
    gs->readOffset = 0;
34
0
    gs->dtlsPacketOffset = 0;
35
0
    gs->dtlsPacket.len = 0;
36
0
    gs->rejectV2Records = PR_FALSE;
37
0
    status = sslBuffer_Grow(&gs->buf, 4096);
38
0
    return status;
39
0
}
40
41
/* Caller must hold RecvBufLock. */
42
void
43
ssl3_DestroyGather(sslGather *gs)
44
0
{
45
0
    if (gs) { /* the PORT_*Free functions check for NULL pointers. */
46
0
        PORT_ZFree(gs->buf.buf, gs->buf.space);
47
0
        PORT_Free(gs->inbuf.buf);
48
0
        PORT_Free(gs->dtlsPacket.buf);
49
0
    }
50
0
}
51
52
/* Checks whether a given buffer is likely an SSLv3 record header.  */
53
PRBool
54
ssl3_isLikelyV3Hello(const unsigned char *buf)
55
0
{
56
0
    /* Even if this was a V2 record header we couldn't possibly parse it
57
0
     * correctly as the second bit denotes a vaguely-defined security escape. */
58
0
    if (buf[0] & 0x40) {
59
0
        return PR_TRUE;
60
0
    }
61
0
62
0
    /* Check for a typical V3 record header. */
63
0
    return (PRBool)(buf[0] >= ssl_ct_change_cipher_spec &&
64
0
                    buf[0] <= ssl_ct_application_data &&
65
0
                    buf[1] == MSB(SSL_LIBRARY_VERSION_3_0));
66
0
}
67
68
/*
69
 * Attempt to read in an entire SSL3 record.
70
 * Blocks here for blocking sockets, otherwise returns -1 with
71
 *  PR_WOULD_BLOCK_ERROR when socket would block.
72
 *
73
 * returns  1 if received a complete SSL3 record.
74
 * returns  0 if recv returns EOF
75
 * returns -1 if recv returns < 0
76
 *  (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
77
 *
78
 * Caller must hold the recv buf lock.
79
 *
80
 * The Gather state machine has 3 states:  GS_INIT, GS_HEADER, GS_DATA.
81
 * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
82
 * GS_DATA:   waiting for the body of the SSL3 record   to come in.
83
 *
84
 * This loop returns when either
85
 *      (a) an error or EOF occurs,
86
 *  (b) PR_WOULD_BLOCK_ERROR,
87
 *  (c) data (entire SSL3 record) has been received.
88
 */
89
static int
90
ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs)
91
0
{
92
0
    unsigned char *bp;
93
0
    unsigned char *lbp;
94
0
    int nb;
95
0
    int err;
96
0
    int rv = 1;
97
0
    PRUint8 v2HdrLength = 0;
98
0
99
0
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
100
0
    if (gs->state == GS_INIT) {
101
0
        gs->state = GS_HEADER;
102
0
        gs->remainder = 5;
103
0
        gs->offset = 0;
104
0
        gs->writeOffset = 0;
105
0
        gs->readOffset = 0;
106
0
        gs->inbuf.len = 0;
107
0
    }
108
0
109
0
    lbp = gs->inbuf.buf;
110
0
    for (;;) {
111
0
        SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
112
0
                     SSL_GETPID(), ss->fd, gs->state, gs->remainder));
113
0
        bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
114
0
        nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
115
0
116
0
        if (nb > 0) {
117
0
            PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
118
0
        } else if (nb == 0) {
119
0
            /* EOF */
120
0
            SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
121
0
            rv = 0;
122
0
            break;
123
0
        } else /* if (nb < 0) */ {
124
0
            SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
125
0
                     PR_GetError()));
126
0
            rv = SECFailure;
127
0
            break;
128
0
        }
129
0
130
0
        PORT_Assert((unsigned int)nb <= gs->remainder);
131
0
        if ((unsigned int)nb > gs->remainder) {
132
0
            /* ssl_DefRecv is misbehaving!  this error is fatal to SSL. */
133
0
            gs->state = GS_INIT; /* so we don't crash next time */
134
0
            rv = SECFailure;
135
0
            break;
136
0
        }
137
0
138
0
        gs->offset += nb;
139
0
        gs->remainder -= nb;
140
0
        if (gs->state == GS_DATA)
141
0
            gs->inbuf.len += nb;
142
0
143
0
        /* if there's more to go, read some more. */
144
0
        if (gs->remainder > 0) {
145
0
            continue;
146
0
        }
147
0
148
0
        /* have received entire record header, or entire record. */
149
0
        switch (gs->state) {
150
0
            case GS_HEADER:
151
0
                /* Check for SSLv2 handshakes. Always assume SSLv3 on clients,
152
0
                 * support SSLv2 handshakes only when ssl2gs != NULL.
153
0
                 * Always assume v3 after we received the first record. */
154
0
                if (!ssl2gs ||
155
0
                    ss->gs.rejectV2Records ||
156
0
                    ssl3_isLikelyV3Hello(gs->hdr)) {
157
0
                    /* Should have a non-SSLv2 record header in gs->hdr. Extract
158
0
                     * the length of the following encrypted data, and then
159
0
                     * read in the rest of the record into gs->inbuf. */
160
0
                    gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
161
0
                    gs->hdrLen = SSL3_RECORD_HEADER_LENGTH;
162
0
                } else {
163
0
                    /* Probably an SSLv2 record header. No need to handle any
164
0
                     * security escapes (gs->hdr[0] & 0x40) as we wouldn't get
165
0
                     * here if one was set. See ssl3_isLikelyV3Hello(). */
166
0
                    gs->remainder = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
167
0
                    ssl2gs->isV2 = PR_TRUE;
168
0
                    v2HdrLength = 2;
169
0
170
0
                    /* Is it a 3-byte header with padding? */
171
0
                    if (!(gs->hdr[0] & 0x80)) {
172
0
                        ssl2gs->padding = gs->hdr[2];
173
0
                        v2HdrLength++;
174
0
                    }
175
0
                }
176
0
177
0
                /* This is the max length for an encrypted SSLv3+ fragment. */
178
0
                if (!v2HdrLength &&
179
0
                    gs->remainder > (MAX_FRAGMENT_LENGTH + 2048)) {
180
0
                    SSL3_SendAlert(ss, alert_fatal, record_overflow);
181
0
                    gs->state = GS_INIT;
182
0
                    PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
183
0
                    return SECFailure;
184
0
                }
185
0
186
0
                gs->state = GS_DATA;
187
0
                gs->offset = 0;
188
0
                gs->inbuf.len = 0;
189
0
190
0
                if (gs->remainder > gs->inbuf.space) {
191
0
                    err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
192
0
                    if (err) { /* realloc has set error code to no mem. */
193
0
                        return err;
194
0
                    }
195
0
                    lbp = gs->inbuf.buf;
196
0
                }
197
0
198
0
                /* When we encounter an SSLv2 hello we've read 2 or 3 bytes too
199
0
                 * many into the gs->hdr[] buffer. Copy them over into inbuf so
200
0
                 * that we can properly process the hello record later. */
201
0
                if (v2HdrLength) {
202
0
                    /* Reject v2 records that don't even carry enough data to
203
0
                     * resemble a valid ClientHello header. */
204
0
                    if (gs->remainder < SSL_HL_CLIENT_HELLO_HBYTES) {
205
0
                        SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
206
0
                        PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
207
0
                        return SECFailure;
208
0
                    }
209
0
210
0
                    PORT_Assert(lbp);
211
0
                    gs->inbuf.len = 5 - v2HdrLength;
212
0
                    PORT_Memcpy(lbp, gs->hdr + v2HdrLength, gs->inbuf.len);
213
0
                    gs->remainder -= gs->inbuf.len;
214
0
                    lbp += gs->inbuf.len;
215
0
                }
216
0
217
0
                if (gs->remainder > 0) {
218
0
                    break; /* End this case.  Continue around the loop. */
219
0
                }
220
0
221
0
            /* FALL THROUGH if (gs->remainder == 0) as we just received
222
0
                 * an empty record and there's really no point in calling
223
0
                 * ssl_DefRecv() with buf=NULL and len=0. */
224
0
225
0
            case GS_DATA:
226
0
                /*
227
0
                ** SSL3 record has been completely received.
228
0
                */
229
0
                SSL_TRC(10, ("%d: SSL[%d]: got record of %d bytes",
230
0
                             SSL_GETPID(), ss->fd, gs->inbuf.len));
231
0
232
0
                /* reject any v2 records from now on */
233
0
                ss->gs.rejectV2Records = PR_TRUE;
234
0
235
0
                gs->state = GS_INIT;
236
0
                return 1;
237
0
        }
238
0
    }
239
0
240
0
    return rv;
241
0
}
242
243
/*
244
 * Read in an entire DTLS record.
245
 *
246
 * Blocks here for blocking sockets, otherwise returns -1 with
247
 *  PR_WOULD_BLOCK_ERROR when socket would block.
248
 *
249
 * This is simpler than SSL because we are reading on a datagram socket
250
 * and datagrams must contain >=1 complete records.
251
 *
252
 * returns  1 if received a complete DTLS record.
253
 * returns  0 if recv returns EOF
254
 * returns -1 if recv returns < 0
255
 *  (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
256
 *
257
 * Caller must hold the recv buf lock.
258
 *
259
 * This loop returns when either
260
 *      (a) an error or EOF occurs,
261
 *  (b) PR_WOULD_BLOCK_ERROR,
262
 *  (c) data (entire DTLS record) has been received.
263
 */
264
static int
265
dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
266
0
{
267
0
    int nb;
268
0
    PRUint8 contentType;
269
0
    unsigned int headerLen;
270
0
    SECStatus rv;
271
0
272
0
    SSL_TRC(30, ("dtls_GatherData"));
273
0
274
0
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
275
0
276
0
    gs->state = GS_HEADER;
277
0
    gs->offset = 0;
278
0
279
0
    if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
280
0
        gs->dtlsPacketOffset = 0;
281
0
        gs->dtlsPacket.len = 0;
282
0
283
0
        /* Resize to the maximum possible size so we can fit a full datagram */
284
0
        /* This is the max fragment length for an encrypted fragment
285
0
        ** plus the size of the record header.
286
0
        ** This magic constant is copied from ssl3_GatherData, with 5 changed
287
0
        ** to 13 (the size of the record header).
288
0
        */
289
0
        if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
290
0
            rv = sslBuffer_Grow(&gs->dtlsPacket,
291
0
                                MAX_FRAGMENT_LENGTH + 2048 + 13);
292
0
            if (rv != SECSuccess) {
293
0
                return -1; /* Code already set. */
294
0
            }
295
0
        }
296
0
297
0
        /* recv() needs to read a full datagram at a time */
298
0
        nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
299
0
        if (nb > 0) {
300
0
            PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
301
0
        } else if (nb == 0) {
302
0
            /* EOF */
303
0
            SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
304
0
            return 0;
305
0
        } else /* if (nb < 0) */ {
306
0
            SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
307
0
                     PR_GetError()));
308
0
            return -1;
309
0
        }
310
0
311
0
        gs->dtlsPacket.len = nb;
312
0
    }
313
0
314
0
    contentType = gs->dtlsPacket.buf[gs->dtlsPacketOffset];
315
0
    if (dtls_IsLongHeader(ss->version, contentType)) {
316
0
        headerLen = 13;
317
0
    } else if (contentType == ssl_ct_application_data) {
318
0
        headerLen = 7;
319
0
    } else if ((contentType & 0xe0) == 0x20) {
320
0
        headerLen = 2;
321
0
    } else {
322
0
        SSL_DBG(("%d: SSL3[%d]: invalid first octet (%d) for DTLS",
323
0
                 SSL_GETPID(), ss->fd, contentType));
324
0
        PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
325
0
        gs->dtlsPacketOffset = 0;
326
0
        gs->dtlsPacket.len = 0;
327
0
        return -1;
328
0
    }
329
0
330
0
    /* At this point we should have >=1 complete records lined up in
331
0
     * dtlsPacket. Read off the header.
332
0
     */
333
0
    if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < headerLen) {
334
0
        SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
335
0
                 "too short to contain header",
336
0
                 SSL_GETPID(), ss->fd));
337
0
        PORT_SetError(PR_WOULD_BLOCK_ERROR);
338
0
        gs->dtlsPacketOffset = 0;
339
0
        gs->dtlsPacket.len = 0;
340
0
        return -1;
341
0
    }
342
0
    memcpy(gs->hdr, SSL_BUFFER_BASE(&gs->dtlsPacket) + gs->dtlsPacketOffset,
343
0
           headerLen);
344
0
    gs->hdrLen = headerLen;
345
0
    gs->dtlsPacketOffset += headerLen;
346
0
347
0
    /* Have received SSL3 record header in gs->hdr. */
348
0
    if (headerLen == 13) {
349
0
        gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
350
0
    } else if (headerLen == 7) {
351
0
        gs->remainder = (gs->hdr[5] << 8) | gs->hdr[6];
352
0
    } else {
353
0
        PORT_Assert(headerLen == 2);
354
0
        gs->remainder = gs->dtlsPacket.len - gs->dtlsPacketOffset;
355
0
    }
356
0
357
0
    if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
358
0
        SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
359
0
                 "to contain rest of body",
360
0
                 SSL_GETPID(), ss->fd));
361
0
        PORT_SetError(PR_WOULD_BLOCK_ERROR);
362
0
        gs->dtlsPacketOffset = 0;
363
0
        gs->dtlsPacket.len = 0;
364
0
        return -1;
365
0
    }
366
0
367
0
    /* OK, we have at least one complete packet, copy into inbuf */
368
0
    gs->inbuf.len = 0;
369
0
    rv = sslBuffer_Append(&gs->inbuf,
370
0
                          SSL_BUFFER_BASE(&gs->dtlsPacket) + gs->dtlsPacketOffset,
371
0
                          gs->remainder);
372
0
    if (rv != SECSuccess) {
373
0
        return -1; /* code already set. */
374
0
    }
375
0
    gs->offset = gs->remainder;
376
0
    gs->dtlsPacketOffset += gs->remainder;
377
0
    gs->state = GS_INIT;
378
0
379
0
    SSL_TRC(20, ("%d: SSL3[%d]: dtls gathered record type=%d len=%d",
380
0
                 SSL_GETPID(), ss->fd, contentType, gs->inbuf.len));
381
0
    return 1;
382
0
}
383
384
/* Gather in a record and when complete, Handle that record.
385
 * Repeat this until the handshake is complete,
386
 * or until application data is available.
387
 *
388
 * Returns  1 when the handshake is completed without error, or
389
 *                 application data is available.
390
 * Returns  0 if ssl3_GatherData hits EOF.
391
 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
392
 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
393
 *
394
 * Called from ssl_GatherRecord1stHandshake       in sslcon.c,
395
 *    and from SSL_ForceHandshake in sslsecur.c
396
 *    and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
397
 *
398
 * Caller must hold the recv buf lock.
399
 */
400
int
401
ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
402
0
{
403
0
    int rv;
404
0
    SSL3Ciphertext cText;
405
0
    PRBool keepGoing = PR_TRUE;
406
0
407
0
    if (ss->ssl3.fatalAlertSent) {
408
0
        SSL_TRC(3, ("%d: SSL3[%d] Cannot gather data; fatal alert already sent",
409
0
                    SSL_GETPID(), ss->fd));
410
0
        PORT_SetError(SSL_ERROR_HANDSHAKE_FAILED);
411
0
        return SECFailure;
412
0
    }
413
0
414
0
    SSL_TRC(30, ("%d: SSL3[%d]: ssl3_GatherCompleteHandshake",
415
0
                 SSL_GETPID(), ss->fd));
416
0
417
0
    /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
418
0
     * which requires the 1stHandshakeLock, which must be acquired before the
419
0
     * RecvBufLock.
420
0
     */
421
0
    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
422
0
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
423
0
424
0
    do {
425
0
        PRBool handleRecordNow = PR_FALSE;
426
0
        PRBool processingEarlyData;
427
0
428
0
        ssl_GetSSL3HandshakeLock(ss);
429
0
430
0
        processingEarlyData = ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
431
0
432
0
        /* Without this, we may end up wrongly reporting
433
0
         * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
434
0
         * peer while we are waiting to be restarted.
435
0
         */
436
0
        if (ss->ssl3.hs.restartTarget) {
437
0
            ssl_ReleaseSSL3HandshakeLock(ss);
438
0
            PORT_SetError(PR_WOULD_BLOCK_ERROR);
439
0
            return (int)SECFailure;
440
0
        }
441
0
442
0
        /* Treat an empty msgState like a NULL msgState. (Most of the time
443
0
         * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
444
0
         * behind a non-NULL but zero-length msgState).
445
0
         * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
446
0
         */
447
0
        if (ss->ssl3.hs.msgState.buf) {
448
0
            if (ss->ssl3.hs.msgState.len == 0) {
449
0
                ss->ssl3.hs.msgState.buf = NULL;
450
0
            } else {
451
0
                handleRecordNow = PR_TRUE;
452
0
            }
453
0
        }
454
0
455
0
        ssl_ReleaseSSL3HandshakeLock(ss);
456
0
457
0
        if (handleRecordNow) {
458
0
            /* ssl3_HandleHandshake previously returned SECWouldBlock and the
459
0
             * as-yet-unprocessed plaintext of that previous handshake record.
460
0
             * We need to process it now before we overwrite it with the next
461
0
             * handshake record.
462
0
             */
463
0
            SSL_DBG(("%d: SSL3[%d]: resuming handshake",
464
0
                     SSL_GETPID(), ss->fd));
465
0
            PORT_Assert(!IS_DTLS(ss));
466
0
            rv = ssl3_HandleNonApplicationData(ss, ssl_ct_handshake,
467
0
                                               0, 0, &ss->gs.buf);
468
0
        } else {
469
0
            /* State for SSLv2 client hello support. */
470
0
            ssl2Gather ssl2gs = { PR_FALSE, 0 };
471
0
            ssl2Gather *ssl2gs_ptr = NULL;
472
0
473
0
            if (ss->sec.isServer && ss->opt.enableV2CompatibleHello &&
474
0
                ss->ssl3.hs.ws == wait_client_hello) {
475
0
                ssl2gs_ptr = &ssl2gs;
476
0
            }
477
0
478
0
            /* bring in the next sslv3 record. */
479
0
            if (ss->recvdCloseNotify) {
480
0
                /* RFC 5246 Section 7.2.1:
481
0
                 *   Any data received after a closure alert is ignored.
482
0
                 */
483
0
                return 0;
484
0
            }
485
0
486
0
            if (!IS_DTLS(ss)) {
487
0
                /* Passing a non-NULL ssl2gs here enables detection of
488
0
                 * SSLv2-compatible ClientHello messages. */
489
0
                rv = ssl3_GatherData(ss, &ss->gs, flags, ssl2gs_ptr);
490
0
            } else {
491
0
                rv = dtls_GatherData(ss, &ss->gs, flags);
492
0
493
0
                /* If we got a would block error, that means that no data was
494
0
                 * available, so we check the timer to see if it's time to
495
0
                 * retransmit */
496
0
                if (rv == SECFailure &&
497
0
                    (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
498
0
                    dtls_CheckTimer(ss);
499
0
                    /* Restore the error in case something succeeded */
500
0
                    PORT_SetError(PR_WOULD_BLOCK_ERROR);
501
0
                }
502
0
            }
503
0
504
0
            if (rv <= 0) {
505
0
                return rv;
506
0
            }
507
0
508
0
            if (ssl2gs.isV2) {
509
0
                rv = ssl3_HandleV2ClientHello(ss, ss->gs.inbuf.buf,
510
0
                                              ss->gs.inbuf.len,
511
0
                                              ssl2gs.padding);
512
0
                if (rv < 0) {
513
0
                    return rv;
514
0
                }
515
0
            } else {
516
0
                /* decipher it, and handle it if it's a handshake.
517
0
                 * If it's application data, ss->gs.buf will not be empty upon return.
518
0
                 * If it's a change cipher spec, alert, or handshake message,
519
0
                 * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
520
0
                 *
521
0
                 * cText only needs to be valid for this next function call, so
522
0
                 * it can borrow gs.hdr.
523
0
                 */
524
0
                cText.hdr = ss->gs.hdr;
525
0
                cText.hdrLen = ss->gs.hdrLen;
526
0
                cText.buf = &ss->gs.inbuf;
527
0
                rv = ssl3_HandleRecord(ss, &cText);
528
0
            }
529
0
        }
530
0
        if (rv < 0) {
531
0
            return ss->recvdCloseNotify ? 0 : rv;
532
0
        }
533
0
        if (ss->gs.buf.len > 0) {
534
0
            /* We have application data to return to the application. This
535
0
             * prioritizes returning application data to the application over
536
0
             * completing any renegotiation handshake we may be doing.
537
0
             */
538
0
            PORT_Assert(ss->firstHsDone);
539
0
            break;
540
0
        }
541
0
542
0
        PORT_Assert(keepGoing);
543
0
        ssl_GetSSL3HandshakeLock(ss);
544
0
        if (ss->ssl3.hs.ws == idle_handshake) {
545
0
            /* We are done with the current handshake so stop trying to
546
0
             * handshake. Note that it would be safe to test ss->firstHsDone
547
0
             * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
548
0
             * we prioritize completing a renegotiation handshake over sending
549
0
             * application data.
550
0
             */
551
0
            PORT_Assert(ss->firstHsDone);
552
0
            PORT_Assert(!ss->ssl3.hs.canFalseStart);
553
0
            keepGoing = PR_FALSE;
554
0
        } else if (ss->ssl3.hs.canFalseStart) {
555
0
            /* Prioritize sending application data over trying to complete
556
0
             * the handshake if we're false starting.
557
0
             *
558
0
             * If we were to do this check at the beginning of the loop instead
559
0
             * of here, then this function would become be a no-op after
560
0
             * receiving the ServerHelloDone in the false start case, and we
561
0
             * would never complete the handshake.
562
0
             */
563
0
            PORT_Assert(!ss->firstHsDone);
564
0
565
0
            if (ssl3_WaitingForServerSecondRound(ss)) {
566
0
                keepGoing = PR_FALSE;
567
0
            } else {
568
0
                ss->ssl3.hs.canFalseStart = PR_FALSE;
569
0
            }
570
0
        } else if (processingEarlyData &&
571
0
                   ss->ssl3.hs.zeroRttState == ssl_0rtt_done &&
572
0
                   !PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) {
573
0
            /* If we were processing early data and we are no longer, then force
574
0
             * the handshake to block.  This ensures that early data is
575
0
             * delivered to the application before the handshake completes. */
576
0
            ssl_ReleaseSSL3HandshakeLock(ss);
577
0
            PORT_SetError(PR_WOULD_BLOCK_ERROR);
578
0
            return SECWouldBlock;
579
0
        }
580
0
        ssl_ReleaseSSL3HandshakeLock(ss);
581
0
    } while (keepGoing);
582
0
583
0
    /* Service the DTLS timer so that the post-handshake timers
584
0
     * fire. */
585
0
    if (IS_DTLS(ss) && (ss->ssl3.hs.ws == idle_handshake)) {
586
0
        dtls_CheckTimer(ss);
587
0
    }
588
0
    ss->gs.readOffset = 0;
589
0
    ss->gs.writeOffset = ss->gs.buf.len;
590
0
    return 1;
591
0
}
592
593
/* Repeatedly gather in a record and when complete, Handle that record.
594
 * Repeat this until some application data is received.
595
 *
596
 * Returns  1 when application data is available.
597
 * Returns  0 if ssl3_GatherData hits EOF.
598
 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
599
 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
600
 *
601
 * Called from DoRecv in sslsecur.c
602
 * Caller must hold the recv buf lock.
603
 */
604
int
605
ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
606
0
{
607
0
    int rv;
608
0
609
0
    /* ssl3_GatherCompleteHandshake requires both of these locks. */
610
0
    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
611
0
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
612
0
613
0
    do {
614
0
        rv = ssl3_GatherCompleteHandshake(ss, flags);
615
0
    } while (rv > 0 && ss->gs.buf.len == 0);
616
0
617
0
    return rv;
618
0
}