typo: should be OPENSSL_free
[openssl.git] / ssl / d1_clnt.c
index ea36ea448ae361b167b838b0982100428b6fe564..8940abc41fa2824eb2bd9187f2efdc13b2c8cbdd 100644 (file)
@@ -1,7 +1,7 @@
 /* ssl/d1_clnt.c */
-/* 
+/*
  * DTLS implementation written by Nagendra Modadugu
- * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
  */
 /* ====================================================================
  * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
@@ -11,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  * This package is an SSL implementation written
  * by Eric Young (eay@cryptsoft.com).
  * The implementation was written so as to conform with Netscapes SSL.
- * 
+ *
  * This library is free for commercial and non-commercial use as long as
  * the following conditions are aheared to.  The following conditions
  * apply to all code found in this distribution, be it the RC4, RSA,
  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  * included with this distribution is covered by the same copyright terms
  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
+ *
  * Copyright remains Eric Young's, and as such any Copyright notices in
  * the code are not to be removed.
  * If this package is used in a product, Eric Young should be given attribution
  * as the author of the parts of the library used.
  * This can be in the form of a textual message at program startup or
  * in documentation (online or textual) provided with the package.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *     Eric Young (eay@cryptsoft.com)"
  *    The word 'cryptographic' can be left out if the rouines from the library
  *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
+ * 4. If you include any Windows specific code (or a derivative thereof) from
  *    the apps directory (application code) you must include an acknowledgement:
  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- * 
+ *
  * The licence and distribution terms for any publically available version or
  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  * copied and put under another distribution licence
 
 #include <stdio.h>
 #include "ssl_locl.h"
-#ifndef OPENSSL_NO_KRB5
-#include "kssl_lcl.h"
-#endif
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/md5.h>
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
+# include <openssl/dh.h>
 #endif
 
 static const SSL_METHOD *dtls1_get_client_method(int ver);
 static int dtls1_get_hello_verify(SSL *s);
 
 static const SSL_METHOD *dtls1_get_client_method(int ver)
-       {
-       if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
-               return(DTLSv1_client_method());
-       else if (ver == DTLS1_2_VERSION)
-               return(DTLSv1_2_client_method());
-       else
-               return(NULL);
-       }
+{
+    if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
+        return (DTLSv1_client_method());
+    else if (ver == DTLS1_2_VERSION)
+        return (DTLSv1_2_client_method());
+    else
+        return (NULL);
+}
 
 IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
-                       DTLSv1_client_method,
-                       ssl_undefined_function,
-                       dtls1_connect,
-                       dtls1_get_client_method,
-                       DTLSv1_enc_data)
-
-IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
-                       DTLSv1_2_client_method,
-                       ssl_undefined_function,
-                       dtls1_connect,
-                       dtls1_get_client_method,
-                       DTLSv1_2_enc_data)
-
-IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
-                       DTLS_client_method,
-                       ssl_undefined_function,
-                       dtls1_connect,
-                       dtls1_get_client_method,
-                       DTLSv1_2_enc_data)
+                          DTLSv1_client_method,
+                          ssl_undefined_function,
+                          dtls1_connect,
+                          dtls1_get_client_method, DTLSv1_enc_data)
+
+    IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
+                          DTLSv1_2_client_method,
+                          ssl_undefined_function,
+                          dtls1_connect,
+                          dtls1_get_client_method, DTLSv1_2_enc_data)
+
+    IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
+                          DTLS_client_method,
+                          ssl_undefined_function,
+                          dtls1_connect,
+                          dtls1_get_client_method, DTLSv1_2_enc_data)
 
 int dtls1_connect(SSL *s)
-       {
-       BUF_MEM *buf=NULL;
-       unsigned long Time=(unsigned long)time(NULL);
-       void (*cb)(const SSL *ssl,int type,int val)=NULL;
-       int ret= -1;
-       int new_state,state,skip=0;
+{
+    BUF_MEM *buf = NULL;
+    unsigned long Time = (unsigned long)time(NULL);
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+    int ret = -1;
+    int new_state, state, skip = 0;
 #ifndef OPENSSL_NO_SCTP
-       unsigned char sctpauthkey[64];
-       char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+    unsigned char sctpauthkey[64];
+    char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
 #endif
 
-       RAND_add(&Time,sizeof(Time),0);
-       ERR_clear_error();
-       clear_sys_error();
+    RAND_add(&Time, sizeof(Time), 0);
+    ERR_clear_error();
+    clear_sys_error();
+
+    if (s->info_callback != NULL)
+        cb = s->info_callback;
+    else if (s->ctx->info_callback != NULL)
+        cb = s->ctx->info_callback;
 
-       if (s->info_callback != NULL)
-               cb=s->info_callback;
-       else if (s->ctx->info_callback != NULL)
-               cb=s->ctx->info_callback;
-       
-       s->in_handshake++;
-       if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
+    s->in_handshake++;
+    if (!SSL_in_init(s) || SSL_in_before(s)) {
+        if (!SSL_clear(s))
+            return -1;
+    }
 
 #ifndef OPENSSL_NO_SCTP
-       /* Notify SCTP BIO socket to enter handshake
-        * mode and prevent stream identifier other
-        * than 0. Will be ignored if no SCTP is used.
-        */
-       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
+    /*
+     * Notify SCTP BIO socket to enter handshake mode and prevent stream
+     * identifier other than 0. Will be ignored if no SCTP is used.
+     */
+    BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
+             s->in_handshake, NULL);
 #endif
 
 #ifndef OPENSSL_NO_HEARTBEATS
