- if (dest_maxlen > 0)
- {
- n = dest_maxlen - *dest_len; /* available space in 'dest' */
- if (rr->length < n)
- n = rr->length; /* available bytes */
-
- /* now move 'n' bytes: */
- while (n-- > 0)
- {
- dest[(*dest_len)++] = rr->data[rr->off++];
- rr->length--;
- }
-
- if (*dest_len < dest_maxlen)
- goto start; /* fragment was too small */
- }
- }
-
- /* s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE;
- * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT.
- * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
-
- /* If we are a client, check for an incoming 'Hello Request': */
- if ((!s->server) &&
- (s->s3->handshake_fragment_len >= 4) &&
- (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
- (s->session != NULL) && (s->session->cipher != NULL))
- {
- s->s3->handshake_fragment_len = 0;
-
- if ((s->s3->handshake_fragment[1] != 0) ||
- (s->s3->handshake_fragment[2] != 0) ||
- (s->s3->handshake_fragment[3] != 0))
- {
- al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
- goto f_err;
- }
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
-
- 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))
- {
- i=s->handshake_func(s);
- if (i < 0) return(i);
- if (i == 0)
- {
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
- return(-1);
- }
-
- if (!(s->mode & SSL_MODE_AUTO_RETRY))
- {
- if (s->s3->rbuf.left == 0) /* no read-ahead left? */
- {
- BIO *bio;
- /* In the case where we try to read application data,
- * but we trigger an SSL handshake, we return -1 with
- * the retry option set. Otherwise renegotiation may
- * cause nasty problems in the blocking world */
- s->rwstate=SSL_READING;
- bio=SSL_get_rbio(s);
- BIO_clear_retry_flags(bio);
- BIO_set_retry_read(bio);
- return(-1);
- }
- }
- }
- }
- /* we either finished a handshake or ignored the request,
- * 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];
- int alert_descr = s->s3->alert_fragment[1];
-
- s->s3->alert_fragment_len = 0;
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_ALERT, s->s3->alert_fragment, 2, s, s->msg_callback_arg);
-
- if (s->info_callback != NULL)
- cb=s->info_callback;
- else if (s->ctx->info_callback != NULL)
- cb=s->ctx->info_callback;
-
- if (cb != NULL)
- {
- j = (alert_level << 8) | alert_descr;
- cb(s, SSL_CB_READ_ALERT, j);
- }
-
- if (alert_level == 1) /* warning */
- {
- s->s3->warn_alert = alert_descr;
- if (alert_descr == SSL_AD_CLOSE_NOTIFY)
- {
- 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;
- }
+ if (dest_maxlen > 0) {
+ n = dest_maxlen - *dest_len; /* available space in 'dest' */
+ if (rr->length < n)
+ n = rr->length; /* available bytes */
+
+ /* now move 'n' bytes: */
+ while (n-- > 0) {
+ dest[(*dest_len)++] = rr->data[rr->off++];
+ rr->length--;
+ }
+
+ if (*dest_len < dest_maxlen)
+ goto start; /* fragment was too small */
+ }
+ }
+
+ /*-
+ * s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE;
+ * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT.
+ * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
+ */
+
+ /* If we are a client, check for an incoming 'Hello Request': */
+ if ((!s->server) &&
+ (s->s3->handshake_fragment_len >= 4) &&
+ (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+ (s->session != NULL) && (s->session->cipher != NULL)) {
+ s->s3->handshake_fragment_len = 0;
+
+ if ((s->s3->handshake_fragment[1] != 0) ||
+ (s->s3->handshake_fragment[2] != 0) ||
+ (s->s3->handshake_fragment[3] != 0)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
+ goto f_err;
+ }
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+ s->s3->handshake_fragment, 4, s,
+ s->msg_callback_arg);
+
+ 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)) {
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_SSL3_READ_BYTES,
+ SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+ if (s->s3->rbuf.left == 0) { /* no read-ahead left? */
+ BIO *bio;
+ /*
+ * In the case where we try to read application data,
+ * but we trigger an SSL handshake, we return -1 with
+ * the retry option set. Otherwise renegotiation may
+ * cause nasty problems in the blocking world
+ */
+ s->rwstate = SSL_READING;
+ bio = SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return (-1);
+ }
+ }
+ }
+ }
+ /*
+ * we either finished a handshake or ignored the request, 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];
+ int alert_descr = s->s3->alert_fragment[1];
+
+ s->s3->alert_fragment_len = 0;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_ALERT,
+ s->s3->alert_fragment, 2, s, s->msg_callback_arg);
+
+ if (s->info_callback != NULL)
+ cb = s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb = s->ctx->info_callback;
+
+ if (cb != NULL) {
+ j = (alert_level << 8) | alert_descr;
+ cb(s, SSL_CB_READ_ALERT, j);
+ }
+
+ if (alert_level == 1) { /* warning */
+ s->s3->warn_alert = alert_descr;
+ if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+ 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;
+ }