1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ssl/sslgathr.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,425 @@ 1.4 +/* 1.5 + * Gather (Read) entire SSL2 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 +#include "cert.h" 1.11 +#include "ssl.h" 1.12 +#include "sslimpl.h" 1.13 +#include "sslproto.h" 1.14 + 1.15 +/* Forward static declarations */ 1.16 +static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss); 1.17 + 1.18 +/* 1.19 +** Gather a single record of data from the receiving stream. This code 1.20 +** first gathers the header (2 or 3 bytes long depending on the value of 1.21 +** the most significant bit in the first byte) then gathers up the data 1.22 +** for the record into gs->buf. This code handles non-blocking I/O 1.23 +** and is to be called multiple times until ss->sec.recordLen != 0. 1.24 +** This function decrypts the gathered record in place, in gs_buf. 1.25 + * 1.26 + * Caller must hold RecvBufLock. 1.27 + * 1.28 + * Returns +1 when it has gathered a complete SSLV2 record. 1.29 + * Returns 0 if it hits EOF. 1.30 + * Returns -1 (SECFailure) on any error 1.31 + * Returns -2 (SECWouldBlock) when it gathers an SSL v3 client hello header. 1.32 +** 1.33 +** The SSL2 Gather State machine has 4 states: 1.34 +** GS_INIT - Done reading in previous record. Haven't begun to read in 1.35 +** next record. When ssl2_GatherData is called with the machine 1.36 +** in this state, the machine will attempt to read the first 3 1.37 +** bytes of the SSL2 record header, and will advance the state 1.38 +** to GS_HEADER. 1.39 +** 1.40 +** GS_HEADER - The machine is in this state while waiting for the completion 1.41 +** of the first 3 bytes of the SSL2 record. When complete, the 1.42 +** machine will compute the remaining unread length of this record 1.43 +** and will initiate a read of that many bytes. The machine will 1.44 +** advance to one of two states, depending on whether the record 1.45 +** is encrypted (GS_MAC), or unencrypted (GS_DATA). 1.46 +** 1.47 +** GS_MAC - The machine is in this state while waiting for the remainder 1.48 +** of the SSL2 record to be read in. When the read is completed, 1.49 +** the machine checks the record for valid length, decrypts it, 1.50 +** and checks and discards the MAC, then advances to GS_INIT. 1.51 +** 1.52 +** GS_DATA - The machine is in this state while waiting for the remainder 1.53 +** of the unencrypted SSL2 record to be read in. Upon completion, 1.54 +** the machine advances to the GS_INIT state and returns the data. 1.55 +*/ 1.56 +int 1.57 +ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) 1.58 +{ 1.59 + unsigned char * bp; 1.60 + unsigned char * pBuf; 1.61 + int nb, err, rv; 1.62 + 1.63 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.64 + 1.65 + if (gs->state == GS_INIT) { 1.66 + /* Initialize gathering engine */ 1.67 + gs->state = GS_HEADER; 1.68 + gs->remainder = 3; 1.69 + gs->count = 3; 1.70 + gs->offset = 0; 1.71 + gs->recordLen = 0; 1.72 + gs->recordPadding = 0; 1.73 + gs->hdr[2] = 0; 1.74 + 1.75 + gs->writeOffset = 0; 1.76 + gs->readOffset = 0; 1.77 + } 1.78 + if (gs->encrypted) { 1.79 + PORT_Assert(ss->sec.hash != 0); 1.80 + } 1.81 + 1.82 + pBuf = gs->buf.buf; 1.83 + for (;;) { 1.84 + SSL_TRC(30, ("%d: SSL[%d]: gather state %d (need %d more)", 1.85 + SSL_GETPID(), ss->fd, gs->state, gs->remainder)); 1.86 + bp = ((gs->state != GS_HEADER) ? pBuf : gs->hdr) + gs->offset; 1.87 + nb = ssl_DefRecv(ss, bp, gs->remainder, flags); 1.88 + if (nb > 0) { 1.89 + PRINT_BUF(60, (ss, "raw gather data:", bp, nb)); 1.90 + } 1.91 + if (nb == 0) { 1.92 + /* EOF */ 1.93 + SSL_TRC(30, ("%d: SSL[%d]: EOF", SSL_GETPID(), ss->fd)); 1.94 + rv = 0; 1.95 + break; 1.96 + } 1.97 + if (nb < 0) { 1.98 + SSL_DBG(("%d: SSL[%d]: recv error %d", SSL_GETPID(), ss->fd, 1.99 + PR_GetError())); 1.100 + rv = SECFailure; 1.101 + break; 1.102 + } 1.103 + 1.104 + gs->offset += nb; 1.105 + gs->remainder -= nb; 1.106 + 1.107 + if (gs->remainder > 0) { 1.108 + continue; 1.109 + } 1.110 + 1.111 + /* Probably finished this piece */ 1.112 + switch (gs->state) { 1.113 + case GS_HEADER: 1.114 + if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && !ss->firstHsDone) { 1.115 + 1.116 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.117 + 1.118 + /* If this looks like an SSL3 handshake record, 1.119 + ** and we're expecting an SSL2 Hello message from our peer, 1.120 + ** handle it here. 1.121 + */ 1.122 + if (gs->hdr[0] == content_handshake) { 1.123 + if ((ss->nextHandshake == ssl2_HandleClientHelloMessage) || 1.124 + (ss->nextHandshake == ssl2_HandleServerHelloMessage)) { 1.125 + rv = ssl2_HandleV3HandshakeRecord(ss); 1.126 + if (rv == SECFailure) { 1.127 + return SECFailure; 1.128 + } 1.129 + } 1.130 + /* XXX_1 The call stack to here is: 1.131 + * ssl_Do1stHandshake -> ssl_GatherRecord1stHandshake -> 1.132 + * ssl2_GatherRecord -> here. 1.133 + * We want to return all the way out to ssl_Do1stHandshake, 1.134 + * and have it call ssl_GatherRecord1stHandshake again. 1.135 + * ssl_GatherRecord1stHandshake will call 1.136 + * ssl3_GatherCompleteHandshake when it is called again. 1.137 + * 1.138 + * Returning SECWouldBlock here causes 1.139 + * ssl_GatherRecord1stHandshake to return without clearing 1.140 + * ss->handshake, ensuring that ssl_Do1stHandshake will 1.141 + * call it again immediately. 1.142 + * 1.143 + * If we return 1 here, ssl_GatherRecord1stHandshake will 1.144 + * clear ss->handshake before returning, and thus will not 1.145 + * be called again by ssl_Do1stHandshake. 1.146 + */ 1.147 + return SECWouldBlock; 1.148 + } else if (gs->hdr[0] == content_alert) { 1.149 + if (ss->nextHandshake == ssl2_HandleServerHelloMessage) { 1.150 + /* XXX This is a hack. We're assuming that any failure 1.151 + * XXX on the client hello is a failure to match 1.152 + * XXX ciphers. 1.153 + */ 1.154 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 1.155 + return SECFailure; 1.156 + } 1.157 + } 1.158 + } 1.159 + 1.160 + /* we've got the first 3 bytes. The header may be two or three. */ 1.161 + if (gs->hdr[0] & 0x80) { 1.162 + /* This record has a 2-byte header, and no padding */ 1.163 + gs->count = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1]; 1.164 + gs->recordPadding = 0; 1.165 + } else { 1.166 + /* This record has a 3-byte header that is all read in now. */ 1.167 + gs->count = ((gs->hdr[0] & 0x3f) << 8) | gs->hdr[1]; 1.168 + /* is_escape = (gs->hdr[0] & 0x40) != 0; */ 1.169 + gs->recordPadding = gs->hdr[2]; 1.170 + } 1.171 + if (!gs->count) { 1.172 + PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); 1.173 + goto cleanup; 1.174 + } 1.175 + 1.176 + if (gs->count > gs->buf.space) { 1.177 + err = sslBuffer_Grow(&gs->buf, gs->count); 1.178 + if (err) { 1.179 + return err; 1.180 + } 1.181 + pBuf = gs->buf.buf; 1.182 + } 1.183 + 1.184 + 1.185 + if (gs->hdr[0] & 0x80) { 1.186 + /* we've already read in the first byte of the body. 1.187 + ** Put it into the buffer. 1.188 + */ 1.189 + pBuf[0] = gs->hdr[2]; 1.190 + gs->offset = 1; 1.191 + gs->remainder = gs->count - 1; 1.192 + } else { 1.193 + gs->offset = 0; 1.194 + gs->remainder = gs->count; 1.195 + } 1.196 + 1.197 + if (gs->encrypted) { 1.198 + gs->state = GS_MAC; 1.199 + gs->recordLen = gs->count - gs->recordPadding 1.200 + - ss->sec.hash->length; 1.201 + } else { 1.202 + gs->state = GS_DATA; 1.203 + gs->recordLen = gs->count; 1.204 + } 1.205 + 1.206 + break; 1.207 + 1.208 + 1.209 + case GS_MAC: 1.210 + /* Have read in entire rest of the ciphertext. 1.211 + ** Check for valid length. 1.212 + ** Decrypt it. 1.213 + ** Check the MAC. 1.214 + */ 1.215 + PORT_Assert(gs->encrypted); 1.216 + 1.217 + { 1.218 + unsigned int macLen; 1.219 + int nout; 1.220 + unsigned char mac[SSL_MAX_MAC_BYTES]; 1.221 + 1.222 + ssl_GetSpecReadLock(ss); /**********************************/ 1.223 + 1.224 + /* If this is a stream cipher, blockSize will be 1, 1.225 + * and this test will always be false. 1.226 + * If this is a block cipher, this will detect records 1.227 + * that are not a multiple of the blocksize in length. 1.228 + */ 1.229 + if (gs->count & (ss->sec.blockSize - 1)) { 1.230 + /* This is an error. Sender is misbehaving */ 1.231 + SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d", 1.232 + SSL_GETPID(), ss->fd, gs->count, 1.233 + ss->sec.blockSize)); 1.234 + PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING); 1.235 + rv = SECFailure; 1.236 + goto spec_locked_done; 1.237 + } 1.238 + PORT_Assert(gs->count == gs->offset); 1.239 + 1.240 + if (gs->offset == 0) { 1.241 + rv = 0; /* means EOF. */ 1.242 + goto spec_locked_done; 1.243 + } 1.244 + 1.245 + /* Decrypt the portion of data that we just received. 1.246 + ** Decrypt it in place. 1.247 + */ 1.248 + rv = (*ss->sec.dec)(ss->sec.readcx, pBuf, &nout, gs->offset, 1.249 + pBuf, gs->offset); 1.250 + if (rv != SECSuccess) { 1.251 + goto spec_locked_done; 1.252 + } 1.253 + 1.254 + 1.255 + /* Have read in all the MAC portion of record 1.256 + ** 1.257 + ** Prepare MAC by resetting it and feeding it the shared secret 1.258 + */ 1.259 + macLen = ss->sec.hash->length; 1.260 + if (gs->offset >= macLen) { 1.261 + PRUint32 sequenceNumber = ss->sec.rcvSequence++; 1.262 + unsigned char seq[4]; 1.263 + 1.264 + seq[0] = (unsigned char) (sequenceNumber >> 24); 1.265 + seq[1] = (unsigned char) (sequenceNumber >> 16); 1.266 + seq[2] = (unsigned char) (sequenceNumber >> 8); 1.267 + seq[3] = (unsigned char) (sequenceNumber); 1.268 + 1.269 + (*ss->sec.hash->begin)(ss->sec.hashcx); 1.270 + (*ss->sec.hash->update)(ss->sec.hashcx, ss->sec.rcvSecret.data, 1.271 + ss->sec.rcvSecret.len); 1.272 + (*ss->sec.hash->update)(ss->sec.hashcx, pBuf + macLen, 1.273 + gs->offset - macLen); 1.274 + (*ss->sec.hash->update)(ss->sec.hashcx, seq, 4); 1.275 + (*ss->sec.hash->end)(ss->sec.hashcx, mac, &macLen, macLen); 1.276 + 1.277 + PORT_Assert(macLen == ss->sec.hash->length); 1.278 + 1.279 + ssl_ReleaseSpecReadLock(ss); /******************************/ 1.280 + 1.281 + if (NSS_SecureMemcmp(mac, pBuf, macLen) != 0) { 1.282 + /* MAC's didn't match... */ 1.283 + SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d", 1.284 + SSL_GETPID(), ss->fd, ss->sec.rcvSequence)); 1.285 + PRINT_BUF(1, (ss, "computed mac:", mac, macLen)); 1.286 + PRINT_BUF(1, (ss, "received mac:", pBuf, macLen)); 1.287 + PORT_SetError(SSL_ERROR_BAD_MAC_READ); 1.288 + rv = SECFailure; 1.289 + goto cleanup; 1.290 + } 1.291 + } else { 1.292 + ssl_ReleaseSpecReadLock(ss); /******************************/ 1.293 + } 1.294 + 1.295 + if (gs->recordPadding + macLen <= gs->offset) { 1.296 + gs->recordOffset = macLen; 1.297 + gs->readOffset = macLen; 1.298 + gs->writeOffset = gs->offset - gs->recordPadding; 1.299 + rv = 1; 1.300 + } else { 1.301 + PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING); 1.302 +cleanup: 1.303 + /* nothing in the buffer any more. */ 1.304 + gs->recordOffset = 0; 1.305 + gs->readOffset = 0; 1.306 + gs->writeOffset = 0; 1.307 + rv = SECFailure; 1.308 + } 1.309 + 1.310 + gs->recordLen = gs->writeOffset - gs->readOffset; 1.311 + gs->recordPadding = 0; /* forget we did any padding. */ 1.312 + gs->state = GS_INIT; 1.313 + 1.314 + 1.315 + if (rv > 0) { 1.316 + PRINT_BUF(50, (ss, "recv clear record:", 1.317 + pBuf + gs->recordOffset, gs->recordLen)); 1.318 + } 1.319 + return rv; 1.320 + 1.321 +spec_locked_done: 1.322 + ssl_ReleaseSpecReadLock(ss); 1.323 + return rv; 1.324 + } 1.325 + 1.326 + case GS_DATA: 1.327 + /* Have read in all the DATA portion of record */ 1.328 + 1.329 + gs->recordOffset = 0; 1.330 + gs->readOffset = 0; 1.331 + gs->writeOffset = gs->offset; 1.332 + PORT_Assert(gs->recordLen == gs->writeOffset - gs->readOffset); 1.333 + gs->recordLen = gs->offset; 1.334 + gs->recordPadding = 0; 1.335 + gs->state = GS_INIT; 1.336 + 1.337 + ++ss->sec.rcvSequence; 1.338 + 1.339 + PRINT_BUF(50, (ss, "recv clear record:", 1.340 + pBuf + gs->recordOffset, gs->recordLen)); 1.341 + return 1; 1.342 + 1.343 + } /* end switch gs->state */ 1.344 + } /* end gather loop. */ 1.345 + return rv; 1.346 +} 1.347 + 1.348 +/* 1.349 +** Gather a single record of data from the receiving stream. This code 1.350 +** first gathers the header (2 or 3 bytes long depending on the value of 1.351 +** the most significant bit in the first byte) then gathers up the data 1.352 +** for the record into the readBuf. This code handles non-blocking I/O 1.353 +** and is to be called multiple times until ss->sec.recordLen != 0. 1.354 + * 1.355 + * Returns +1 when it has gathered a complete SSLV2 record. 1.356 + * Returns 0 if it hits EOF. 1.357 + * Returns -1 (SECFailure) on any error 1.358 + * Returns -2 (SECWouldBlock) 1.359 + * 1.360 + * Called by ssl_GatherRecord1stHandshake in sslcon.c, 1.361 + * and by DoRecv in sslsecur.c 1.362 + * Caller must hold RecvBufLock. 1.363 + */ 1.364 +int 1.365 +ssl2_GatherRecord(sslSocket *ss, int flags) 1.366 +{ 1.367 + return ssl2_GatherData(ss, &ss->gs, flags); 1.368 +} 1.369 + 1.370 +/* Caller should hold RecvBufLock. */ 1.371 +SECStatus 1.372 +ssl_InitGather(sslGather *gs) 1.373 +{ 1.374 + SECStatus status; 1.375 + 1.376 + gs->state = GS_INIT; 1.377 + gs->writeOffset = 0; 1.378 + gs->readOffset = 0; 1.379 + gs->dtlsPacketOffset = 0; 1.380 + gs->dtlsPacket.len = 0; 1.381 + status = sslBuffer_Grow(&gs->buf, 4096); 1.382 + return status; 1.383 +} 1.384 + 1.385 +/* Caller must hold RecvBufLock. */ 1.386 +void 1.387 +ssl_DestroyGather(sslGather *gs) 1.388 +{ 1.389 + if (gs) { /* the PORT_*Free functions check for NULL pointers. */ 1.390 + PORT_ZFree(gs->buf.buf, gs->buf.space); 1.391 + PORT_Free(gs->inbuf.buf); 1.392 + PORT_Free(gs->dtlsPacket.buf); 1.393 + } 1.394 +} 1.395 + 1.396 +/* Caller must hold RecvBufLock. */ 1.397 +static SECStatus 1.398 +ssl2_HandleV3HandshakeRecord(sslSocket *ss) 1.399 +{ 1.400 + SECStatus rv; 1.401 + 1.402 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.403 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.404 + 1.405 + /* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */ 1.406 + ss->gs.remainder = 2; 1.407 + ss->gs.count = 0; 1.408 + 1.409 + /* Clearing these handshake pointers ensures that 1.410 + * ssl_Do1stHandshake won't call ssl2_HandleMessage when we return. 1.411 + */ 1.412 + ss->nextHandshake = 0; 1.413 + ss->securityHandshake = 0; 1.414 + 1.415 + /* Setting ss->version to an SSL 3.x value will cause 1.416 + ** ssl_GatherRecord1stHandshake to invoke ssl3_GatherCompleteHandshake() 1.417 + ** the next time it is called. 1.418 + **/ 1.419 + rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, 1.420 + PR_TRUE); 1.421 + if (rv != SECSuccess) { 1.422 + return rv; 1.423 + } 1.424 + 1.425 + ss->sec.send = ssl3_SendApplicationData; 1.426 + 1.427 + return SECSuccess; 1.428 +}