-       /* If we're awaiting a HeartbeatResponse, pretend we
-        * already got and don't await it anymore, because
-        * Heartbeats don't make sense during handshakes anyway.
-        */
-       if (s->tlsext_hb_pending)
-               {
-               dtls1_stop_timer(s);
-               s->tlsext_hb_pending = 0;
-               s->tlsext_hb_seq++;
-               }
+    /*
+     * If we're awaiting a HeartbeatResponse, pretend we already got and
+     * don't await it anymore, because Heartbeats don't make sense during
+     * handshakes anyway.
+     */
+    if (s->tlsext_hb_pending) {
+        dtls1_stop_timer(s);
+        s->tlsext_hb_pending = 0;
+        s->tlsext_hb_seq++;
+    }
 #endif
 
-       for (;;)
-               {
-               state=s->state;
-
-               switch(s->state)
-                       {
-               case SSL_ST_RENEGOTIATE:
-                       s->renegotiate=1;
-                       s->state=SSL_ST_CONNECT;
-                       s->ctx->stats.sess_connect_renegotiate++;
-                       /* break */
-               case SSL_ST_BEFORE:
-               case SSL_ST_CONNECT:
-               case SSL_ST_BEFORE|SSL_ST_CONNECT:
-               case SSL_ST_OK|SSL_ST_CONNECT:
-
-                       s->server=0;
-                       if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
-
-                       if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00) &&
-                           (s->version & 0xff00 ) != (DTLS1_BAD_VER & 0xff00))
-                               {
-                               SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
-                               ret = -1;
-                               goto end;
-                               }
-                               
-                       /* s->version=SSL3_VERSION; */
-                       s->type=SSL_ST_CONNECT;
-
-                       if (s->init_buf == NULL)
-                               {
-                               if ((buf=BUF_MEM_new()) == NULL)
-                                       {
-                                       ret= -1;
-                                       goto end;
-                                       }
-                               if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
-                                       {
-                                       ret= -1;
-                                       goto end;
-                                       }
-                               s->init_buf=buf;
-                               buf=NULL;
-                               }
-
-                       if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
-
-                       /* setup buffing BIO */
-                       if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
-
-                       /* don't push the buffering BIO quite yet */
-
-                       s->state=SSL3_ST_CW_CLNT_HELLO_A;
-                       s->ctx->stats.sess_connect++;
-                       s->init_num=0;
-                       /* mark client_random uninitialized */
-                       memset(s->s3->client_random,0,sizeof(s->s3->client_random));
-                       s->d1->send_cookie = 0;
-                       s->hit = 0;
-                       s->d1->change_cipher_spec_ok = 0;
-                       /* Should have been reset by ssl3_get_finished, too. */
-                       s->s3->change_cipher_spec = 0;
-                       break;
+    for (;;) {
+        state = s->state;
+
+        switch (s->state) {
+        case SSL_ST_RENEGOTIATE:
+            s->renegotiate = 1;
+            s->state = SSL_ST_CONNECT;
+            s->ctx->stats.sess_connect_renegotiate++;
+            /* break */
+        case SSL_ST_BEFORE:
+        case SSL_ST_CONNECT:
+        case SSL_ST_BEFORE | SSL_ST_CONNECT:
+        case SSL_ST_OK | SSL_ST_CONNECT:
+
+            s->server = 0;
+            if (cb != NULL)
+                cb(s, SSL_CB_HANDSHAKE_START, 1);
+
+            if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
+                (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) {
+                SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
+                ret = -1;
+                s->state = SSL_ST_ERR;
+                goto end;
+            }
+
+            /* s->version=SSL3_VERSION; */
+            s->type = SSL_ST_CONNECT;
+
+            if (s->init_buf == NULL) {
+                if ((buf = BUF_MEM_new()) == NULL) {
+                    ret = -1;
+                    s->state = SSL_ST_ERR;
+                    goto end;
+                }
+                if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
+                    ret = -1;
+                    s->state = SSL_ST_ERR;
+                    goto end;
+                }
+                s->init_buf = buf;
+                buf = NULL;
+            }
+
+            if (!ssl3_setup_buffers(s)) {
+                ret = -1;
+                s->state = SSL_ST_ERR;
+                goto end;
+            }
+
+            /* setup buffing BIO */
+            if (!ssl_init_wbio_buffer(s, 0)) {
+                ret = -1;
+                s->state = SSL_ST_ERR;
+                goto end;
+            }
+
+            /* don't push the buffering BIO quite yet */
+
+            s->state = SSL3_ST_CW_CLNT_HELLO_A;
+            s->ctx->stats.sess_connect++;
+            s->init_num = 0;
+            /* mark client_random uninitialized */
+            memset(s->s3->client_random, 0, sizeof(s->s3->client_random));
+            s->d1->send_cookie = 0;
+            s->hit = 0;
+            s->d1->change_cipher_spec_ok = 0;
+            /*
+             * Should have been reset by ssl3_get_finished, too.
+             */
+            s->s3->change_cipher_spec = 0;
+            break;
 
 #ifndef OPENSSL_NO_SCTP
-               case DTLS1_SCTP_ST_CR_READ_SOCK:
-
-                       if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)))
-                       {
-                               s->s3->in_read_app_data=2;
-                               s->rwstate=SSL_READING;
-                               BIO_clear_retry_flags(SSL_get_rbio(s));
-                               BIO_set_retry_read(SSL_get_rbio(s));
-                               ret = -1;
-                               goto end;
-                       }
-
-                       s->state=s->s3->tmp.next_state;
-                       break;
-
-               case DTLS1_SCTP_ST_CW_WRITE_SOCK:
-                       /* read app data until dry event */
-
-                       ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
-                       if (ret < 0) goto end;
-
-                       if (ret == 0)
-                       {
-                               s->s3->in_read_app_data=2;
-                               s->rwstate=SSL_READING;
-                               BIO_clear_retry_flags(SSL_get_rbio(s));
-                               BIO_set_retry_read(SSL_get_rbio(s));
-                               ret = -1;
-                               goto end;
-                       }
-
-                       s->state=s->d1->next_state;
-                       break;
+        case DTLS1_SCTP_ST_CR_READ_SOCK:
+
+            if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+                s->s3->in_read_app_data = 2;
+                s->rwstate = SSL_READING;
+                BIO_clear_retry_flags(SSL_get_rbio(s));
+                BIO_set_retry_read(SSL_get_rbio(s));
+                ret = -1;
+                goto end;
+            }
+
+            s->state = s->s3->tmp.next_state;
+            break;
+
+        case DTLS1_SCTP_ST_CW_WRITE_SOCK:
+            /* read app data until dry event */
+
+            ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+            if (ret < 0)
+                goto end;
+
+            if (ret == 0) {
+                s->s3->in_read_app_data = 2;
+                s->rwstate = SSL_READING;
+                BIO_clear_retry_flags(SSL_get_rbio(s));
+                BIO_set_retry_read(SSL_get_rbio(s));
+                ret = -1;
+                goto end;
+            }
+
+            s->state = s->d1->next_state;
+            break;
 #endif
 
