}
}
+/*
+ * Return values are as per SSL_read(), i.e.
+ * >0 The number of read bytes
+ * 0 Failure (not retryable)
+ * <0 Failure (may be retryable)
+ */
int ssl3_read_n(SSL *s, int n, int max, int extend, int clearold)
{
/*
/* ... now we can act as if 'extend' was set */
}
+ len = s->rlayer.packet_length;
+ pkt = rb->buf + align;
+ /*
+ * Move any available bytes to front of buffer: 'len' bytes already
+ * pointed to by 'packet', 'left' extra ones at the end
+ */
+ if (s->rlayer.packet != pkt && clearold == 1) {
+ memmove(pkt, s->rlayer.packet, len + left);
+ s->rlayer.packet = pkt;
+ rb->offset = len + align;
+ }
+
/*
* For DTLS/UDP reads should not span multiple packets because the read
* operation returns the whole packet at once (as long as it fits into
/* else we need to read more data */
- len = s->rlayer.packet_length;
- pkt = rb->buf + align;
- /*
- * Move any available bytes to front of buffer: 'len' bytes already
- * pointed to by 'packet', 'left' extra ones at the end
- */
- if (s->rlayer.packet != pkt && clearold == 1) { /* len > 0 */
- memmove(pkt, s->rlayer.packet, len + left);
- s->rlayer.packet = pkt;
- rb->offset = len + align;
- }
-
if (n > (int)(rb->len - rb->offset)) { /* does not happen */
SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR);
return -1;
if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
if (len + left == 0)
ssl3_release_read_buffer(s);
- return (i);
+ return -1;
}
left += i;
/*
return -1;
}
-/* if s->s3->wbuf.left != 0, we need to call this */
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_read(), i.e.
+ * >0 The number of read bytes
+ * 0 Failure (not retryable)
+ * <0 Failure (may be retryable)
+ */
int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
unsigned int len)
{
*/
SSL3_BUFFER_set_left(&wb[currbuf], 0);
}
- return (i);
+ return -1;
}
SSL3_BUFFER_add_offset(&wb[currbuf], i);
SSL3_BUFFER_add_left(&wb[currbuf], -i);
} while (num_recs == 0);
rr = &rr[curr_rec];
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
+ && SSL3_RECORD_get_length(rr) != 0)
+ s->rlayer.alert_count = 0;
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
memcpy(buf, &(rr->data[rr->off]), n);
buf += n;
- if (!peek) {
+ if (peek) {
+ /* Mark any zero length record as consumed CVE-2016-6305 */
+ if (SSL3_RECORD_get_length(rr) == 0)
+ SSL3_RECORD_set_read(rr);
+ } else {
SSL3_RECORD_sub_length(rr, n);
SSL3_RECORD_add_off(rr, n);
if (SSL3_RECORD_get_length(rr) == 0) {
if (alert_level == SSL3_AL_WARNING) {
s->s3->warn_alert = alert_descr;
SSL3_RECORD_set_read(rr);
+
+ s->rlayer.alert_count++;
+ if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+ goto f_err;
+ }
+
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return (0);