summaryrefslogtreecommitdiffstats
path: root/crypto/openssl/ssl/s3_pkt.c
diff options
context:
space:
mode:
authorsimon <simon@FreeBSD.org>2010-03-13 19:22:41 +0000
committersimon <simon@FreeBSD.org>2010-03-13 19:22:41 +0000
commit0d816bbd980d8201a2ad23ccd05f7bde16565282 (patch)
tree909a7c21b7df72ae8c08b80b468a4dd75b3820be /crypto/openssl/ssl/s3_pkt.c
parent7fd3bd147ec574621124307eca10ead5353e34ba (diff)
parentcdb6eef1f013e22a10ab5f5829dcdc3b5e32d385 (diff)
downloadFreeBSD-src-0d816bbd980d8201a2ad23ccd05f7bde16565282.zip
FreeBSD-src-0d816bbd980d8201a2ad23ccd05f7bde16565282.tar.gz
Merge OpenSSL 0.9.8m into head.
This also "reverts" some FreeBSD local changes so we should now be back to using entirely stock OpenSSL. The local changes were simple $FreeBSD$ lines additions, which were required in the CVS days, and the patch for FreeBSD-SA-09:15.ssl which has been superseded with OpenSSL 0.9.8m's RFC5746 'TLS renegotiation extension' support. MFC after: 3 weeks
Diffstat (limited to 'crypto/openssl/ssl/s3_pkt.c')
-rw-r--r--crypto/openssl/ssl/s3_pkt.c64
1 files changed, 55 insertions, 9 deletions
diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c
index 1644f19..a2ba574 100644
--- a/crypto/openssl/ssl/s3_pkt.c
+++ b/crypto/openssl/ssl/s3_pkt.c
@@ -141,9 +141,10 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
/* ... 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)
{
if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
n = s->s3->rbuf.left;
@@ -209,6 +210,14 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
return(i);
}
newb+=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)
+ {
+ if (n > newb)
+ n = newb; /* makes the while condition false */
+ }
}
/* done reading, now the book-keeping */
@@ -983,7 +992,9 @@ start:
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
- if (0)
+ if (SSL_is_init_finished(s) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+ !s->s3->renegotiate)
{
ssl3_renegotiate(s);
if (ssl3_renegotiate_check(s))
@@ -1018,7 +1029,25 @@ start:
* 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];
@@ -1048,6 +1077,21 @@ start:
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 */
{
@@ -1114,7 +1158,8 @@ start:
/* Unexpected handshake message (Client Hello, or protocol violation) */
if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake)
{
- if (0)
+ if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
{
#if 0 /* worked only because C operator preferences are not as expected (and
* because this is not really needed for clients except for detecting
@@ -1265,13 +1310,13 @@ int ssl3_do_change_cipher_spec(SSL *s)
return(1);
}
-void ssl3_send_alert(SSL *s, int level, int desc)
+int ssl3_send_alert(SSL *s, int level, int desc)
{
/* Map tls/ssl alert value to correct one */
desc=s->method->ssl3_enc->alert_value(desc);
if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */
- if (desc < 0) return;
+ if (desc < 0) return -1;
/* If a fatal one, remove from cache */
if ((level == 2) && (s->session != NULL))
SSL_CTX_remove_session(s->ctx,s->session);
@@ -1280,9 +1325,10 @@ void ssl3_send_alert(SSL *s, int level, int desc)
s->s3->send_alert[0]=level;
s->s3->send_alert[1]=desc;
if (s->s3->wbuf.left == 0) /* data still being written out? */
- s->method->ssl_dispatch_alert(s);
+ return s->method->ssl_dispatch_alert(s);
/* else data is still being written out, we will get written
* some time in the future */
+ return -1;
}
int ssl3_dispatch_alert(SSL *s)
OpenPOWER on IntegriCloud