-               case SSL3_ST_CW_CLNT_HELLO_A:
-               case SSL3_ST_CW_CLNT_HELLO_B:
+        case SSL3_ST_CW_CLNT_HELLO_A:
+        case SSL3_ST_CW_CLNT_HELLO_B:
 
-                       s->shutdown=0;
+            s->shutdown = 0;
 
-                       /* every DTLS ClientHello resets Finished MAC */
-                       ssl3_init_finished_mac(s);
+            /* every DTLS ClientHello resets Finished MAC */
+            ssl3_init_finished_mac(s);
 
-                       dtls1_start_timer(s);
-                       ret=ssl3_client_hello(s);
-                       if (ret <= 0) goto end;
+            dtls1_start_timer(s);
+            ret = ssl3_client_hello(s);
+            if (ret <= 0)
+                goto end;
 
-                       if ( s->d1->send_cookie)
-                               {
-                               s->state=SSL3_ST_CW_FLUSH;
-                               s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A;
-                               }
-                       else
-                               s->state=SSL3_ST_CR_SRVR_HELLO_A;
+            if (s->d1->send_cookie) {
+                s->state = SSL3_ST_CW_FLUSH;
+                s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
+            } else
+                s->state = SSL3_ST_CR_SRVR_HELLO_A;
 
-                       s->init_num=0;
+            s->init_num = 0;
 
 #ifndef OPENSSL_NO_SCTP
-                       /* Disable buffering for SCTP */
-                       if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
-                               {
+            /* Disable buffering for SCTP */
+            if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) {
 #endif
-                               /* turn on buffering for the next lot of output */
-                               if (s->bbio != s->wbio)
-                                       s->wbio=BIO_push(s->bbio,s->wbio);
+                /*
+                 * turn on buffering for the next lot of output
+                 */
+                if (s->bbio != s->wbio)
+                    s->wbio = BIO_push(s->bbio, s->wbio);
 #ifndef OPENSSL_NO_SCTP
-                               }
+            }
 #endif
 
-                       break;
+            break;
 
