1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ssl/ssl3gthr.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,455 @@ 1.4 +/* 1.5 + * Gather (Read) entire SSL3 records from socket into buffer. 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "cert.h" 1.12 +#include "ssl.h" 1.13 +#include "sslimpl.h" 1.14 +#include "ssl3prot.h" 1.15 + 1.16 +/* 1.17 + * Attempt to read in an entire SSL3 record. 1.18 + * Blocks here for blocking sockets, otherwise returns -1 with 1.19 + * PR_WOULD_BLOCK_ERROR when socket would block. 1.20 + * 1.21 + * returns 1 if received a complete SSL3 record. 1.22 + * returns 0 if recv returns EOF 1.23 + * returns -1 if recv returns < 0 1.24 + * (The error value may have already been set to PR_WOULD_BLOCK_ERROR) 1.25 + * 1.26 + * Caller must hold the recv buf lock. 1.27 + * 1.28 + * The Gather state machine has 3 states: GS_INIT, GS_HEADER, GS_DATA. 1.29 + * GS_HEADER: waiting for the 5-byte SSL3 record header to come in. 1.30 + * GS_DATA: waiting for the body of the SSL3 record to come in. 1.31 + * 1.32 + * This loop returns when either 1.33 + * (a) an error or EOF occurs, 1.34 + * (b) PR_WOULD_BLOCK_ERROR, 1.35 + * (c) data (entire SSL3 record) has been received. 1.36 + */ 1.37 +static int 1.38 +ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags) 1.39 +{ 1.40 + unsigned char *bp; 1.41 + unsigned char *lbp; 1.42 + int nb; 1.43 + int err; 1.44 + int rv = 1; 1.45 + 1.46 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.47 + if (gs->state == GS_INIT) { 1.48 + gs->state = GS_HEADER; 1.49 + gs->remainder = 5; 1.50 + gs->offset = 0; 1.51 + gs->writeOffset = 0; 1.52 + gs->readOffset = 0; 1.53 + gs->inbuf.len = 0; 1.54 + } 1.55 + 1.56 + lbp = gs->inbuf.buf; 1.57 + for(;;) { 1.58 + SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)", 1.59 + SSL_GETPID(), ss->fd, gs->state, gs->remainder)); 1.60 + bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset; 1.61 + nb = ssl_DefRecv(ss, bp, gs->remainder, flags); 1.62 + 1.63 + if (nb > 0) { 1.64 + PRINT_BUF(60, (ss, "raw gather data:", bp, nb)); 1.65 + } else if (nb == 0) { 1.66 + /* EOF */ 1.67 + SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd)); 1.68 + rv = 0; 1.69 + break; 1.70 + } else /* if (nb < 0) */ { 1.71 + SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd, 1.72 + PR_GetError())); 1.73 + rv = SECFailure; 1.74 + break; 1.75 + } 1.76 + 1.77 + PORT_Assert( nb <= gs->remainder ); 1.78 + if (nb > gs->remainder) { 1.79 + /* ssl_DefRecv is misbehaving! this error is fatal to SSL. */ 1.80 + gs->state = GS_INIT; /* so we don't crash next time */ 1.81 + rv = SECFailure; 1.82 + break; 1.83 + } 1.84 + 1.85 + gs->offset += nb; 1.86 + gs->remainder -= nb; 1.87 + if (gs->state == GS_DATA) 1.88 + gs->inbuf.len += nb; 1.89 + 1.90 + /* if there's more to go, read some more. */ 1.91 + if (gs->remainder > 0) { 1.92 + continue; 1.93 + } 1.94 + 1.95 + /* have received entire record header, or entire record. */ 1.96 + switch (gs->state) { 1.97 + case GS_HEADER: 1.98 + /* 1.99 + ** Have received SSL3 record header in gs->hdr. 1.100 + ** Now extract the length of the following encrypted data, 1.101 + ** and then read in the rest of the SSL3 record into gs->inbuf. 1.102 + */ 1.103 + gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4]; 1.104 + 1.105 + /* This is the max fragment length for an encrypted fragment 1.106 + ** plus the size of the record header. 1.107 + */ 1.108 + if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) { 1.109 + SSL3_SendAlert(ss, alert_fatal, unexpected_message); 1.110 + gs->state = GS_INIT; 1.111 + PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); 1.112 + return SECFailure; 1.113 + } 1.114 + 1.115 + gs->state = GS_DATA; 1.116 + gs->offset = 0; 1.117 + gs->inbuf.len = 0; 1.118 + 1.119 + if (gs->remainder > gs->inbuf.space) { 1.120 + err = sslBuffer_Grow(&gs->inbuf, gs->remainder); 1.121 + if (err) { /* realloc has set error code to no mem. */ 1.122 + return err; 1.123 + } 1.124 + lbp = gs->inbuf.buf; 1.125 + } 1.126 + break; /* End this case. Continue around the loop. */ 1.127 + 1.128 + 1.129 + case GS_DATA: 1.130 + /* 1.131 + ** SSL3 record has been completely received. 1.132 + */ 1.133 + gs->state = GS_INIT; 1.134 + return 1; 1.135 + } 1.136 + } 1.137 + 1.138 + return rv; 1.139 +} 1.140 + 1.141 +/* 1.142 + * Read in an entire DTLS record. 1.143 + * 1.144 + * Blocks here for blocking sockets, otherwise returns -1 with 1.145 + * PR_WOULD_BLOCK_ERROR when socket would block. 1.146 + * 1.147 + * This is simpler than SSL because we are reading on a datagram socket 1.148 + * and datagrams must contain >=1 complete records. 1.149 + * 1.150 + * returns 1 if received a complete DTLS record. 1.151 + * returns 0 if recv returns EOF 1.152 + * returns -1 if recv returns < 0 1.153 + * (The error value may have already been set to PR_WOULD_BLOCK_ERROR) 1.154 + * 1.155 + * Caller must hold the recv buf lock. 1.156 + * 1.157 + * This loop returns when either 1.158 + * (a) an error or EOF occurs, 1.159 + * (b) PR_WOULD_BLOCK_ERROR, 1.160 + * (c) data (entire DTLS record) has been received. 1.161 + */ 1.162 +static int 1.163 +dtls_GatherData(sslSocket *ss, sslGather *gs, int flags) 1.164 +{ 1.165 + int nb; 1.166 + int err; 1.167 + int rv = 1; 1.168 + 1.169 + SSL_TRC(30, ("dtls_GatherData")); 1.170 + 1.171 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.172 + 1.173 + gs->state = GS_HEADER; 1.174 + gs->offset = 0; 1.175 + 1.176 + if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */ 1.177 + gs->dtlsPacketOffset = 0; 1.178 + gs->dtlsPacket.len = 0; 1.179 + 1.180 + /* Resize to the maximum possible size so we can fit a full datagram */ 1.181 + /* This is the max fragment length for an encrypted fragment 1.182 + ** plus the size of the record header. 1.183 + ** This magic constant is copied from ssl3_GatherData, with 5 changed 1.184 + ** to 13 (the size of the record header). 1.185 + */ 1.186 + if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) { 1.187 + err = sslBuffer_Grow(&gs->dtlsPacket, 1.188 + MAX_FRAGMENT_LENGTH + 2048 + 13); 1.189 + if (err) { /* realloc has set error code to no mem. */ 1.190 + return err; 1.191 + } 1.192 + } 1.193 + 1.194 + /* recv() needs to read a full datagram at a time */ 1.195 + nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags); 1.196 + 1.197 + if (nb > 0) { 1.198 + PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb)); 1.199 + } else if (nb == 0) { 1.200 + /* EOF */ 1.201 + SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd)); 1.202 + rv = 0; 1.203 + return rv; 1.204 + } else /* if (nb < 0) */ { 1.205 + SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd, 1.206 + PR_GetError())); 1.207 + rv = SECFailure; 1.208 + return rv; 1.209 + } 1.210 + 1.211 + gs->dtlsPacket.len = nb; 1.212 + } 1.213 + 1.214 + /* At this point we should have >=1 complete records lined up in 1.215 + * dtlsPacket. Read off the header. 1.216 + */ 1.217 + if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) { 1.218 + SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet " 1.219 + "too short to contain header", SSL_GETPID(), ss->fd)); 1.220 + PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 1.221 + gs->dtlsPacketOffset = 0; 1.222 + gs->dtlsPacket.len = 0; 1.223 + rv = SECFailure; 1.224 + return rv; 1.225 + } 1.226 + memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13); 1.227 + gs->dtlsPacketOffset += 13; 1.228 + 1.229 + /* Have received SSL3 record header in gs->hdr. */ 1.230 + gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12]; 1.231 + 1.232 + if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) { 1.233 + SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short " 1.234 + "to contain rest of body", SSL_GETPID(), ss->fd)); 1.235 + PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 1.236 + gs->dtlsPacketOffset = 0; 1.237 + gs->dtlsPacket.len = 0; 1.238 + rv = SECFailure; 1.239 + return rv; 1.240 + } 1.241 + 1.242 + /* OK, we have at least one complete packet, copy into inbuf */ 1.243 + if (gs->remainder > gs->inbuf.space) { 1.244 + err = sslBuffer_Grow(&gs->inbuf, gs->remainder); 1.245 + if (err) { /* realloc has set error code to no mem. */ 1.246 + return err; 1.247 + } 1.248 + } 1.249 + 1.250 + memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 1.251 + gs->remainder); 1.252 + gs->inbuf.len = gs->remainder; 1.253 + gs->offset = gs->remainder; 1.254 + gs->dtlsPacketOffset += gs->remainder; 1.255 + gs->state = GS_INIT; 1.256 + 1.257 + return 1; 1.258 +} 1.259 + 1.260 +/* Gather in a record and when complete, Handle that record. 1.261 + * Repeat this until the handshake is complete, 1.262 + * or until application data is available. 1.263 + * 1.264 + * Returns 1 when the handshake is completed without error, or 1.265 + * application data is available. 1.266 + * Returns 0 if ssl3_GatherData hits EOF. 1.267 + * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. 1.268 + * Returns -2 on SECWouldBlock return from ssl3_HandleRecord. 1.269 + * 1.270 + * Called from ssl_GatherRecord1stHandshake in sslcon.c, 1.271 + * and from SSL_ForceHandshake in sslsecur.c 1.272 + * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c). 1.273 + * 1.274 + * Caller must hold the recv buf lock. 1.275 + */ 1.276 +int 1.277 +ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) 1.278 +{ 1.279 + SSL3Ciphertext cText; 1.280 + int rv; 1.281 + PRBool keepGoing = PR_TRUE; 1.282 + 1.283 + SSL_TRC(30, ("ssl3_GatherCompleteHandshake")); 1.284 + 1.285 + /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake, 1.286 + * which requires the 1stHandshakeLock, which must be acquired before the 1.287 + * RecvBufLock. 1.288 + */ 1.289 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.290 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.291 + 1.292 + do { 1.293 + PRBool handleRecordNow = PR_FALSE; 1.294 + 1.295 + ssl_GetSSL3HandshakeLock(ss); 1.296 + 1.297 + /* Without this, we may end up wrongly reporting 1.298 + * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the 1.299 + * peer while we are waiting to be restarted. 1.300 + */ 1.301 + if (ss->ssl3.hs.restartTarget) { 1.302 + ssl_ReleaseSSL3HandshakeLock(ss); 1.303 + PORT_SetError(PR_WOULD_BLOCK_ERROR); 1.304 + return (int) SECFailure; 1.305 + } 1.306 + 1.307 + /* Treat an empty msgState like a NULL msgState. (Most of the time 1.308 + * when ssl3_HandleHandshake returns SECWouldBlock, it leaves 1.309 + * behind a non-NULL but zero-length msgState). 1.310 + * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record 1.311 + */ 1.312 + if (ss->ssl3.hs.msgState.buf) { 1.313 + if (ss->ssl3.hs.msgState.len == 0) { 1.314 + ss->ssl3.hs.msgState.buf = NULL; 1.315 + } else { 1.316 + handleRecordNow = PR_TRUE; 1.317 + } 1.318 + } 1.319 + 1.320 + ssl_ReleaseSSL3HandshakeLock(ss); 1.321 + 1.322 + if (handleRecordNow) { 1.323 + /* ssl3_HandleHandshake previously returned SECWouldBlock and the 1.324 + * as-yet-unprocessed plaintext of that previous handshake record. 1.325 + * We need to process it now before we overwrite it with the next 1.326 + * handshake record. 1.327 + */ 1.328 + rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); 1.329 + } else { 1.330 + /* bring in the next sslv3 record. */ 1.331 + if (ss->recvdCloseNotify) { 1.332 + /* RFC 5246 Section 7.2.1: 1.333 + * Any data received after a closure alert is ignored. 1.334 + */ 1.335 + return 0; 1.336 + } 1.337 + if (!IS_DTLS(ss)) { 1.338 + rv = ssl3_GatherData(ss, &ss->gs, flags); 1.339 + } else { 1.340 + rv = dtls_GatherData(ss, &ss->gs, flags); 1.341 + 1.342 + /* If we got a would block error, that means that no data was 1.343 + * available, so we check the timer to see if it's time to 1.344 + * retransmit */ 1.345 + if (rv == SECFailure && 1.346 + (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) { 1.347 + ssl_GetSSL3HandshakeLock(ss); 1.348 + dtls_CheckTimer(ss); 1.349 + ssl_ReleaseSSL3HandshakeLock(ss); 1.350 + /* Restore the error in case something succeeded */ 1.351 + PORT_SetError(PR_WOULD_BLOCK_ERROR); 1.352 + } 1.353 + } 1.354 + 1.355 + if (rv <= 0) { 1.356 + return rv; 1.357 + } 1.358 + 1.359 + /* decipher it, and handle it if it's a handshake. 1.360 + * If it's application data, ss->gs.buf will not be empty upon return. 1.361 + * If it's a change cipher spec, alert, or handshake message, 1.362 + * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess. 1.363 + */ 1.364 + cText.type = (SSL3ContentType)ss->gs.hdr[0]; 1.365 + cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; 1.366 + 1.367 + if (IS_DTLS(ss)) { 1.368 + int i; 1.369 + 1.370 + cText.version = dtls_DTLSVersionToTLSVersion(cText.version); 1.371 + /* DTLS sequence number */ 1.372 + cText.seq_num.high = 0; cText.seq_num.low = 0; 1.373 + for (i = 0; i < 4; i++) { 1.374 + cText.seq_num.high <<= 8; cText.seq_num.low <<= 8; 1.375 + cText.seq_num.high |= ss->gs.hdr[3 + i]; 1.376 + cText.seq_num.low |= ss->gs.hdr[7 + i]; 1.377 + } 1.378 + } 1.379 + 1.380 + cText.buf = &ss->gs.inbuf; 1.381 + rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); 1.382 + } 1.383 + if (rv < 0) { 1.384 + return ss->recvdCloseNotify ? 0 : rv; 1.385 + } 1.386 + if (ss->gs.buf.len > 0) { 1.387 + /* We have application data to return to the application. This 1.388 + * prioritizes returning application data to the application over 1.389 + * completing any renegotiation handshake we may be doing. 1.390 + */ 1.391 + PORT_Assert(ss->firstHsDone); 1.392 + PORT_Assert(cText.type == content_application_data); 1.393 + break; 1.394 + } 1.395 + 1.396 + PORT_Assert(keepGoing); 1.397 + ssl_GetSSL3HandshakeLock(ss); 1.398 + if (ss->ssl3.hs.ws == idle_handshake) { 1.399 + /* We are done with the current handshake so stop trying to 1.400 + * handshake. Note that it would be safe to test ss->firstHsDone 1.401 + * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead, 1.402 + * we prioritize completing a renegotiation handshake over sending 1.403 + * application data. 1.404 + */ 1.405 + PORT_Assert(ss->firstHsDone); 1.406 + PORT_Assert(!ss->ssl3.hs.canFalseStart); 1.407 + keepGoing = PR_FALSE; 1.408 + } else if (ss->ssl3.hs.canFalseStart) { 1.409 + /* Prioritize sending application data over trying to complete 1.410 + * the handshake if we're false starting. 1.411 + * 1.412 + * If we were to do this check at the beginning of the loop instead 1.413 + * of here, then this function would become be a no-op after 1.414 + * receiving the ServerHelloDone in the false start case, and we 1.415 + * would never complete the handshake. 1.416 + */ 1.417 + PORT_Assert(!ss->firstHsDone); 1.418 + 1.419 + if (ssl3_WaitingForStartOfServerSecondRound(ss)) { 1.420 + keepGoing = PR_FALSE; 1.421 + } else { 1.422 + ss->ssl3.hs.canFalseStart = PR_FALSE; 1.423 + } 1.424 + } 1.425 + ssl_ReleaseSSL3HandshakeLock(ss); 1.426 + } while (keepGoing); 1.427 + 1.428 + ss->gs.readOffset = 0; 1.429 + ss->gs.writeOffset = ss->gs.buf.len; 1.430 + return 1; 1.431 +} 1.432 + 1.433 +/* Repeatedly gather in a record and when complete, Handle that record. 1.434 + * Repeat this until some application data is received. 1.435 + * 1.436 + * Returns 1 when application data is available. 1.437 + * Returns 0 if ssl3_GatherData hits EOF. 1.438 + * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. 1.439 + * Returns -2 on SECWouldBlock return from ssl3_HandleRecord. 1.440 + * 1.441 + * Called from DoRecv in sslsecur.c 1.442 + * Caller must hold the recv buf lock. 1.443 + */ 1.444 +int 1.445 +ssl3_GatherAppDataRecord(sslSocket *ss, int flags) 1.446 +{ 1.447 + int rv; 1.448 + 1.449 + /* ssl3_GatherCompleteHandshake requires both of these locks. */ 1.450 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.451 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.452 + 1.453 + do { 1.454 + rv = ssl3_GatherCompleteHandshake(ss, flags); 1.455 + } while (rv > 0 && ss->gs.buf.len == 0); 1.456 + 1.457 + return rv; 1.458 +}