Home | History | Annotate | Download | only in ssl
      1 /*
      2  * Gather (Read) entire SSL3 records from socket into buffer.
      3  *
      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/. */
      7 
      8 #include "cert.h"
      9 #include "ssl.h"
     10 #include "sslimpl.h"
     11 #include "ssl3prot.h"
     12 
     13 /*
     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.
     17  *
     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)
     22  *
     23  * Caller must hold the recv buf lock.
     24  *
     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.
     28  *
     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.
     33  */
     34 static int
     35 ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
     36 {
     37     unsigned char *bp;
     38     unsigned char *lbp;
     39     int            nb;
     40     int            err;
     41     int            rv		= 1;
     42 
     43     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
     44     if (gs->state == GS_INIT) {
     45 	gs->state       = GS_HEADER;
     46 	gs->remainder   = 5;
     47 	gs->offset      = 0;
     48 	gs->writeOffset = 0;
     49 	gs->readOffset  = 0;
     50 	gs->inbuf.len   = 0;
     51     }
     52 
     53     lbp = gs->inbuf.buf;
     54     for(;;) {
     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);
     59 
     60 	if (nb > 0) {
     61 	    PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
     62 	} else if (nb == 0) {
     63 	    /* EOF */
     64 	    SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
     65 	    rv = 0;
     66 	    break;
     67 	} else /* if (nb < 0) */ {
     68 	    SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
     69 		     PR_GetError()));
     70 	    rv = SECFailure;
     71 	    break;
     72 	}
     73 
     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 */
     78 	    rv = SECFailure;
     79 	    break;
     80 	}
     81 
     82 	gs->offset    += nb;
     83 	gs->remainder -= nb;
     84 	if (gs->state == GS_DATA)
     85 	    gs->inbuf.len += nb;
     86 
     87 	/* if there's more to go, read some more. */
     88 	if (gs->remainder > 0) {
     89 	    continue;
     90 	}
     91 
     92 	/* have received entire record header, or entire record. */
     93 	switch (gs->state) {
     94 	case GS_HEADER:
     95 	    /*
     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.
     99 	    */
    100 	    gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
    101 
    102 	    /* This is the max fragment length for an encrypted fragment
    103 	    ** plus the size of the record header.
    104 	    */
    105 	    if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
    106 		SSL3_SendAlert(ss, alert_fatal, unexpected_message);
    107 		gs->state = GS_INIT;
    108 		PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
    109 		return SECFailure;
    110 	    }
    111 
    112 	    gs->state     = GS_DATA;
    113 	    gs->offset    = 0;
    114 	    gs->inbuf.len = 0;
    115 
    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. */
    119 		    return err;
    120 		}
    121 		lbp = gs->inbuf.buf;
    122 	    }
    123 	    break;	/* End this case.  Continue around the loop. */
    124 
    125 
    126 	case GS_DATA:
    127 	    /*
    128 	    ** SSL3 record has been completely received.
    129 	    */
    130 	    gs->state = GS_INIT;
    131 	    return 1;
    132 	}
    133     }
    134 
    135     return rv;
    136 }
    137 
    138 /*
    139  * Read in an entire DTLS record.
    140  *
    141  * Blocks here for blocking sockets, otherwise returns -1 with
    142  * 	PR_WOULD_BLOCK_ERROR when socket would block.
    143  *
    144  * This is simpler than SSL because we are reading on a datagram socket
    145  * and datagrams must contain >=1 complete records.
    146  *
    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)
    151  *
    152  * Caller must hold the recv buf lock.
    153  *
    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.
    158  */
    159 static int
    160 dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
    161 {
    162     int            nb;
    163     int            err;
    164     int            rv		= 1;
    165 
    166     SSL_TRC(30, ("dtls_GatherData"));
    167 
    168     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    169 
    170     gs->state = GS_HEADER;
    171     gs->offset = 0;
    172 
    173     if (gs->dtlsPacketOffset == gs->dtlsPacket.len) {  /* No data left */
    174         gs->dtlsPacketOffset = 0;
    175         gs->dtlsPacket.len = 0;
    176 
    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).
    182 	*/
    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. */
    187                 return err;
    188             }
    189         }
    190 
    191         /* recv() needs to read a full datagram at a time */
    192         nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
    193 
    194         if (nb > 0) {
    195             PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
    196         } else if (nb == 0) {
    197             /* EOF */
    198             SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
    199             rv = 0;
    200             return rv;
    201         } else /* if (nb < 0) */ {
    202             SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
    203                      PR_GetError()));
    204             rv = SECFailure;
    205             return rv;
    206         }
    207 
    208         gs->dtlsPacket.len = nb;
    209     }
    210 
    211     /* At this point we should have >=1 complete records lined up in
    212      * dtlsPacket. Read off the header.
    213      */
    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;
    220         rv = SECFailure;
    221         return rv;
    222     }
    223     memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13);
    224     gs->dtlsPacketOffset += 13;
    225 
    226     /* Have received SSL3 record header in gs->hdr. */
    227     gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
    228 
    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;
    235         rv = SECFailure;
    236         return rv;
    237     }
    238 
    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. */
    243 	    return err;
    244 	}
    245     }
    246 
    247     memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
    248 	   gs->remainder);
    249     gs->inbuf.len = gs->remainder;
    250     gs->offset = gs->remainder;
    251     gs->dtlsPacketOffset += gs->remainder;
    252     gs->state = GS_INIT;
    253 
    254     return 1;
    255 }
    256 
    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.
    260  *
    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.
    266  *
    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).
    270  *
    271  * Caller must hold the recv buf lock.
    272  */
    273 int
    274 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
    275 {
    276     SSL3Ciphertext cText;
    277     int            rv;
    278     PRBool         keepGoing = PR_TRUE;
    279 
    280     SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
    281 
    282     /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
    283      * which requires the 1stHandshakeLock, which must be acquired before the
    284      * RecvBufLock.
    285      */
    286     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    287     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    288 
    289     do {
    290 	PRBool handleRecordNow = PR_FALSE;
    291 
    292 	ssl_GetSSL3HandshakeLock(ss);
    293 
    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.
    297 	 */
    298 	if (ss->ssl3.hs.restartTarget) {
    299 	    ssl_ReleaseSSL3HandshakeLock(ss);
    300 	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
    301 	    return (int) SECFailure;
    302 	}
    303 
    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
    308 	 */
    309 	if (ss->ssl3.hs.msgState.buf) {
    310 	    if (ss->ssl3.hs.msgState.len == 0) {
    311 		ss->ssl3.hs.msgState.buf = NULL;
    312 	    } else {
    313 		handleRecordNow = PR_TRUE;
    314 	    }
    315 	}
    316 
    317 	ssl_ReleaseSSL3HandshakeLock(ss);
    318 
    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
    323 	     * handshake record.
    324 	     */
    325 	    rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
    326 	} else {
    327 	    /* bring in the next sslv3 record. */
    328 	    if (!IS_DTLS(ss)) {
    329 		rv = ssl3_GatherData(ss, &ss->gs, flags);
    330 	    } else {
    331 		rv = dtls_GatherData(ss, &ss->gs, flags);
    332 
    333 		/* If we got a would block error, that means that no data was
    334 		 * available, so we check the timer to see if it's time to
    335 		 * retransmit */
    336 		if (rv == SECFailure &&
    337 		    (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
    338 		    ssl_GetSSL3HandshakeLock(ss);
    339 		    dtls_CheckTimer(ss);
    340 		    ssl_ReleaseSSL3HandshakeLock(ss);
    341 		    /* Restore the error in case something succeeded */
    342 		    PORT_SetError(PR_WOULD_BLOCK_ERROR);
    343 		}
    344 	    }
    345 
    346 	    if (rv <= 0) {
    347 		return rv;
    348 	    }
    349 
    350 	    /* decipher it, and handle it if it's a handshake.
    351 	     * If it's application data, ss->gs.buf will not be empty upon return.
    352 	     * If it's a change cipher spec, alert, or handshake message,
    353 	     * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
    354 	     */
    355 	    cText.type    = (SSL3ContentType)ss->gs.hdr[0];
    356 	    cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
    357 
    358 	    if (IS_DTLS(ss)) {
    359 		int i;
    360 
    361 		cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
    362 		/* DTLS sequence number */
    363 		cText.seq_num.high = 0; cText.seq_num.low = 0;
    364 		for (i = 0; i < 4; i++) {
    365 		    cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
    366 		    cText.seq_num.high |= ss->gs.hdr[3 + i];
    367 		    cText.seq_num.low |= ss->gs.hdr[7 + i];
    368 		}
    369 	    }
    370 
    371 	    cText.buf     = &ss->gs.inbuf;
    372 	    rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
    373 
    374 	    if (rv == (int) SECSuccess && ss->gs.buf.len > 0) {
    375 		/* We have application data to return to the application. This
    376 		 * prioritizes returning application data to the application over
    377 		 * completing any renegotiation handshake we may be doing.
    378 		 */
    379 		PORT_Assert(ss->firstHsDone);
    380 		PORT_Assert(cText.type == content_application_data);
    381 		break;
    382 	    }
    383 	}
    384 	if (rv < 0) {
    385 	    return ss->recvdCloseNotify ? 0 : rv;
    386 	}
    387 
    388 	PORT_Assert(keepGoing);
    389 	ssl_GetSSL3HandshakeLock(ss);
    390 	if (ss->ssl3.hs.ws == idle_handshake) {
    391 	    /* We are done with the current handshake so stop trying to
    392 	     * handshake. Note that it would be safe to test ss->firstHsDone
    393 	     * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
    394 	     * we prioritize completing a renegotiation handshake over sending
    395 	     * application data.
    396 	     */
    397 	    PORT_Assert(ss->firstHsDone);
    398 	    PORT_Assert(!ss->ssl3.hs.canFalseStart);
    399 	    keepGoing = PR_FALSE;
    400 	} else if (ss->ssl3.hs.canFalseStart) {
    401 	    /* Prioritize sending application data over trying to complete
    402 	     * the handshake if we're false starting.
    403 	     *
    404 	     * If we were to do this check at the beginning of the loop instead
    405 	     * of here, then this function would become be a no-op after
    406 	     * receiving the ServerHelloDone in the false start case, and we
    407 	     * would never complete the handshake.
    408 	     */
    409 	    PORT_Assert(!ss->firstHsDone);
    410 
    411 	    if (ssl3_WaitingForStartOfServerSecondRound(ss)) {
    412 		keepGoing = PR_FALSE;
    413 	    } else {
    414 		ss->ssl3.hs.canFalseStart = PR_FALSE;
    415 	    }
    416 	}
    417 	ssl_ReleaseSSL3HandshakeLock(ss);
    418     } while (keepGoing);
    419 
    420     ss->gs.readOffset = 0;
    421     ss->gs.writeOffset = ss->gs.buf.len;
    422     return 1;
    423 }
    424 
    425 /* Repeatedly gather in a record and when complete, Handle that record.
    426  * Repeat this until some application data is received.
    427  *
    428  * Returns  1 when application data is available.
    429  * Returns  0 if ssl3_GatherData hits EOF.
    430  * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
    431  * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
    432  *
    433  * Called from DoRecv in sslsecur.c
    434  * Caller must hold the recv buf lock.
    435  */
    436 int
    437 ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
    438 {
    439     int            rv;
    440 
    441     /* ssl3_GatherCompleteHandshake requires both of these locks. */
    442     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    443     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    444 
    445     do {
    446 	rv = ssl3_GatherCompleteHandshake(ss, flags);
    447     } while (rv > 0 && ss->gs.buf.len == 0);
    448 
    449     return rv;
    450 }
    451