-               case SSL3_ST_CR_SRVR_HELLO_A:
-               case SSL3_ST_CR_SRVR_HELLO_B:
-                       ret=ssl3_get_server_hello(s);
-                       if (ret <= 0) goto end;
-                       else
-                               {
-                               if (s->hit)
-                                       {
+        case SSL3_ST_CR_SRVR_HELLO_A:
+        case SSL3_ST_CR_SRVR_HELLO_B:
+            ret = ssl3_get_server_hello(s);
+            if (ret <= 0)
+                goto end;
+            else {
+                if (s->hit) {
 #ifndef OPENSSL_NO_SCTP
-                                       /* Add new shared key for SCTP-Auth,
-                                        * will be ignored if no SCTP used.
-                                        */
-                                       snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
-                                                DTLS1_SCTP_AUTH_LABEL);
-
-                                       SSL_export_keying_material(s, sctpauthkey,
-                                                                  sizeof(sctpauthkey), labelbuffer,
-                                                                  sizeof(labelbuffer), NULL, 0, 0);
-
-                                       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
-                                                        sizeof(sctpauthkey), sctpauthkey);
+                    /*
+                     * Add new shared key for SCTP-Auth, will be ignored if
+                     * no SCTP used.
+                     */
+                    snprintf((char *)labelbuffer,
+                             sizeof(DTLS1_SCTP_AUTH_LABEL),
+                             DTLS1_SCTP_AUTH_LABEL);
+
+                    SSL_export_keying_material(s, sctpauthkey,
+                                               sizeof(sctpauthkey),
+                                               labelbuffer,
+                                               sizeof(labelbuffer), NULL, 0,
+                                               0);
+
+                    BIO_ctrl(SSL_get_wbio(s),
+                             BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+                             sizeof(sctpauthkey), sctpauthkey);
 #endif
 
-                                       s->state=SSL3_ST_CR_FINISHED_A;
-                                       }
-                               else
-                                       s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
-                               }
-                       s->init_num=0;
-                       break;
-
-               case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
-               case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
-
-                       ret = dtls1_get_hello_verify(s);
-                       if ( ret <= 0)
-                               goto end;
-                       dtls1_stop_timer(s);
-                       if ( s->d1->send_cookie) /* start again, with a cookie */
-                               s->state=SSL3_ST_CW_CLNT_HELLO_A;
-                       else
-                               s->state = SSL3_ST_CR_CERT_A;
-                       s->init_num = 0;
-                       break;
-
-               case SSL3_ST_CR_CERT_A:
-               case SSL3_ST_CR_CERT_B:
-                       /* Check if it is anon DH or PSK */
-                       if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
-                           !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
-                               {
-                               ret=ssl3_get_server_certificate(s);
-                               if (ret <= 0) goto end;
-#ifndef OPENSSL_NO_TLSEXT
-                               if (s->tlsext_status_expected)
-                                       s->state=SSL3_ST_CR_CERT_STATUS_A;
-                               else
-                                       s->state=SSL3_ST_CR_KEY_EXCH_A;
-                               }
-                       else
-                               {
-                               skip = 1;
-                               s->state=SSL3_ST_CR_KEY_EXCH_A;
-                               }
-#else
-                               }
-                       else
-                               skip=1;
+                    s->state = SSL3_ST_CR_FINISHED_A;
+                } else
+                    s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
+            }
+            s->init_num = 0;
+            break;
+
+        case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
+        case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
+
+            ret = dtls1_get_hello_verify(s);
+            if (ret <= 0)
+                goto end;
+            dtls1_stop_timer(s);
+            if (s->d1->send_cookie) /* start again, with a cookie */
+                s->state = SSL3_ST_CW_CLNT_HELLO_A;
+            else
+                s->state = SSL3_ST_CR_CERT_A;
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CR_CERT_A:
+        case SSL3_ST_CR_CERT_B:
+            /* Check if it is anon DH or PSK */
+            if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+                !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
+                ret = ssl3_get_server_certificate(s);
+                if (ret <= 0)
+                    goto end;
+
+                if (s->tlsext_status_expected)
+                    s->state = SSL3_ST_CR_CERT_STATUS_A;
+                else
+                    s->state = SSL3_ST_CR_KEY_EXCH_A;
+            } else {
+                skip = 1;
+                s->state = SSL3_ST_CR_KEY_EXCH_A;
+            }
+
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CR_KEY_EXCH_A:
+        case SSL3_ST_CR_KEY_EXCH_B:
+            ret = ssl3_get_key_exchange(s);
+            if (ret <= 0)
+                goto end;
+            s->state = SSL3_ST_CR_CERT_REQ_A;
+            s->init_num = 0;
+
+            /*
+             * at this point we check that we have the required stuff from
+             * the server
+             */
+            if (!ssl3_check_cert_and_algorithm(s)) {
+                ret = -1;
+                s->state = SSL_ST_ERR;
+                goto end;
+            }
+            break;
+
+        case SSL3_ST_CR_CERT_REQ_A:
+        case SSL3_ST_CR_CERT_REQ_B:
+            ret = ssl3_get_certificate_request(s);
+            if (ret <= 0)
+                goto end;
+            s->state = SSL3_ST_CR_SRVR_DONE_A;
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CR_SRVR_DONE_A:
+        case SSL3_ST_CR_SRVR_DONE_B:
+            ret = ssl3_get_server_done(s);
+            if (ret <= 0)
+                goto end;
+            dtls1_stop_timer(s);
+            if (s->s3->tmp.cert_req)
+                s->s3->tmp.next_state = SSL3_ST_CW_CERT_A;
+            else
+                s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
+            s->init_num = 0;
 
-                       s->state=SSL3_ST_CR_KEY_EXCH_A;
+#ifndef OPENSSL_NO_SCTP
+            if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+                state == SSL_ST_RENEGOTIATE)
+                s->state = DTLS1_SCTP_ST_CR_READ_SOCK;
+            else
 #endif
