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         canFalseStart = PR_FALSE;
    279 
    280     SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
    281 
    282     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    283     do {
    284 	PRBool handleRecordNow = PR_FALSE;
    285 
    286 	ssl_GetSSL3HandshakeLock(ss);
    287 
    288 	/* Without this, we may end up wrongly reporting
    289 	 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
    290 	 * peer while we are waiting to be restarted.
    291 	 */
    292 	if (ss->ssl3.hs.restartTarget) {
    293 	    ssl_ReleaseSSL3HandshakeLock(ss);
    294 	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
    295 	    return (int) SECFailure;
    296 	}
    297 
    298 	/* Treat an empty msgState like a NULL msgState. (Most of the time
    299 	 * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
    300 	 * behind a non-NULL but zero-length msgState).
    301 	 * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
    302 	 */
    303 	if (ss->ssl3.hs.msgState.buf) {
    304 	    if (ss->ssl3.hs.msgState.len == 0) {
    305 		ss->ssl3.hs.msgState.buf = NULL;
    306 	    } else {
    307 		handleRecordNow = PR_TRUE;
    308 	    }
    309 	}
    310 
    311 	ssl_ReleaseSSL3HandshakeLock(ss);
    312 
    313 	if (handleRecordNow) {
    314 	    /* ssl3_HandleHandshake previously returned SECWouldBlock and the
    315 	     * as-yet-unprocessed plaintext of that previous handshake record.
    316 	     * We need to process it now before we overwrite it with the next
    317 	     * handshake record.
    318 	     */
    319 	    rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
    320 	} else {
    321 	    /* bring in the next sslv3 record. */
    322 	    if (!IS_DTLS(ss)) {
    323 		rv = ssl3_GatherData(ss, &ss->gs, flags);
    324 	    } else {
    325 		rv = dtls_GatherData(ss, &ss->gs, flags);
    326 
    327 		/* If we got a would block error, that means that no data was
    328 		 * available, so we check the timer to see if it's time to
    329 		 * retransmit */
    330 		if (rv == SECFailure &&
    331 		    (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
    332 		    ssl_GetSSL3HandshakeLock(ss);
    333 		    dtls_CheckTimer(ss);
    334 		    ssl_ReleaseSSL3HandshakeLock(ss);
    335 		    /* Restore the error in case something succeeded */
    336 		    PORT_SetError(PR_WOULD_BLOCK_ERROR);
    337 		}
    338 	    }
    339 
    340 	    if (rv <= 0) {
    341 		return rv;
    342 	    }
    343 
    344 	    /* decipher it, and handle it if it's a handshake.
    345 	     * If it's application data, ss->gs.buf will not be empty upon return.
    346 	     * If it's a change cipher spec, alert, or handshake message,
    347 	     * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
    348 	     */
    349 	    cText.type    = (SSL3ContentType)ss->gs.hdr[0];
    350 	    cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
    351 
    352 	    if (IS_DTLS(ss)) {
    353 		int i;
    354 
    355 		cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
    356 		/* DTLS sequence number */
    357 		cText.seq_num.high = 0; cText.seq_num.low = 0;
    358 		for (i = 0; i < 4; i++) {
    359 		    cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
    360 		    cText.seq_num.high |= ss->gs.hdr[3 + i];
    361 		    cText.seq_num.low |= ss->gs.hdr[7 + i];
    362 		}
    363 	    }
    364 
    365 	    cText.buf     = &ss->gs.inbuf;
    366 	    rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
    367 	}
    368 	if (rv < 0) {
    369 	    return ss->recvdCloseNotify ? 0 : rv;
    370 	}
    371 
    372 	/* If we kicked off a false start in ssl3_HandleServerHelloDone, break
    373 	 * out of this loop early without finishing the handshake.
    374 	 */
    375 	if (ss->opt.enableFalseStart) {
    376 	    ssl_GetSSL3HandshakeLock(ss);
    377 	    canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
    378 			     ss->ssl3.hs.ws == wait_new_session_ticket) &&
    379 		            ssl3_CanFalseStart(ss);
    380 	    ssl_ReleaseSSL3HandshakeLock(ss);
    381 	}
    382     } while (ss->ssl3.hs.ws != idle_handshake &&
    383              !canFalseStart &&
    384              ss->gs.buf.len == 0);
    385 
    386     ss->gs.readOffset = 0;
    387     ss->gs.writeOffset = ss->gs.buf.len;
    388     return 1;
    389 }
    390 
    391 /* Repeatedly gather in a record and when complete, Handle that record.
    392  * Repeat this until some application data is received.
    393  *
    394  * Returns  1 when application data is available.
    395  * Returns  0 if ssl3_GatherData hits EOF.
    396  * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
    397  * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
    398  *
    399  * Called from DoRecv in sslsecur.c
    400  * Caller must hold the recv buf lock.
    401  */
    402 int
    403 ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
    404 {
    405     int            rv;
    406 
    407     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    408     do {
    409 	rv = ssl3_GatherCompleteHandshake(ss, flags);
    410     } while (rv > 0 && ss->gs.buf.len == 0);
    411 
    412     return rv;
    413 }
    414