if (pkt[0] == SSL3_RT_APPLICATION_DATA
&& (pkt[3]<<8|pkt[4]) >= 128)
{
- /* Note that even if packet is corrupted
+ /* Note that even if packet is corrupted
* and its length field is insane, we can
* only be led to wrong decision about
* whether memmove will occur or not.
/* ... now we can act as if 'extend' was set */
}
- /* extend reads should not span multiple packets for DTLS */
- if ( SSL_version(s) == DTLS1_VERSION &&
- extend)
+ /* 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 the buffer). */
+ if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
{
- if ( left > 0 && n > left)
+ if (left > 0 && n > left)
n = left;
}
rb->offset = len + align;
}
- max = rb->len - rb->offset;
- if (n > max) /* does not happen */
+ if (n > (int)(rb->len - rb->offset)) /* does not happen */
{
SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR);
return -1;
}
if (!s->read_ahead)
- max=n;
+ /* ignore max parameter */
+ max = n;
+ else
+ {
+ if (max < n)
+ max = n;
+ if (max > (int)(rb->len - rb->offset))
+ max = rb->len - rb->offset;
+ }
while (left < n)
{
return(i);
}
left+=i;
+ /* reads should *never* span multiple packets for DTLS because
+ * the underlying transport protocol is message oriented as opposed
+ * to byte oriented as in the TLS case. */
+ if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+ {
+ if (n > left)
+ n = left; /* makes the while condition false */
+ }
}
/* done reading, now the book-keeping */
return(s->s3->wpend_ret);
}
else if (i <= 0) {
- if (s->version == DTLS1_VERSION) {
+ if (s->version == DTLS1_VERSION ||
+ s->version == DTLS1_BAD_VER) {
/* For DTLS, just drop it. That's kind of the whole
point in using a datagram service */
wb->left = 0;
* now try again to obtain the (application) data we were asked for */
goto start;
}
-
+ /* If we are a server and get a client hello when renegotiation isn't
+ * allowed send back a no renegotiation alert and carry on.
+ * WARNING: experimental code, needs reviewing (steve)
+ */
+ if (s->server &&
+ SSL_is_init_finished(s) &&
+ !s->s3->send_connection_binding &&
+ (s->version > SSL3_VERSION) &&
+ (s->s3->handshake_fragment_len >= 4) &&
+ (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
+ (s->session != NULL) && (s->session->cipher != NULL) &&
+ !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+
+ {
+ /*s->s3->handshake_fragment_len = 0;*/
+ rr->length = 0;
+ ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ goto start;
+ }
if (s->s3->alert_fragment_len >= 2)
{
int alert_level = s->s3->alert_fragment[0];
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return(0);
}
+ /* This is a warning but we receive it if we requested
+ * renegotiation and the peer denied it. Terminate with
+ * a fatal alert because if application tried to
+ * renegotiatie it presumably had a good reason and
+ * expects it to succeed.
+ *
+ * In future we might have a renegotiation where we
+ * don't care if the peer refused it where we carry on.
+ */
+ else if (alert_descr == SSL_AD_NO_RENEGOTIATION)
+ {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
+ goto f_err;
+ }
}
else if (alert_level == 2) /* fatal */
{