-                       s->init_num=0;
-                       break;
-
-               case SSL3_ST_CR_KEY_EXCH_A:
-               case SSL3_ST_CR_KEY_EXCH_B:
-                       ret=ssl3_get_key_exchange(s);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CR_CERT_REQ_A;
-                       s->init_num=0;
-
-                       /* at this point we check that we have the
-                        * required stuff from the server */
-                       if (!ssl3_check_cert_and_algorithm(s))
-                               {
-                               ret= -1;
-                               goto end;
-                               }
-                       break;
-
-               case SSL3_ST_CR_CERT_REQ_A:
-               case SSL3_ST_CR_CERT_REQ_B:
-                       ret=ssl3_get_certificate_request(s);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CR_SRVR_DONE_A;
-                       s->init_num=0;
-                       break;
-
-               case SSL3_ST_CR_SRVR_DONE_A:
-               case SSL3_ST_CR_SRVR_DONE_B:
-                       ret=ssl3_get_server_done(s);
-                       if (ret <= 0) goto end;
-                       dtls1_stop_timer(s);
-                       if (s->s3->tmp.cert_req)
-                               s->s3->tmp.next_state=SSL3_ST_CW_CERT_A;
-                       else
-                               s->s3->tmp.next_state=SSL3_ST_CW_KEY_EXCH_A;
-                       s->init_num=0;
-
-#ifndef OPENSSL_NO_SCTP                        
-                       if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
-                           state == SSL_ST_RENEGOTIATE)
-                               s->state=DTLS1_SCTP_ST_CR_READ_SOCK;
-                       else
-#endif                 
-                       s->state=s->s3->tmp.next_state;
-                       break;
-
-               case SSL3_ST_CW_CERT_A:
-               case SSL3_ST_CW_CERT_B:
-               case SSL3_ST_CW_CERT_C:
-               case SSL3_ST_CW_CERT_D:
-                       dtls1_start_timer(s);
-                       ret=ssl3_send_client_certificate(s);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CW_KEY_EXCH_A;
-                       s->init_num=0;
-                       break;
-
-               case SSL3_ST_CW_KEY_EXCH_A:
-               case SSL3_ST_CW_KEY_EXCH_B:
-                       dtls1_start_timer(s);
-                       ret=ssl3_send_client_key_exchange(s);
-                       if (ret <= 0) goto end;
+                s->state = s->s3->tmp.next_state;
+            break;
+
+        case SSL3_ST_CW_CERT_A:
+        case SSL3_ST_CW_CERT_B:
+        case SSL3_ST_CW_CERT_C:
+        case SSL3_ST_CW_CERT_D:
+            dtls1_start_timer(s);
+            ret = ssl3_send_client_certificate(s);
+            if (ret <= 0)
+                goto end;
+            s->state = SSL3_ST_CW_KEY_EXCH_A;
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CW_KEY_EXCH_A:
+        case SSL3_ST_CW_KEY_EXCH_B:
+            dtls1_start_timer(s);
+            ret = ssl3_send_client_key_exchange(s);
+            if (ret <= 0)
+                goto end;
 
 #ifndef OPENSSL_NO_SCTP
-                       /* Add new shared key for SCTP-Auth,
-                        * will be ignored if no SCTP used.
-                        */
-                       snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
-                                DTLS1_SCTP_AUTH_LABEL);
-
-                       SSL_export_keying_material(s, sctpauthkey,
-                                                  sizeof(sctpauthkey), labelbuffer,
-                                                  sizeof(labelbuffer), NULL, 0, 0);
-
-                       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
-                                        sizeof(sctpauthkey), sctpauthkey);
+            /*
+             * Add new shared key for SCTP-Auth, will be ignored if no SCTP
+             * used.
+             */
+            snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
+                     DTLS1_SCTP_AUTH_LABEL);
+
+            SSL_export_keying_material(s, sctpauthkey,
+                                       sizeof(sctpauthkey), labelbuffer,
+                                       sizeof(labelbuffer), NULL, 0, 0);
+
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+                     sizeof(sctpauthkey), sctpauthkey);
 #endif
 
-                       /* EAY EAY EAY need to check for DH fix cert
-                        * sent back */
-                       /* For TLS, cert_req is set to 2, so a cert chain
-                        * of nothing is sent, but no verify packet is sent */
-                       if (s->s3->tmp.cert_req == 1)
-                               {
-                               s->state=SSL3_ST_CW_CERT_VRFY_A;
-                               }
-                       else
-                               {
+            /*
+             * EAY EAY EAY need to check for DH fix cert sent back
+             */
+            /*
+             * For TLS, cert_req is set to 2, so a cert chain of nothing is
+             * sent, but no verify packet is sent
+             */
+            if (s->s3->tmp.cert_req == 1) {
+                s->state = SSL3_ST_CW_CERT_VRFY_A;
+            } else {
 #ifndef OPENSSL_NO_SCTP
-                               if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
-                                       {
-                                       s->d1->next_state=SSL3_ST_CW_CHANGE_A;
-                                       s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
-                                       }
-                               else
+                if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+                    s->d1->next_state = SSL3_ST_CW_CHANGE_A;
+                    s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
+                } else
 #endif
-                                       s->state=SSL3_ST_CW_CHANGE_A;
-                               }
-
-                       s->init_num=0;
-                       break;
-
-               case SSL3_ST_CW_CERT_VRFY_A:
-               case SSL3_ST_CW_CERT_VRFY_B:
-                       dtls1_start_timer(s);
-                       ret=ssl3_send_client_verify(s);
-                       if (ret <= 0) goto end;
+                    s->state = SSL3_ST_CW_CHANGE_A;
+            }
+
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CW_CERT_VRFY_A:
+        case SSL3_ST_CW_CERT_VRFY_B:
+            dtls1_start_timer(s);
+            ret = ssl3_send_client_verify(s);
+            if (ret <= 0)
+                goto end;
 #ifndef OPENSSL_NO_SCTP
-                       if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
-                       {
-                               s->d1->next_state=SSL3_ST_CW_CHANGE_A;
-                               s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
-                       }
-                       else
+            if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+                s->d1->next_state = SSL3_ST_CW_CHANGE_A;
+                s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
+            } else
 #endif
-                               s->state=SSL3_ST_CW_CHANGE_A;
-                       s->init_num=0;
-                       break;
-
-               case SSL3_ST_CW_CHANGE_A:
-               case SSL3_ST_CW_CHANGE_B:
-                       if (!s->hit)
-                               dtls1_start_timer(s);
-                       ret=dtls1_send_change_cipher_spec(s,
-                               SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
-                       if (ret <= 0) goto end;
-
-                       s->state=SSL3_ST_CW_FINISHED_A;
-                       s->init_num=0;
-
-                       s->session->cipher=s->s3->tmp.new_cipher;
+                s->state = SSL3_ST_CW_CHANGE_A;
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CW_CHANGE_A:
+        case SSL3_ST_CW_CHANGE_B:
+            if (!s->hit)
+                dtls1_start_timer(s);
+            ret = dtls1_send_change_cipher_spec(s,
+                                                SSL3_ST_CW_CHANGE_A,
+                                                SSL3_ST_CW_CHANGE_B);
+            if (ret <= 0)
+                goto end;
+
+            s->state = SSL3_ST_CW_FINISHED_A;
+            s->init_num = 0;
+
+            s->session->cipher = s->s3->tmp.new_cipher;
 #ifdef OPENSSL_NO_COMP
-                       s->session->compress_meth=0;
+            s->session->compress_meth = 0;
 #else
-                       if (s->s3->tmp.new_compression == NULL)
-                               s->session->compress_meth=0;
-                       else
-                               s->session->compress_meth=
-                                       s->s3->tmp.new_compression->id;
+            if (s->s3->tmp.new_compression == NULL)
+                s->session->compress_meth = 0;
+            else
+                s->session->compress_meth = s->s3->tmp.new_compression->id;
 #endif
-                       if (!s->method->ssl3_enc->setup_key_block(s))
-                               {
-                               ret= -1;
-                               goto end;
-                               }
-
-                       if (!s->method->ssl3_enc->change_cipher_state(s,
-                               SSL3_CHANGE_CIPHER_CLIENT_WRITE))
-                               {
-                               ret= -1;
-                               goto end;
-                               }
-                       
+            if (!s->method->ssl3_enc->setup_key_block(s)) {
+                ret = -1;
+                s->state = SSL_ST_ERR;
+                goto end;
+            }
+
+            if (!s->method->ssl3_enc->change_cipher_state(s,
+                                                          SSL3_CHANGE_CIPHER_CLIENT_WRITE))
+            {
+                ret = -1;
+                s->state = SSL_ST_ERR;
+                goto end;
+            }
 #ifndef OPENSSL_NO_SCTP
-                               if (s->hit)
-                                       {
-                                       /* Change to new shared key of SCTP-Auth,
-                                        * will be ignored if no SCTP used.
-                                        */
-                                       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
-                                       }
+            if (s->hit) {
+                /*
+                 * Change to new shared key of SCTP-Auth, will be ignored if
+                 * no SCTP used.
+                 */
+                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
+                         0, NULL);
+            }
 #endif
 
-                       dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
-                       break;
-
-               case SSL3_ST_CW_FINISHED_A:
-               case SSL3_ST_CW_FINISHED_B:
-                       if (!s->hit)
-                               dtls1_start_timer(s);
-                       ret=ssl3_send_finished(s,
-                               SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
-                               s->method->ssl3_enc->client_finished_label,
-                               s->method->ssl3_enc->client_finished_label_len);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CW_FLUSH;
-
-                       /* clear flags */
-                       s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
-                       if (s->hit)
-                               {
-                               s->s3->tmp.next_state=SSL_ST_OK;
+            dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
+            break;
+
+        case SSL3_ST_CW_FINISHED_A:
+        case SSL3_ST_CW_FINISHED_B:
+            if (!s->hit)
+                dtls1_start_timer(s);
+            ret = ssl3_send_finished(s,
+                                     SSL3_ST_CW_FINISHED_A,
+                                     SSL3_ST_CW_FINISHED_B,
+                                     s->method->
+                                     ssl3_enc->client_finished_label,
+                                     s->method->
+                                     ssl3_enc->client_finished_label_len);
+            if (ret <= 0)
+                goto end;
+            s->state = SSL3_ST_CW_FLUSH;
+
+            /* clear flags */
+            s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
+            if (s->hit) {
+                s->s3->tmp.next_state = SSL_ST_OK;
 #ifndef OPENSSL_NO_SCTP
-                               if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
-                                       {
-                                               s->d1->next_state = s->s3->tmp.next_state;
-                                               s->s3->tmp.next_state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
-                                       }
+                if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+                    s->d1->next_state = s->s3->tmp.next_state;
+                    s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
+                }
 #endif
-                               if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
-                                       {
-                                       s->state=SSL_ST_OK;
+                if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) {
+                    s->state = SSL_ST_OK;
 #ifndef OPENSSL_NO_SCTP
-                                       if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
-                                               {
-                                                       s->d1->next_state = SSL_ST_OK;
-                                                       s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
-                                               }
+                    if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+                        s->d1->next_state = SSL_ST_OK;
+                        s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
+                    }
 #endif
-                                       s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
-                                       s->s3->delay_buf_pop_ret=0;
-                                       }
-                               }
-                       else
-                               {
+                    s->s3->flags |= SSL3_FLAGS_POP_BUFFER;
+                    s->s3->delay_buf_pop_ret = 0;
+                }
+            } else {
 #ifndef OPENSSL_NO_SCTP
-                               /* Change to new shared key of SCTP-Auth,
-                                * will be ignored if no SCTP used.
-                                */
-                               BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
-#endif
-
-#ifndef OPENSSL_NO_TLSEXT
-                               /* Allow NewSessionTicket if ticket expected */
-                               if (s->tlsext_ticket_expected)
-                                       s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
-                               else
+                /*
+                 * Change to new shared key of SCTP-Auth, will be ignored if
+                 * no SCTP used.
+                 */
+                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
+                         0, NULL);
 #endif
-                               
-                               s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
-                               }
-                       s->init_num=0;
-                       break;
-
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_CR_SESSION_TICKET_A:
-               case SSL3_ST_CR_SESSION_TICKET_B:
-                       ret=ssl3_get_new_session_ticket(s);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CR_FINISHED_A;
-                       s->init_num=0;
-               break;
-
-               case SSL3_ST_CR_CERT_STATUS_A:
-               case SSL3_ST_CR_CERT_STATUS_B:
-                       ret=ssl3_get_cert_status(s);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CR_KEY_EXCH_A;
-                       s->init_num=0;
-               break;
-#endif
-
-               case SSL3_ST_CR_FINISHED_A:
-               case SSL3_ST_CR_FINISHED_B:
-                       s->d1->change_cipher_spec_ok = 1;
-                       ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
-                               SSL3_ST_CR_FINISHED_B);
-                       if (ret <= 0) goto end;
-                       dtls1_stop_timer(s);
 
-                       if (s->hit)
-                               s->state=SSL3_ST_CW_CHANGE_A;
-                       else
-                               s->state=SSL_ST_OK;
+                /*
+                 * Allow NewSessionTicket if ticket expected
+                 */
+                if (s->tlsext_ticket_expected)
+                    s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
+                else
+                    s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A;
+            }
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CR_SESSION_TICKET_A:
+        case SSL3_ST_CR_SESSION_TICKET_B:
+            ret = ssl3_get_new_session_ticket(s);
+            if (ret <= 0)
+                goto end;
+            s->state = SSL3_ST_CR_FINISHED_A;
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CR_CERT_STATUS_A:
+        case SSL3_ST_CR_CERT_STATUS_B:
+            ret = ssl3_get_cert_status(s);
+            if (ret <= 0)
+                goto end;
+            s->state = SSL3_ST_CR_KEY_EXCH_A;
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CR_FINISHED_A:
+        case SSL3_ST_CR_FINISHED_B:
+            s->d1->change_cipher_spec_ok = 1;
+            ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A,
+                                    SSL3_ST_CR_FINISHED_B);
+            if (ret <= 0)
+                goto end;
+            dtls1_stop_timer(s);
+
+            if (s->hit)
+                s->state = SSL3_ST_CW_CHANGE_A;
+            else
+                s->state = SSL_ST_OK;
 
 #ifndef OPENSSL_NO_SCTP
-                       if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
-                               state == SSL_ST_RENEGOTIATE)
-                               {
-                               s->d1->next_state=s->state;
-                               s->state=DTLS1_SCTP_ST_CW_WRITE_SOCK;
-                               }
+            if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+                state == SSL_ST_RENEGOTIATE) {
+                s->d1->next_state = s->state;
+                s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
+            }
 #endif
 
-                       s->init_num=0;
-                       break;
-
-               case SSL3_ST_CW_FLUSH:
-                       s->rwstate=SSL_WRITING;
-                       if (BIO_flush(s->wbio) <= 0)
-                               {
-                               /* If the write error was fatal, stop trying */
-                               if (!BIO_should_retry(s->wbio))
-                                       {
-                                       s->rwstate=SSL_NOTHING;
-                                       s->state=s->s3->tmp.next_state;
-                                       }
-                               
-                               ret= -1;
-                               goto end;
-                               }
-                       s->rwstate=SSL_NOTHING;
-                       s->state=s->s3->tmp.next_state;
-                       break;
-
-               case SSL_ST_OK:
-                       /* clean a few things up */
-                       ssl3_cleanup_key_block(s);
-
-#if 0
-                       if (s->init_buf != NULL)
-                               {
-                               BUF_MEM_free(s->init_buf);
-                               s->init_buf=NULL;
-                               }
-#endif
+            s->init_num = 0;
+            break;
+
+        case SSL3_ST_CW_FLUSH:
+            s->rwstate = SSL_WRITING;
+            if (BIO_flush(s->wbio) <= 0) {
+                /*
+                 * If the write error was fatal, stop trying
+                 */
+                if (!BIO_should_retry(s->wbio)) {
+                    s->rwstate = SSL_NOTHING;
+                    s->state = s->s3->tmp.next_state;
+                }
+
+                ret = -1;
+                goto end;
+            }
+            s->rwstate = SSL_NOTHING;
+            s->state = s->s3->tmp.next_state;
+            break;
+
+        case SSL_ST_OK:
+            /* clean a few things up */
+            ssl3_cleanup_key_block(s);
+
+            /*
+             * If we are not 'joining' the last two packets, remove the
+             * buffering now
+             */
+            if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
+                ssl_free_wbio_buffer(s);
+            /* else do it later in ssl3_write */
+
+            s->init_num = 0;
+            s->renegotiate = 0;
+            s->new_session = 0;
+
+            ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+            if (s->hit)
+                s->ctx->stats.sess_hit++;
+
+            ret = 1;
+            /* s->server=0; */
+            s->handshake_func = dtls1_connect;
+            s->ctx->stats.sess_connect_good++;
+
+            if (cb != NULL)
+                cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+
+            /* done with handshaking */
+            s->d1->handshake_read_seq = 0;
+            s->d1->next_handshake_write_seq = 0;
+            goto end;
+            /* break; */
+
+        case SSL_ST_ERR:
+        default:
+            SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE);
+            ret = -1;
+            goto end;
+            /* break; */
+        }
+
+        /* did we do anything */
+        if (!s->s3->tmp.reuse_message && !skip) {
+            if (s->debug) {
+                if ((ret = BIO_flush(s->wbio)) <= 0)
+                    goto end;
+            }
+
+            if ((cb != NULL) && (s->state != state)) {
+                new_state = s->state;
+                s->state = state;
+                cb(s, SSL_CB_CONNECT_LOOP, 1);
+                s->state = new_state;
+            }
+        }
+        skip = 0;
+    }
+ end:
+    s->in_handshake--;
 
-                       /* If we are not 'joining' the last two packets,
-                        * remove the buffering now */
-                       if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
-                               ssl_free_wbio_buffer(s);
-                       /* else do it later in ssl3_write */
-
-                       s->init_num=0;
-                       s->renegotiate=0;
-                       s->new_session=0;
-
-                       ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
-                       if (s->hit) s->ctx->stats.sess_hit++;
-
-                       ret=1;
-                       /* s->server=0; */
-                       s->handshake_func=dtls1_connect;
-                       s->ctx->stats.sess_connect_good++;
-
-                       if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
-
-                       /* done with handshaking */
-                       s->d1->handshake_read_seq  = 0;
-                       s->d1->next_handshake_write_seq = 0;
-                       goto end;
-                       /* break; */
-                       
-               default:
-                       SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE);
-                       ret= -1;
-                       goto end;
-                       /* break; */
-                       }
-
-               /* did we do anything */
-               if (!s->s3->tmp.reuse_message && !skip)
-                       {
-                       if (s->debug)
-                               {
-                               if ((ret=BIO_flush(s->wbio)) <= 0)
-                                       goto end;
-                               }
-
-                       if ((cb != NULL) && (s->state != state))
-                               {
-                               new_state=s->state;
-                               s->state=state;
-                               cb(s,SSL_CB_CONNECT_LOOP,1);
-                               s->state=new_state;
-                               }
-                       }
-               skip=0;
-               }
-end:
-       s->in_handshake--;
-       
 #ifndef OPENSSL_NO_SCTP
-       /* Notify SCTP BIO socket to leave handshake
-        * mode and allow stream identifier other
-        * than 0. Will be ignored if no SCTP is used.
-        */
-       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL);
+    /*
+     * Notify SCTP BIO socket to leave handshake mode and allow stream
+     * identifier other than 0. Will be ignored if no SCTP is used.
+     */
+    BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
+             s->in_handshake, NULL);
 #endif
 
-       if (buf != NULL)
-               BUF_MEM_free(buf);
-       if (cb != NULL)
-               cb(s,SSL_CB_CONNECT_EXIT,ret);
-       return(ret);
-       }
+    BUF_MEM_free(buf);
+    if (cb != NULL)
+        cb(s, SSL_CB_CONNECT_EXIT, ret);
+    return (ret);
+}
 
 static int dtls1_get_hello_verify(SSL *s)
-       {
-       int n, al, ok = 0;
-       unsigned char *data;
-       unsigned int cookie_len;
-
-       s->first_packet = 1;
-       n=s->method->ssl_get_message(s,
-               DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
-               DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
-               -1,
-               s->max_cert_list,
-               &ok);
-       s->first_packet = 0;
-
-       if (!ok) return((int)n);
-
-       if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST)
-               {
-               s->d1->send_cookie = 0;
-               s->s3->tmp.reuse_message=1;
-               return(1);
-               }
-
-       data = (unsigned char *)s->init_msg;
-#if 0
-       if (s->method->version != DTLS_ANY_VERSION &&
-               ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff))))
-               {
-               SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION);
-               s->version=(s->version&0xff00)|data[1];
-               al = SSL_AD_PROTOCOL_VERSION;
-               goto f_err;
-               }
-#endif
-       data+=2;
-
-       cookie_len = *(data++);
-       if ( cookie_len > sizeof(s->d1->cookie))
-               {
-               al=SSL_AD_ILLEGAL_PARAMETER;
-               goto f_err;
-               }
-
-       memcpy(s->d1->cookie, data, cookie_len);
-       s->d1->cookie_len = cookie_len;
-
-       s->d1->send_cookie = 1;
-       return 1;
-
-f_err:
-       ssl3_send_alert(s, SSL3_AL_FATAL, al);
-       return -1;
-       }
+{
+    int n, al, ok = 0;
+    unsigned char *data;
+    unsigned int cookie_len;
+
+    s->first_packet = 1;
+    n = s->method->ssl_get_message(s,
+                                   DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
+                                   DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
+                                   -1, s->max_cert_list, &ok);
+    s->first_packet = 0;
+
+    if (!ok)
+        return ((int)n);
+
+    if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
+        s->d1->send_cookie = 0;
+        s->s3->tmp.reuse_message = 1;
+        return (1);
+    }
+
+    data = (unsigned char *)s->init_msg;
+    data += 2;
+
+    cookie_len = *(data++);
+    if (cookie_len > sizeof(s->d1->cookie)) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        goto f_err;
+    }
+
+    memcpy(s->d1->cookie, data, cookie_len);
+    s->d1->cookie_len = cookie_len;
+
+    s->d1->send_cookie = 1;
+    return 1;
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    s->state = SSL_ST_ERR;
+    return -1;
+}